OSDN Git Service

* config/i386/i386.md (rex64suffix): New mode attribute.
[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 ;; Mapping of signed max and min
534 (define_code_iterator smaxmin [smax smin])
535
536 ;; Mapping of unsigned max and min
537 (define_code_iterator umaxmin [umax umin])
538
539 ;; Base name for integer and FP insn mnemonic
540 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins") (umax "maxu") (umin "minu")])
541 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
542
543 ;; All single word integer modes.
544 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
545
546 ;; Instruction suffix for integer modes.
547 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
548
549 ;; Register class for integer modes.
550 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
551
552 ;; Immediate operand constraint for integer modes.
553 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
554
555 ;; General operand predicate for integer modes.
556 (define_mode_attr general_operand
557         [(QI "general_operand")
558          (HI "general_operand")
559          (SI "general_operand")
560          (DI "x86_64_general_operand")])
561
562 ;; SSE and x87 SFmode and DFmode floating point modes
563 (define_mode_iterator MODEF [SF DF])
564
565 ;; All x87 floating point modes
566 (define_mode_iterator X87MODEF [SF DF XF])
567
568 ;; All integer modes handled by x87 fisttp operator.
569 (define_mode_iterator X87MODEI [HI SI DI])
570
571 ;; All integer modes handled by integer x87 operators.
572 (define_mode_iterator X87MODEI12 [HI SI])
573
574 ;; All integer modes handled by SSE cvtts?2si* operators.
575 (define_mode_iterator SSEMODEI24 [SI DI])
576
577 ;; SSE asm suffix for floating point modes
578 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
579
580 ;; SSE vector mode corresponding to a scalar mode
581 (define_mode_attr ssevecmode
582   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
583
584 ;; Instruction suffix for REX 64bit operators.
585 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
586 \f
587 ;; Scheduling descriptions
588
589 (include "pentium.md")
590 (include "ppro.md")
591 (include "k6.md")
592 (include "athlon.md")
593 (include "geode.md")
594
595 \f
596 ;; Operand and operator predicates and constraints
597
598 (include "predicates.md")
599 (include "constraints.md")
600
601 \f
602 ;; Compare instructions.
603
604 ;; All compare insns have expanders that save the operands away without
605 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
606 ;; after the cmp) will actually emit the cmpM.
607
608 (define_expand "cmpti"
609   [(set (reg:CC FLAGS_REG)
610         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
611                     (match_operand:TI 1 "x86_64_general_operand" "")))]
612   "TARGET_64BIT"
613 {
614   if (MEM_P (operands[0]) && MEM_P (operands[1]))
615     operands[0] = force_reg (TImode, operands[0]);
616   ix86_compare_op0 = operands[0];
617   ix86_compare_op1 = operands[1];
618   DONE;
619 })
620
621 (define_expand "cmpdi"
622   [(set (reg:CC FLAGS_REG)
623         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
624                     (match_operand:DI 1 "x86_64_general_operand" "")))]
625   ""
626 {
627   if (MEM_P (operands[0]) && MEM_P (operands[1]))
628     operands[0] = force_reg (DImode, operands[0]);
629   ix86_compare_op0 = operands[0];
630   ix86_compare_op1 = operands[1];
631   DONE;
632 })
633
634 (define_expand "cmpsi"
635   [(set (reg:CC FLAGS_REG)
636         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
637                     (match_operand:SI 1 "general_operand" "")))]
638   ""
639 {
640   if (MEM_P (operands[0]) && MEM_P (operands[1]))
641     operands[0] = force_reg (SImode, operands[0]);
642   ix86_compare_op0 = operands[0];
643   ix86_compare_op1 = operands[1];
644   DONE;
645 })
646
647 (define_expand "cmphi"
648   [(set (reg:CC FLAGS_REG)
649         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
650                     (match_operand:HI 1 "general_operand" "")))]
651   ""
652 {
653   if (MEM_P (operands[0]) && MEM_P (operands[1]))
654     operands[0] = force_reg (HImode, operands[0]);
655   ix86_compare_op0 = operands[0];
656   ix86_compare_op1 = operands[1];
657   DONE;
658 })
659
660 (define_expand "cmpqi"
661   [(set (reg:CC FLAGS_REG)
662         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
663                     (match_operand:QI 1 "general_operand" "")))]
664   "TARGET_QIMODE_MATH"
665 {
666   if (MEM_P (operands[0]) && MEM_P (operands[1]))
667     operands[0] = force_reg (QImode, operands[0]);
668   ix86_compare_op0 = operands[0];
669   ix86_compare_op1 = operands[1];
670   DONE;
671 })
672
673 (define_insn "cmpdi_ccno_1_rex64"
674   [(set (reg FLAGS_REG)
675         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
676                  (match_operand:DI 1 "const0_operand" "n,n")))]
677   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
678   "@
679    test{q}\t%0, %0
680    cmp{q}\t{%1, %0|%0, %1}"
681   [(set_attr "type" "test,icmp")
682    (set_attr "length_immediate" "0,1")
683    (set_attr "mode" "DI")])
684
685 (define_insn "*cmpdi_minus_1_rex64"
686   [(set (reg FLAGS_REG)
687         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
688                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
689                  (const_int 0)))]
690   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
691   "cmp{q}\t{%1, %0|%0, %1}"
692   [(set_attr "type" "icmp")
693    (set_attr "mode" "DI")])
694
695 (define_expand "cmpdi_1_rex64"
696   [(set (reg:CC FLAGS_REG)
697         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
698                     (match_operand:DI 1 "general_operand" "")))]
699   "TARGET_64BIT"
700   "")
701
702 (define_insn "cmpdi_1_insn_rex64"
703   [(set (reg FLAGS_REG)
704         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
705                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
706   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707   "cmp{q}\t{%1, %0|%0, %1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "DI")])
710
711
712 (define_insn "*cmpsi_ccno_1"
713   [(set (reg FLAGS_REG)
714         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
715                  (match_operand:SI 1 "const0_operand" "n,n")))]
716   "ix86_match_ccmode (insn, CCNOmode)"
717   "@
718    test{l}\t%0, %0
719    cmp{l}\t{%1, %0|%0, %1}"
720   [(set_attr "type" "test,icmp")
721    (set_attr "length_immediate" "0,1")
722    (set_attr "mode" "SI")])
723
724 (define_insn "*cmpsi_minus_1"
725   [(set (reg FLAGS_REG)
726         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
727                            (match_operand:SI 1 "general_operand" "ri,mr"))
728                  (const_int 0)))]
729   "ix86_match_ccmode (insn, CCGOCmode)"
730   "cmp{l}\t{%1, %0|%0, %1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "SI")])
733
734 (define_expand "cmpsi_1"
735   [(set (reg:CC FLAGS_REG)
736         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
737                     (match_operand:SI 1 "general_operand" "")))]
738   ""
739   "")
740
741 (define_insn "*cmpsi_1_insn"
742   [(set (reg FLAGS_REG)
743         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
744                  (match_operand:SI 1 "general_operand" "ri,mr")))]
745   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
746     && ix86_match_ccmode (insn, CCmode)"
747   "cmp{l}\t{%1, %0|%0, %1}"
748   [(set_attr "type" "icmp")
749    (set_attr "mode" "SI")])
750
751 (define_insn "*cmphi_ccno_1"
752   [(set (reg FLAGS_REG)
753         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
754                  (match_operand:HI 1 "const0_operand" "n,n")))]
755   "ix86_match_ccmode (insn, CCNOmode)"
756   "@
757    test{w}\t%0, %0
758    cmp{w}\t{%1, %0|%0, %1}"
759   [(set_attr "type" "test,icmp")
760    (set_attr "length_immediate" "0,1")
761    (set_attr "mode" "HI")])
762
763 (define_insn "*cmphi_minus_1"
764   [(set (reg FLAGS_REG)
765         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
766                            (match_operand:HI 1 "general_operand" "ri,mr"))
767                  (const_int 0)))]
768   "ix86_match_ccmode (insn, CCGOCmode)"
769   "cmp{w}\t{%1, %0|%0, %1}"
770   [(set_attr "type" "icmp")
771    (set_attr "mode" "HI")])
772
773 (define_insn "*cmphi_1"
774   [(set (reg FLAGS_REG)
775         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
776                  (match_operand:HI 1 "general_operand" "ri,mr")))]
777   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
778    && ix86_match_ccmode (insn, CCmode)"
779   "cmp{w}\t{%1, %0|%0, %1}"
780   [(set_attr "type" "icmp")
781    (set_attr "mode" "HI")])
782
783 (define_insn "*cmpqi_ccno_1"
784   [(set (reg FLAGS_REG)
785         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
786                  (match_operand:QI 1 "const0_operand" "n,n")))]
787   "ix86_match_ccmode (insn, CCNOmode)"
788   "@
789    test{b}\t%0, %0
790    cmp{b}\t{$0, %0|%0, 0}"
791   [(set_attr "type" "test,icmp")
792    (set_attr "length_immediate" "0,1")
793    (set_attr "mode" "QI")])
794
795 (define_insn "*cmpqi_1"
796   [(set (reg FLAGS_REG)
797         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
798                  (match_operand:QI 1 "general_operand" "qi,mq")))]
799   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
800     && ix86_match_ccmode (insn, CCmode)"
801   "cmp{b}\t{%1, %0|%0, %1}"
802   [(set_attr "type" "icmp")
803    (set_attr "mode" "QI")])
804
805 (define_insn "*cmpqi_minus_1"
806   [(set (reg FLAGS_REG)
807         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
808                            (match_operand:QI 1 "general_operand" "qi,mq"))
809                  (const_int 0)))]
810   "ix86_match_ccmode (insn, CCGOCmode)"
811   "cmp{b}\t{%1, %0|%0, %1}"
812   [(set_attr "type" "icmp")
813    (set_attr "mode" "QI")])
814
815 (define_insn "*cmpqi_ext_1"
816   [(set (reg FLAGS_REG)
817         (compare
818           (match_operand:QI 0 "general_operand" "Qm")
819           (subreg:QI
820             (zero_extract:SI
821               (match_operand 1 "ext_register_operand" "Q")
822               (const_int 8)
823               (const_int 8)) 0)))]
824   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
825   "cmp{b}\t{%h1, %0|%0, %h1}"
826   [(set_attr "type" "icmp")
827    (set_attr "mode" "QI")])
828
829 (define_insn "*cmpqi_ext_1_rex64"
830   [(set (reg FLAGS_REG)
831         (compare
832           (match_operand:QI 0 "register_operand" "Q")
833           (subreg:QI
834             (zero_extract:SI
835               (match_operand 1 "ext_register_operand" "Q")
836               (const_int 8)
837               (const_int 8)) 0)))]
838   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
839   "cmp{b}\t{%h1, %0|%0, %h1}"
840   [(set_attr "type" "icmp")
841    (set_attr "mode" "QI")])
842
843 (define_insn "*cmpqi_ext_2"
844   [(set (reg FLAGS_REG)
845         (compare
846           (subreg:QI
847             (zero_extract:SI
848               (match_operand 0 "ext_register_operand" "Q")
849               (const_int 8)
850               (const_int 8)) 0)
851           (match_operand:QI 1 "const0_operand" "n")))]
852   "ix86_match_ccmode (insn, CCNOmode)"
853   "test{b}\t%h0, %h0"
854   [(set_attr "type" "test")
855    (set_attr "length_immediate" "0")
856    (set_attr "mode" "QI")])
857
858 (define_expand "cmpqi_ext_3"
859   [(set (reg:CC FLAGS_REG)
860         (compare:CC
861           (subreg:QI
862             (zero_extract:SI
863               (match_operand 0 "ext_register_operand" "")
864               (const_int 8)
865               (const_int 8)) 0)
866           (match_operand:QI 1 "general_operand" "")))]
867   ""
868   "")
869
870 (define_insn "cmpqi_ext_3_insn"
871   [(set (reg FLAGS_REG)
872         (compare
873           (subreg:QI
874             (zero_extract:SI
875               (match_operand 0 "ext_register_operand" "Q")
876               (const_int 8)
877               (const_int 8)) 0)
878           (match_operand:QI 1 "general_operand" "Qmn")))]
879   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
880   "cmp{b}\t{%1, %h0|%h0, %1}"
881   [(set_attr "type" "icmp")
882    (set_attr "mode" "QI")])
883
884 (define_insn "cmpqi_ext_3_insn_rex64"
885   [(set (reg FLAGS_REG)
886         (compare
887           (subreg:QI
888             (zero_extract:SI
889               (match_operand 0 "ext_register_operand" "Q")
890               (const_int 8)
891               (const_int 8)) 0)
892           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
893   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
894   "cmp{b}\t{%1, %h0|%h0, %1}"
895   [(set_attr "type" "icmp")
896    (set_attr "mode" "QI")])
897
898 (define_insn "*cmpqi_ext_4"
899   [(set (reg FLAGS_REG)
900         (compare
901           (subreg:QI
902             (zero_extract:SI
903               (match_operand 0 "ext_register_operand" "Q")
904               (const_int 8)
905               (const_int 8)) 0)
906           (subreg:QI
907             (zero_extract:SI
908               (match_operand 1 "ext_register_operand" "Q")
909               (const_int 8)
910               (const_int 8)) 0)))]
911   "ix86_match_ccmode (insn, CCmode)"
912   "cmp{b}\t{%h1, %h0|%h0, %h1}"
913   [(set_attr "type" "icmp")
914    (set_attr "mode" "QI")])
915
916 ;; These implement float point compares.
917 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
918 ;; which would allow mix and match FP modes on the compares.  Which is what
919 ;; the old patterns did, but with many more of them.
920
921 (define_expand "cmpxf"
922   [(set (reg:CC FLAGS_REG)
923         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
924                     (match_operand:XF 1 "nonmemory_operand" "")))]
925   "TARGET_80387"
926 {
927   ix86_compare_op0 = operands[0];
928   ix86_compare_op1 = operands[1];
929   DONE;
930 })
931
932 (define_expand "cmp<mode>"
933   [(set (reg:CC FLAGS_REG)
934         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
935                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
936   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
937 {
938   ix86_compare_op0 = operands[0];
939   ix86_compare_op1 = operands[1];
940   DONE;
941 })
942
943 ;; FP compares, step 1:
944 ;; Set the FP condition codes.
945 ;;
946 ;; CCFPmode     compare with exceptions
947 ;; CCFPUmode    compare with no exceptions
948
949 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
950 ;; used to manage the reg stack popping would not be preserved.
951
952 (define_insn "*cmpfp_0"
953   [(set (match_operand:HI 0 "register_operand" "=a")
954         (unspec:HI
955           [(compare:CCFP
956              (match_operand 1 "register_operand" "f")
957              (match_operand 2 "const0_operand" "X"))]
958         UNSPEC_FNSTSW))]
959   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
961   "* return output_fp_compare (insn, operands, 0, 0);"
962   [(set_attr "type" "multi")
963    (set_attr "unit" "i387")
964    (set (attr "mode")
965      (cond [(match_operand:SF 1 "" "")
966               (const_string "SF")
967             (match_operand:DF 1 "" "")
968               (const_string "DF")
969            ]
970            (const_string "XF")))])
971
972 (define_insn_and_split "*cmpfp_0_cc"
973   [(set (reg:CCFP FLAGS_REG)
974         (compare:CCFP
975           (match_operand 1 "register_operand" "f")
976           (match_operand 2 "const0_operand" "X")))
977    (clobber (match_operand:HI 0 "register_operand" "=a"))]
978   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
979    && TARGET_SAHF && !TARGET_CMOVE
980    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
981   "#"
982   "&& reload_completed"
983   [(set (match_dup 0)
984         (unspec:HI
985           [(compare:CCFP (match_dup 1)(match_dup 2))]
986         UNSPEC_FNSTSW))
987    (set (reg:CC FLAGS_REG)
988         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
989   ""
990   [(set_attr "type" "multi")
991    (set_attr "unit" "i387")
992    (set (attr "mode")
993      (cond [(match_operand:SF 1 "" "")
994               (const_string "SF")
995             (match_operand:DF 1 "" "")
996               (const_string "DF")
997            ]
998            (const_string "XF")))])
999
1000 (define_insn "*cmpfp_xf"
1001   [(set (match_operand:HI 0 "register_operand" "=a")
1002         (unspec:HI
1003           [(compare:CCFP
1004              (match_operand:XF 1 "register_operand" "f")
1005              (match_operand:XF 2 "register_operand" "f"))]
1006           UNSPEC_FNSTSW))]
1007   "TARGET_80387"
1008   "* return output_fp_compare (insn, operands, 0, 0);"
1009   [(set_attr "type" "multi")
1010    (set_attr "unit" "i387")
1011    (set_attr "mode" "XF")])
1012
1013 (define_insn_and_split "*cmpfp_xf_cc"
1014   [(set (reg:CCFP FLAGS_REG)
1015         (compare:CCFP
1016           (match_operand:XF 1 "register_operand" "f")
1017           (match_operand:XF 2 "register_operand" "f")))
1018    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1019   "TARGET_80387
1020    && TARGET_SAHF && !TARGET_CMOVE"
1021   "#"
1022   "&& reload_completed"
1023   [(set (match_dup 0)
1024         (unspec:HI
1025           [(compare:CCFP (match_dup 1)(match_dup 2))]
1026         UNSPEC_FNSTSW))
1027    (set (reg:CC FLAGS_REG)
1028         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1029   ""
1030   [(set_attr "type" "multi")
1031    (set_attr "unit" "i387")
1032    (set_attr "mode" "XF")])
1033
1034 (define_insn "*cmpfp_<mode>"
1035   [(set (match_operand:HI 0 "register_operand" "=a")
1036         (unspec:HI
1037           [(compare:CCFP
1038              (match_operand:MODEF 1 "register_operand" "f")
1039              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1040           UNSPEC_FNSTSW))]
1041   "TARGET_80387"
1042   "* return output_fp_compare (insn, operands, 0, 0);"
1043   [(set_attr "type" "multi")
1044    (set_attr "unit" "i387")
1045    (set_attr "mode" "<MODE>")])
1046
1047 (define_insn_and_split "*cmpfp_<mode>_cc"
1048   [(set (reg:CCFP FLAGS_REG)
1049         (compare:CCFP
1050           (match_operand:MODEF 1 "register_operand" "f")
1051           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1052    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1053   "TARGET_80387
1054    && TARGET_SAHF && !TARGET_CMOVE"
1055   "#"
1056   "&& reload_completed"
1057   [(set (match_dup 0)
1058         (unspec:HI
1059           [(compare:CCFP (match_dup 1)(match_dup 2))]
1060         UNSPEC_FNSTSW))
1061    (set (reg:CC FLAGS_REG)
1062         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1063   ""
1064   [(set_attr "type" "multi")
1065    (set_attr "unit" "i387")
1066    (set_attr "mode" "<MODE>")])
1067
1068 (define_insn "*cmpfp_u"
1069   [(set (match_operand:HI 0 "register_operand" "=a")
1070         (unspec:HI
1071           [(compare:CCFPU
1072              (match_operand 1 "register_operand" "f")
1073              (match_operand 2 "register_operand" "f"))]
1074           UNSPEC_FNSTSW))]
1075   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077   "* return output_fp_compare (insn, operands, 0, 1);"
1078   [(set_attr "type" "multi")
1079    (set_attr "unit" "i387")
1080    (set (attr "mode")
1081      (cond [(match_operand:SF 1 "" "")
1082               (const_string "SF")
1083             (match_operand:DF 1 "" "")
1084               (const_string "DF")
1085            ]
1086            (const_string "XF")))])
1087
1088 (define_insn_and_split "*cmpfp_u_cc"
1089   [(set (reg:CCFPU FLAGS_REG)
1090         (compare:CCFPU
1091           (match_operand 1 "register_operand" "f")
1092           (match_operand 2 "register_operand" "f")))
1093    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1094   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1095    && TARGET_SAHF && !TARGET_CMOVE
1096    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097   "#"
1098   "&& reload_completed"
1099   [(set (match_dup 0)
1100         (unspec:HI
1101           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1102         UNSPEC_FNSTSW))
1103    (set (reg:CC FLAGS_REG)
1104         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1105   ""
1106   [(set_attr "type" "multi")
1107    (set_attr "unit" "i387")
1108    (set (attr "mode")
1109      (cond [(match_operand:SF 1 "" "")
1110               (const_string "SF")
1111             (match_operand:DF 1 "" "")
1112               (const_string "DF")
1113            ]
1114            (const_string "XF")))])
1115
1116 (define_insn "*cmpfp_<mode>"
1117   [(set (match_operand:HI 0 "register_operand" "=a")
1118         (unspec:HI
1119           [(compare:CCFP
1120              (match_operand 1 "register_operand" "f")
1121              (match_operator 3 "float_operator"
1122                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1123           UNSPEC_FNSTSW))]
1124   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1125    && TARGET_USE_<MODE>MODE_FIOP
1126    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1127   "* return output_fp_compare (insn, operands, 0, 0);"
1128   [(set_attr "type" "multi")
1129    (set_attr "unit" "i387")
1130    (set_attr "fp_int_src" "true")
1131    (set_attr "mode" "<MODE>")])
1132
1133 (define_insn_and_split "*cmpfp_<mode>_cc"
1134   [(set (reg:CCFP FLAGS_REG)
1135         (compare:CCFP
1136           (match_operand 1 "register_operand" "f")
1137           (match_operator 3 "float_operator"
1138             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1139    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1140   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1141    && TARGET_SAHF && !TARGET_CMOVE
1142    && TARGET_USE_<MODE>MODE_FIOP
1143    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1144   "#"
1145   "&& reload_completed"
1146   [(set (match_dup 0)
1147         (unspec:HI
1148           [(compare:CCFP
1149              (match_dup 1)
1150              (match_op_dup 3 [(match_dup 2)]))]
1151         UNSPEC_FNSTSW))
1152    (set (reg:CC FLAGS_REG)
1153         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1154   ""
1155   [(set_attr "type" "multi")
1156    (set_attr "unit" "i387")
1157    (set_attr "fp_int_src" "true")
1158    (set_attr "mode" "<MODE>")])
1159
1160 ;; FP compares, step 2
1161 ;; Move the fpsw to ax.
1162
1163 (define_insn "x86_fnstsw_1"
1164   [(set (match_operand:HI 0 "register_operand" "=a")
1165         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1166   "TARGET_80387"
1167   "fnstsw\t%0"
1168   [(set_attr "length" "2")
1169    (set_attr "mode" "SI")
1170    (set_attr "unit" "i387")])
1171
1172 ;; FP compares, step 3
1173 ;; Get ax into flags, general case.
1174
1175 (define_insn "x86_sahf_1"
1176   [(set (reg:CC FLAGS_REG)
1177         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1178                    UNSPEC_SAHF))]
1179   "TARGET_SAHF"
1180 {
1181 #ifdef HAVE_AS_IX86_SAHF
1182   return "sahf";
1183 #else
1184   return ".byte\t0x9e";
1185 #endif
1186 }
1187   [(set_attr "length" "1")
1188    (set_attr "athlon_decode" "vector")
1189    (set_attr "amdfam10_decode" "direct")
1190    (set_attr "mode" "SI")])
1191
1192 ;; Pentium Pro can do steps 1 through 3 in one go.
1193 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1194 (define_insn "*cmpfp_i_mixed"
1195   [(set (reg:CCFP FLAGS_REG)
1196         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1197                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1198   "TARGET_MIX_SSE_I387
1199    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1200    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1201   "* return output_fp_compare (insn, operands, 1, 0);"
1202   [(set_attr "type" "fcmp,ssecomi")
1203    (set (attr "mode")
1204      (if_then_else (match_operand:SF 1 "" "")
1205         (const_string "SF")
1206         (const_string "DF")))
1207    (set_attr "athlon_decode" "vector")
1208    (set_attr "amdfam10_decode" "direct")])
1209
1210 (define_insn "*cmpfp_i_sse"
1211   [(set (reg:CCFP FLAGS_REG)
1212         (compare:CCFP (match_operand 0 "register_operand" "x")
1213                       (match_operand 1 "nonimmediate_operand" "xm")))]
1214   "TARGET_SSE_MATH
1215    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1216    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1217   "* return output_fp_compare (insn, operands, 1, 0);"
1218   [(set_attr "type" "ssecomi")
1219    (set (attr "mode")
1220      (if_then_else (match_operand:SF 1 "" "")
1221         (const_string "SF")
1222         (const_string "DF")))
1223    (set_attr "athlon_decode" "vector")
1224    (set_attr "amdfam10_decode" "direct")])
1225
1226 (define_insn "*cmpfp_i_i387"
1227   [(set (reg:CCFP FLAGS_REG)
1228         (compare:CCFP (match_operand 0 "register_operand" "f")
1229                       (match_operand 1 "register_operand" "f")))]
1230   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1231    && TARGET_CMOVE
1232    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1233    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234   "* return output_fp_compare (insn, operands, 1, 0);"
1235   [(set_attr "type" "fcmp")
1236    (set (attr "mode")
1237      (cond [(match_operand:SF 1 "" "")
1238               (const_string "SF")
1239             (match_operand:DF 1 "" "")
1240               (const_string "DF")
1241            ]
1242            (const_string "XF")))
1243    (set_attr "athlon_decode" "vector")
1244    (set_attr "amdfam10_decode" "direct")])
1245
1246 (define_insn "*cmpfp_iu_mixed"
1247   [(set (reg:CCFPU FLAGS_REG)
1248         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1249                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1250   "TARGET_MIX_SSE_I387
1251    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1252    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1253   "* return output_fp_compare (insn, operands, 1, 1);"
1254   [(set_attr "type" "fcmp,ssecomi")
1255    (set (attr "mode")
1256      (if_then_else (match_operand:SF 1 "" "")
1257         (const_string "SF")
1258         (const_string "DF")))
1259    (set_attr "athlon_decode" "vector")
1260    (set_attr "amdfam10_decode" "direct")])
1261
1262 (define_insn "*cmpfp_iu_sse"
1263   [(set (reg:CCFPU FLAGS_REG)
1264         (compare:CCFPU (match_operand 0 "register_operand" "x")
1265                        (match_operand 1 "nonimmediate_operand" "xm")))]
1266   "TARGET_SSE_MATH
1267    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1268    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1269   "* return output_fp_compare (insn, operands, 1, 1);"
1270   [(set_attr "type" "ssecomi")
1271    (set (attr "mode")
1272      (if_then_else (match_operand:SF 1 "" "")
1273         (const_string "SF")
1274         (const_string "DF")))
1275    (set_attr "athlon_decode" "vector")
1276    (set_attr "amdfam10_decode" "direct")])
1277
1278 (define_insn "*cmpfp_iu_387"
1279   [(set (reg:CCFPU FLAGS_REG)
1280         (compare:CCFPU (match_operand 0 "register_operand" "f")
1281                        (match_operand 1 "register_operand" "f")))]
1282   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1283    && TARGET_CMOVE
1284    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1285    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286   "* return output_fp_compare (insn, operands, 1, 1);"
1287   [(set_attr "type" "fcmp")
1288    (set (attr "mode")
1289      (cond [(match_operand:SF 1 "" "")
1290               (const_string "SF")
1291             (match_operand:DF 1 "" "")
1292               (const_string "DF")
1293            ]
1294            (const_string "XF")))
1295    (set_attr "athlon_decode" "vector")
1296    (set_attr "amdfam10_decode" "direct")])
1297 \f
1298 ;; Move instructions.
1299
1300 ;; General case of fullword move.
1301
1302 (define_expand "movsi"
1303   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1304         (match_operand:SI 1 "general_operand" ""))]
1305   ""
1306   "ix86_expand_move (SImode, operands); DONE;")
1307
1308 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1309 ;; general_operand.
1310 ;;
1311 ;; %%% We don't use a post-inc memory reference because x86 is not a
1312 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1313 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1314 ;; targets without our curiosities, and it is just as easy to represent
1315 ;; this differently.
1316
1317 (define_insn "*pushsi2"
1318   [(set (match_operand:SI 0 "push_operand" "=<")
1319         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1320   "!TARGET_64BIT"
1321   "push{l}\t%1"
1322   [(set_attr "type" "push")
1323    (set_attr "mode" "SI")])
1324
1325 ;; For 64BIT abi we always round up to 8 bytes.
1326 (define_insn "*pushsi2_rex64"
1327   [(set (match_operand:SI 0 "push_operand" "=X")
1328         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1329   "TARGET_64BIT"
1330   "push{q}\t%q1"
1331   [(set_attr "type" "push")
1332    (set_attr "mode" "SI")])
1333
1334 (define_insn "*pushsi2_prologue"
1335   [(set (match_operand:SI 0 "push_operand" "=<")
1336         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1337    (clobber (mem:BLK (scratch)))]
1338   "!TARGET_64BIT"
1339   "push{l}\t%1"
1340   [(set_attr "type" "push")
1341    (set_attr "mode" "SI")])
1342
1343 (define_insn "*popsi1_epilogue"
1344   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1345         (mem:SI (reg:SI SP_REG)))
1346    (set (reg:SI SP_REG)
1347         (plus:SI (reg:SI SP_REG) (const_int 4)))
1348    (clobber (mem:BLK (scratch)))]
1349   "!TARGET_64BIT"
1350   "pop{l}\t%0"
1351   [(set_attr "type" "pop")
1352    (set_attr "mode" "SI")])
1353
1354 (define_insn "popsi1"
1355   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1356         (mem:SI (reg:SI SP_REG)))
1357    (set (reg:SI SP_REG)
1358         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1359   "!TARGET_64BIT"
1360   "pop{l}\t%0"
1361   [(set_attr "type" "pop")
1362    (set_attr "mode" "SI")])
1363
1364 (define_insn "*movsi_xor"
1365   [(set (match_operand:SI 0 "register_operand" "=r")
1366         (match_operand:SI 1 "const0_operand" "i"))
1367    (clobber (reg:CC FLAGS_REG))]
1368   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1369   "xor{l}\t%0, %0"
1370   [(set_attr "type" "alu1")
1371    (set_attr "mode" "SI")
1372    (set_attr "length_immediate" "0")])
1373
1374 (define_insn "*movsi_or"
1375   [(set (match_operand:SI 0 "register_operand" "=r")
1376         (match_operand:SI 1 "immediate_operand" "i"))
1377    (clobber (reg:CC FLAGS_REG))]
1378   "reload_completed
1379    && operands[1] == constm1_rtx
1380    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1381 {
1382   operands[1] = constm1_rtx;
1383   return "or{l}\t{%1, %0|%0, %1}";
1384 }
1385   [(set_attr "type" "alu1")
1386    (set_attr "mode" "SI")
1387    (set_attr "length_immediate" "1")])
1388
1389 (define_insn "*movsi_1"
1390   [(set (match_operand:SI 0 "nonimmediate_operand"
1391                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1392         (match_operand:SI 1 "general_operand"
1393                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1394   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1395 {
1396   switch (get_attr_type (insn))
1397     {
1398     case TYPE_SSELOG1:
1399       if (get_attr_mode (insn) == MODE_TI)
1400         return "pxor\t%0, %0";
1401       return "xorps\t%0, %0";
1402
1403     case TYPE_SSEMOV:
1404       switch (get_attr_mode (insn))
1405         {
1406         case MODE_TI:
1407           return "movdqa\t{%1, %0|%0, %1}";
1408         case MODE_V4SF:
1409           return "movaps\t{%1, %0|%0, %1}";
1410         case MODE_SI:
1411           return "movd\t{%1, %0|%0, %1}";
1412         case MODE_SF:
1413           return "movss\t{%1, %0|%0, %1}";
1414         default:
1415           gcc_unreachable ();
1416         }
1417
1418     case TYPE_MMXADD:
1419       return "pxor\t%0, %0";
1420
1421     case TYPE_MMXMOV:
1422       if (get_attr_mode (insn) == MODE_DI)
1423         return "movq\t{%1, %0|%0, %1}";
1424       return "movd\t{%1, %0|%0, %1}";
1425
1426     case TYPE_LEA:
1427       return "lea{l}\t{%1, %0|%0, %1}";
1428
1429     default:
1430       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1431       return "mov{l}\t{%1, %0|%0, %1}";
1432     }
1433 }
1434   [(set (attr "type")
1435      (cond [(eq_attr "alternative" "2")
1436               (const_string "mmxadd")
1437             (eq_attr "alternative" "3,4,5")
1438               (const_string "mmxmov")
1439             (eq_attr "alternative" "6")
1440               (const_string "sselog1")
1441             (eq_attr "alternative" "7,8,9,10,11")
1442               (const_string "ssemov")
1443             (match_operand:DI 1 "pic_32bit_operand" "")
1444               (const_string "lea")
1445            ]
1446            (const_string "imov")))
1447    (set (attr "mode")
1448      (cond [(eq_attr "alternative" "2,3")
1449               (const_string "DI")
1450             (eq_attr "alternative" "6,7")
1451               (if_then_else
1452                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1453                 (const_string "V4SF")
1454                 (const_string "TI"))
1455             (and (eq_attr "alternative" "8,9,10,11")
1456                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1457               (const_string "SF")
1458            ]
1459            (const_string "SI")))])
1460
1461 ;; Stores and loads of ax to arbitrary constant address.
1462 ;; We fake an second form of instruction to force reload to load address
1463 ;; into register when rax is not available
1464 (define_insn "*movabssi_1_rex64"
1465   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1466         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1467   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1468   "@
1469    movabs{l}\t{%1, %P0|%P0, %1}
1470    mov{l}\t{%1, %a0|%a0, %1}"
1471   [(set_attr "type" "imov")
1472    (set_attr "modrm" "0,*")
1473    (set_attr "length_address" "8,0")
1474    (set_attr "length_immediate" "0,*")
1475    (set_attr "memory" "store")
1476    (set_attr "mode" "SI")])
1477
1478 (define_insn "*movabssi_2_rex64"
1479   [(set (match_operand:SI 0 "register_operand" "=a,r")
1480         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1481   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1482   "@
1483    movabs{l}\t{%P1, %0|%0, %P1}
1484    mov{l}\t{%a1, %0|%0, %a1}"
1485   [(set_attr "type" "imov")
1486    (set_attr "modrm" "0,*")
1487    (set_attr "length_address" "8,0")
1488    (set_attr "length_immediate" "0")
1489    (set_attr "memory" "load")
1490    (set_attr "mode" "SI")])
1491
1492 (define_insn "*swapsi"
1493   [(set (match_operand:SI 0 "register_operand" "+r")
1494         (match_operand:SI 1 "register_operand" "+r"))
1495    (set (match_dup 1)
1496         (match_dup 0))]
1497   ""
1498   "xchg{l}\t%1, %0"
1499   [(set_attr "type" "imov")
1500    (set_attr "mode" "SI")
1501    (set_attr "pent_pair" "np")
1502    (set_attr "athlon_decode" "vector")
1503    (set_attr "amdfam10_decode" "double")])
1504
1505 (define_expand "movhi"
1506   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1507         (match_operand:HI 1 "general_operand" ""))]
1508   ""
1509   "ix86_expand_move (HImode, operands); DONE;")
1510
1511 (define_insn "*pushhi2"
1512   [(set (match_operand:HI 0 "push_operand" "=X")
1513         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1514   "!TARGET_64BIT"
1515   "push{l}\t%k1"
1516   [(set_attr "type" "push")
1517    (set_attr "mode" "SI")])
1518
1519 ;; For 64BIT abi we always round up to 8 bytes.
1520 (define_insn "*pushhi2_rex64"
1521   [(set (match_operand:HI 0 "push_operand" "=X")
1522         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1523   "TARGET_64BIT"
1524   "push{q}\t%q1"
1525   [(set_attr "type" "push")
1526    (set_attr "mode" "DI")])
1527
1528 (define_insn "*movhi_1"
1529   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1530         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1531   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1532 {
1533   switch (get_attr_type (insn))
1534     {
1535     case TYPE_IMOVX:
1536       /* movzwl is faster than movw on p2 due to partial word stalls,
1537          though not as fast as an aligned movl.  */
1538       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1539     default:
1540       if (get_attr_mode (insn) == MODE_SI)
1541         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1542       else
1543         return "mov{w}\t{%1, %0|%0, %1}";
1544     }
1545 }
1546   [(set (attr "type")
1547      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1548               (const_string "imov")
1549             (and (eq_attr "alternative" "0")
1550                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1551                           (const_int 0))
1552                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1553                           (const_int 0))))
1554               (const_string "imov")
1555             (and (eq_attr "alternative" "1,2")
1556                  (match_operand:HI 1 "aligned_operand" ""))
1557               (const_string "imov")
1558             (and (ne (symbol_ref "TARGET_MOVX")
1559                      (const_int 0))
1560                  (eq_attr "alternative" "0,2"))
1561               (const_string "imovx")
1562            ]
1563            (const_string "imov")))
1564     (set (attr "mode")
1565       (cond [(eq_attr "type" "imovx")
1566                (const_string "SI")
1567              (and (eq_attr "alternative" "1,2")
1568                   (match_operand:HI 1 "aligned_operand" ""))
1569                (const_string "SI")
1570              (and (eq_attr "alternative" "0")
1571                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1572                            (const_int 0))
1573                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1574                            (const_int 0))))
1575                (const_string "SI")
1576             ]
1577             (const_string "HI")))])
1578
1579 ;; Stores and loads of ax to arbitrary constant address.
1580 ;; We fake an second form of instruction to force reload to load address
1581 ;; into register when rax is not available
1582 (define_insn "*movabshi_1_rex64"
1583   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1584         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1585   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1586   "@
1587    movabs{w}\t{%1, %P0|%P0, %1}
1588    mov{w}\t{%1, %a0|%a0, %1}"
1589   [(set_attr "type" "imov")
1590    (set_attr "modrm" "0,*")
1591    (set_attr "length_address" "8,0")
1592    (set_attr "length_immediate" "0,*")
1593    (set_attr "memory" "store")
1594    (set_attr "mode" "HI")])
1595
1596 (define_insn "*movabshi_2_rex64"
1597   [(set (match_operand:HI 0 "register_operand" "=a,r")
1598         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1599   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1600   "@
1601    movabs{w}\t{%P1, %0|%0, %P1}
1602    mov{w}\t{%a1, %0|%0, %a1}"
1603   [(set_attr "type" "imov")
1604    (set_attr "modrm" "0,*")
1605    (set_attr "length_address" "8,0")
1606    (set_attr "length_immediate" "0")
1607    (set_attr "memory" "load")
1608    (set_attr "mode" "HI")])
1609
1610 (define_insn "*swaphi_1"
1611   [(set (match_operand:HI 0 "register_operand" "+r")
1612         (match_operand:HI 1 "register_operand" "+r"))
1613    (set (match_dup 1)
1614         (match_dup 0))]
1615   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1616   "xchg{l}\t%k1, %k0"
1617   [(set_attr "type" "imov")
1618    (set_attr "mode" "SI")
1619    (set_attr "pent_pair" "np")
1620    (set_attr "athlon_decode" "vector")
1621    (set_attr "amdfam10_decode" "double")])
1622
1623 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1624 (define_insn "*swaphi_2"
1625   [(set (match_operand:HI 0 "register_operand" "+r")
1626         (match_operand:HI 1 "register_operand" "+r"))
1627    (set (match_dup 1)
1628         (match_dup 0))]
1629   "TARGET_PARTIAL_REG_STALL"
1630   "xchg{w}\t%1, %0"
1631   [(set_attr "type" "imov")
1632    (set_attr "mode" "HI")
1633    (set_attr "pent_pair" "np")
1634    (set_attr "athlon_decode" "vector")])
1635
1636 (define_expand "movstricthi"
1637   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1638         (match_operand:HI 1 "general_operand" ""))]
1639   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1640 {
1641   /* Don't generate memory->memory moves, go through a register */
1642   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1643     operands[1] = force_reg (HImode, operands[1]);
1644 })
1645
1646 (define_insn "*movstricthi_1"
1647   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1648         (match_operand:HI 1 "general_operand" "rn,m"))]
1649   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1650    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1651   "mov{w}\t{%1, %0|%0, %1}"
1652   [(set_attr "type" "imov")
1653    (set_attr "mode" "HI")])
1654
1655 (define_insn "*movstricthi_xor"
1656   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1657         (match_operand:HI 1 "const0_operand" "i"))
1658    (clobber (reg:CC FLAGS_REG))]
1659   "reload_completed
1660    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1661   "xor{w}\t%0, %0"
1662   [(set_attr "type" "alu1")
1663    (set_attr "mode" "HI")
1664    (set_attr "length_immediate" "0")])
1665
1666 (define_expand "movqi"
1667   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1668         (match_operand:QI 1 "general_operand" ""))]
1669   ""
1670   "ix86_expand_move (QImode, operands); DONE;")
1671
1672 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1673 ;; "push a byte".  But actually we use pushl, which has the effect
1674 ;; of rounding the amount pushed up to a word.
1675
1676 (define_insn "*pushqi2"
1677   [(set (match_operand:QI 0 "push_operand" "=X")
1678         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1679   "!TARGET_64BIT"
1680   "push{l}\t%k1"
1681   [(set_attr "type" "push")
1682    (set_attr "mode" "SI")])
1683
1684 ;; For 64BIT abi we always round up to 8 bytes.
1685 (define_insn "*pushqi2_rex64"
1686   [(set (match_operand:QI 0 "push_operand" "=X")
1687         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1688   "TARGET_64BIT"
1689   "push{q}\t%q1"
1690   [(set_attr "type" "push")
1691    (set_attr "mode" "DI")])
1692
1693 ;; Situation is quite tricky about when to choose full sized (SImode) move
1694 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1695 ;; partial register dependency machines (such as AMD Athlon), where QImode
1696 ;; moves issue extra dependency and for partial register stalls machines
1697 ;; that don't use QImode patterns (and QImode move cause stall on the next
1698 ;; instruction).
1699 ;;
1700 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1701 ;; register stall machines with, where we use QImode instructions, since
1702 ;; partial register stall can be caused there.  Then we use movzx.
1703 (define_insn "*movqi_1"
1704   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1705         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1706   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1707 {
1708   switch (get_attr_type (insn))
1709     {
1710     case TYPE_IMOVX:
1711       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1712       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1713     default:
1714       if (get_attr_mode (insn) == MODE_SI)
1715         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1716       else
1717         return "mov{b}\t{%1, %0|%0, %1}";
1718     }
1719 }
1720   [(set (attr "type")
1721      (cond [(and (eq_attr "alternative" "5")
1722                  (not (match_operand:QI 1 "aligned_operand" "")))
1723               (const_string "imovx")
1724             (ne (symbol_ref "optimize_size") (const_int 0))
1725               (const_string "imov")
1726             (and (eq_attr "alternative" "3")
1727                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1728                           (const_int 0))
1729                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1730                           (const_int 0))))
1731               (const_string "imov")
1732             (eq_attr "alternative" "3,5")
1733               (const_string "imovx")
1734             (and (ne (symbol_ref "TARGET_MOVX")
1735                      (const_int 0))
1736                  (eq_attr "alternative" "2"))
1737               (const_string "imovx")
1738            ]
1739            (const_string "imov")))
1740    (set (attr "mode")
1741       (cond [(eq_attr "alternative" "3,4,5")
1742                (const_string "SI")
1743              (eq_attr "alternative" "6")
1744                (const_string "QI")
1745              (eq_attr "type" "imovx")
1746                (const_string "SI")
1747              (and (eq_attr "type" "imov")
1748                   (and (eq_attr "alternative" "0,1")
1749                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1750                                 (const_int 0))
1751                             (and (eq (symbol_ref "optimize_size")
1752                                      (const_int 0))
1753                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1754                                      (const_int 0))))))
1755                (const_string "SI")
1756              ;; Avoid partial register stalls when not using QImode arithmetic
1757              (and (eq_attr "type" "imov")
1758                   (and (eq_attr "alternative" "0,1")
1759                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1760                                 (const_int 0))
1761                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1762                                 (const_int 0)))))
1763                (const_string "SI")
1764            ]
1765            (const_string "QI")))])
1766
1767 (define_expand "reload_outqi"
1768   [(parallel [(match_operand:QI 0 "" "=m")
1769               (match_operand:QI 1 "register_operand" "r")
1770               (match_operand:QI 2 "register_operand" "=&q")])]
1771   ""
1772 {
1773   rtx op0, op1, op2;
1774   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1775
1776   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1777   if (! q_regs_operand (op1, QImode))
1778     {
1779       emit_insn (gen_movqi (op2, op1));
1780       op1 = op2;
1781     }
1782   emit_insn (gen_movqi (op0, op1));
1783   DONE;
1784 })
1785
1786 (define_insn "*swapqi_1"
1787   [(set (match_operand:QI 0 "register_operand" "+r")
1788         (match_operand:QI 1 "register_operand" "+r"))
1789    (set (match_dup 1)
1790         (match_dup 0))]
1791   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1792   "xchg{l}\t%k1, %k0"
1793   [(set_attr "type" "imov")
1794    (set_attr "mode" "SI")
1795    (set_attr "pent_pair" "np")
1796    (set_attr "athlon_decode" "vector")
1797    (set_attr "amdfam10_decode" "vector")])
1798
1799 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1800 (define_insn "*swapqi_2"
1801   [(set (match_operand:QI 0 "register_operand" "+q")
1802         (match_operand:QI 1 "register_operand" "+q"))
1803    (set (match_dup 1)
1804         (match_dup 0))]
1805   "TARGET_PARTIAL_REG_STALL"
1806   "xchg{b}\t%1, %0"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")
1809    (set_attr "pent_pair" "np")
1810    (set_attr "athlon_decode" "vector")])
1811
1812 (define_expand "movstrictqi"
1813   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1814         (match_operand:QI 1 "general_operand" ""))]
1815   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1816 {
1817   /* Don't generate memory->memory moves, go through a register.  */
1818   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1819     operands[1] = force_reg (QImode, operands[1]);
1820 })
1821
1822 (define_insn "*movstrictqi_1"
1823   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1824         (match_operand:QI 1 "general_operand" "*qn,m"))]
1825   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1826    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827   "mov{b}\t{%1, %0|%0, %1}"
1828   [(set_attr "type" "imov")
1829    (set_attr "mode" "QI")])
1830
1831 (define_insn "*movstrictqi_xor"
1832   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1833         (match_operand:QI 1 "const0_operand" "i"))
1834    (clobber (reg:CC FLAGS_REG))]
1835   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1836   "xor{b}\t%0, %0"
1837   [(set_attr "type" "alu1")
1838    (set_attr "mode" "QI")
1839    (set_attr "length_immediate" "0")])
1840
1841 (define_insn "*movsi_extv_1"
1842   [(set (match_operand:SI 0 "register_operand" "=R")
1843         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1844                          (const_int 8)
1845                          (const_int 8)))]
1846   ""
1847   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1848   [(set_attr "type" "imovx")
1849    (set_attr "mode" "SI")])
1850
1851 (define_insn "*movhi_extv_1"
1852   [(set (match_operand:HI 0 "register_operand" "=R")
1853         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1854                          (const_int 8)
1855                          (const_int 8)))]
1856   ""
1857   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1858   [(set_attr "type" "imovx")
1859    (set_attr "mode" "SI")])
1860
1861 (define_insn "*movqi_extv_1"
1862   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1863         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1864                          (const_int 8)
1865                          (const_int 8)))]
1866   "!TARGET_64BIT"
1867 {
1868   switch (get_attr_type (insn))
1869     {
1870     case TYPE_IMOVX:
1871       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1872     default:
1873       return "mov{b}\t{%h1, %0|%0, %h1}";
1874     }
1875 }
1876   [(set (attr "type")
1877      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1878                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1879                              (ne (symbol_ref "TARGET_MOVX")
1880                                  (const_int 0))))
1881         (const_string "imovx")
1882         (const_string "imov")))
1883    (set (attr "mode")
1884      (if_then_else (eq_attr "type" "imovx")
1885         (const_string "SI")
1886         (const_string "QI")))])
1887
1888 (define_insn "*movqi_extv_1_rex64"
1889   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1890         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1891                          (const_int 8)
1892                          (const_int 8)))]
1893   "TARGET_64BIT"
1894 {
1895   switch (get_attr_type (insn))
1896     {
1897     case TYPE_IMOVX:
1898       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1899     default:
1900       return "mov{b}\t{%h1, %0|%0, %h1}";
1901     }
1902 }
1903   [(set (attr "type")
1904      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1905                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1906                              (ne (symbol_ref "TARGET_MOVX")
1907                                  (const_int 0))))
1908         (const_string "imovx")
1909         (const_string "imov")))
1910    (set (attr "mode")
1911      (if_then_else (eq_attr "type" "imovx")
1912         (const_string "SI")
1913         (const_string "QI")))])
1914
1915 ;; Stores and loads of ax to arbitrary constant address.
1916 ;; We fake an second form of instruction to force reload to load address
1917 ;; into register when rax is not available
1918 (define_insn "*movabsqi_1_rex64"
1919   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1920         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1921   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1922   "@
1923    movabs{b}\t{%1, %P0|%P0, %1}
1924    mov{b}\t{%1, %a0|%a0, %1}"
1925   [(set_attr "type" "imov")
1926    (set_attr "modrm" "0,*")
1927    (set_attr "length_address" "8,0")
1928    (set_attr "length_immediate" "0,*")
1929    (set_attr "memory" "store")
1930    (set_attr "mode" "QI")])
1931
1932 (define_insn "*movabsqi_2_rex64"
1933   [(set (match_operand:QI 0 "register_operand" "=a,r")
1934         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1935   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1936   "@
1937    movabs{b}\t{%P1, %0|%0, %P1}
1938    mov{b}\t{%a1, %0|%0, %a1}"
1939   [(set_attr "type" "imov")
1940    (set_attr "modrm" "0,*")
1941    (set_attr "length_address" "8,0")
1942    (set_attr "length_immediate" "0")
1943    (set_attr "memory" "load")
1944    (set_attr "mode" "QI")])
1945
1946 (define_insn "*movdi_extzv_1"
1947   [(set (match_operand:DI 0 "register_operand" "=R")
1948         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1949                          (const_int 8)
1950                          (const_int 8)))]
1951   "TARGET_64BIT"
1952   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1953   [(set_attr "type" "imovx")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movsi_extzv_1"
1957   [(set (match_operand:SI 0 "register_operand" "=R")
1958         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1959                          (const_int 8)
1960                          (const_int 8)))]
1961   ""
1962   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1963   [(set_attr "type" "imovx")
1964    (set_attr "mode" "SI")])
1965
1966 (define_insn "*movqi_extzv_2"
1967   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1968         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1969                                     (const_int 8)
1970                                     (const_int 8)) 0))]
1971   "!TARGET_64BIT"
1972 {
1973   switch (get_attr_type (insn))
1974     {
1975     case TYPE_IMOVX:
1976       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1977     default:
1978       return "mov{b}\t{%h1, %0|%0, %h1}";
1979     }
1980 }
1981   [(set (attr "type")
1982      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1983                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1984                              (ne (symbol_ref "TARGET_MOVX")
1985                                  (const_int 0))))
1986         (const_string "imovx")
1987         (const_string "imov")))
1988    (set (attr "mode")
1989      (if_then_else (eq_attr "type" "imovx")
1990         (const_string "SI")
1991         (const_string "QI")))])
1992
1993 (define_insn "*movqi_extzv_2_rex64"
1994   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1995         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1996                                     (const_int 8)
1997                                     (const_int 8)) 0))]
1998   "TARGET_64BIT"
1999 {
2000   switch (get_attr_type (insn))
2001     {
2002     case TYPE_IMOVX:
2003       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2004     default:
2005       return "mov{b}\t{%h1, %0|%0, %h1}";
2006     }
2007 }
2008   [(set (attr "type")
2009      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2010                         (ne (symbol_ref "TARGET_MOVX")
2011                             (const_int 0)))
2012         (const_string "imovx")
2013         (const_string "imov")))
2014    (set (attr "mode")
2015      (if_then_else (eq_attr "type" "imovx")
2016         (const_string "SI")
2017         (const_string "QI")))])
2018
2019 (define_insn "movsi_insv_1"
2020   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2021                          (const_int 8)
2022                          (const_int 8))
2023         (match_operand:SI 1 "general_operand" "Qmn"))]
2024   "!TARGET_64BIT"
2025   "mov{b}\t{%b1, %h0|%h0, %b1}"
2026   [(set_attr "type" "imov")
2027    (set_attr "mode" "QI")])
2028
2029 (define_insn "*movsi_insv_1_rex64"
2030   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2031                          (const_int 8)
2032                          (const_int 8))
2033         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2034   "TARGET_64BIT"
2035   "mov{b}\t{%b1, %h0|%h0, %b1}"
2036   [(set_attr "type" "imov")
2037    (set_attr "mode" "QI")])
2038
2039 (define_insn "movdi_insv_1_rex64"
2040   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2041                          (const_int 8)
2042                          (const_int 8))
2043         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2044   "TARGET_64BIT"
2045   "mov{b}\t{%b1, %h0|%h0, %b1}"
2046   [(set_attr "type" "imov")
2047    (set_attr "mode" "QI")])
2048
2049 (define_insn "*movqi_insv_2"
2050   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2051                          (const_int 8)
2052                          (const_int 8))
2053         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2054                      (const_int 8)))]
2055   ""
2056   "mov{b}\t{%h1, %h0|%h0, %h1}"
2057   [(set_attr "type" "imov")
2058    (set_attr "mode" "QI")])
2059
2060 (define_expand "movdi"
2061   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2062         (match_operand:DI 1 "general_operand" ""))]
2063   ""
2064   "ix86_expand_move (DImode, operands); DONE;")
2065
2066 (define_insn "*pushdi"
2067   [(set (match_operand:DI 0 "push_operand" "=<")
2068         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2069   "!TARGET_64BIT"
2070   "#")
2071
2072 (define_insn "*pushdi2_rex64"
2073   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2074         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2075   "TARGET_64BIT"
2076   "@
2077    push{q}\t%1
2078    #"
2079   [(set_attr "type" "push,multi")
2080    (set_attr "mode" "DI")])
2081
2082 ;; Convert impossible pushes of immediate to existing instructions.
2083 ;; First try to get scratch register and go through it.  In case this
2084 ;; fails, push sign extended lower part first and then overwrite
2085 ;; upper part by 32bit move.
2086 (define_peephole2
2087   [(match_scratch:DI 2 "r")
2088    (set (match_operand:DI 0 "push_operand" "")
2089         (match_operand:DI 1 "immediate_operand" ""))]
2090   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode)"
2092   [(set (match_dup 2) (match_dup 1))
2093    (set (match_dup 0) (match_dup 2))]
2094   "")
2095
2096 ;; We need to define this as both peepholer and splitter for case
2097 ;; peephole2 pass is not run.
2098 ;; "&& 1" is needed to keep it from matching the previous pattern.
2099 (define_peephole2
2100   [(set (match_operand:DI 0 "push_operand" "")
2101         (match_operand:DI 1 "immediate_operand" ""))]
2102   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2104   [(set (match_dup 0) (match_dup 1))
2105    (set (match_dup 2) (match_dup 3))]
2106   "split_di (operands + 1, 1, operands + 2, operands + 3);
2107    operands[1] = gen_lowpart (DImode, operands[2]);
2108    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2109                                                     GEN_INT (4)));
2110   ")
2111
2112 (define_split
2113   [(set (match_operand:DI 0 "push_operand" "")
2114         (match_operand:DI 1 "immediate_operand" ""))]
2115   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2116                     ? epilogue_completed : reload_completed)
2117    && !symbolic_operand (operands[1], DImode)
2118    && !x86_64_immediate_operand (operands[1], DImode)"
2119   [(set (match_dup 0) (match_dup 1))
2120    (set (match_dup 2) (match_dup 3))]
2121   "split_di (operands + 1, 1, operands + 2, operands + 3);
2122    operands[1] = gen_lowpart (DImode, operands[2]);
2123    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2124                                                     GEN_INT (4)));
2125   ")
2126
2127 (define_insn "*pushdi2_prologue_rex64"
2128   [(set (match_operand:DI 0 "push_operand" "=<")
2129         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2130    (clobber (mem:BLK (scratch)))]
2131   "TARGET_64BIT"
2132   "push{q}\t%1"
2133   [(set_attr "type" "push")
2134    (set_attr "mode" "DI")])
2135
2136 (define_insn "*popdi1_epilogue_rex64"
2137   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2138         (mem:DI (reg:DI SP_REG)))
2139    (set (reg:DI SP_REG)
2140         (plus:DI (reg:DI SP_REG) (const_int 8)))
2141    (clobber (mem:BLK (scratch)))]
2142   "TARGET_64BIT"
2143   "pop{q}\t%0"
2144   [(set_attr "type" "pop")
2145    (set_attr "mode" "DI")])
2146
2147 (define_insn "popdi1"
2148   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2149         (mem:DI (reg:DI SP_REG)))
2150    (set (reg:DI SP_REG)
2151         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2152   "TARGET_64BIT"
2153   "pop{q}\t%0"
2154   [(set_attr "type" "pop")
2155    (set_attr "mode" "DI")])
2156
2157 (define_insn "*movdi_xor_rex64"
2158   [(set (match_operand:DI 0 "register_operand" "=r")
2159         (match_operand:DI 1 "const0_operand" "i"))
2160    (clobber (reg:CC FLAGS_REG))]
2161   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2162    && reload_completed"
2163   "xor{l}\t%k0, %k0";
2164   [(set_attr "type" "alu1")
2165    (set_attr "mode" "SI")
2166    (set_attr "length_immediate" "0")])
2167
2168 (define_insn "*movdi_or_rex64"
2169   [(set (match_operand:DI 0 "register_operand" "=r")
2170         (match_operand:DI 1 "const_int_operand" "i"))
2171    (clobber (reg:CC FLAGS_REG))]
2172   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2173    && reload_completed
2174    && operands[1] == constm1_rtx"
2175 {
2176   operands[1] = constm1_rtx;
2177   return "or{q}\t{%1, %0|%0, %1}";
2178 }
2179   [(set_attr "type" "alu1")
2180    (set_attr "mode" "DI")
2181    (set_attr "length_immediate" "1")])
2182
2183 (define_insn "*movdi_2"
2184   [(set (match_operand:DI 0 "nonimmediate_operand"
2185                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2186         (match_operand:DI 1 "general_operand"
2187                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2188   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189   "@
2190    #
2191    #
2192    pxor\t%0, %0
2193    movq\t{%1, %0|%0, %1}
2194    movq\t{%1, %0|%0, %1}
2195    pxor\t%0, %0
2196    movq\t{%1, %0|%0, %1}
2197    movdqa\t{%1, %0|%0, %1}
2198    movq\t{%1, %0|%0, %1}
2199    xorps\t%0, %0
2200    movlps\t{%1, %0|%0, %1}
2201    movaps\t{%1, %0|%0, %1}
2202    movlps\t{%1, %0|%0, %1}"
2203   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2204    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2205
2206 (define_split
2207   [(set (match_operand:DI 0 "push_operand" "")
2208         (match_operand:DI 1 "general_operand" ""))]
2209   "!TARGET_64BIT && reload_completed
2210    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2211   [(const_int 0)]
2212   "ix86_split_long_move (operands); DONE;")
2213
2214 ;; %%% This multiword shite has got to go.
2215 (define_split
2216   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2217         (match_operand:DI 1 "general_operand" ""))]
2218   "!TARGET_64BIT && reload_completed
2219    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2220    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2221   [(const_int 0)]
2222   "ix86_split_long_move (operands); DONE;")
2223
2224 (define_insn "*movdi_1_rex64"
2225   [(set (match_operand:DI 0 "nonimmediate_operand"
2226           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2227         (match_operand:DI 1 "general_operand"
2228           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2229   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230 {
2231   switch (get_attr_type (insn))
2232     {
2233     case TYPE_SSECVT:
2234       if (SSE_REG_P (operands[0]))
2235         return "movq2dq\t{%1, %0|%0, %1}";
2236       else
2237         return "movdq2q\t{%1, %0|%0, %1}";
2238
2239     case TYPE_SSEMOV:
2240       if (get_attr_mode (insn) == MODE_TI)
2241         return "movdqa\t{%1, %0|%0, %1}";
2242       /* FALLTHRU */
2243
2244     case TYPE_MMXMOV:
2245       /* Moves from and into integer register is done using movd
2246          opcode with REX prefix.  */
2247       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2248         return "movd\t{%1, %0|%0, %1}";
2249       return "movq\t{%1, %0|%0, %1}";
2250
2251     case TYPE_SSELOG1:
2252     case TYPE_MMXADD:
2253       return "pxor\t%0, %0";
2254
2255     case TYPE_MULTI:
2256       return "#";
2257
2258     case TYPE_LEA:
2259       return "lea{q}\t{%a1, %0|%0, %a1}";
2260
2261     default:
2262       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2263       if (get_attr_mode (insn) == MODE_SI)
2264         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2265       else if (which_alternative == 2)
2266         return "movabs{q}\t{%1, %0|%0, %1}";
2267       else
2268         return "mov{q}\t{%1, %0|%0, %1}";
2269     }
2270 }
2271   [(set (attr "type")
2272      (cond [(eq_attr "alternative" "5")
2273               (const_string "mmxadd")
2274             (eq_attr "alternative" "6,7,8,9,10")
2275               (const_string "mmxmov")
2276             (eq_attr "alternative" "11")
2277               (const_string "sselog1")
2278             (eq_attr "alternative" "12,13,14,15,16")
2279               (const_string "ssemov")
2280             (eq_attr "alternative" "17,18")
2281               (const_string "ssecvt")
2282             (eq_attr "alternative" "4")
2283               (const_string "multi")
2284             (match_operand:DI 1 "pic_32bit_operand" "")
2285               (const_string "lea")
2286            ]
2287            (const_string "imov")))
2288    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2289    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2290    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2291
2292 ;; Stores and loads of ax to arbitrary constant address.
2293 ;; We fake an second form of instruction to force reload to load address
2294 ;; into register when rax is not available
2295 (define_insn "*movabsdi_1_rex64"
2296   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2297         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2298   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2299   "@
2300    movabs{q}\t{%1, %P0|%P0, %1}
2301    mov{q}\t{%1, %a0|%a0, %1}"
2302   [(set_attr "type" "imov")
2303    (set_attr "modrm" "0,*")
2304    (set_attr "length_address" "8,0")
2305    (set_attr "length_immediate" "0,*")
2306    (set_attr "memory" "store")
2307    (set_attr "mode" "DI")])
2308
2309 (define_insn "*movabsdi_2_rex64"
2310   [(set (match_operand:DI 0 "register_operand" "=a,r")
2311         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2312   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2313   "@
2314    movabs{q}\t{%P1, %0|%0, %P1}
2315    mov{q}\t{%a1, %0|%0, %a1}"
2316   [(set_attr "type" "imov")
2317    (set_attr "modrm" "0,*")
2318    (set_attr "length_address" "8,0")
2319    (set_attr "length_immediate" "0")
2320    (set_attr "memory" "load")
2321    (set_attr "mode" "DI")])
2322
2323 ;; Convert impossible stores of immediate to existing instructions.
2324 ;; First try to get scratch register and go through it.  In case this
2325 ;; fails, move by 32bit parts.
2326 (define_peephole2
2327   [(match_scratch:DI 2 "r")
2328    (set (match_operand:DI 0 "memory_operand" "")
2329         (match_operand:DI 1 "immediate_operand" ""))]
2330   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2331    && !x86_64_immediate_operand (operands[1], DImode)"
2332   [(set (match_dup 2) (match_dup 1))
2333    (set (match_dup 0) (match_dup 2))]
2334   "")
2335
2336 ;; We need to define this as both peepholer and splitter for case
2337 ;; peephole2 pass is not run.
2338 ;; "&& 1" is needed to keep it from matching the previous pattern.
2339 (define_peephole2
2340   [(set (match_operand:DI 0 "memory_operand" "")
2341         (match_operand:DI 1 "immediate_operand" ""))]
2342   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2343    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2344   [(set (match_dup 2) (match_dup 3))
2345    (set (match_dup 4) (match_dup 5))]
2346   "split_di (operands, 2, operands + 2, operands + 4);")
2347
2348 (define_split
2349   [(set (match_operand:DI 0 "memory_operand" "")
2350         (match_operand:DI 1 "immediate_operand" ""))]
2351   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2352                     ? epilogue_completed : reload_completed)
2353    && !symbolic_operand (operands[1], DImode)
2354    && !x86_64_immediate_operand (operands[1], DImode)"
2355   [(set (match_dup 2) (match_dup 3))
2356    (set (match_dup 4) (match_dup 5))]
2357   "split_di (operands, 2, operands + 2, operands + 4);")
2358
2359 (define_insn "*swapdi_rex64"
2360   [(set (match_operand:DI 0 "register_operand" "+r")
2361         (match_operand:DI 1 "register_operand" "+r"))
2362    (set (match_dup 1)
2363         (match_dup 0))]
2364   "TARGET_64BIT"
2365   "xchg{q}\t%1, %0"
2366   [(set_attr "type" "imov")
2367    (set_attr "mode" "DI")
2368    (set_attr "pent_pair" "np")
2369    (set_attr "athlon_decode" "vector")
2370    (set_attr "amdfam10_decode" "double")])
2371
2372 (define_expand "movti"
2373   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2374         (match_operand:TI 1 "nonimmediate_operand" ""))]
2375   "TARGET_SSE || TARGET_64BIT"
2376 {
2377   if (TARGET_64BIT)
2378     ix86_expand_move (TImode, operands);
2379   else if (push_operand (operands[0], TImode))
2380     ix86_expand_push (TImode, operands[1]);
2381   else
2382     ix86_expand_vector_move (TImode, operands);
2383   DONE;
2384 })
2385
2386 (define_insn "*movti_internal"
2387   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2388         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2389   "TARGET_SSE && !TARGET_64BIT
2390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2391 {
2392   switch (which_alternative)
2393     {
2394     case 0:
2395       if (get_attr_mode (insn) == MODE_V4SF)
2396         return "xorps\t%0, %0";
2397       else
2398         return "pxor\t%0, %0";
2399     case 1:
2400     case 2:
2401       /* TDmode values are passed as TImode on the stack.  Moving them
2402          to stack may result in unaligned memory access.  */
2403       if (misaligned_operand (operands[0], TImode)
2404           || misaligned_operand (operands[1], TImode))
2405         { 
2406           if (get_attr_mode (insn) == MODE_V4SF)
2407             return "movups\t{%1, %0|%0, %1}";
2408          else
2409            return "movdqu\t{%1, %0|%0, %1}";
2410         }
2411       else
2412         { 
2413           if (get_attr_mode (insn) == MODE_V4SF)
2414             return "movaps\t{%1, %0|%0, %1}";
2415          else
2416            return "movdqa\t{%1, %0|%0, %1}";
2417         }
2418     default:
2419       gcc_unreachable ();
2420     }
2421 }
2422   [(set_attr "type" "sselog1,ssemov,ssemov")
2423    (set (attr "mode")
2424         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2425                     (ne (symbol_ref "optimize_size") (const_int 0)))
2426                  (const_string "V4SF")
2427                (and (eq_attr "alternative" "2")
2428                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2429                         (const_int 0)))
2430                  (const_string "V4SF")]
2431               (const_string "TI")))])
2432
2433 (define_insn "*movti_rex64"
2434   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2435         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2436   "TARGET_64BIT
2437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2438 {
2439   switch (which_alternative)
2440     {
2441     case 0:
2442     case 1:
2443       return "#";
2444     case 2:
2445       if (get_attr_mode (insn) == MODE_V4SF)
2446         return "xorps\t%0, %0";
2447       else
2448         return "pxor\t%0, %0";
2449     case 3:
2450     case 4:
2451       /* TDmode values are passed as TImode on the stack.  Moving them
2452          to stack may result in unaligned memory access.  */
2453       if (misaligned_operand (operands[0], TImode)
2454           || misaligned_operand (operands[1], TImode))
2455         { 
2456           if (get_attr_mode (insn) == MODE_V4SF)
2457             return "movups\t{%1, %0|%0, %1}";
2458          else
2459            return "movdqu\t{%1, %0|%0, %1}";
2460         }
2461       else
2462         { 
2463           if (get_attr_mode (insn) == MODE_V4SF)
2464             return "movaps\t{%1, %0|%0, %1}";
2465          else
2466            return "movdqa\t{%1, %0|%0, %1}";
2467         }
2468     default:
2469       gcc_unreachable ();
2470     }
2471 }
2472   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2473    (set (attr "mode")
2474         (cond [(eq_attr "alternative" "2,3")
2475                  (if_then_else
2476                    (ne (symbol_ref "optimize_size")
2477                        (const_int 0))
2478                    (const_string "V4SF")
2479                    (const_string "TI"))
2480                (eq_attr "alternative" "4")
2481                  (if_then_else
2482                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2483                             (const_int 0))
2484                         (ne (symbol_ref "optimize_size")
2485                             (const_int 0)))
2486                    (const_string "V4SF")
2487                    (const_string "TI"))]
2488                (const_string "DI")))])
2489
2490 (define_split
2491   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2492         (match_operand:TI 1 "general_operand" ""))]
2493   "reload_completed && !SSE_REG_P (operands[0])
2494    && !SSE_REG_P (operands[1])"
2495   [(const_int 0)]
2496   "ix86_split_long_move (operands); DONE;")
2497
2498 ;; This expands to what emit_move_complex would generate if we didn't
2499 ;; have a movti pattern.  Having this avoids problems with reload on
2500 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2501 ;; to have around all the time.
2502 (define_expand "movcdi"
2503   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2504         (match_operand:CDI 1 "general_operand" ""))]
2505   ""
2506 {
2507   if (push_operand (operands[0], CDImode))
2508     emit_move_complex_push (CDImode, operands[0], operands[1]);
2509   else
2510     emit_move_complex_parts (operands[0], operands[1]);
2511   DONE;
2512 })
2513
2514 (define_expand "movsf"
2515   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2516         (match_operand:SF 1 "general_operand" ""))]
2517   ""
2518   "ix86_expand_move (SFmode, operands); DONE;")
2519
2520 (define_insn "*pushsf"
2521   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2522         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2523   "!TARGET_64BIT"
2524 {
2525   /* Anything else should be already split before reg-stack.  */
2526   gcc_assert (which_alternative == 1);
2527   return "push{l}\t%1";
2528 }
2529   [(set_attr "type" "multi,push,multi")
2530    (set_attr "unit" "i387,*,*")
2531    (set_attr "mode" "SF,SI,SF")])
2532
2533 (define_insn "*pushsf_rex64"
2534   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2535         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2536   "TARGET_64BIT"
2537 {
2538   /* Anything else should be already split before reg-stack.  */
2539   gcc_assert (which_alternative == 1);
2540   return "push{q}\t%q1";
2541 }
2542   [(set_attr "type" "multi,push,multi")
2543    (set_attr "unit" "i387,*,*")
2544    (set_attr "mode" "SF,DI,SF")])
2545
2546 (define_split
2547   [(set (match_operand:SF 0 "push_operand" "")
2548         (match_operand:SF 1 "memory_operand" ""))]
2549   "reload_completed
2550    && MEM_P (operands[1])
2551    && (operands[2] = find_constant_src (insn))"
2552   [(set (match_dup 0)
2553         (match_dup 2))])
2554
2555
2556 ;; %%% Kill this when call knows how to work this out.
2557 (define_split
2558   [(set (match_operand:SF 0 "push_operand" "")
2559         (match_operand:SF 1 "any_fp_register_operand" ""))]
2560   "!TARGET_64BIT"
2561   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2562    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2563
2564 (define_split
2565   [(set (match_operand:SF 0 "push_operand" "")
2566         (match_operand:SF 1 "any_fp_register_operand" ""))]
2567   "TARGET_64BIT"
2568   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2569    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2570
2571 (define_insn "*movsf_1"
2572   [(set (match_operand:SF 0 "nonimmediate_operand"
2573           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2574         (match_operand:SF 1 "general_operand"
2575           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2576   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2577    && (reload_in_progress || reload_completed
2578        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579        || (!TARGET_SSE_MATH && optimize_size
2580            && standard_80387_constant_p (operands[1]))
2581        || GET_CODE (operands[1]) != CONST_DOUBLE
2582        || memory_operand (operands[0], SFmode))"
2583 {
2584   switch (which_alternative)
2585     {
2586     case 0:
2587     case 1:
2588       return output_387_reg_move (insn, operands);
2589
2590     case 2:
2591       return standard_80387_constant_opcode (operands[1]);
2592
2593     case 3:
2594     case 4:
2595       return "mov{l}\t{%1, %0|%0, %1}";
2596     case 5:
2597       if (get_attr_mode (insn) == MODE_TI)
2598         return "pxor\t%0, %0";
2599       else
2600         return "xorps\t%0, %0";
2601     case 6:
2602       if (get_attr_mode (insn) == MODE_V4SF)
2603         return "movaps\t{%1, %0|%0, %1}";
2604       else
2605         return "movss\t{%1, %0|%0, %1}";
2606     case 7: case 8:
2607       return "movss\t{%1, %0|%0, %1}";
2608
2609     case 9: case 10:
2610     case 12: case 13: case 14: case 15:
2611       return "movd\t{%1, %0|%0, %1}";
2612
2613     case 11:
2614       return "movq\t{%1, %0|%0, %1}";
2615
2616     default:
2617       gcc_unreachable ();
2618     }
2619 }
2620   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2621    (set (attr "mode")
2622         (cond [(eq_attr "alternative" "3,4,9,10")
2623                  (const_string "SI")
2624                (eq_attr "alternative" "5")
2625                  (if_then_else
2626                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2627                                  (const_int 0))
2628                              (ne (symbol_ref "TARGET_SSE2")
2629                                  (const_int 0)))
2630                         (eq (symbol_ref "optimize_size")
2631                             (const_int 0)))
2632                    (const_string "TI")
2633                    (const_string "V4SF"))
2634                /* For architectures resolving dependencies on
2635                   whole SSE registers use APS move to break dependency
2636                   chains, otherwise use short move to avoid extra work.
2637
2638                   Do the same for architectures resolving dependencies on
2639                   the parts.  While in DF mode it is better to always handle
2640                   just register parts, the SF mode is different due to lack
2641                   of instructions to load just part of the register.  It is
2642                   better to maintain the whole registers in single format
2643                   to avoid problems on using packed logical operations.  */
2644                (eq_attr "alternative" "6")
2645                  (if_then_else
2646                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2647                             (const_int 0))
2648                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2649                             (const_int 0)))
2650                    (const_string "V4SF")
2651                    (const_string "SF"))
2652                (eq_attr "alternative" "11")
2653                  (const_string "DI")]
2654                (const_string "SF")))])
2655
2656 (define_insn "*swapsf"
2657   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2658         (match_operand:SF 1 "fp_register_operand" "+f"))
2659    (set (match_dup 1)
2660         (match_dup 0))]
2661   "reload_completed || TARGET_80387"
2662 {
2663   if (STACK_TOP_P (operands[0]))
2664     return "fxch\t%1";
2665   else
2666     return "fxch\t%0";
2667 }
2668   [(set_attr "type" "fxch")
2669    (set_attr "mode" "SF")])
2670
2671 (define_expand "movdf"
2672   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2673         (match_operand:DF 1 "general_operand" ""))]
2674   ""
2675   "ix86_expand_move (DFmode, operands); DONE;")
2676
2677 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2678 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2679 ;; On the average, pushdf using integers can be still shorter.  Allow this
2680 ;; pattern for optimize_size too.
2681
2682 (define_insn "*pushdf_nointeger"
2683   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2684         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2685   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2686 {
2687   /* This insn should be already split before reg-stack.  */
2688   gcc_unreachable ();
2689 }
2690   [(set_attr "type" "multi")
2691    (set_attr "unit" "i387,*,*,*")
2692    (set_attr "mode" "DF,SI,SI,DF")])
2693
2694 (define_insn "*pushdf_integer"
2695   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2696         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2697   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2698 {
2699   /* This insn should be already split before reg-stack.  */
2700   gcc_unreachable ();
2701 }
2702   [(set_attr "type" "multi")
2703    (set_attr "unit" "i387,*,*")
2704    (set_attr "mode" "DF,SI,DF")])
2705
2706 ;; %%% Kill this when call knows how to work this out.
2707 (define_split
2708   [(set (match_operand:DF 0 "push_operand" "")
2709         (match_operand:DF 1 "any_fp_register_operand" ""))]
2710   "!TARGET_64BIT && reload_completed"
2711   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2712    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2713   "")
2714
2715 (define_split
2716   [(set (match_operand:DF 0 "push_operand" "")
2717         (match_operand:DF 1 "any_fp_register_operand" ""))]
2718   "TARGET_64BIT && reload_completed"
2719   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2720    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2721   "")
2722
2723 (define_split
2724   [(set (match_operand:DF 0 "push_operand" "")
2725         (match_operand:DF 1 "general_operand" ""))]
2726   "reload_completed"
2727   [(const_int 0)]
2728   "ix86_split_long_move (operands); DONE;")
2729
2730 ;; Moving is usually shorter when only FP registers are used. This separate
2731 ;; movdf pattern avoids the use of integer registers for FP operations
2732 ;; when optimizing for size.
2733
2734 (define_insn "*movdf_nointeger"
2735   [(set (match_operand:DF 0 "nonimmediate_operand"
2736                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2737         (match_operand:DF 1 "general_operand"
2738                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2739   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2740    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2741    && (reload_in_progress || reload_completed
2742        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2743        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2744            && !memory_operand (operands[0], DFmode)
2745            && standard_80387_constant_p (operands[1]))
2746        || GET_CODE (operands[1]) != CONST_DOUBLE
2747        || ((optimize_size
2748             || !TARGET_MEMORY_MISMATCH_STALL
2749             || reload_in_progress || reload_completed)
2750            && memory_operand (operands[0], DFmode)))"
2751 {
2752   switch (which_alternative)
2753     {
2754     case 0:
2755     case 1:
2756       return output_387_reg_move (insn, operands);
2757
2758     case 2:
2759       return standard_80387_constant_opcode (operands[1]);
2760
2761     case 3:
2762     case 4:
2763       return "#";
2764     case 5:
2765       switch (get_attr_mode (insn))
2766         {
2767         case MODE_V4SF:
2768           return "xorps\t%0, %0";
2769         case MODE_V2DF:
2770           return "xorpd\t%0, %0";
2771         case MODE_TI:
2772           return "pxor\t%0, %0";
2773         default:
2774           gcc_unreachable ();
2775         }
2776     case 6:
2777     case 7:
2778     case 8:
2779       switch (get_attr_mode (insn))
2780         {
2781         case MODE_V4SF:
2782           return "movaps\t{%1, %0|%0, %1}";
2783         case MODE_V2DF:
2784           return "movapd\t{%1, %0|%0, %1}";
2785         case MODE_TI:
2786           return "movdqa\t{%1, %0|%0, %1}";
2787         case MODE_DI:
2788           return "movq\t{%1, %0|%0, %1}";
2789         case MODE_DF:
2790           return "movsd\t{%1, %0|%0, %1}";
2791         case MODE_V1DF:
2792           return "movlpd\t{%1, %0|%0, %1}";
2793         case MODE_V2SF:
2794           return "movlps\t{%1, %0|%0, %1}";
2795         default:
2796           gcc_unreachable ();
2797         }
2798
2799     default:
2800       gcc_unreachable ();
2801     }
2802 }
2803   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2804    (set (attr "mode")
2805         (cond [(eq_attr "alternative" "0,1,2")
2806                  (const_string "DF")
2807                (eq_attr "alternative" "3,4")
2808                  (const_string "SI")
2809
2810                /* For SSE1, we have many fewer alternatives.  */
2811                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2812                  (cond [(eq_attr "alternative" "5,6")
2813                           (const_string "V4SF")
2814                        ]
2815                    (const_string "V2SF"))
2816
2817                /* xorps is one byte shorter.  */
2818                (eq_attr "alternative" "5")
2819                  (cond [(ne (symbol_ref "optimize_size")
2820                             (const_int 0))
2821                           (const_string "V4SF")
2822                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2823                             (const_int 0))
2824                           (const_string "TI")
2825                        ]
2826                        (const_string "V2DF"))
2827
2828                /* For architectures resolving dependencies on
2829                   whole SSE registers use APD move to break dependency
2830                   chains, otherwise use short move to avoid extra work.
2831
2832                   movaps encodes one byte shorter.  */
2833                (eq_attr "alternative" "6")
2834                  (cond
2835                    [(ne (symbol_ref "optimize_size")
2836                         (const_int 0))
2837                       (const_string "V4SF")
2838                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2839                         (const_int 0))
2840                       (const_string "V2DF")
2841                    ]
2842                    (const_string "DF"))
2843                /* For architectures resolving dependencies on register
2844                   parts we may avoid extra work to zero out upper part
2845                   of register.  */
2846                (eq_attr "alternative" "7")
2847                  (if_then_else
2848                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2849                        (const_int 0))
2850                    (const_string "V1DF")
2851                    (const_string "DF"))
2852               ]
2853               (const_string "DF")))])
2854
2855 (define_insn "*movdf_integer_rex64"
2856   [(set (match_operand:DF 0 "nonimmediate_operand"
2857                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2858         (match_operand:DF 1 "general_operand"
2859                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2860   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2861    && (reload_in_progress || reload_completed
2862        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2863        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2864            && standard_80387_constant_p (operands[1]))
2865        || GET_CODE (operands[1]) != CONST_DOUBLE
2866        || memory_operand (operands[0], DFmode))"
2867 {
2868   switch (which_alternative)
2869     {
2870     case 0:
2871     case 1:
2872       return output_387_reg_move (insn, operands);
2873
2874     case 2:
2875       return standard_80387_constant_opcode (operands[1]);
2876
2877     case 3:
2878     case 4:
2879       return "#";
2880
2881     case 5:
2882       switch (get_attr_mode (insn))
2883         {
2884         case MODE_V4SF:
2885           return "xorps\t%0, %0";
2886         case MODE_V2DF:
2887           return "xorpd\t%0, %0";
2888         case MODE_TI:
2889           return "pxor\t%0, %0";
2890         default:
2891           gcc_unreachable ();
2892         }
2893     case 6:
2894     case 7:
2895     case 8:
2896       switch (get_attr_mode (insn))
2897         {
2898         case MODE_V4SF:
2899           return "movaps\t{%1, %0|%0, %1}";
2900         case MODE_V2DF:
2901           return "movapd\t{%1, %0|%0, %1}";
2902         case MODE_TI:
2903           return "movdqa\t{%1, %0|%0, %1}";
2904         case MODE_DI:
2905           return "movq\t{%1, %0|%0, %1}";
2906         case MODE_DF:
2907           return "movsd\t{%1, %0|%0, %1}";
2908         case MODE_V1DF:
2909           return "movlpd\t{%1, %0|%0, %1}";
2910         case MODE_V2SF:
2911           return "movlps\t{%1, %0|%0, %1}";
2912         default:
2913           gcc_unreachable ();
2914         }
2915
2916     case 9:
2917     case 10:
2918       return "movd\t{%1, %0|%0, %1}";
2919
2920     default:
2921       gcc_unreachable();
2922     }
2923 }
2924   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2925    (set (attr "mode")
2926         (cond [(eq_attr "alternative" "0,1,2")
2927                  (const_string "DF")
2928                (eq_attr "alternative" "3,4,9,10")
2929                  (const_string "DI")
2930
2931                /* For SSE1, we have many fewer alternatives.  */
2932                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2933                  (cond [(eq_attr "alternative" "5,6")
2934                           (const_string "V4SF")
2935                        ]
2936                    (const_string "V2SF"))
2937
2938                /* xorps is one byte shorter.  */
2939                (eq_attr "alternative" "5")
2940                  (cond [(ne (symbol_ref "optimize_size")
2941                             (const_int 0))
2942                           (const_string "V4SF")
2943                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2944                             (const_int 0))
2945                           (const_string "TI")
2946                        ]
2947                        (const_string "V2DF"))
2948
2949                /* For architectures resolving dependencies on
2950                   whole SSE registers use APD move to break dependency
2951                   chains, otherwise use short move to avoid extra work.
2952
2953                   movaps encodes one byte shorter.  */
2954                (eq_attr "alternative" "6")
2955                  (cond
2956                    [(ne (symbol_ref "optimize_size")
2957                         (const_int 0))
2958                       (const_string "V4SF")
2959                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2960                         (const_int 0))
2961                       (const_string "V2DF")
2962                    ]
2963                    (const_string "DF"))
2964                /* For architectures resolving dependencies on register
2965                   parts we may avoid extra work to zero out upper part
2966                   of register.  */
2967                (eq_attr "alternative" "7")
2968                  (if_then_else
2969                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2970                        (const_int 0))
2971                    (const_string "V1DF")
2972                    (const_string "DF"))
2973               ]
2974               (const_string "DF")))])
2975
2976 (define_insn "*movdf_integer"
2977   [(set (match_operand:DF 0 "nonimmediate_operand"
2978                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2979         (match_operand:DF 1 "general_operand"
2980                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2981   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2982    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2983    && (reload_in_progress || reload_completed
2984        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2985        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2986            && standard_80387_constant_p (operands[1]))
2987        || GET_CODE (operands[1]) != CONST_DOUBLE
2988        || memory_operand (operands[0], DFmode))"
2989 {
2990   switch (which_alternative)
2991     {
2992     case 0:
2993     case 1:
2994       return output_387_reg_move (insn, operands);
2995
2996     case 2:
2997       return standard_80387_constant_opcode (operands[1]);
2998
2999     case 3:
3000     case 4:
3001       return "#";
3002
3003     case 5:
3004       switch (get_attr_mode (insn))
3005         {
3006         case MODE_V4SF:
3007           return "xorps\t%0, %0";
3008         case MODE_V2DF:
3009           return "xorpd\t%0, %0";
3010         case MODE_TI:
3011           return "pxor\t%0, %0";
3012         default:
3013           gcc_unreachable ();
3014         }
3015     case 6:
3016     case 7:
3017     case 8:
3018       switch (get_attr_mode (insn))
3019         {
3020         case MODE_V4SF:
3021           return "movaps\t{%1, %0|%0, %1}";
3022         case MODE_V2DF:
3023           return "movapd\t{%1, %0|%0, %1}";
3024         case MODE_TI:
3025           return "movdqa\t{%1, %0|%0, %1}";
3026         case MODE_DI:
3027           return "movq\t{%1, %0|%0, %1}";
3028         case MODE_DF:
3029           return "movsd\t{%1, %0|%0, %1}";
3030         case MODE_V1DF:
3031           return "movlpd\t{%1, %0|%0, %1}";
3032         case MODE_V2SF:
3033           return "movlps\t{%1, %0|%0, %1}";
3034         default:
3035           gcc_unreachable ();
3036         }
3037
3038     default:
3039       gcc_unreachable();
3040     }
3041 }
3042   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3043    (set (attr "mode")
3044         (cond [(eq_attr "alternative" "0,1,2")
3045                  (const_string "DF")
3046                (eq_attr "alternative" "3,4")
3047                  (const_string "SI")
3048
3049                /* For SSE1, we have many fewer alternatives.  */
3050                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3051                  (cond [(eq_attr "alternative" "5,6")
3052                           (const_string "V4SF")
3053                        ]
3054                    (const_string "V2SF"))
3055
3056                /* xorps is one byte shorter.  */
3057                (eq_attr "alternative" "5")
3058                  (cond [(ne (symbol_ref "optimize_size")
3059                             (const_int 0))
3060                           (const_string "V4SF")
3061                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3062                             (const_int 0))
3063                           (const_string "TI")
3064                        ]
3065                        (const_string "V2DF"))
3066
3067                /* For architectures resolving dependencies on
3068                   whole SSE registers use APD move to break dependency
3069                   chains, otherwise use short move to avoid extra work.
3070
3071                   movaps encodes one byte shorter.  */
3072                (eq_attr "alternative" "6")
3073                  (cond
3074                    [(ne (symbol_ref "optimize_size")
3075                         (const_int 0))
3076                       (const_string "V4SF")
3077                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3078                         (const_int 0))
3079                       (const_string "V2DF")
3080                    ]
3081                    (const_string "DF"))
3082                /* For architectures resolving dependencies on register
3083                   parts we may avoid extra work to zero out upper part
3084                   of register.  */
3085                (eq_attr "alternative" "7")
3086                  (if_then_else
3087                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3088                        (const_int 0))
3089                    (const_string "V1DF")
3090                    (const_string "DF"))
3091               ]
3092               (const_string "DF")))])
3093
3094 (define_split
3095   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3096         (match_operand:DF 1 "general_operand" ""))]
3097   "reload_completed
3098    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3099    && ! (ANY_FP_REG_P (operands[0]) ||
3100          (GET_CODE (operands[0]) == SUBREG
3101           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3102    && ! (ANY_FP_REG_P (operands[1]) ||
3103          (GET_CODE (operands[1]) == SUBREG
3104           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3105   [(const_int 0)]
3106   "ix86_split_long_move (operands); DONE;")
3107
3108 (define_insn "*swapdf"
3109   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3110         (match_operand:DF 1 "fp_register_operand" "+f"))
3111    (set (match_dup 1)
3112         (match_dup 0))]
3113   "reload_completed || TARGET_80387"
3114 {
3115   if (STACK_TOP_P (operands[0]))
3116     return "fxch\t%1";
3117   else
3118     return "fxch\t%0";
3119 }
3120   [(set_attr "type" "fxch")
3121    (set_attr "mode" "DF")])
3122
3123 (define_expand "movxf"
3124   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3125         (match_operand:XF 1 "general_operand" ""))]
3126   ""
3127   "ix86_expand_move (XFmode, operands); DONE;")
3128
3129 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3130 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3131 ;; Pushing using integer instructions is longer except for constants
3132 ;; and direct memory references.
3133 ;; (assuming that any given constant is pushed only once, but this ought to be
3134 ;;  handled elsewhere).
3135
3136 (define_insn "*pushxf_nointeger"
3137   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3138         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3139   "optimize_size"
3140 {
3141   /* This insn should be already split before reg-stack.  */
3142   gcc_unreachable ();
3143 }
3144   [(set_attr "type" "multi")
3145    (set_attr "unit" "i387,*,*")
3146    (set_attr "mode" "XF,SI,SI")])
3147
3148 (define_insn "*pushxf_integer"
3149   [(set (match_operand:XF 0 "push_operand" "=<,<")
3150         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3151   "!optimize_size"
3152 {
3153   /* This insn should be already split before reg-stack.  */
3154   gcc_unreachable ();
3155 }
3156   [(set_attr "type" "multi")
3157    (set_attr "unit" "i387,*")
3158    (set_attr "mode" "XF,SI")])
3159
3160 (define_split
3161   [(set (match_operand 0 "push_operand" "")
3162         (match_operand 1 "general_operand" ""))]
3163   "reload_completed
3164    && (GET_MODE (operands[0]) == XFmode
3165        || GET_MODE (operands[0]) == DFmode)
3166    && !ANY_FP_REG_P (operands[1])"
3167   [(const_int 0)]
3168   "ix86_split_long_move (operands); DONE;")
3169
3170 (define_split
3171   [(set (match_operand:XF 0 "push_operand" "")
3172         (match_operand:XF 1 "any_fp_register_operand" ""))]
3173   "!TARGET_64BIT"
3174   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3175    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3176   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3177
3178 (define_split
3179   [(set (match_operand:XF 0 "push_operand" "")
3180         (match_operand:XF 1 "any_fp_register_operand" ""))]
3181   "TARGET_64BIT"
3182   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3183    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3184   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3185
3186 ;; Do not use integer registers when optimizing for size
3187 (define_insn "*movxf_nointeger"
3188   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3189         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3190   "optimize_size
3191    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3192    && (reload_in_progress || reload_completed
3193        || (optimize_size && standard_80387_constant_p (operands[1]))
3194        || GET_CODE (operands[1]) != CONST_DOUBLE
3195        || memory_operand (operands[0], XFmode))"
3196 {
3197   switch (which_alternative)
3198     {
3199     case 0:
3200     case 1:
3201       return output_387_reg_move (insn, operands);
3202
3203     case 2:
3204       return standard_80387_constant_opcode (operands[1]);
3205
3206     case 3: case 4:
3207       return "#";
3208     default:
3209       gcc_unreachable ();
3210     }
3211 }
3212   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3213    (set_attr "mode" "XF,XF,XF,SI,SI")])
3214
3215 (define_insn "*movxf_integer"
3216   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3217         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3218   "!optimize_size
3219    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3220    && (reload_in_progress || reload_completed
3221        || (optimize_size && standard_80387_constant_p (operands[1]))
3222        || GET_CODE (operands[1]) != CONST_DOUBLE
3223        || memory_operand (operands[0], XFmode))"
3224 {
3225   switch (which_alternative)
3226     {
3227     case 0:
3228     case 1:
3229       return output_387_reg_move (insn, operands);
3230
3231     case 2:
3232       return standard_80387_constant_opcode (operands[1]);
3233
3234     case 3: case 4:
3235       return "#";
3236
3237     default:
3238       gcc_unreachable ();
3239     }
3240 }
3241   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3242    (set_attr "mode" "XF,XF,XF,SI,SI")])
3243
3244 (define_expand "movtf"
3245   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3246         (match_operand:TF 1 "nonimmediate_operand" ""))]
3247   "TARGET_64BIT"
3248 {
3249   ix86_expand_move (TFmode, operands);
3250   DONE;
3251 })
3252
3253 (define_insn "*movtf_internal"
3254   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3255         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3256   "TARGET_64BIT
3257    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3258 {
3259   switch (which_alternative)
3260     {
3261     case 0:
3262     case 1:
3263       if (get_attr_mode (insn) == MODE_V4SF)
3264         return "movaps\t{%1, %0|%0, %1}";
3265       else
3266         return "movdqa\t{%1, %0|%0, %1}";
3267     case 2:
3268       if (get_attr_mode (insn) == MODE_V4SF)
3269         return "xorps\t%0, %0";
3270       else
3271         return "pxor\t%0, %0";
3272     case 3:
3273     case 4:
3274         return "#";
3275     default:
3276       gcc_unreachable ();
3277     }
3278 }
3279   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3280    (set (attr "mode")
3281         (cond [(eq_attr "alternative" "0,2")
3282                  (if_then_else
3283                    (ne (symbol_ref "optimize_size")
3284                        (const_int 0))
3285                    (const_string "V4SF")
3286                    (const_string "TI"))
3287                (eq_attr "alternative" "1")
3288                  (if_then_else
3289                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3290                             (const_int 0))
3291                         (ne (symbol_ref "optimize_size")
3292                             (const_int 0)))
3293                    (const_string "V4SF")
3294                    (const_string "TI"))]
3295                (const_string "DI")))])
3296
3297 (define_split
3298   [(set (match_operand 0 "nonimmediate_operand" "")
3299         (match_operand 1 "general_operand" ""))]
3300   "reload_completed
3301    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3302    && GET_MODE (operands[0]) == XFmode
3303    && ! (ANY_FP_REG_P (operands[0]) ||
3304          (GET_CODE (operands[0]) == SUBREG
3305           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3306    && ! (ANY_FP_REG_P (operands[1]) ||
3307          (GET_CODE (operands[1]) == SUBREG
3308           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3309   [(const_int 0)]
3310   "ix86_split_long_move (operands); DONE;")
3311
3312 (define_split
3313   [(set (match_operand 0 "register_operand" "")
3314         (match_operand 1 "memory_operand" ""))]
3315   "reload_completed
3316    && MEM_P (operands[1])
3317    && (GET_MODE (operands[0]) == TFmode
3318        || GET_MODE (operands[0]) == XFmode
3319        || GET_MODE (operands[0]) == SFmode
3320        || GET_MODE (operands[0]) == DFmode)
3321    && (operands[2] = find_constant_src (insn))"
3322   [(set (match_dup 0) (match_dup 2))]
3323 {
3324   rtx c = operands[2];
3325   rtx r = operands[0];
3326
3327   if (GET_CODE (r) == SUBREG)
3328     r = SUBREG_REG (r);
3329
3330   if (SSE_REG_P (r))
3331     {
3332       if (!standard_sse_constant_p (c))
3333         FAIL;
3334     }
3335   else if (FP_REG_P (r))
3336     {
3337       if (!standard_80387_constant_p (c))
3338         FAIL;
3339     }
3340   else if (MMX_REG_P (r))
3341     FAIL;
3342 })
3343
3344 (define_split
3345   [(set (match_operand 0 "register_operand" "")
3346         (float_extend (match_operand 1 "memory_operand" "")))]
3347   "reload_completed
3348    && MEM_P (operands[1])
3349    && (GET_MODE (operands[0]) == TFmode
3350        || GET_MODE (operands[0]) == XFmode
3351        || GET_MODE (operands[0]) == SFmode
3352        || GET_MODE (operands[0]) == DFmode)
3353    && (operands[2] = find_constant_src (insn))"
3354   [(set (match_dup 0) (match_dup 2))]
3355 {
3356   rtx c = operands[2];
3357   rtx r = operands[0];
3358
3359   if (GET_CODE (r) == SUBREG)
3360     r = SUBREG_REG (r);
3361
3362   if (SSE_REG_P (r))
3363     {
3364       if (!standard_sse_constant_p (c))
3365         FAIL;
3366     }
3367   else if (FP_REG_P (r))
3368     {
3369       if (!standard_80387_constant_p (c))
3370         FAIL;
3371     }
3372   else if (MMX_REG_P (r))
3373     FAIL;
3374 })
3375
3376 (define_insn "swapxf"
3377   [(set (match_operand:XF 0 "register_operand" "+f")
3378         (match_operand:XF 1 "register_operand" "+f"))
3379    (set (match_dup 1)
3380         (match_dup 0))]
3381   "TARGET_80387"
3382 {
3383   if (STACK_TOP_P (operands[0]))
3384     return "fxch\t%1";
3385   else
3386     return "fxch\t%0";
3387 }
3388   [(set_attr "type" "fxch")
3389    (set_attr "mode" "XF")])
3390
3391 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3392 (define_split
3393   [(set (match_operand:X87MODEF 0 "register_operand" "")
3394         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3395   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3396    && (standard_80387_constant_p (operands[1]) == 8
3397        || standard_80387_constant_p (operands[1]) == 9)"
3398   [(set (match_dup 0)(match_dup 1))
3399    (set (match_dup 0)
3400         (neg:X87MODEF (match_dup 0)))]
3401 {
3402   REAL_VALUE_TYPE r;
3403
3404   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3405   if (real_isnegzero (&r))
3406     operands[1] = CONST0_RTX (<MODE>mode);
3407   else
3408     operands[1] = CONST1_RTX (<MODE>mode);
3409 })
3410
3411 (define_split
3412   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3413         (match_operand:TF 1 "general_operand" ""))]
3414   "reload_completed
3415    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3416   [(const_int 0)]
3417   "ix86_split_long_move (operands); DONE;")
3418 \f
3419 ;; Zero extension instructions
3420
3421 (define_expand "zero_extendhisi2"
3422   [(set (match_operand:SI 0 "register_operand" "")
3423      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3424   ""
3425 {
3426   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3427     {
3428       operands[1] = force_reg (HImode, operands[1]);
3429       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3430       DONE;
3431     }
3432 })
3433
3434 (define_insn "zero_extendhisi2_and"
3435   [(set (match_operand:SI 0 "register_operand" "=r")
3436      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3437    (clobber (reg:CC FLAGS_REG))]
3438   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3439   "#"
3440   [(set_attr "type" "alu1")
3441    (set_attr "mode" "SI")])
3442
3443 (define_split
3444   [(set (match_operand:SI 0 "register_operand" "")
3445         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3446    (clobber (reg:CC FLAGS_REG))]
3447   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3448   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3449               (clobber (reg:CC FLAGS_REG))])]
3450   "")
3451
3452 (define_insn "*zero_extendhisi2_movzwl"
3453   [(set (match_operand:SI 0 "register_operand" "=r")
3454      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3455   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3456   "movz{wl|x}\t{%1, %0|%0, %1}"
3457   [(set_attr "type" "imovx")
3458    (set_attr "mode" "SI")])
3459
3460 (define_expand "zero_extendqihi2"
3461   [(parallel
3462     [(set (match_operand:HI 0 "register_operand" "")
3463        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3464      (clobber (reg:CC FLAGS_REG))])]
3465   ""
3466   "")
3467
3468 (define_insn "*zero_extendqihi2_and"
3469   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3470      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3471    (clobber (reg:CC FLAGS_REG))]
3472   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3473   "#"
3474   [(set_attr "type" "alu1")
3475    (set_attr "mode" "HI")])
3476
3477 (define_insn "*zero_extendqihi2_movzbw_and"
3478   [(set (match_operand:HI 0 "register_operand" "=r,r")
3479      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3480    (clobber (reg:CC FLAGS_REG))]
3481   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3482   "#"
3483   [(set_attr "type" "imovx,alu1")
3484    (set_attr "mode" "HI")])
3485
3486 ; zero extend to SImode here to avoid partial register stalls
3487 (define_insn "*zero_extendqihi2_movzbl"
3488   [(set (match_operand:HI 0 "register_operand" "=r")
3489      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3490   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3491   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3492   [(set_attr "type" "imovx")
3493    (set_attr "mode" "SI")])
3494
3495 ;; For the movzbw case strip only the clobber
3496 (define_split
3497   [(set (match_operand:HI 0 "register_operand" "")
3498         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3499    (clobber (reg:CC FLAGS_REG))]
3500   "reload_completed
3501    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3502    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3503   [(set (match_operand:HI 0 "register_operand" "")
3504         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3505
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3508 (define_split
3509   [(set (match_operand:HI 0 "register_operand" "")
3510         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3511    (clobber (reg:CC FLAGS_REG))]
3512   "reload_completed
3513    && ANY_QI_REG_P (operands[0])
3514    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3515    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3516   [(set (match_dup 0) (const_int 0))
3517    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3518   "operands[2] = gen_lowpart (QImode, operands[0]);")
3519
3520 ;; Rest is handled by single and.
3521 (define_split
3522   [(set (match_operand:HI 0 "register_operand" "")
3523         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3524    (clobber (reg:CC FLAGS_REG))]
3525   "reload_completed
3526    && true_regnum (operands[0]) == true_regnum (operands[1])"
3527   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3528               (clobber (reg:CC FLAGS_REG))])]
3529   "")
3530
3531 (define_expand "zero_extendqisi2"
3532   [(parallel
3533     [(set (match_operand:SI 0 "register_operand" "")
3534        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3535      (clobber (reg:CC FLAGS_REG))])]
3536   ""
3537   "")
3538
3539 (define_insn "*zero_extendqisi2_and"
3540   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3541      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3542    (clobber (reg:CC FLAGS_REG))]
3543   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3544   "#"
3545   [(set_attr "type" "alu1")
3546    (set_attr "mode" "SI")])
3547
3548 (define_insn "*zero_extendqisi2_movzbw_and"
3549   [(set (match_operand:SI 0 "register_operand" "=r,r")
3550      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3551    (clobber (reg:CC FLAGS_REG))]
3552   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3553   "#"
3554   [(set_attr "type" "imovx,alu1")
3555    (set_attr "mode" "SI")])
3556
3557 (define_insn "*zero_extendqisi2_movzbw"
3558   [(set (match_operand:SI 0 "register_operand" "=r")
3559      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3560   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3561   "movz{bl|x}\t{%1, %0|%0, %1}"
3562   [(set_attr "type" "imovx")
3563    (set_attr "mode" "SI")])
3564
3565 ;; For the movzbl case strip only the clobber
3566 (define_split
3567   [(set (match_operand:SI 0 "register_operand" "")
3568         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3569    (clobber (reg:CC FLAGS_REG))]
3570   "reload_completed
3571    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3572    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3573   [(set (match_dup 0)
3574         (zero_extend:SI (match_dup 1)))])
3575
3576 ;; When source and destination does not overlap, clear destination
3577 ;; first and then do the movb
3578 (define_split
3579   [(set (match_operand:SI 0 "register_operand" "")
3580         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3581    (clobber (reg:CC FLAGS_REG))]
3582   "reload_completed
3583    && ANY_QI_REG_P (operands[0])
3584    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3585    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3586    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3587   [(set (match_dup 0) (const_int 0))
3588    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3589   "operands[2] = gen_lowpart (QImode, operands[0]);")
3590
3591 ;; Rest is handled by single and.
3592 (define_split
3593   [(set (match_operand:SI 0 "register_operand" "")
3594         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3595    (clobber (reg:CC FLAGS_REG))]
3596   "reload_completed
3597    && true_regnum (operands[0]) == true_regnum (operands[1])"
3598   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3599               (clobber (reg:CC FLAGS_REG))])]
3600   "")
3601
3602 ;; %%% Kill me once multi-word ops are sane.
3603 (define_expand "zero_extendsidi2"
3604   [(set (match_operand:DI 0 "register_operand" "")
3605      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3606   ""
3607 {
3608   if (!TARGET_64BIT)
3609     {
3610       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3611       DONE;
3612     }
3613 })
3614
3615 (define_insn "zero_extendsidi2_32"
3616   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3617         (zero_extend:DI
3618          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3619    (clobber (reg:CC FLAGS_REG))]
3620   "!TARGET_64BIT"
3621   "@
3622    #
3623    #
3624    #
3625    movd\t{%1, %0|%0, %1}
3626    movd\t{%1, %0|%0, %1}
3627    movd\t{%1, %0|%0, %1}
3628    movd\t{%1, %0|%0, %1}"
3629   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3630    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3631
3632 (define_insn "zero_extendsidi2_rex64"
3633   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3634      (zero_extend:DI
3635        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3636   "TARGET_64BIT"
3637   "@
3638    mov\t{%k1, %k0|%k0, %k1}
3639    #
3640    movd\t{%1, %0|%0, %1}
3641    movd\t{%1, %0|%0, %1}
3642    movd\t{%1, %0|%0, %1}
3643    movd\t{%1, %0|%0, %1}"
3644   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3645    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3646
3647 (define_split
3648   [(set (match_operand:DI 0 "memory_operand" "")
3649      (zero_extend:DI (match_dup 0)))]
3650   "TARGET_64BIT"
3651   [(set (match_dup 4) (const_int 0))]
3652   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3653
3654 (define_split
3655   [(set (match_operand:DI 0 "register_operand" "")
3656         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3657    (clobber (reg:CC FLAGS_REG))]
3658   "!TARGET_64BIT && reload_completed
3659    && true_regnum (operands[0]) == true_regnum (operands[1])"
3660   [(set (match_dup 4) (const_int 0))]
3661   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3662
3663 (define_split
3664   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3665         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3666    (clobber (reg:CC FLAGS_REG))]
3667   "!TARGET_64BIT && reload_completed
3668    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3669   [(set (match_dup 3) (match_dup 1))
3670    (set (match_dup 4) (const_int 0))]
3671   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3672
3673 (define_insn "zero_extendhidi2"
3674   [(set (match_operand:DI 0 "register_operand" "=r")
3675      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3676   "TARGET_64BIT"
3677   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3678   [(set_attr "type" "imovx")
3679    (set_attr "mode" "DI")])
3680
3681 (define_insn "zero_extendqidi2"
3682   [(set (match_operand:DI 0 "register_operand" "=r")
3683      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3684   "TARGET_64BIT"
3685   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3686   [(set_attr "type" "imovx")
3687    (set_attr "mode" "DI")])
3688 \f
3689 ;; Sign extension instructions
3690
3691 (define_expand "extendsidi2"
3692   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3693                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3694               (clobber (reg:CC FLAGS_REG))
3695               (clobber (match_scratch:SI 2 ""))])]
3696   ""
3697 {
3698   if (TARGET_64BIT)
3699     {
3700       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3701       DONE;
3702     }
3703 })
3704
3705 (define_insn "*extendsidi2_1"
3706   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3707         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3708    (clobber (reg:CC FLAGS_REG))
3709    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3710   "!TARGET_64BIT"
3711   "#")
3712
3713 (define_insn "extendsidi2_rex64"
3714   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3715         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3716   "TARGET_64BIT"
3717   "@
3718    {cltq|cdqe}
3719    movs{lq|x}\t{%1,%0|%0, %1}"
3720   [(set_attr "type" "imovx")
3721    (set_attr "mode" "DI")
3722    (set_attr "prefix_0f" "0")
3723    (set_attr "modrm" "0,1")])
3724
3725 (define_insn "extendhidi2"
3726   [(set (match_operand:DI 0 "register_operand" "=r")
3727         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3728   "TARGET_64BIT"
3729   "movs{wq|x}\t{%1,%0|%0, %1}"
3730   [(set_attr "type" "imovx")
3731    (set_attr "mode" "DI")])
3732
3733 (define_insn "extendqidi2"
3734   [(set (match_operand:DI 0 "register_operand" "=r")
3735         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3736   "TARGET_64BIT"
3737   "movs{bq|x}\t{%1,%0|%0, %1}"
3738    [(set_attr "type" "imovx")
3739     (set_attr "mode" "DI")])
3740
3741 ;; Extend to memory case when source register does die.
3742 (define_split
3743   [(set (match_operand:DI 0 "memory_operand" "")
3744         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3745    (clobber (reg:CC FLAGS_REG))
3746    (clobber (match_operand:SI 2 "register_operand" ""))]
3747   "(reload_completed
3748     && dead_or_set_p (insn, operands[1])
3749     && !reg_mentioned_p (operands[1], operands[0]))"
3750   [(set (match_dup 3) (match_dup 1))
3751    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3752               (clobber (reg:CC FLAGS_REG))])
3753    (set (match_dup 4) (match_dup 1))]
3754   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3755
3756 ;; Extend to memory case when source register does not die.
3757 (define_split
3758   [(set (match_operand:DI 0 "memory_operand" "")
3759         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3760    (clobber (reg:CC FLAGS_REG))
3761    (clobber (match_operand:SI 2 "register_operand" ""))]
3762   "reload_completed"
3763   [(const_int 0)]
3764 {
3765   split_di (&operands[0], 1, &operands[3], &operands[4]);
3766
3767   emit_move_insn (operands[3], operands[1]);
3768
3769   /* Generate a cltd if possible and doing so it profitable.  */
3770   if ((optimize_size || TARGET_USE_CLTD)
3771       && true_regnum (operands[1]) == AX_REG
3772       && true_regnum (operands[2]) == DX_REG)
3773     {
3774       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3775     }
3776   else
3777     {
3778       emit_move_insn (operands[2], operands[1]);
3779       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3780     }
3781   emit_move_insn (operands[4], operands[2]);
3782   DONE;
3783 })
3784
3785 ;; Extend to register case.  Optimize case where source and destination
3786 ;; registers match and cases where we can use cltd.
3787 (define_split
3788   [(set (match_operand:DI 0 "register_operand" "")
3789         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3790    (clobber (reg:CC FLAGS_REG))
3791    (clobber (match_scratch:SI 2 ""))]
3792   "reload_completed"
3793   [(const_int 0)]
3794 {
3795   split_di (&operands[0], 1, &operands[3], &operands[4]);
3796
3797   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3798     emit_move_insn (operands[3], operands[1]);
3799
3800   /* Generate a cltd if possible and doing so it profitable.  */
3801   if ((optimize_size || TARGET_USE_CLTD)
3802       && true_regnum (operands[3]) == AX_REG)
3803     {
3804       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3805       DONE;
3806     }
3807
3808   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3809     emit_move_insn (operands[4], operands[1]);
3810
3811   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3812   DONE;
3813 })
3814
3815 (define_insn "extendhisi2"
3816   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3817         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3818   ""
3819 {
3820   switch (get_attr_prefix_0f (insn))
3821     {
3822     case 0:
3823       return "{cwtl|cwde}";
3824     default:
3825       return "movs{wl|x}\t{%1,%0|%0, %1}";
3826     }
3827 }
3828   [(set_attr "type" "imovx")
3829    (set_attr "mode" "SI")
3830    (set (attr "prefix_0f")
3831      ;; movsx is short decodable while cwtl is vector decoded.
3832      (if_then_else (and (eq_attr "cpu" "!k6")
3833                         (eq_attr "alternative" "0"))
3834         (const_string "0")
3835         (const_string "1")))
3836    (set (attr "modrm")
3837      (if_then_else (eq_attr "prefix_0f" "0")
3838         (const_string "0")
3839         (const_string "1")))])
3840
3841 (define_insn "*extendhisi2_zext"
3842   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3843         (zero_extend:DI
3844           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3845   "TARGET_64BIT"
3846 {
3847   switch (get_attr_prefix_0f (insn))
3848     {
3849     case 0:
3850       return "{cwtl|cwde}";
3851     default:
3852       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3853     }
3854 }
3855   [(set_attr "type" "imovx")
3856    (set_attr "mode" "SI")
3857    (set (attr "prefix_0f")
3858      ;; movsx is short decodable while cwtl is vector decoded.
3859      (if_then_else (and (eq_attr "cpu" "!k6")
3860                         (eq_attr "alternative" "0"))
3861         (const_string "0")
3862         (const_string "1")))
3863    (set (attr "modrm")
3864      (if_then_else (eq_attr "prefix_0f" "0")
3865         (const_string "0")
3866         (const_string "1")))])
3867
3868 (define_insn "extendqihi2"
3869   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3870         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3871   ""
3872 {
3873   switch (get_attr_prefix_0f (insn))
3874     {
3875     case 0:
3876       return "{cbtw|cbw}";
3877     default:
3878       return "movs{bw|x}\t{%1,%0|%0, %1}";
3879     }
3880 }
3881   [(set_attr "type" "imovx")
3882    (set_attr "mode" "HI")
3883    (set (attr "prefix_0f")
3884      ;; movsx is short decodable while cwtl is vector decoded.
3885      (if_then_else (and (eq_attr "cpu" "!k6")
3886                         (eq_attr "alternative" "0"))
3887         (const_string "0")
3888         (const_string "1")))
3889    (set (attr "modrm")
3890      (if_then_else (eq_attr "prefix_0f" "0")
3891         (const_string "0")
3892         (const_string "1")))])
3893
3894 (define_insn "extendqisi2"
3895   [(set (match_operand:SI 0 "register_operand" "=r")
3896         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3897   ""
3898   "movs{bl|x}\t{%1,%0|%0, %1}"
3899    [(set_attr "type" "imovx")
3900     (set_attr "mode" "SI")])
3901
3902 (define_insn "*extendqisi2_zext"
3903   [(set (match_operand:DI 0 "register_operand" "=r")
3904         (zero_extend:DI
3905           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3906   "TARGET_64BIT"
3907   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3908    [(set_attr "type" "imovx")
3909     (set_attr "mode" "SI")])
3910 \f
3911 ;; Conversions between float and double.
3912
3913 ;; These are all no-ops in the model used for the 80387.  So just
3914 ;; emit moves.
3915
3916 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3917 (define_insn "*dummy_extendsfdf2"
3918   [(set (match_operand:DF 0 "push_operand" "=<")
3919         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3920   "0"
3921   "#")
3922
3923 (define_split
3924   [(set (match_operand:DF 0 "push_operand" "")
3925         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3926   "!TARGET_64BIT"
3927   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3928    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3929
3930 (define_split
3931   [(set (match_operand:DF 0 "push_operand" "")
3932         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3933   "TARGET_64BIT"
3934   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3935    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3936
3937 (define_insn "*dummy_extendsfxf2"
3938   [(set (match_operand:XF 0 "push_operand" "=<")
3939         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3940   "0"
3941   "#")
3942
3943 (define_split
3944   [(set (match_operand:XF 0 "push_operand" "")
3945         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3946   ""
3947   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3948    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3949   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3950
3951 (define_split
3952   [(set (match_operand:XF 0 "push_operand" "")
3953         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3954   "TARGET_64BIT"
3955   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3956    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3957   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3958
3959 (define_split
3960   [(set (match_operand:XF 0 "push_operand" "")
3961         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3962   ""
3963   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3964    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3965   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3966
3967 (define_split
3968   [(set (match_operand:XF 0 "push_operand" "")
3969         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3970   "TARGET_64BIT"
3971   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3972    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3973   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3974
3975 (define_expand "extendsfdf2"
3976   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3977         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3978   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3979 {
3980   /* ??? Needed for compress_float_constant since all fp constants
3981      are LEGITIMATE_CONSTANT_P.  */
3982   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3983     {
3984       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3985           && standard_80387_constant_p (operands[1]) > 0)
3986         {
3987           operands[1] = simplify_const_unary_operation
3988             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3989           emit_move_insn_1 (operands[0], operands[1]);
3990           DONE;
3991         }
3992       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3993     }
3994 })
3995
3996 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3997    cvtss2sd:
3998       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3999       cvtps2pd xmm2,xmm1
4000    We do the conversion post reload to avoid producing of 128bit spills
4001    that might lead to ICE on 32bit target.  The sequence unlikely combine
4002    anyway.  */
4003 (define_split
4004   [(set (match_operand:DF 0 "register_operand" "")
4005         (float_extend:DF
4006           (match_operand:SF 1 "nonimmediate_operand" "")))]
4007   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4008    && reload_completed && SSE_REG_P (operands[0])"
4009    [(set (match_dup 2)
4010          (float_extend:V2DF
4011            (vec_select:V2SF
4012              (match_dup 3)
4013              (parallel [(const_int 0) (const_int 1)]))))]
4014 {
4015   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4016   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4017   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4018      Try to avoid move when unpacking can be done in source.  */
4019   if (REG_P (operands[1]))
4020     {
4021       /* If it is unsafe to overwrite upper half of source, we need
4022          to move to destination and unpack there.  */
4023       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4024            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4025           && true_regnum (operands[0]) != true_regnum (operands[1]))
4026         {
4027           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4028           emit_move_insn (tmp, operands[1]);
4029         }
4030       else
4031         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4032       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4033     }
4034   else
4035     emit_insn (gen_vec_setv4sf_0 (operands[3],
4036                                   CONST0_RTX (V4SFmode), operands[1]));
4037 })
4038
4039 (define_insn "*extendsfdf2_mixed"
4040   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4041         (float_extend:DF
4042           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4043   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4044 {
4045   switch (which_alternative)
4046     {
4047     case 0:
4048     case 1:
4049       return output_387_reg_move (insn, operands);
4050
4051     case 2:
4052       return "cvtss2sd\t{%1, %0|%0, %1}";
4053
4054     default:
4055       gcc_unreachable ();
4056     }
4057 }
4058   [(set_attr "type" "fmov,fmov,ssecvt")
4059    (set_attr "mode" "SF,XF,DF")])
4060
4061 (define_insn "*extendsfdf2_sse"
4062   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4063         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4064   "TARGET_SSE2 && TARGET_SSE_MATH"
4065   "cvtss2sd\t{%1, %0|%0, %1}"
4066   [(set_attr "type" "ssecvt")
4067    (set_attr "mode" "DF")])
4068
4069 (define_insn "*extendsfdf2_i387"
4070   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4071         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4072   "TARGET_80387"
4073   "* return output_387_reg_move (insn, operands);"
4074   [(set_attr "type" "fmov")
4075    (set_attr "mode" "SF,XF")])
4076
4077 (define_expand "extend<mode>xf2"
4078   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4079         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4080   "TARGET_80387"
4081 {
4082   /* ??? Needed for compress_float_constant since all fp constants
4083      are LEGITIMATE_CONSTANT_P.  */
4084   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4085     {
4086       if (standard_80387_constant_p (operands[1]) > 0)
4087         {
4088           operands[1] = simplify_const_unary_operation
4089             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4090           emit_move_insn_1 (operands[0], operands[1]);
4091           DONE;
4092         }
4093       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4094     }
4095 })
4096
4097 (define_insn "*extend<mode>xf2_i387"
4098   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4099         (float_extend:XF
4100           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4101   "TARGET_80387"
4102   "* return output_387_reg_move (insn, operands);"
4103   [(set_attr "type" "fmov")
4104    (set_attr "mode" "<MODE>,XF")])
4105
4106 ;; %%% This seems bad bad news.
4107 ;; This cannot output into an f-reg because there is no way to be sure
4108 ;; of truncating in that case.  Otherwise this is just like a simple move
4109 ;; insn.  So we pretend we can output to a reg in order to get better
4110 ;; register preferencing, but we really use a stack slot.
4111
4112 ;; Conversion from DFmode to SFmode.
4113
4114 (define_expand "truncdfsf2"
4115   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4116         (float_truncate:SF
4117           (match_operand:DF 1 "nonimmediate_operand" "")))]
4118   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4119 {
4120   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4121     ;
4122   else if (flag_unsafe_math_optimizations)
4123     ;
4124   else
4125     {
4126       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4127       rtx temp = assign_386_stack_local (SFmode, slot);
4128       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4129       DONE;
4130     }
4131 })
4132
4133 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4134    cvtsd2ss:
4135       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4136       cvtpd2ps xmm2,xmm1
4137    We do the conversion post reload to avoid producing of 128bit spills
4138    that might lead to ICE on 32bit target.  The sequence unlikely combine
4139    anyway.  */
4140 (define_split
4141   [(set (match_operand:SF 0 "register_operand" "")
4142         (float_truncate:SF
4143           (match_operand:DF 1 "nonimmediate_operand" "")))]
4144   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4145    && reload_completed && SSE_REG_P (operands[0])"
4146    [(set (match_dup 2)
4147          (vec_concat:V4SF
4148            (float_truncate:V2SF
4149              (match_dup 4))
4150            (match_dup 3)))]
4151 {
4152   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4153   operands[3] = CONST0_RTX (V2SFmode);
4154   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4155   /* Use movsd for loading from memory, unpcklpd for registers.
4156      Try to avoid move when unpacking can be done in source, or SSE3
4157      movddup is available.  */
4158   if (REG_P (operands[1]))
4159     {
4160       if (!TARGET_SSE3
4161           && true_regnum (operands[0]) != true_regnum (operands[1])
4162           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4163               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4164         {
4165           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4166           emit_move_insn (tmp, operands[1]);
4167           operands[1] = tmp;
4168         }
4169       else if (!TARGET_SSE3)
4170         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4171       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4172     }
4173   else
4174     emit_insn (gen_sse2_loadlpd (operands[4],
4175                                  CONST0_RTX (V2DFmode), operands[1]));
4176 })
4177
4178 (define_expand "truncdfsf2_with_temp"
4179   [(parallel [(set (match_operand:SF 0 "" "")
4180                    (float_truncate:SF (match_operand:DF 1 "" "")))
4181               (clobber (match_operand:SF 2 "" ""))])]
4182   "")
4183
4184 (define_insn "*truncdfsf_fast_mixed"
4185   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4186         (float_truncate:SF
4187           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4188   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4189 {
4190   switch (which_alternative)
4191     {
4192     case 0:
4193     case 1:
4194       return output_387_reg_move (insn, operands);
4195     case 2:
4196       return "cvtsd2ss\t{%1, %0|%0, %1}";
4197     default:
4198       gcc_unreachable ();
4199     }
4200 }
4201   [(set_attr "type" "fmov,fmov,ssecvt")
4202    (set_attr "mode" "SF")])
4203
4204 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4205 ;; because nothing we do here is unsafe.
4206 (define_insn "*truncdfsf_fast_sse"
4207   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4208         (float_truncate:SF
4209           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4210   "TARGET_SSE2 && TARGET_SSE_MATH"
4211   "cvtsd2ss\t{%1, %0|%0, %1}"
4212   [(set_attr "type" "ssecvt")
4213    (set_attr "mode" "SF")])
4214
4215 (define_insn "*truncdfsf_fast_i387"
4216   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4217         (float_truncate:SF
4218           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4219   "TARGET_80387 && flag_unsafe_math_optimizations"
4220   "* return output_387_reg_move (insn, operands);"
4221   [(set_attr "type" "fmov")
4222    (set_attr "mode" "SF")])
4223
4224 (define_insn "*truncdfsf_mixed"
4225   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4226         (float_truncate:SF
4227           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4228    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4229   "TARGET_MIX_SSE_I387"
4230 {
4231   switch (which_alternative)
4232     {
4233     case 0:
4234       return output_387_reg_move (insn, operands);
4235
4236     case 1:
4237       return "#";
4238     case 2:
4239       return "cvtsd2ss\t{%1, %0|%0, %1}";
4240     default:
4241       gcc_unreachable ();
4242     }
4243 }
4244   [(set_attr "type" "fmov,multi,ssecvt")
4245    (set_attr "unit" "*,i387,*")
4246    (set_attr "mode" "SF")])
4247
4248 (define_insn "*truncdfsf_i387"
4249   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4250         (float_truncate:SF
4251           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4252    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4253   "TARGET_80387"
4254 {
4255   switch (which_alternative)
4256     {
4257     case 0:
4258       return output_387_reg_move (insn, operands);
4259
4260     case 1:
4261       return "#";
4262     default:
4263       gcc_unreachable ();
4264     }
4265 }
4266   [(set_attr "type" "fmov,multi")
4267    (set_attr "unit" "*,i387")
4268    (set_attr "mode" "SF")])
4269
4270 (define_insn "*truncdfsf2_i387_1"
4271   [(set (match_operand:SF 0 "memory_operand" "=m")
4272         (float_truncate:SF
4273           (match_operand:DF 1 "register_operand" "f")))]
4274   "TARGET_80387
4275    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4276    && !TARGET_MIX_SSE_I387"
4277   "* return output_387_reg_move (insn, operands);"
4278   [(set_attr "type" "fmov")
4279    (set_attr "mode" "SF")])
4280
4281 (define_split
4282   [(set (match_operand:SF 0 "register_operand" "")
4283         (float_truncate:SF
4284          (match_operand:DF 1 "fp_register_operand" "")))
4285    (clobber (match_operand 2 "" ""))]
4286   "reload_completed"
4287   [(set (match_dup 2) (match_dup 1))
4288    (set (match_dup 0) (match_dup 2))]
4289 {
4290   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4291 })
4292
4293 ;; Conversion from XFmode to {SF,DF}mode
4294
4295 (define_expand "truncxf<mode>2"
4296   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4297                    (float_truncate:MODEF
4298                      (match_operand:XF 1 "register_operand" "")))
4299               (clobber (match_dup 2))])]
4300   "TARGET_80387"
4301 {
4302   if (flag_unsafe_math_optimizations)
4303     {
4304       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4305       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4306       if (reg != operands[0])
4307         emit_move_insn (operands[0], reg);
4308       DONE;
4309     }
4310   else
4311     {
4312       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4313       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4314     }
4315 })
4316
4317 (define_insn "*truncxfsf2_mixed"
4318   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4319         (float_truncate:SF
4320           (match_operand:XF 1 "register_operand" "f,f")))
4321    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4322   "TARGET_80387"
4323 {
4324   gcc_assert (!which_alternative);
4325   return output_387_reg_move (insn, operands);
4326 }
4327   [(set_attr "type" "fmov,multi")
4328    (set_attr "unit" "*,i387")
4329    (set_attr "mode" "SF")])
4330
4331 (define_insn "*truncxfdf2_mixed"
4332   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4333         (float_truncate:DF
4334           (match_operand:XF 1 "register_operand" "f,f")))
4335    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4336   "TARGET_80387"
4337 {
4338   gcc_assert (!which_alternative);
4339   return output_387_reg_move (insn, operands);
4340 }
4341   [(set_attr "type" "fmov,multi")
4342    (set_attr "unit" "*,i387")
4343    (set_attr "mode" "DF")])
4344
4345 (define_insn "truncxf<mode>2_i387_noop"
4346   [(set (match_operand:MODEF 0 "register_operand" "=f")
4347         (float_truncate:MODEF
4348           (match_operand:XF 1 "register_operand" "f")))]
4349   "TARGET_80387 && flag_unsafe_math_optimizations"
4350   "* return output_387_reg_move (insn, operands);"
4351   [(set_attr "type" "fmov")
4352    (set_attr "mode" "<MODE>")])
4353
4354 (define_insn "*truncxf<mode>2_i387"
4355   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4356         (float_truncate:MODEF
4357           (match_operand:XF 1 "register_operand" "f")))]
4358   "TARGET_80387"
4359   "* return output_387_reg_move (insn, operands);"
4360   [(set_attr "type" "fmov")
4361    (set_attr "mode" "<MODE>")])
4362
4363 (define_split
4364   [(set (match_operand:MODEF 0 "register_operand" "")
4365         (float_truncate:MODEF
4366           (match_operand:XF 1 "register_operand" "")))
4367    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4368   "TARGET_80387 && reload_completed"
4369   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4370    (set (match_dup 0) (match_dup 2))]
4371   "")
4372
4373 (define_split
4374   [(set (match_operand:MODEF 0 "memory_operand" "")
4375         (float_truncate:MODEF
4376           (match_operand:XF 1 "register_operand" "")))
4377    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4378   "TARGET_80387"
4379   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4380   "")
4381 \f
4382 ;; Signed conversion to DImode.
4383
4384 (define_expand "fix_truncxfdi2"
4385   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4386                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4387               (clobber (reg:CC FLAGS_REG))])]
4388   "TARGET_80387"
4389 {
4390   if (TARGET_FISTTP)
4391    {
4392      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4393      DONE;
4394    }
4395 })
4396
4397 (define_expand "fix_trunc<mode>di2"
4398   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4399                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4400               (clobber (reg:CC FLAGS_REG))])]
4401   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4402 {
4403   if (TARGET_FISTTP
4404       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4405    {
4406      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4407      DONE;
4408    }
4409   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4410    {
4411      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4412      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4413      if (out != operands[0])
4414         emit_move_insn (operands[0], out);
4415      DONE;
4416    }
4417 })
4418
4419 ;; Signed conversion to SImode.
4420
4421 (define_expand "fix_truncxfsi2"
4422   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4423                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4424               (clobber (reg:CC FLAGS_REG))])]
4425   "TARGET_80387"
4426 {
4427   if (TARGET_FISTTP)
4428    {
4429      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4430      DONE;
4431    }
4432 })
4433
4434 (define_expand "fix_trunc<mode>si2"
4435   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4436                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4437               (clobber (reg:CC FLAGS_REG))])]
4438   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4439 {
4440   if (TARGET_FISTTP
4441       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4442    {
4443      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4444      DONE;
4445    }
4446   if (SSE_FLOAT_MODE_P (<MODE>mode))
4447    {
4448      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4449      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4450      if (out != operands[0])
4451         emit_move_insn (operands[0], out);
4452      DONE;
4453    }
4454 })
4455
4456 ;; Signed conversion to HImode.
4457
4458 (define_expand "fix_trunc<mode>hi2"
4459   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4460                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4461               (clobber (reg:CC FLAGS_REG))])]
4462   "TARGET_80387
4463    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4464 {
4465   if (TARGET_FISTTP)
4466    {
4467      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4468      DONE;
4469    }
4470 })
4471
4472 ;; Unsigned conversion to SImode.
4473
4474 (define_expand "fixuns_trunc<mode>si2"
4475   [(parallel
4476     [(set (match_operand:SI 0 "register_operand" "")
4477           (unsigned_fix:SI
4478             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4479      (use (match_dup 2))
4480      (clobber (match_scratch:<ssevecmode> 3 ""))
4481      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4482   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4483 {
4484   enum machine_mode mode = <MODE>mode;
4485   enum machine_mode vecmode = <ssevecmode>mode;
4486   REAL_VALUE_TYPE TWO31r;
4487   rtx two31;
4488
4489   real_ldexp (&TWO31r, &dconst1, 31);
4490   two31 = const_double_from_real_value (TWO31r, mode);
4491   two31 = ix86_build_const_vector (mode, true, two31);
4492   operands[2] = force_reg (vecmode, two31);
4493 })
4494
4495 (define_insn_and_split "*fixuns_trunc<mode>_1"
4496   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4497         (unsigned_fix:SI
4498           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4499    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4500    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4501    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4502   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4503   "#"
4504   "&& reload_completed"
4505   [(const_int 0)]
4506 {
4507   ix86_split_convert_uns_si_sse (operands);
4508   DONE;
4509 })
4510
4511 ;; Unsigned conversion to HImode.
4512 ;; Without these patterns, we'll try the unsigned SI conversion which
4513 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4514
4515 (define_expand "fixuns_trunc<mode>hi2"
4516   [(set (match_dup 2)
4517         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4518    (set (match_operand:HI 0 "nonimmediate_operand" "")
4519         (subreg:HI (match_dup 2) 0))]
4520   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4521   "operands[2] = gen_reg_rtx (SImode);")
4522
4523 ;; When SSE is available, it is always faster to use it!
4524 (define_insn "fix_trunc<mode>di_sse"
4525   [(set (match_operand:DI 0 "register_operand" "=r,r")
4526         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4527   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4528    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4529   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4530   [(set_attr "type" "sseicvt")
4531    (set_attr "mode" "<MODE>")
4532    (set_attr "athlon_decode" "double,vector")
4533    (set_attr "amdfam10_decode" "double,double")])
4534
4535 (define_insn "fix_trunc<mode>si_sse"
4536   [(set (match_operand:SI 0 "register_operand" "=r,r")
4537         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4538   "SSE_FLOAT_MODE_P (<MODE>mode)
4539    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4540   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4541   [(set_attr "type" "sseicvt")
4542    (set_attr "mode" "<MODE>")
4543    (set_attr "athlon_decode" "double,vector")
4544    (set_attr "amdfam10_decode" "double,double")])
4545
4546 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4547 (define_peephole2
4548   [(set (match_operand:MODEF 0 "register_operand" "")
4549         (match_operand:MODEF 1 "memory_operand" ""))
4550    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4551         (fix:SSEMODEI24 (match_dup 0)))]
4552   "TARGET_SHORTEN_X87_SSE
4553    && peep2_reg_dead_p (2, operands[0])"
4554   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4555   "")
4556
4557 ;; Avoid vector decoded forms of the instruction.
4558 (define_peephole2
4559   [(match_scratch:DF 2 "Y2")
4560    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4561         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4562   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4563   [(set (match_dup 2) (match_dup 1))
4564    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4565   "")
4566
4567 (define_peephole2
4568   [(match_scratch:SF 2 "x")
4569    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4570         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4571   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4572   [(set (match_dup 2) (match_dup 1))
4573    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4574   "")
4575
4576 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4577   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4578         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4579   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4580    && TARGET_FISTTP
4581    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4582          && (TARGET_64BIT || <MODE>mode != DImode))
4583         && TARGET_SSE_MATH)
4584    && !(reload_completed || reload_in_progress)"
4585   "#"
4586   "&& 1"
4587   [(const_int 0)]
4588 {
4589   if (memory_operand (operands[0], VOIDmode))
4590     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4591   else
4592     {
4593       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4594       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4595                                                             operands[1],
4596                                                             operands[2]));
4597     }
4598   DONE;
4599 }
4600   [(set_attr "type" "fisttp")
4601    (set_attr "mode" "<MODE>")])
4602
4603 (define_insn "fix_trunc<mode>_i387_fisttp"
4604   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4605         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4606    (clobber (match_scratch:XF 2 "=&1f"))]
4607   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4608    && TARGET_FISTTP
4609    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4610          && (TARGET_64BIT || <MODE>mode != DImode))
4611         && TARGET_SSE_MATH)"
4612   "* return output_fix_trunc (insn, operands, 1);"
4613   [(set_attr "type" "fisttp")
4614    (set_attr "mode" "<MODE>")])
4615
4616 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4617   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4618         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4619    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4620    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
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         && TARGET_SSE_MATH)"
4626   "#"
4627   [(set_attr "type" "fisttp")
4628    (set_attr "mode" "<MODE>")])
4629
4630 (define_split
4631   [(set (match_operand:X87MODEI 0 "register_operand" "")
4632         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4633    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4634    (clobber (match_scratch 3 ""))]
4635   "reload_completed"
4636   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4637               (clobber (match_dup 3))])
4638    (set (match_dup 0) (match_dup 2))]
4639   "")
4640
4641 (define_split
4642   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4643         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4644    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4645    (clobber (match_scratch 3 ""))]
4646   "reload_completed"
4647   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4648               (clobber (match_dup 3))])]
4649   "")
4650
4651 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4652 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4653 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4654 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4655 ;; function in i386.c.
4656 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4657   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4658         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659    (clobber (reg:CC FLAGS_REG))]
4660   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4661    && !TARGET_FISTTP
4662    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4663          && (TARGET_64BIT || <MODE>mode != DImode))
4664    && !(reload_completed || reload_in_progress)"
4665   "#"
4666   "&& 1"
4667   [(const_int 0)]
4668 {
4669   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4670
4671   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4672   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4673   if (memory_operand (operands[0], VOIDmode))
4674     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4675                                          operands[2], operands[3]));
4676   else
4677     {
4678       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4679       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4680                                                      operands[2], operands[3],
4681                                                      operands[4]));
4682     }
4683   DONE;
4684 }
4685   [(set_attr "type" "fistp")
4686    (set_attr "i387_cw" "trunc")
4687    (set_attr "mode" "<MODE>")])
4688
4689 (define_insn "fix_truncdi_i387"
4690   [(set (match_operand:DI 0 "memory_operand" "=m")
4691         (fix:DI (match_operand 1 "register_operand" "f")))
4692    (use (match_operand:HI 2 "memory_operand" "m"))
4693    (use (match_operand:HI 3 "memory_operand" "m"))
4694    (clobber (match_scratch:XF 4 "=&1f"))]
4695   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4696    && !TARGET_FISTTP
4697    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4698   "* return output_fix_trunc (insn, operands, 0);"
4699   [(set_attr "type" "fistp")
4700    (set_attr "i387_cw" "trunc")
4701    (set_attr "mode" "DI")])
4702
4703 (define_insn "fix_truncdi_i387_with_temp"
4704   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4705         (fix:DI (match_operand 1 "register_operand" "f,f")))
4706    (use (match_operand:HI 2 "memory_operand" "m,m"))
4707    (use (match_operand:HI 3 "memory_operand" "m,m"))
4708    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4709    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4710   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4711    && !TARGET_FISTTP
4712    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4713   "#"
4714   [(set_attr "type" "fistp")
4715    (set_attr "i387_cw" "trunc")
4716    (set_attr "mode" "DI")])
4717
4718 (define_split
4719   [(set (match_operand:DI 0 "register_operand" "")
4720         (fix:DI (match_operand 1 "register_operand" "")))
4721    (use (match_operand:HI 2 "memory_operand" ""))
4722    (use (match_operand:HI 3 "memory_operand" ""))
4723    (clobber (match_operand:DI 4 "memory_operand" ""))
4724    (clobber (match_scratch 5 ""))]
4725   "reload_completed"
4726   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4727               (use (match_dup 2))
4728               (use (match_dup 3))
4729               (clobber (match_dup 5))])
4730    (set (match_dup 0) (match_dup 4))]
4731   "")
4732
4733 (define_split
4734   [(set (match_operand:DI 0 "memory_operand" "")
4735         (fix:DI (match_operand 1 "register_operand" "")))
4736    (use (match_operand:HI 2 "memory_operand" ""))
4737    (use (match_operand:HI 3 "memory_operand" ""))
4738    (clobber (match_operand:DI 4 "memory_operand" ""))
4739    (clobber (match_scratch 5 ""))]
4740   "reload_completed"
4741   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4742               (use (match_dup 2))
4743               (use (match_dup 3))
4744               (clobber (match_dup 5))])]
4745   "")
4746
4747 (define_insn "fix_trunc<mode>_i387"
4748   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4749         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4750    (use (match_operand:HI 2 "memory_operand" "m"))
4751    (use (match_operand:HI 3 "memory_operand" "m"))]
4752   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4753    && !TARGET_FISTTP
4754    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4755   "* return output_fix_trunc (insn, operands, 0);"
4756   [(set_attr "type" "fistp")
4757    (set_attr "i387_cw" "trunc")
4758    (set_attr "mode" "<MODE>")])
4759
4760 (define_insn "fix_trunc<mode>_i387_with_temp"
4761   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4762         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4763    (use (match_operand:HI 2 "memory_operand" "m,m"))
4764    (use (match_operand:HI 3 "memory_operand" "m,m"))
4765    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4766   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4767    && !TARGET_FISTTP
4768    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4769   "#"
4770   [(set_attr "type" "fistp")
4771    (set_attr "i387_cw" "trunc")
4772    (set_attr "mode" "<MODE>")])
4773
4774 (define_split
4775   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4776         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4777    (use (match_operand:HI 2 "memory_operand" ""))
4778    (use (match_operand:HI 3 "memory_operand" ""))
4779    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4780   "reload_completed"
4781   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4782               (use (match_dup 2))
4783               (use (match_dup 3))])
4784    (set (match_dup 0) (match_dup 4))]
4785   "")
4786
4787 (define_split
4788   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4789         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4790    (use (match_operand:HI 2 "memory_operand" ""))
4791    (use (match_operand:HI 3 "memory_operand" ""))
4792    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4793   "reload_completed"
4794   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4795               (use (match_dup 2))
4796               (use (match_dup 3))])]
4797   "")
4798
4799 (define_insn "x86_fnstcw_1"
4800   [(set (match_operand:HI 0 "memory_operand" "=m")
4801         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4802   "TARGET_80387"
4803   "fnstcw\t%0"
4804   [(set_attr "length" "2")
4805    (set_attr "mode" "HI")
4806    (set_attr "unit" "i387")])
4807
4808 (define_insn "x86_fldcw_1"
4809   [(set (reg:HI FPCR_REG)
4810         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4811   "TARGET_80387"
4812   "fldcw\t%0"
4813   [(set_attr "length" "2")
4814    (set_attr "mode" "HI")
4815    (set_attr "unit" "i387")
4816    (set_attr "athlon_decode" "vector")
4817    (set_attr "amdfam10_decode" "vector")])
4818 \f
4819 ;; Conversion between fixed point and floating point.
4820
4821 ;; Even though we only accept memory inputs, the backend _really_
4822 ;; wants to be able to do this between registers.
4823
4824 (define_expand "floathi<mode>2"
4825   [(set (match_operand:X87MODEF 0 "register_operand" "")
4826         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4827   "TARGET_80387
4828    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4829        || TARGET_MIX_SSE_I387)"
4830   "")
4831
4832 ;; Pre-reload splitter to add memory clobber to the pattern.
4833 (define_insn_and_split "*floathi<mode>2_1"
4834   [(set (match_operand:X87MODEF 0 "register_operand" "")
4835         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4836   "TARGET_80387
4837    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4838        || TARGET_MIX_SSE_I387)
4839    && !(reload_completed || reload_in_progress)"
4840   "#"
4841   "&& 1"
4842   [(parallel [(set (match_dup 0)
4843               (float:X87MODEF (match_dup 1)))
4844    (clobber (match_dup 2))])]
4845   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4846
4847 (define_insn "*floathi<mode>2_i387_with_temp"
4848   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4849         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4850   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4851   "TARGET_80387
4852    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4853        || TARGET_MIX_SSE_I387)"
4854   "#"
4855   [(set_attr "type" "fmov,multi")
4856    (set_attr "mode" "<MODE>")
4857    (set_attr "unit" "*,i387")
4858    (set_attr "fp_int_src" "true")])
4859
4860 (define_insn "*floathi<mode>2_i387"
4861   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4862         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4863   "TARGET_80387
4864    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4865        || TARGET_MIX_SSE_I387)"
4866   "fild%z1\t%1"
4867   [(set_attr "type" "fmov")
4868    (set_attr "mode" "<MODE>")
4869    (set_attr "fp_int_src" "true")])
4870
4871 (define_split
4872   [(set (match_operand:X87MODEF 0 "register_operand" "")
4873         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4874    (clobber (match_operand:HI 2 "memory_operand" ""))]
4875   "TARGET_80387
4876    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4877        || TARGET_MIX_SSE_I387)
4878    && reload_completed"
4879   [(set (match_dup 2) (match_dup 1))
4880    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4881   "")
4882
4883 (define_split
4884   [(set (match_operand:X87MODEF 0 "register_operand" "")
4885         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4886    (clobber (match_operand:HI 2 "memory_operand" ""))]
4887    "TARGET_80387
4888     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4889         || TARGET_MIX_SSE_I387)
4890     && reload_completed"
4891   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4892   "")
4893
4894 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4895   [(set (match_operand:X87MODEF 0 "register_operand" "")
4896         (float:X87MODEF
4897           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4898   "TARGET_80387
4899    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4900        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4901   "")
4902
4903 ;; Pre-reload splitter to add memory clobber to the pattern.
4904 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4905   [(set (match_operand:X87MODEF 0 "register_operand" "")
4906         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4907   "((TARGET_80387
4908      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4909            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4910          || TARGET_MIX_SSE_I387))
4911     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4912         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4913         && ((<SSEMODEI24:MODE>mode == SImode
4914              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4915              && flag_trapping_math)
4916             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4917    && !(reload_completed || reload_in_progress)"
4918   "#"
4919   "&& 1"
4920   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4921               (clobber (match_dup 2))])]
4922   "operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);")
4923
4924 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4925   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4926         (float:MODEF
4927           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4928    (clobber (match_operand:SI 2 "memory_operand" "=m,m,m,m,m"))]
4929   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4930    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4931   "#"
4932   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4933    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4934    (set_attr "unit" "*,i387,*,*,*")
4935    (set_attr "athlon_decode" "*,*,double,direct,double")
4936    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4937    (set_attr "fp_int_src" "true")])
4938
4939 (define_insn "*floatsi<mode>2_vector_mixed"
4940   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4941         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4942   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4943    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4944   "@
4945    fild%z1\t%1
4946    #"
4947   [(set_attr "type" "fmov,sseicvt")
4948    (set_attr "mode" "<MODE>,<ssevecmode>")
4949    (set_attr "unit" "i387,*")
4950    (set_attr "athlon_decode" "*,direct")
4951    (set_attr "amdfam10_decode" "*,double")
4952    (set_attr "fp_int_src" "true")])
4953
4954 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4955   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4956         (float:MODEF
4957           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4958   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m,m,m"))]
4959   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4960    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4961   "#"
4962   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4963    (set_attr "mode" "<MODEF:MODE>")
4964    (set_attr "unit" "*,i387,*,*")
4965    (set_attr "athlon_decode" "*,*,double,direct")
4966    (set_attr "amdfam10_decode" "*,*,vector,double")
4967    (set_attr "fp_int_src" "true")])
4968
4969 (define_split
4970   [(set (match_operand:MODEF 0 "register_operand" "")
4971         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4972    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4973   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4974    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4975    && TARGET_INTER_UNIT_CONVERSIONS
4976    && reload_completed
4977    && (SSE_REG_P (operands[0])
4978        || (GET_CODE (operands[0]) == SUBREG
4979            && SSE_REG_P (operands[0])))"
4980   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
4981   "")
4982
4983 (define_split
4984   [(set (match_operand:MODEF 0 "register_operand" "")
4985         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4986    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4987   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4988    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4989    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
4990    && reload_completed
4991    && (SSE_REG_P (operands[0])
4992        || (GET_CODE (operands[0]) == SUBREG
4993            && SSE_REG_P (operands[0])))"
4994   [(set (match_dup 2) (match_dup 1))
4995    (set (match_dup 0) (float:MODEF (match_dup 2)))]
4996   "")
4997
4998 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4999   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5000         (float:MODEF
5001           (match_operand:SSEMODEI24 1 "register_operand" "m,r,m")))]
5002   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5003    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5004    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5005   "@
5006    fild%z1\t%1
5007    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5008    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5009   [(set_attr "type" "fmov,sseicvt,sseicvt")
5010    (set_attr "mode" "<MODEF:MODE>")
5011    (set_attr "unit" "i387,*,*")
5012    (set_attr "athlon_decode" "*,double,direct")
5013    (set_attr "amdfam10_decode" "*,vector,double")
5014    (set_attr "fp_int_src" "true")])
5015
5016 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5017   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5018         (float:MODEF
5019           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5020   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5021    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5022    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5023   "@
5024    fild%z1\t%1
5025    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5026   [(set_attr "type" "fmov,sseicvt")
5027    (set_attr "mode" "<MODEF:MODE>")
5028    (set_attr "athlon_decode" "*,direct")
5029    (set_attr "amdfam10_decode" "*,double")
5030    (set_attr "fp_int_src" "true")])
5031
5032 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5033   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5034         (float:MODEF
5035           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5036    (clobber (match_operand:SI 2 "memory_operand" "=m,m,m"))]
5037   "TARGET_SSE2 && TARGET_SSE_MATH
5038    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5039   "#"
5040   [(set_attr "type" "sseicvt")
5041    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5042    (set_attr "athlon_decode" "double,direct,double")
5043    (set_attr "amdfam10_decode" "vector,double,double")
5044    (set_attr "fp_int_src" "true")])
5045
5046 (define_insn "*floatsi<mode>2_vector_sse"
5047   [(set (match_operand:MODEF 0 "register_operand" "=x")
5048         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5049   "TARGET_SSE2 && TARGET_SSE_MATH
5050    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5051   "#"
5052   [(set_attr "type" "sseicvt")
5053    (set_attr "mode" "<MODE>")
5054    (set_attr "athlon_decode" "direct")
5055    (set_attr "amdfam10_decode" "double")
5056    (set_attr "fp_int_src" "true")])
5057
5058 (define_split
5059   [(set (match_operand:MODEF 0 "register_operand" "")
5060         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5061    (clobber (match_operand:SI 2 "memory_operand" ""))]
5062   "TARGET_SSE2 && TARGET_SSE_MATH
5063    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5064    && reload_completed
5065    && (SSE_REG_P (operands[0])
5066        || (GET_CODE (operands[0]) == SUBREG
5067            && SSE_REG_P (operands[0])))"
5068   [(const_int 0)]
5069 {
5070   rtx op1 = operands[1];
5071
5072   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5073                                      <MODE>mode, 0);
5074   if (GET_CODE (op1) == SUBREG)
5075     op1 = SUBREG_REG (op1);
5076
5077   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5078     {
5079       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5080       emit_insn (gen_sse2_loadld (operands[4],
5081                                   CONST0_RTX (V4SImode), operands[1]));
5082     }
5083   /* We can ignore possible trapping value in the
5084      high part of SSE register for non-trapping math. */
5085   else if (SSE_REG_P (op1) && !flag_trapping_math)
5086     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5087   else
5088     {
5089       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5090       emit_move_insn (operands[2], operands[1]);
5091       emit_insn (gen_sse2_loadld (operands[4],
5092                                   CONST0_RTX (V4SImode), operands[2]));
5093     }
5094   emit_insn
5095     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5096   DONE;
5097 })
5098
5099 (define_split
5100   [(set (match_operand:MODEF 0 "register_operand" "")
5101         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5102    (clobber (match_operand:SI 2 "memory_operand" ""))]
5103   "TARGET_SSE2 && TARGET_SSE_MATH
5104    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5105    && reload_completed
5106    && (SSE_REG_P (operands[0])
5107        || (GET_CODE (operands[0]) == SUBREG
5108            && SSE_REG_P (operands[0])))"
5109   [(const_int 0)]
5110 {
5111   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5112                                      <MODE>mode, 0);
5113   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5114
5115   emit_insn (gen_sse2_loadld (operands[4],
5116                               CONST0_RTX (V4SImode), operands[1]));
5117   emit_insn
5118     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5119   DONE;
5120 })
5121
5122 (define_split
5123   [(set (match_operand:MODEF 0 "register_operand" "")
5124         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5125   "TARGET_SSE2 && TARGET_SSE_MATH
5126    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5127    && reload_completed
5128    && (SSE_REG_P (operands[0])
5129        || (GET_CODE (operands[0]) == SUBREG
5130            && SSE_REG_P (operands[0])))"
5131   [(const_int 0)]
5132 {
5133   rtx op1 = operands[1];
5134
5135   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5136                                      <MODE>mode, 0);
5137   if (GET_CODE (op1) == SUBREG)
5138     op1 = SUBREG_REG (op1);
5139
5140   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5141     {
5142       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5143       emit_insn (gen_sse2_loadld (operands[4],
5144                                   CONST0_RTX (V4SImode), operands[1]));
5145     }
5146   /* We can ignore possible trapping value in the
5147      high part of SSE register for non-trapping math. */
5148   else if (SSE_REG_P (op1) && !flag_trapping_math)
5149     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5150   else
5151     gcc_unreachable ();
5152 })
5153
5154 (define_split
5155   [(set (match_operand:MODEF 0 "register_operand" "")
5156         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5157   "TARGET_SSE2 && TARGET_SSE_MATH
5158    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5159    && reload_completed
5160    && (SSE_REG_P (operands[0])
5161        || (GET_CODE (operands[0]) == SUBREG
5162            && SSE_REG_P (operands[0])))"
5163   [(const_int 0)]
5164 {
5165   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5166                                      <MODE>mode, 0);
5167   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5168
5169   emit_insn (gen_sse2_loadld (operands[4],
5170                               CONST0_RTX (V4SImode), operands[1]));
5171   emit_insn
5172     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5173   DONE;
5174 })
5175
5176 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5177   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5178         (float:MODEF
5179           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5180   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5181   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5182    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5183   "#"
5184   [(set_attr "type" "sseicvt")
5185    (set_attr "mode" "<MODEF:MODE>")
5186    (set_attr "athlon_decode" "double,direct")
5187    (set_attr "amdfam10_decode" "vector,double")
5188    (set_attr "fp_int_src" "true")])
5189
5190 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5191   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5192         (float:MODEF
5193           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5194   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5195    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5196    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5197   "@
5198    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5199    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5200   [(set_attr "type" "sseicvt")
5201    (set_attr "mode" "<MODEF:MODE>")
5202    (set_attr "athlon_decode" "double,direct")
5203    (set_attr "amdfam10_decode" "vector,double")
5204    (set_attr "fp_int_src" "true")])
5205
5206 (define_split
5207   [(set (match_operand:MODEF 0 "register_operand" "")
5208         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5209    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5210   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5211    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5213    && reload_completed
5214    && (SSE_REG_P (operands[0])
5215        || (GET_CODE (operands[0]) == SUBREG
5216            && SSE_REG_P (operands[0])))"
5217   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5218   "")
5219
5220 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5221   [(set (match_operand:MODEF 0 "register_operand" "=x")
5222         (float:MODEF
5223           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5224   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5225    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5226    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5227   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5228   [(set_attr "type" "sseicvt")
5229    (set_attr "mode" "<MODEF:MODE>")
5230    (set_attr "athlon_decode" "direct")
5231    (set_attr "amdfam10_decode" "double")
5232    (set_attr "fp_int_src" "true")])
5233
5234 (define_split
5235   [(set (match_operand:MODEF 0 "register_operand" "")
5236         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5237    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5238   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5239    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5240    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5241    && reload_completed
5242    && (SSE_REG_P (operands[0])
5243        || (GET_CODE (operands[0]) == SUBREG
5244            && SSE_REG_P (operands[0])))"
5245   [(set (match_dup 2) (match_dup 1))
5246    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5247   "")
5248
5249 (define_split
5250   [(set (match_operand:MODEF 0 "register_operand" "")
5251         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5252    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5253   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5254    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5255    && reload_completed
5256    && (SSE_REG_P (operands[0])
5257        || (GET_CODE (operands[0]) == SUBREG
5258            && SSE_REG_P (operands[0])))"
5259   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5260   "")
5261
5262 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5263   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5264         (float:X87MODEF
5265           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5266   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5267   "TARGET_80387"
5268   "@
5269    fild%z1\t%1
5270    #"
5271   [(set_attr "type" "fmov,multi")
5272    (set_attr "mode" "<X87MODEF:MODE>")
5273    (set_attr "unit" "*,i387")
5274    (set_attr "fp_int_src" "true")])
5275
5276 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5277   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5278         (float:X87MODEF
5279           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5280   "TARGET_80387"
5281   "fild%z1\t%1"
5282   [(set_attr "type" "fmov")
5283    (set_attr "mode" "<X87MODEF:MODE>")
5284    (set_attr "fp_int_src" "true")])
5285
5286 (define_split
5287   [(set (match_operand:X87MODEF 0 "register_operand" "")
5288         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5289    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5290   "TARGET_80387
5291    && reload_completed
5292    && FP_REG_P (operands[0])"
5293   [(set (match_dup 2) (match_dup 1))
5294    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5295   "")
5296
5297 (define_split
5298   [(set (match_operand:X87MODEF 0 "register_operand" "")
5299         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5300    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5301   "TARGET_80387
5302    && reload_completed
5303    && FP_REG_P (operands[0])"
5304   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5305   "")
5306
5307 ;; Avoid store forwarding (partial memory) stall penalty by extending
5308 ;; SImode value to DImode through XMM register instead of pushing two
5309 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5310 ;; targets benefit from this optimization. Also note that fild
5311 ;; loads from memory only.
5312
5313 (define_insn "*floatunssi<mode>2_1"
5314   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5315         (unsigned_float:X87MODEF
5316           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5317    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5318    (clobber (match_scratch:SI 3 "=X,x"))]
5319   "!TARGET_64BIT
5320    && TARGET_80387 && TARGET_SSE"
5321   "#"
5322   [(set_attr "type" "multi")
5323    (set_attr "mode" "<MODE>")])
5324
5325 (define_split
5326   [(set (match_operand:X87MODEF 0 "register_operand" "")
5327         (unsigned_float:X87MODEF
5328           (match_operand:SI 1 "register_operand" "")))
5329    (clobber (match_operand:DI 2 "memory_operand" ""))
5330    (clobber (match_scratch:SI 3 ""))]
5331   "!TARGET_64BIT
5332    && TARGET_80387 && TARGET_SSE
5333    && reload_completed"
5334   [(set (match_dup 2) (match_dup 1))
5335    (set (match_dup 0)
5336         (float:X87MODEF (match_dup 2)))]
5337   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5338
5339 (define_split
5340   [(set (match_operand:X87MODEF 0 "register_operand" "")
5341         (unsigned_float:X87MODEF
5342           (match_operand:SI 1 "memory_operand" "")))
5343    (clobber (match_operand:DI 2 "memory_operand" ""))
5344    (clobber (match_scratch:SI 3 ""))]
5345   "!TARGET_64BIT
5346    && TARGET_80387 && TARGET_SSE
5347    && reload_completed"
5348   [(set (match_dup 2) (match_dup 3))
5349    (set (match_dup 0)
5350         (float:X87MODEF (match_dup 2)))]
5351 {
5352   emit_move_insn (operands[3], operands[1]);
5353   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5354 })
5355
5356 (define_expand "floatunssi<mode>2"
5357   [(parallel
5358      [(set (match_operand:X87MODEF 0 "register_operand" "")
5359            (unsigned_float:X87MODEF
5360              (match_operand:SI 1 "nonimmediate_operand" "")))
5361       (clobber (match_dup 2))
5362       (clobber (match_scratch:SI 3 ""))])]
5363   "!TARGET_64BIT
5364    && ((TARGET_80387 && TARGET_SSE)
5365        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5366 {
5367   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5368     {
5369       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5370       DONE;
5371     }
5372   else
5373     {
5374       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5375       operands[2] = assign_386_stack_local (DImode, slot);
5376     }
5377 })
5378
5379 (define_expand "floatunsdisf2"
5380   [(use (match_operand:SF 0 "register_operand" ""))
5381    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5382   "TARGET_64BIT && TARGET_SSE_MATH"
5383   "x86_emit_floatuns (operands); DONE;")
5384
5385 (define_expand "floatunsdidf2"
5386   [(use (match_operand:DF 0 "register_operand" ""))
5387    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5388   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5389    && TARGET_SSE2 && TARGET_SSE_MATH"
5390 {
5391   if (TARGET_64BIT)
5392     x86_emit_floatuns (operands);
5393   else
5394     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5395   DONE;
5396 })
5397 \f
5398 ;; Add instructions
5399
5400 ;; %%% splits for addditi3
5401
5402 (define_expand "addti3"
5403   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5404         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5405                  (match_operand:TI 2 "x86_64_general_operand" "")))
5406    (clobber (reg:CC FLAGS_REG))]
5407   "TARGET_64BIT"
5408   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5409
5410 (define_insn "*addti3_1"
5411   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5412         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5413                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5414    (clobber (reg:CC FLAGS_REG))]
5415   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5416   "#")
5417
5418 (define_split
5419   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5420         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5421                  (match_operand:TI 2 "x86_64_general_operand" "")))
5422    (clobber (reg:CC FLAGS_REG))]
5423   "TARGET_64BIT && reload_completed"
5424   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5425                                           UNSPEC_ADD_CARRY))
5426               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5427    (parallel [(set (match_dup 3)
5428                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5429                                      (match_dup 4))
5430                             (match_dup 5)))
5431               (clobber (reg:CC FLAGS_REG))])]
5432   "split_ti (operands+0, 1, operands+0, operands+3);
5433    split_ti (operands+1, 1, operands+1, operands+4);
5434    split_ti (operands+2, 1, operands+2, operands+5);")
5435
5436 ;; %%% splits for addsidi3
5437 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5438 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5439 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5440
5441 (define_expand "adddi3"
5442   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5443         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5444                  (match_operand:DI 2 "x86_64_general_operand" "")))
5445    (clobber (reg:CC FLAGS_REG))]
5446   ""
5447   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5448
5449 (define_insn "*adddi3_1"
5450   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5451         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5452                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5453    (clobber (reg:CC FLAGS_REG))]
5454   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5455   "#")
5456
5457 (define_split
5458   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5459         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5460                  (match_operand:DI 2 "general_operand" "")))
5461    (clobber (reg:CC FLAGS_REG))]
5462   "!TARGET_64BIT && reload_completed"
5463   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5464                                           UNSPEC_ADD_CARRY))
5465               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5466    (parallel [(set (match_dup 3)
5467                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5468                                      (match_dup 4))
5469                             (match_dup 5)))
5470               (clobber (reg:CC FLAGS_REG))])]
5471   "split_di (operands+0, 1, operands+0, operands+3);
5472    split_di (operands+1, 1, operands+1, operands+4);
5473    split_di (operands+2, 1, operands+2, operands+5);")
5474
5475 (define_insn "adddi3_carry_rex64"
5476   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5477           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5478                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5479                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5480    (clobber (reg:CC FLAGS_REG))]
5481   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5482   "adc{q}\t{%2, %0|%0, %2}"
5483   [(set_attr "type" "alu")
5484    (set_attr "pent_pair" "pu")
5485    (set_attr "mode" "DI")])
5486
5487 (define_insn "*adddi3_cc_rex64"
5488   [(set (reg:CC FLAGS_REG)
5489         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5490                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5491                    UNSPEC_ADD_CARRY))
5492    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5493         (plus:DI (match_dup 1) (match_dup 2)))]
5494   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5495   "add{q}\t{%2, %0|%0, %2}"
5496   [(set_attr "type" "alu")
5497    (set_attr "mode" "DI")])
5498
5499 (define_insn "*<addsub><mode>3_cc_overflow"
5500   [(set (reg:CCC FLAGS_REG)
5501         (compare:CCC
5502             (plusminus:SWI
5503                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5504                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5505             (match_dup 1)))
5506    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5507         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5508   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5509   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5510   [(set_attr "type" "alu")
5511    (set_attr "mode" "<MODE>")])
5512
5513 (define_insn "*add<mode>3_cconly_overflow"
5514   [(set (reg:CCC FLAGS_REG)
5515         (compare:CCC
5516                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5517                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5518                 (match_dup 1)))
5519    (clobber (match_scratch:SWI 0 "=<r>"))]
5520   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5521   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5522   [(set_attr "type" "alu")
5523    (set_attr "mode" "<MODE>")])
5524
5525 (define_insn "*sub<mode>3_cconly_overflow"
5526   [(set (reg:CCC FLAGS_REG)
5527         (compare:CCC
5528              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5529                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5530              (match_dup 0)))]
5531   ""
5532   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5533   [(set_attr "type" "icmp")
5534    (set_attr "mode" "<MODE>")])
5535
5536 (define_insn "*<addsub>si3_zext_cc_overflow"
5537   [(set (reg:CCC FLAGS_REG)
5538         (compare:CCC
5539             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5540                           (match_operand:SI 2 "general_operand" "g"))
5541             (match_dup 1)))
5542    (set (match_operand:DI 0 "register_operand" "=r")
5543         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5544   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5545   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5546   [(set_attr "type" "alu")
5547    (set_attr "mode" "SI")])
5548
5549 (define_insn "addqi3_carry"
5550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5551           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5552                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5553                    (match_operand:QI 2 "general_operand" "qi,qm")))
5554    (clobber (reg:CC FLAGS_REG))]
5555   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5556   "adc{b}\t{%2, %0|%0, %2}"
5557   [(set_attr "type" "alu")
5558    (set_attr "pent_pair" "pu")
5559    (set_attr "mode" "QI")])
5560
5561 (define_insn "addhi3_carry"
5562   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5563           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5564                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5565                    (match_operand:HI 2 "general_operand" "ri,rm")))
5566    (clobber (reg:CC FLAGS_REG))]
5567   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5568   "adc{w}\t{%2, %0|%0, %2}"
5569   [(set_attr "type" "alu")
5570    (set_attr "pent_pair" "pu")
5571    (set_attr "mode" "HI")])
5572
5573 (define_insn "addsi3_carry"
5574   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5575           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5576                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5577                    (match_operand:SI 2 "general_operand" "ri,rm")))
5578    (clobber (reg:CC FLAGS_REG))]
5579   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5580   "adc{l}\t{%2, %0|%0, %2}"
5581   [(set_attr "type" "alu")
5582    (set_attr "pent_pair" "pu")
5583    (set_attr "mode" "SI")])
5584
5585 (define_insn "*addsi3_carry_zext"
5586   [(set (match_operand:DI 0 "register_operand" "=r")
5587           (zero_extend:DI
5588             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5589                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5590                      (match_operand:SI 2 "general_operand" "g"))))
5591    (clobber (reg:CC FLAGS_REG))]
5592   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5593   "adc{l}\t{%2, %k0|%k0, %2}"
5594   [(set_attr "type" "alu")
5595    (set_attr "pent_pair" "pu")
5596    (set_attr "mode" "SI")])
5597
5598 (define_insn "*addsi3_cc"
5599   [(set (reg:CC FLAGS_REG)
5600         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5601                     (match_operand:SI 2 "general_operand" "ri,rm")]
5602                    UNSPEC_ADD_CARRY))
5603    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5604         (plus:SI (match_dup 1) (match_dup 2)))]
5605   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5606   "add{l}\t{%2, %0|%0, %2}"
5607   [(set_attr "type" "alu")
5608    (set_attr "mode" "SI")])
5609
5610 (define_insn "addqi3_cc"
5611   [(set (reg:CC FLAGS_REG)
5612         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5613                     (match_operand:QI 2 "general_operand" "qi,qm")]
5614                    UNSPEC_ADD_CARRY))
5615    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5616         (plus:QI (match_dup 1) (match_dup 2)))]
5617   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5618   "add{b}\t{%2, %0|%0, %2}"
5619   [(set_attr "type" "alu")
5620    (set_attr "mode" "QI")])
5621
5622 (define_expand "addsi3"
5623   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5624                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5625                             (match_operand:SI 2 "general_operand" "")))
5626               (clobber (reg:CC FLAGS_REG))])]
5627   ""
5628   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5629
5630 (define_insn "*lea_1"
5631   [(set (match_operand:SI 0 "register_operand" "=r")
5632         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5633   "!TARGET_64BIT"
5634   "lea{l}\t{%a1, %0|%0, %a1}"
5635   [(set_attr "type" "lea")
5636    (set_attr "mode" "SI")])
5637
5638 (define_insn "*lea_1_rex64"
5639   [(set (match_operand:SI 0 "register_operand" "=r")
5640         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5641   "TARGET_64BIT"
5642   "lea{l}\t{%a1, %0|%0, %a1}"
5643   [(set_attr "type" "lea")
5644    (set_attr "mode" "SI")])
5645
5646 (define_insn "*lea_1_zext"
5647   [(set (match_operand:DI 0 "register_operand" "=r")
5648         (zero_extend:DI
5649          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5650   "TARGET_64BIT"
5651   "lea{l}\t{%a1, %k0|%k0, %a1}"
5652   [(set_attr "type" "lea")
5653    (set_attr "mode" "SI")])
5654
5655 (define_insn "*lea_2_rex64"
5656   [(set (match_operand:DI 0 "register_operand" "=r")
5657         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5658   "TARGET_64BIT"
5659   "lea{q}\t{%a1, %0|%0, %a1}"
5660   [(set_attr "type" "lea")
5661    (set_attr "mode" "DI")])
5662
5663 ;; The lea patterns for non-Pmodes needs to be matched by several
5664 ;; insns converted to real lea by splitters.
5665
5666 (define_insn_and_split "*lea_general_1"
5667   [(set (match_operand 0 "register_operand" "=r")
5668         (plus (plus (match_operand 1 "index_register_operand" "l")
5669                     (match_operand 2 "register_operand" "r"))
5670               (match_operand 3 "immediate_operand" "i")))]
5671   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5672     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5673    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5674    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5675    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5676    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5677        || GET_MODE (operands[3]) == VOIDmode)"
5678   "#"
5679   "&& reload_completed"
5680   [(const_int 0)]
5681 {
5682   rtx pat;
5683   operands[0] = gen_lowpart (SImode, operands[0]);
5684   operands[1] = gen_lowpart (Pmode, operands[1]);
5685   operands[2] = gen_lowpart (Pmode, operands[2]);
5686   operands[3] = gen_lowpart (Pmode, operands[3]);
5687   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5688                       operands[3]);
5689   if (Pmode != SImode)
5690     pat = gen_rtx_SUBREG (SImode, pat, 0);
5691   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5692   DONE;
5693 }
5694   [(set_attr "type" "lea")
5695    (set_attr "mode" "SI")])
5696
5697 (define_insn_and_split "*lea_general_1_zext"
5698   [(set (match_operand:DI 0 "register_operand" "=r")
5699         (zero_extend:DI
5700           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5701                             (match_operand:SI 2 "register_operand" "r"))
5702                    (match_operand:SI 3 "immediate_operand" "i"))))]
5703   "TARGET_64BIT"
5704   "#"
5705   "&& reload_completed"
5706   [(set (match_dup 0)
5707         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5708                                                      (match_dup 2))
5709                                             (match_dup 3)) 0)))]
5710 {
5711   operands[1] = gen_lowpart (Pmode, operands[1]);
5712   operands[2] = gen_lowpart (Pmode, operands[2]);
5713   operands[3] = gen_lowpart (Pmode, operands[3]);
5714 }
5715   [(set_attr "type" "lea")
5716    (set_attr "mode" "SI")])
5717
5718 (define_insn_and_split "*lea_general_2"
5719   [(set (match_operand 0 "register_operand" "=r")
5720         (plus (mult (match_operand 1 "index_register_operand" "l")
5721                     (match_operand 2 "const248_operand" "i"))
5722               (match_operand 3 "nonmemory_operand" "ri")))]
5723   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5724     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5725    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5726    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5727    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5728        || GET_MODE (operands[3]) == VOIDmode)"
5729   "#"
5730   "&& reload_completed"
5731   [(const_int 0)]
5732 {
5733   rtx pat;
5734   operands[0] = gen_lowpart (SImode, operands[0]);
5735   operands[1] = gen_lowpart (Pmode, operands[1]);
5736   operands[3] = gen_lowpart (Pmode, operands[3]);
5737   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5738                       operands[3]);
5739   if (Pmode != SImode)
5740     pat = gen_rtx_SUBREG (SImode, pat, 0);
5741   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5742   DONE;
5743 }
5744   [(set_attr "type" "lea")
5745    (set_attr "mode" "SI")])
5746
5747 (define_insn_and_split "*lea_general_2_zext"
5748   [(set (match_operand:DI 0 "register_operand" "=r")
5749         (zero_extend:DI
5750           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5751                             (match_operand:SI 2 "const248_operand" "n"))
5752                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5753   "TARGET_64BIT"
5754   "#"
5755   "&& reload_completed"
5756   [(set (match_dup 0)
5757         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5758                                                      (match_dup 2))
5759                                             (match_dup 3)) 0)))]
5760 {
5761   operands[1] = gen_lowpart (Pmode, operands[1]);
5762   operands[3] = gen_lowpart (Pmode, operands[3]);
5763 }
5764   [(set_attr "type" "lea")
5765    (set_attr "mode" "SI")])
5766
5767 (define_insn_and_split "*lea_general_3"
5768   [(set (match_operand 0 "register_operand" "=r")
5769         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5770                           (match_operand 2 "const248_operand" "i"))
5771                     (match_operand 3 "register_operand" "r"))
5772               (match_operand 4 "immediate_operand" "i")))]
5773   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5774     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5775    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5776    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5777    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5778   "#"
5779   "&& reload_completed"
5780   [(const_int 0)]
5781 {
5782   rtx pat;
5783   operands[0] = gen_lowpart (SImode, operands[0]);
5784   operands[1] = gen_lowpart (Pmode, operands[1]);
5785   operands[3] = gen_lowpart (Pmode, operands[3]);
5786   operands[4] = gen_lowpart (Pmode, operands[4]);
5787   pat = gen_rtx_PLUS (Pmode,
5788                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5789                                                          operands[2]),
5790                                     operands[3]),
5791                       operands[4]);
5792   if (Pmode != SImode)
5793     pat = gen_rtx_SUBREG (SImode, pat, 0);
5794   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5795   DONE;
5796 }
5797   [(set_attr "type" "lea")
5798    (set_attr "mode" "SI")])
5799
5800 (define_insn_and_split "*lea_general_3_zext"
5801   [(set (match_operand:DI 0 "register_operand" "=r")
5802         (zero_extend:DI
5803           (plus:SI (plus:SI (mult:SI
5804                               (match_operand:SI 1 "index_register_operand" "l")
5805                               (match_operand:SI 2 "const248_operand" "n"))
5806                             (match_operand:SI 3 "register_operand" "r"))
5807                    (match_operand:SI 4 "immediate_operand" "i"))))]
5808   "TARGET_64BIT"
5809   "#"
5810   "&& reload_completed"
5811   [(set (match_dup 0)
5812         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5813                                                               (match_dup 2))
5814                                                      (match_dup 3))
5815                                             (match_dup 4)) 0)))]
5816 {
5817   operands[1] = gen_lowpart (Pmode, operands[1]);
5818   operands[3] = gen_lowpart (Pmode, operands[3]);
5819   operands[4] = gen_lowpart (Pmode, operands[4]);
5820 }
5821   [(set_attr "type" "lea")
5822    (set_attr "mode" "SI")])
5823
5824 (define_insn "*adddi_1_rex64"
5825   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5826         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5827                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5828    (clobber (reg:CC FLAGS_REG))]
5829   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5830 {
5831   switch (get_attr_type (insn))
5832     {
5833     case TYPE_LEA:
5834       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5835       return "lea{q}\t{%a2, %0|%0, %a2}";
5836
5837     case TYPE_INCDEC:
5838       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5839       if (operands[2] == const1_rtx)
5840         return "inc{q}\t%0";
5841       else
5842         {
5843           gcc_assert (operands[2] == constm1_rtx);
5844           return "dec{q}\t%0";
5845         }
5846
5847     default:
5848       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5849
5850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5852       if (CONST_INT_P (operands[2])
5853           /* Avoid overflows.  */
5854           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5855           && (INTVAL (operands[2]) == 128
5856               || (INTVAL (operands[2]) < 0
5857                   && INTVAL (operands[2]) != -128)))
5858         {
5859           operands[2] = GEN_INT (-INTVAL (operands[2]));
5860           return "sub{q}\t{%2, %0|%0, %2}";
5861         }
5862       return "add{q}\t{%2, %0|%0, %2}";
5863     }
5864 }
5865   [(set (attr "type")
5866      (cond [(eq_attr "alternative" "2")
5867               (const_string "lea")
5868             ; Current assemblers are broken and do not allow @GOTOFF in
5869             ; ought but a memory context.
5870             (match_operand:DI 2 "pic_symbolic_operand" "")
5871               (const_string "lea")
5872             (match_operand:DI 2 "incdec_operand" "")
5873               (const_string "incdec")
5874            ]
5875            (const_string "alu")))
5876    (set_attr "mode" "DI")])
5877
5878 ;; Convert lea to the lea pattern to avoid flags dependency.
5879 (define_split
5880   [(set (match_operand:DI 0 "register_operand" "")
5881         (plus:DI (match_operand:DI 1 "register_operand" "")
5882                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5883    (clobber (reg:CC FLAGS_REG))]
5884   "TARGET_64BIT && reload_completed
5885    && true_regnum (operands[0]) != true_regnum (operands[1])"
5886   [(set (match_dup 0)
5887         (plus:DI (match_dup 1)
5888                  (match_dup 2)))]
5889   "")
5890
5891 (define_insn "*adddi_2_rex64"
5892   [(set (reg FLAGS_REG)
5893         (compare
5894           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5895                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5896           (const_int 0)))
5897    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5898         (plus:DI (match_dup 1) (match_dup 2)))]
5899   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5900    && ix86_binary_operator_ok (PLUS, DImode, operands)
5901    /* Current assemblers are broken and do not allow @GOTOFF in
5902       ought but a memory context.  */
5903    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5904 {
5905   switch (get_attr_type (insn))
5906     {
5907     case TYPE_INCDEC:
5908       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909       if (operands[2] == const1_rtx)
5910         return "inc{q}\t%0";
5911       else
5912         {
5913           gcc_assert (operands[2] == constm1_rtx);
5914           return "dec{q}\t%0";
5915         }
5916
5917     default:
5918       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5919       /* ???? We ought to handle there the 32bit case too
5920          - do we need new constraint?  */
5921       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5923       if (CONST_INT_P (operands[2])
5924           /* Avoid overflows.  */
5925           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5926           && (INTVAL (operands[2]) == 128
5927               || (INTVAL (operands[2]) < 0
5928                   && INTVAL (operands[2]) != -128)))
5929         {
5930           operands[2] = GEN_INT (-INTVAL (operands[2]));
5931           return "sub{q}\t{%2, %0|%0, %2}";
5932         }
5933       return "add{q}\t{%2, %0|%0, %2}";
5934     }
5935 }
5936   [(set (attr "type")
5937      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5938         (const_string "incdec")
5939         (const_string "alu")))
5940    (set_attr "mode" "DI")])
5941
5942 (define_insn "*adddi_3_rex64"
5943   [(set (reg FLAGS_REG)
5944         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5945                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5946    (clobber (match_scratch:DI 0 "=r"))]
5947   "TARGET_64BIT
5948    && ix86_match_ccmode (insn, CCZmode)
5949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5950    /* Current assemblers are broken and do not allow @GOTOFF in
5951       ought but a memory context.  */
5952    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5953 {
5954   switch (get_attr_type (insn))
5955     {
5956     case TYPE_INCDEC:
5957       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5958       if (operands[2] == const1_rtx)
5959         return "inc{q}\t%0";
5960       else
5961         {
5962           gcc_assert (operands[2] == constm1_rtx);
5963           return "dec{q}\t%0";
5964         }
5965
5966     default:
5967       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5968       /* ???? We ought to handle there the 32bit case too
5969          - do we need new constraint?  */
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if (CONST_INT_P (operands[2])
5973           /* Avoid overflows.  */
5974           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5975           && (INTVAL (operands[2]) == 128
5976               || (INTVAL (operands[2]) < 0
5977                   && INTVAL (operands[2]) != -128)))
5978         {
5979           operands[2] = GEN_INT (-INTVAL (operands[2]));
5980           return "sub{q}\t{%2, %0|%0, %2}";
5981         }
5982       return "add{q}\t{%2, %0|%0, %2}";
5983     }
5984 }
5985   [(set (attr "type")
5986      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5987         (const_string "incdec")
5988         (const_string "alu")))
5989    (set_attr "mode" "DI")])
5990
5991 ; For comparisons against 1, -1 and 128, we may generate better code
5992 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5993 ; is matched then.  We can't accept general immediate, because for
5994 ; case of overflows,  the result is messed up.
5995 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5996 ; when negated.
5997 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5998 ; only for comparisons not depending on it.
5999 (define_insn "*adddi_4_rex64"
6000   [(set (reg FLAGS_REG)
6001         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6002                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6003    (clobber (match_scratch:DI 0 "=rm"))]
6004   "TARGET_64BIT
6005    &&  ix86_match_ccmode (insn, CCGCmode)"
6006 {
6007   switch (get_attr_type (insn))
6008     {
6009     case TYPE_INCDEC:
6010       if (operands[2] == constm1_rtx)
6011         return "inc{q}\t%0";
6012       else
6013         {
6014           gcc_assert (operands[2] == const1_rtx);
6015           return "dec{q}\t%0";
6016         }
6017
6018     default:
6019       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6020       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6021          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6022       if ((INTVAL (operands[2]) == -128
6023            || (INTVAL (operands[2]) > 0
6024                && INTVAL (operands[2]) != 128))
6025           /* Avoid overflows.  */
6026           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6027         return "sub{q}\t{%2, %0|%0, %2}";
6028       operands[2] = GEN_INT (-INTVAL (operands[2]));
6029       return "add{q}\t{%2, %0|%0, %2}";
6030     }
6031 }
6032   [(set (attr "type")
6033      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6034         (const_string "incdec")
6035         (const_string "alu")))
6036    (set_attr "mode" "DI")])
6037
6038 (define_insn "*adddi_5_rex64"
6039   [(set (reg FLAGS_REG)
6040         (compare
6041           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6042                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6043           (const_int 0)))
6044    (clobber (match_scratch:DI 0 "=r"))]
6045   "TARGET_64BIT
6046    && ix86_match_ccmode (insn, CCGOCmode)
6047    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6048    /* Current assemblers are broken and do not allow @GOTOFF in
6049       ought but a memory context.  */
6050    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6051 {
6052   switch (get_attr_type (insn))
6053     {
6054     case TYPE_INCDEC:
6055       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6056       if (operands[2] == const1_rtx)
6057         return "inc{q}\t%0";
6058       else
6059         {
6060           gcc_assert (operands[2] == constm1_rtx);
6061           return "dec{q}\t%0";
6062         }
6063
6064     default:
6065       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6066       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6067          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6068       if (CONST_INT_P (operands[2])
6069           /* Avoid overflows.  */
6070           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6071           && (INTVAL (operands[2]) == 128
6072               || (INTVAL (operands[2]) < 0
6073                   && INTVAL (operands[2]) != -128)))
6074         {
6075           operands[2] = GEN_INT (-INTVAL (operands[2]));
6076           return "sub{q}\t{%2, %0|%0, %2}";
6077         }
6078       return "add{q}\t{%2, %0|%0, %2}";
6079     }
6080 }
6081   [(set (attr "type")
6082      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6083         (const_string "incdec")
6084         (const_string "alu")))
6085    (set_attr "mode" "DI")])
6086
6087
6088 (define_insn "*addsi_1"
6089   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6090         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6091                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6092    (clobber (reg:CC FLAGS_REG))]
6093   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6094 {
6095   switch (get_attr_type (insn))
6096     {
6097     case TYPE_LEA:
6098       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6099       return "lea{l}\t{%a2, %0|%0, %a2}";
6100
6101     case TYPE_INCDEC:
6102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6103       if (operands[2] == const1_rtx)
6104         return "inc{l}\t%0";
6105       else
6106         {
6107           gcc_assert (operands[2] == constm1_rtx);
6108           return "dec{l}\t%0";
6109         }
6110
6111     default:
6112       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6113
6114       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6115          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6116       if (CONST_INT_P (operands[2])
6117           && (INTVAL (operands[2]) == 128
6118               || (INTVAL (operands[2]) < 0
6119                   && INTVAL (operands[2]) != -128)))
6120         {
6121           operands[2] = GEN_INT (-INTVAL (operands[2]));
6122           return "sub{l}\t{%2, %0|%0, %2}";
6123         }
6124       return "add{l}\t{%2, %0|%0, %2}";
6125     }
6126 }
6127   [(set (attr "type")
6128      (cond [(eq_attr "alternative" "2")
6129               (const_string "lea")
6130             ; Current assemblers are broken and do not allow @GOTOFF in
6131             ; ought but a memory context.
6132             (match_operand:SI 2 "pic_symbolic_operand" "")
6133               (const_string "lea")
6134             (match_operand:SI 2 "incdec_operand" "")
6135               (const_string "incdec")
6136            ]
6137            (const_string "alu")))
6138    (set_attr "mode" "SI")])
6139
6140 ;; Convert lea to the lea pattern to avoid flags dependency.
6141 (define_split
6142   [(set (match_operand 0 "register_operand" "")
6143         (plus (match_operand 1 "register_operand" "")
6144               (match_operand 2 "nonmemory_operand" "")))
6145    (clobber (reg:CC FLAGS_REG))]
6146   "reload_completed
6147    && true_regnum (operands[0]) != true_regnum (operands[1])"
6148   [(const_int 0)]
6149 {
6150   rtx pat;
6151   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6152      may confuse gen_lowpart.  */
6153   if (GET_MODE (operands[0]) != Pmode)
6154     {
6155       operands[1] = gen_lowpart (Pmode, operands[1]);
6156       operands[2] = gen_lowpart (Pmode, operands[2]);
6157     }
6158   operands[0] = gen_lowpart (SImode, operands[0]);
6159   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6160   if (Pmode != SImode)
6161     pat = gen_rtx_SUBREG (SImode, pat, 0);
6162   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6163   DONE;
6164 })
6165
6166 ;; It may seem that nonimmediate operand is proper one for operand 1.
6167 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6168 ;; we take care in ix86_binary_operator_ok to not allow two memory
6169 ;; operands so proper swapping will be done in reload.  This allow
6170 ;; patterns constructed from addsi_1 to match.
6171 (define_insn "addsi_1_zext"
6172   [(set (match_operand:DI 0 "register_operand" "=r,r")
6173         (zero_extend:DI
6174           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6175                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6176    (clobber (reg:CC FLAGS_REG))]
6177   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6178 {
6179   switch (get_attr_type (insn))
6180     {
6181     case TYPE_LEA:
6182       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6183       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6184
6185     case TYPE_INCDEC:
6186       if (operands[2] == const1_rtx)
6187         return "inc{l}\t%k0";
6188       else
6189         {
6190           gcc_assert (operands[2] == constm1_rtx);
6191           return "dec{l}\t%k0";
6192         }
6193
6194     default:
6195       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6196          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6197       if (CONST_INT_P (operands[2])
6198           && (INTVAL (operands[2]) == 128
6199               || (INTVAL (operands[2]) < 0
6200                   && INTVAL (operands[2]) != -128)))
6201         {
6202           operands[2] = GEN_INT (-INTVAL (operands[2]));
6203           return "sub{l}\t{%2, %k0|%k0, %2}";
6204         }
6205       return "add{l}\t{%2, %k0|%k0, %2}";
6206     }
6207 }
6208   [(set (attr "type")
6209      (cond [(eq_attr "alternative" "1")
6210               (const_string "lea")
6211             ; Current assemblers are broken and do not allow @GOTOFF in
6212             ; ought but a memory context.
6213             (match_operand:SI 2 "pic_symbolic_operand" "")
6214               (const_string "lea")
6215             (match_operand:SI 2 "incdec_operand" "")
6216               (const_string "incdec")
6217            ]
6218            (const_string "alu")))
6219    (set_attr "mode" "SI")])
6220
6221 ;; Convert lea to the lea pattern to avoid flags dependency.
6222 (define_split
6223   [(set (match_operand:DI 0 "register_operand" "")
6224         (zero_extend:DI
6225           (plus:SI (match_operand:SI 1 "register_operand" "")
6226                    (match_operand:SI 2 "nonmemory_operand" ""))))
6227    (clobber (reg:CC FLAGS_REG))]
6228   "TARGET_64BIT && reload_completed
6229    && true_regnum (operands[0]) != true_regnum (operands[1])"
6230   [(set (match_dup 0)
6231         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6232 {
6233   operands[1] = gen_lowpart (Pmode, operands[1]);
6234   operands[2] = gen_lowpart (Pmode, operands[2]);
6235 })
6236
6237 (define_insn "*addsi_2"
6238   [(set (reg FLAGS_REG)
6239         (compare
6240           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6241                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6242           (const_int 0)))
6243    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6244         (plus:SI (match_dup 1) (match_dup 2)))]
6245   "ix86_match_ccmode (insn, CCGOCmode)
6246    && ix86_binary_operator_ok (PLUS, SImode, operands)
6247    /* Current assemblers are broken and do not allow @GOTOFF in
6248       ought but a memory context.  */
6249    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6250 {
6251   switch (get_attr_type (insn))
6252     {
6253     case TYPE_INCDEC:
6254       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6255       if (operands[2] == const1_rtx)
6256         return "inc{l}\t%0";
6257       else
6258         {
6259           gcc_assert (operands[2] == constm1_rtx);
6260           return "dec{l}\t%0";
6261         }
6262
6263     default:
6264       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6267       if (CONST_INT_P (operands[2])
6268           && (INTVAL (operands[2]) == 128
6269               || (INTVAL (operands[2]) < 0
6270                   && INTVAL (operands[2]) != -128)))
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           return "sub{l}\t{%2, %0|%0, %2}";
6274         }
6275       return "add{l}\t{%2, %0|%0, %2}";
6276     }
6277 }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu")))
6282    (set_attr "mode" "SI")])
6283
6284 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6285 (define_insn "*addsi_2_zext"
6286   [(set (reg FLAGS_REG)
6287         (compare
6288           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6289                    (match_operand:SI 2 "general_operand" "rmni"))
6290           (const_int 0)))
6291    (set (match_operand:DI 0 "register_operand" "=r")
6292         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6293   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6294    && ix86_binary_operator_ok (PLUS, SImode, operands)
6295    /* Current assemblers are broken and do not allow @GOTOFF in
6296       ought but a memory context.  */
6297    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6298 {
6299   switch (get_attr_type (insn))
6300     {
6301     case TYPE_INCDEC:
6302       if (operands[2] == const1_rtx)
6303         return "inc{l}\t%k0";
6304       else
6305         {
6306           gcc_assert (operands[2] == constm1_rtx);
6307           return "dec{l}\t%k0";
6308         }
6309
6310     default:
6311       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6312          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6313       if (CONST_INT_P (operands[2])
6314           && (INTVAL (operands[2]) == 128
6315               || (INTVAL (operands[2]) < 0
6316                   && INTVAL (operands[2]) != -128)))
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           return "sub{l}\t{%2, %k0|%k0, %2}";
6320         }
6321       return "add{l}\t{%2, %k0|%k0, %2}";
6322     }
6323 }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "SI")])
6329
6330 (define_insn "*addsi_3"
6331   [(set (reg FLAGS_REG)
6332         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6333                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6334    (clobber (match_scratch:SI 0 "=r"))]
6335   "ix86_match_ccmode (insn, CCZmode)
6336    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6337    /* Current assemblers are broken and do not allow @GOTOFF in
6338       ought but a memory context.  */
6339    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345       if (operands[2] == const1_rtx)
6346         return "inc{l}\t%0";
6347       else
6348         {
6349           gcc_assert (operands[2] == constm1_rtx);
6350           return "dec{l}\t%0";
6351         }
6352
6353     default:
6354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6356          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6357       if (CONST_INT_P (operands[2])
6358           && (INTVAL (operands[2]) == 128
6359               || (INTVAL (operands[2]) < 0
6360                   && INTVAL (operands[2]) != -128)))
6361         {
6362           operands[2] = GEN_INT (-INTVAL (operands[2]));
6363           return "sub{l}\t{%2, %0|%0, %2}";
6364         }
6365       return "add{l}\t{%2, %0|%0, %2}";
6366     }
6367 }
6368   [(set (attr "type")
6369      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6370         (const_string "incdec")
6371         (const_string "alu")))
6372    (set_attr "mode" "SI")])
6373
6374 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6375 (define_insn "*addsi_3_zext"
6376   [(set (reg FLAGS_REG)
6377         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6378                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6379    (set (match_operand:DI 0 "register_operand" "=r")
6380         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6381   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6382    && ix86_binary_operator_ok (PLUS, SImode, operands)
6383    /* Current assemblers are broken and do not allow @GOTOFF in
6384       ought but a memory context.  */
6385    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6386 {
6387   switch (get_attr_type (insn))
6388     {
6389     case TYPE_INCDEC:
6390       if (operands[2] == const1_rtx)
6391         return "inc{l}\t%k0";
6392       else
6393         {
6394           gcc_assert (operands[2] == constm1_rtx);
6395           return "dec{l}\t%k0";
6396         }
6397
6398     default:
6399       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6400          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6401       if (CONST_INT_P (operands[2])
6402           && (INTVAL (operands[2]) == 128
6403               || (INTVAL (operands[2]) < 0
6404                   && INTVAL (operands[2]) != -128)))
6405         {
6406           operands[2] = GEN_INT (-INTVAL (operands[2]));
6407           return "sub{l}\t{%2, %k0|%k0, %2}";
6408         }
6409       return "add{l}\t{%2, %k0|%k0, %2}";
6410     }
6411 }
6412   [(set (attr "type")
6413      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6414         (const_string "incdec")
6415         (const_string "alu")))
6416    (set_attr "mode" "SI")])
6417
6418 ; For comparisons against 1, -1 and 128, we may generate better code
6419 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6420 ; is matched then.  We can't accept general immediate, because for
6421 ; case of overflows,  the result is messed up.
6422 ; This pattern also don't hold of 0x80000000, since the value overflows
6423 ; when negated.
6424 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6425 ; only for comparisons not depending on it.
6426 (define_insn "*addsi_4"
6427   [(set (reg FLAGS_REG)
6428         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6429                  (match_operand:SI 2 "const_int_operand" "n")))
6430    (clobber (match_scratch:SI 0 "=rm"))]
6431   "ix86_match_ccmode (insn, CCGCmode)
6432    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6433 {
6434   switch (get_attr_type (insn))
6435     {
6436     case TYPE_INCDEC:
6437       if (operands[2] == constm1_rtx)
6438         return "inc{l}\t%0";
6439       else
6440         {
6441           gcc_assert (operands[2] == const1_rtx);
6442           return "dec{l}\t%0";
6443         }
6444
6445     default:
6446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6447       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6448          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6449       if ((INTVAL (operands[2]) == -128
6450            || (INTVAL (operands[2]) > 0
6451                && INTVAL (operands[2]) != 128)))
6452         return "sub{l}\t{%2, %0|%0, %2}";
6453       operands[2] = GEN_INT (-INTVAL (operands[2]));
6454       return "add{l}\t{%2, %0|%0, %2}";
6455     }
6456 }
6457   [(set (attr "type")
6458      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6459         (const_string "incdec")
6460         (const_string "alu")))
6461    (set_attr "mode" "SI")])
6462
6463 (define_insn "*addsi_5"
6464   [(set (reg FLAGS_REG)
6465         (compare
6466           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6467                    (match_operand:SI 2 "general_operand" "rmni"))
6468           (const_int 0)))
6469    (clobber (match_scratch:SI 0 "=r"))]
6470   "ix86_match_ccmode (insn, CCGOCmode)
6471    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6472    /* Current assemblers are broken and do not allow @GOTOFF in
6473       ought but a memory context.  */
6474    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6475 {
6476   switch (get_attr_type (insn))
6477     {
6478     case TYPE_INCDEC:
6479       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6480       if (operands[2] == const1_rtx)
6481         return "inc{l}\t%0";
6482       else
6483         {
6484           gcc_assert (operands[2] == constm1_rtx);
6485           return "dec{l}\t%0";
6486         }
6487
6488     default:
6489       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6490       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6491          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6492       if (CONST_INT_P (operands[2])
6493           && (INTVAL (operands[2]) == 128
6494               || (INTVAL (operands[2]) < 0
6495                   && INTVAL (operands[2]) != -128)))
6496         {
6497           operands[2] = GEN_INT (-INTVAL (operands[2]));
6498           return "sub{l}\t{%2, %0|%0, %2}";
6499         }
6500       return "add{l}\t{%2, %0|%0, %2}";
6501     }
6502 }
6503   [(set (attr "type")
6504      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6505         (const_string "incdec")
6506         (const_string "alu")))
6507    (set_attr "mode" "SI")])
6508
6509 (define_expand "addhi3"
6510   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6511                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6512                             (match_operand:HI 2 "general_operand" "")))
6513               (clobber (reg:CC FLAGS_REG))])]
6514   "TARGET_HIMODE_MATH"
6515   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6516
6517 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6518 ;; type optimizations enabled by define-splits.  This is not important
6519 ;; for PII, and in fact harmful because of partial register stalls.
6520
6521 (define_insn "*addhi_1_lea"
6522   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6523         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6524                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6525    (clobber (reg:CC FLAGS_REG))]
6526   "!TARGET_PARTIAL_REG_STALL
6527    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6528 {
6529   switch (get_attr_type (insn))
6530     {
6531     case TYPE_LEA:
6532       return "#";
6533     case TYPE_INCDEC:
6534       if (operands[2] == const1_rtx)
6535         return "inc{w}\t%0";
6536       else
6537         {
6538           gcc_assert (operands[2] == constm1_rtx);
6539           return "dec{w}\t%0";
6540         }
6541
6542     default:
6543       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6544          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6545       if (CONST_INT_P (operands[2])
6546           && (INTVAL (operands[2]) == 128
6547               || (INTVAL (operands[2]) < 0
6548                   && INTVAL (operands[2]) != -128)))
6549         {
6550           operands[2] = GEN_INT (-INTVAL (operands[2]));
6551           return "sub{w}\t{%2, %0|%0, %2}";
6552         }
6553       return "add{w}\t{%2, %0|%0, %2}";
6554     }
6555 }
6556   [(set (attr "type")
6557      (if_then_else (eq_attr "alternative" "2")
6558         (const_string "lea")
6559         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6560            (const_string "incdec")
6561            (const_string "alu"))))
6562    (set_attr "mode" "HI,HI,SI")])
6563
6564 (define_insn "*addhi_1"
6565   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6566         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6567                  (match_operand:HI 2 "general_operand" "ri,rm")))
6568    (clobber (reg:CC FLAGS_REG))]
6569   "TARGET_PARTIAL_REG_STALL
6570    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6571 {
6572   switch (get_attr_type (insn))
6573     {
6574     case TYPE_INCDEC:
6575       if (operands[2] == const1_rtx)
6576         return "inc{w}\t%0";
6577       else
6578         {
6579           gcc_assert (operands[2] == constm1_rtx);
6580           return "dec{w}\t%0";
6581         }
6582
6583     default:
6584       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6585          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6586       if (CONST_INT_P (operands[2])
6587           && (INTVAL (operands[2]) == 128
6588               || (INTVAL (operands[2]) < 0
6589                   && INTVAL (operands[2]) != -128)))
6590         {
6591           operands[2] = GEN_INT (-INTVAL (operands[2]));
6592           return "sub{w}\t{%2, %0|%0, %2}";
6593         }
6594       return "add{w}\t{%2, %0|%0, %2}";
6595     }
6596 }
6597   [(set (attr "type")
6598      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6599         (const_string "incdec")
6600         (const_string "alu")))
6601    (set_attr "mode" "HI")])
6602
6603 (define_insn "*addhi_2"
6604   [(set (reg FLAGS_REG)
6605         (compare
6606           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6607                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6608           (const_int 0)))
6609    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6610         (plus:HI (match_dup 1) (match_dup 2)))]
6611   "ix86_match_ccmode (insn, CCGOCmode)
6612    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6613 {
6614   switch (get_attr_type (insn))
6615     {
6616     case TYPE_INCDEC:
6617       if (operands[2] == const1_rtx)
6618         return "inc{w}\t%0";
6619       else
6620         {
6621           gcc_assert (operands[2] == constm1_rtx);
6622           return "dec{w}\t%0";
6623         }
6624
6625     default:
6626       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6627          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6628       if (CONST_INT_P (operands[2])
6629           && (INTVAL (operands[2]) == 128
6630               || (INTVAL (operands[2]) < 0
6631                   && INTVAL (operands[2]) != -128)))
6632         {
6633           operands[2] = GEN_INT (-INTVAL (operands[2]));
6634           return "sub{w}\t{%2, %0|%0, %2}";
6635         }
6636       return "add{w}\t{%2, %0|%0, %2}";
6637     }
6638 }
6639   [(set (attr "type")
6640      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6641         (const_string "incdec")
6642         (const_string "alu")))
6643    (set_attr "mode" "HI")])
6644
6645 (define_insn "*addhi_3"
6646   [(set (reg FLAGS_REG)
6647         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6648                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6649    (clobber (match_scratch:HI 0 "=r"))]
6650   "ix86_match_ccmode (insn, CCZmode)
6651    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6652 {
6653   switch (get_attr_type (insn))
6654     {
6655     case TYPE_INCDEC:
6656       if (operands[2] == const1_rtx)
6657         return "inc{w}\t%0";
6658       else
6659         {
6660           gcc_assert (operands[2] == constm1_rtx);
6661           return "dec{w}\t%0";
6662         }
6663
6664     default:
6665       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6666          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6667       if (CONST_INT_P (operands[2])
6668           && (INTVAL (operands[2]) == 128
6669               || (INTVAL (operands[2]) < 0
6670                   && INTVAL (operands[2]) != -128)))
6671         {
6672           operands[2] = GEN_INT (-INTVAL (operands[2]));
6673           return "sub{w}\t{%2, %0|%0, %2}";
6674         }
6675       return "add{w}\t{%2, %0|%0, %2}";
6676     }
6677 }
6678   [(set (attr "type")
6679      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6680         (const_string "incdec")
6681         (const_string "alu")))
6682    (set_attr "mode" "HI")])
6683
6684 ; See comments above addsi_4 for details.
6685 (define_insn "*addhi_4"
6686   [(set (reg FLAGS_REG)
6687         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6688                  (match_operand:HI 2 "const_int_operand" "n")))
6689    (clobber (match_scratch:HI 0 "=rm"))]
6690   "ix86_match_ccmode (insn, CCGCmode)
6691    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6692 {
6693   switch (get_attr_type (insn))
6694     {
6695     case TYPE_INCDEC:
6696       if (operands[2] == constm1_rtx)
6697         return "inc{w}\t%0";
6698       else
6699         {
6700           gcc_assert (operands[2] == const1_rtx);
6701           return "dec{w}\t%0";
6702         }
6703
6704     default:
6705       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6706       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6708       if ((INTVAL (operands[2]) == -128
6709            || (INTVAL (operands[2]) > 0
6710                && INTVAL (operands[2]) != 128)))
6711         return "sub{w}\t{%2, %0|%0, %2}";
6712       operands[2] = GEN_INT (-INTVAL (operands[2]));
6713       return "add{w}\t{%2, %0|%0, %2}";
6714     }
6715 }
6716   [(set (attr "type")
6717      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6718         (const_string "incdec")
6719         (const_string "alu")))
6720    (set_attr "mode" "SI")])
6721
6722
6723 (define_insn "*addhi_5"
6724   [(set (reg FLAGS_REG)
6725         (compare
6726           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6727                    (match_operand:HI 2 "general_operand" "rmni"))
6728           (const_int 0)))
6729    (clobber (match_scratch:HI 0 "=r"))]
6730   "ix86_match_ccmode (insn, CCGOCmode)
6731    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6732 {
6733   switch (get_attr_type (insn))
6734     {
6735     case TYPE_INCDEC:
6736       if (operands[2] == const1_rtx)
6737         return "inc{w}\t%0";
6738       else
6739         {
6740           gcc_assert (operands[2] == constm1_rtx);
6741           return "dec{w}\t%0";
6742         }
6743
6744     default:
6745       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6746          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6747       if (CONST_INT_P (operands[2])
6748           && (INTVAL (operands[2]) == 128
6749               || (INTVAL (operands[2]) < 0
6750                   && INTVAL (operands[2]) != -128)))
6751         {
6752           operands[2] = GEN_INT (-INTVAL (operands[2]));
6753           return "sub{w}\t{%2, %0|%0, %2}";
6754         }
6755       return "add{w}\t{%2, %0|%0, %2}";
6756     }
6757 }
6758   [(set (attr "type")
6759      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6760         (const_string "incdec")
6761         (const_string "alu")))
6762    (set_attr "mode" "HI")])
6763
6764 (define_expand "addqi3"
6765   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6766                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6767                             (match_operand:QI 2 "general_operand" "")))
6768               (clobber (reg:CC FLAGS_REG))])]
6769   "TARGET_QIMODE_MATH"
6770   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6771
6772 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6773 (define_insn "*addqi_1_lea"
6774   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6775         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6776                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "!TARGET_PARTIAL_REG_STALL
6779    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6780 {
6781   int widen = (which_alternative == 2);
6782   switch (get_attr_type (insn))
6783     {
6784     case TYPE_LEA:
6785       return "#";
6786     case TYPE_INCDEC:
6787       if (operands[2] == const1_rtx)
6788         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6789       else
6790         {
6791           gcc_assert (operands[2] == constm1_rtx);
6792           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6793         }
6794
6795     default:
6796       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6797          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6798       if (CONST_INT_P (operands[2])
6799           && (INTVAL (operands[2]) == 128
6800               || (INTVAL (operands[2]) < 0
6801                   && INTVAL (operands[2]) != -128)))
6802         {
6803           operands[2] = GEN_INT (-INTVAL (operands[2]));
6804           if (widen)
6805             return "sub{l}\t{%2, %k0|%k0, %2}";
6806           else
6807             return "sub{b}\t{%2, %0|%0, %2}";
6808         }
6809       if (widen)
6810         return "add{l}\t{%k2, %k0|%k0, %k2}";
6811       else
6812         return "add{b}\t{%2, %0|%0, %2}";
6813     }
6814 }
6815   [(set (attr "type")
6816      (if_then_else (eq_attr "alternative" "3")
6817         (const_string "lea")
6818         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6819            (const_string "incdec")
6820            (const_string "alu"))))
6821    (set_attr "mode" "QI,QI,SI,SI")])
6822
6823 (define_insn "*addqi_1"
6824   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6825         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6826                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6827    (clobber (reg:CC FLAGS_REG))]
6828   "TARGET_PARTIAL_REG_STALL
6829    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6830 {
6831   int widen = (which_alternative == 2);
6832   switch (get_attr_type (insn))
6833     {
6834     case TYPE_INCDEC:
6835       if (operands[2] == const1_rtx)
6836         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6837       else
6838         {
6839           gcc_assert (operands[2] == constm1_rtx);
6840           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6841         }
6842
6843     default:
6844       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6845          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6846       if (CONST_INT_P (operands[2])
6847           && (INTVAL (operands[2]) == 128
6848               || (INTVAL (operands[2]) < 0
6849                   && INTVAL (operands[2]) != -128)))
6850         {
6851           operands[2] = GEN_INT (-INTVAL (operands[2]));
6852           if (widen)
6853             return "sub{l}\t{%2, %k0|%k0, %2}";
6854           else
6855             return "sub{b}\t{%2, %0|%0, %2}";
6856         }
6857       if (widen)
6858         return "add{l}\t{%k2, %k0|%k0, %k2}";
6859       else
6860         return "add{b}\t{%2, %0|%0, %2}";
6861     }
6862 }
6863   [(set (attr "type")
6864      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6865         (const_string "incdec")
6866         (const_string "alu")))
6867    (set_attr "mode" "QI,QI,SI")])
6868
6869 (define_insn "*addqi_1_slp"
6870   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6871         (plus:QI (match_dup 0)
6872                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6873    (clobber (reg:CC FLAGS_REG))]
6874   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6875    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6876 {
6877   switch (get_attr_type (insn))
6878     {
6879     case TYPE_INCDEC:
6880       if (operands[1] == const1_rtx)
6881         return "inc{b}\t%0";
6882       else
6883         {
6884           gcc_assert (operands[1] == constm1_rtx);
6885           return "dec{b}\t%0";
6886         }
6887
6888     default:
6889       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6890       if (CONST_INT_P (operands[1])
6891           && INTVAL (operands[1]) < 0)
6892         {
6893           operands[1] = GEN_INT (-INTVAL (operands[1]));
6894           return "sub{b}\t{%1, %0|%0, %1}";
6895         }
6896       return "add{b}\t{%1, %0|%0, %1}";
6897     }
6898 }
6899   [(set (attr "type")
6900      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6901         (const_string "incdec")
6902         (const_string "alu1")))
6903    (set (attr "memory")
6904      (if_then_else (match_operand 1 "memory_operand" "")
6905         (const_string "load")
6906         (const_string "none")))
6907    (set_attr "mode" "QI")])
6908
6909 (define_insn "*addqi_2"
6910   [(set (reg FLAGS_REG)
6911         (compare
6912           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6913                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6914           (const_int 0)))
6915    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6916         (plus:QI (match_dup 1) (match_dup 2)))]
6917   "ix86_match_ccmode (insn, CCGOCmode)
6918    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6919 {
6920   switch (get_attr_type (insn))
6921     {
6922     case TYPE_INCDEC:
6923       if (operands[2] == const1_rtx)
6924         return "inc{b}\t%0";
6925       else
6926         {
6927           gcc_assert (operands[2] == constm1_rtx
6928                       || (CONST_INT_P (operands[2])
6929                           && INTVAL (operands[2]) == 255));
6930           return "dec{b}\t%0";
6931         }
6932
6933     default:
6934       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6935       if (CONST_INT_P (operands[2])
6936           && INTVAL (operands[2]) < 0)
6937         {
6938           operands[2] = GEN_INT (-INTVAL (operands[2]));
6939           return "sub{b}\t{%2, %0|%0, %2}";
6940         }
6941       return "add{b}\t{%2, %0|%0, %2}";
6942     }
6943 }
6944   [(set (attr "type")
6945      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6946         (const_string "incdec")
6947         (const_string "alu")))
6948    (set_attr "mode" "QI")])
6949
6950 (define_insn "*addqi_3"
6951   [(set (reg FLAGS_REG)
6952         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6953                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6954    (clobber (match_scratch:QI 0 "=q"))]
6955   "ix86_match_ccmode (insn, CCZmode)
6956    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6957 {
6958   switch (get_attr_type (insn))
6959     {
6960     case TYPE_INCDEC:
6961       if (operands[2] == const1_rtx)
6962         return "inc{b}\t%0";
6963       else
6964         {
6965           gcc_assert (operands[2] == constm1_rtx
6966                       || (CONST_INT_P (operands[2])
6967                           && INTVAL (operands[2]) == 255));
6968           return "dec{b}\t%0";
6969         }
6970
6971     default:
6972       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6973       if (CONST_INT_P (operands[2])
6974           && INTVAL (operands[2]) < 0)
6975         {
6976           operands[2] = GEN_INT (-INTVAL (operands[2]));
6977           return "sub{b}\t{%2, %0|%0, %2}";
6978         }
6979       return "add{b}\t{%2, %0|%0, %2}";
6980     }
6981 }
6982   [(set (attr "type")
6983      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6984         (const_string "incdec")
6985         (const_string "alu")))
6986    (set_attr "mode" "QI")])
6987
6988 ; See comments above addsi_4 for details.
6989 (define_insn "*addqi_4"
6990   [(set (reg FLAGS_REG)
6991         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6992                  (match_operand:QI 2 "const_int_operand" "n")))
6993    (clobber (match_scratch:QI 0 "=qm"))]
6994   "ix86_match_ccmode (insn, CCGCmode)
6995    && (INTVAL (operands[2]) & 0xff) != 0x80"
6996 {
6997   switch (get_attr_type (insn))
6998     {
6999     case TYPE_INCDEC:
7000       if (operands[2] == constm1_rtx
7001           || (CONST_INT_P (operands[2])
7002               && INTVAL (operands[2]) == 255))
7003         return "inc{b}\t%0";
7004       else
7005         {
7006           gcc_assert (operands[2] == const1_rtx);
7007           return "dec{b}\t%0";
7008         }
7009
7010     default:
7011       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7012       if (INTVAL (operands[2]) < 0)
7013         {
7014           operands[2] = GEN_INT (-INTVAL (operands[2]));
7015           return "add{b}\t{%2, %0|%0, %2}";
7016         }
7017       return "sub{b}\t{%2, %0|%0, %2}";
7018     }
7019 }
7020   [(set (attr "type")
7021      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7022         (const_string "incdec")
7023         (const_string "alu")))
7024    (set_attr "mode" "QI")])
7025
7026
7027 (define_insn "*addqi_5"
7028   [(set (reg FLAGS_REG)
7029         (compare
7030           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031                    (match_operand:QI 2 "general_operand" "qmni"))
7032           (const_int 0)))
7033    (clobber (match_scratch:QI 0 "=q"))]
7034   "ix86_match_ccmode (insn, CCGOCmode)
7035    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 {
7037   switch (get_attr_type (insn))
7038     {
7039     case TYPE_INCDEC:
7040       if (operands[2] == const1_rtx)
7041         return "inc{b}\t%0";
7042       else
7043         {
7044           gcc_assert (operands[2] == constm1_rtx
7045                       || (CONST_INT_P (operands[2])
7046                           && INTVAL (operands[2]) == 255));
7047           return "dec{b}\t%0";
7048         }
7049
7050     default:
7051       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7052       if (CONST_INT_P (operands[2])
7053           && INTVAL (operands[2]) < 0)
7054         {
7055           operands[2] = GEN_INT (-INTVAL (operands[2]));
7056           return "sub{b}\t{%2, %0|%0, %2}";
7057         }
7058       return "add{b}\t{%2, %0|%0, %2}";
7059     }
7060 }
7061   [(set (attr "type")
7062      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7063         (const_string "incdec")
7064         (const_string "alu")))
7065    (set_attr "mode" "QI")])
7066
7067
7068 (define_insn "addqi_ext_1"
7069   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7070                          (const_int 8)
7071                          (const_int 8))
7072         (plus:SI
7073           (zero_extract:SI
7074             (match_operand 1 "ext_register_operand" "0")
7075             (const_int 8)
7076             (const_int 8))
7077           (match_operand:QI 2 "general_operand" "Qmn")))
7078    (clobber (reg:CC FLAGS_REG))]
7079   "!TARGET_64BIT"
7080 {
7081   switch (get_attr_type (insn))
7082     {
7083     case TYPE_INCDEC:
7084       if (operands[2] == const1_rtx)
7085         return "inc{b}\t%h0";
7086       else
7087         {
7088           gcc_assert (operands[2] == constm1_rtx
7089                       || (CONST_INT_P (operands[2])
7090                           && INTVAL (operands[2]) == 255));
7091           return "dec{b}\t%h0";
7092         }
7093
7094     default:
7095       return "add{b}\t{%2, %h0|%h0, %2}";
7096     }
7097 }
7098   [(set (attr "type")
7099      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7100         (const_string "incdec")
7101         (const_string "alu")))
7102    (set_attr "mode" "QI")])
7103
7104 (define_insn "*addqi_ext_1_rex64"
7105   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7106                          (const_int 8)
7107                          (const_int 8))
7108         (plus:SI
7109           (zero_extract:SI
7110             (match_operand 1 "ext_register_operand" "0")
7111             (const_int 8)
7112             (const_int 8))
7113           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7114    (clobber (reg:CC FLAGS_REG))]
7115   "TARGET_64BIT"
7116 {
7117   switch (get_attr_type (insn))
7118     {
7119     case TYPE_INCDEC:
7120       if (operands[2] == const1_rtx)
7121         return "inc{b}\t%h0";
7122       else
7123         {
7124           gcc_assert (operands[2] == constm1_rtx
7125                       || (CONST_INT_P (operands[2])
7126                           && INTVAL (operands[2]) == 255));
7127           return "dec{b}\t%h0";
7128         }
7129
7130     default:
7131       return "add{b}\t{%2, %h0|%h0, %2}";
7132     }
7133 }
7134   [(set (attr "type")
7135      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7136         (const_string "incdec")
7137         (const_string "alu")))
7138    (set_attr "mode" "QI")])
7139
7140 (define_insn "*addqi_ext_2"
7141   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7142                          (const_int 8)
7143                          (const_int 8))
7144         (plus:SI
7145           (zero_extract:SI
7146             (match_operand 1 "ext_register_operand" "%0")
7147             (const_int 8)
7148             (const_int 8))
7149           (zero_extract:SI
7150             (match_operand 2 "ext_register_operand" "Q")
7151             (const_int 8)
7152             (const_int 8))))
7153    (clobber (reg:CC FLAGS_REG))]
7154   ""
7155   "add{b}\t{%h2, %h0|%h0, %h2}"
7156   [(set_attr "type" "alu")
7157    (set_attr "mode" "QI")])
7158
7159 ;; The patterns that match these are at the end of this file.
7160
7161 (define_expand "addxf3"
7162   [(set (match_operand:XF 0 "register_operand" "")
7163         (plus:XF (match_operand:XF 1 "register_operand" "")
7164                  (match_operand:XF 2 "register_operand" "")))]
7165   "TARGET_80387"
7166   "")
7167
7168 (define_expand "add<mode>3"
7169   [(set (match_operand:MODEF 0 "register_operand" "")
7170         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7171                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7172   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7173   "")
7174 \f
7175 ;; Subtract instructions
7176
7177 ;; %%% splits for subditi3
7178
7179 (define_expand "subti3"
7180   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7181                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7182                              (match_operand:TI 2 "x86_64_general_operand" "")))
7183               (clobber (reg:CC FLAGS_REG))])]
7184   "TARGET_64BIT"
7185   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7186
7187 (define_insn "*subti3_1"
7188   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7189         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7190                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7191    (clobber (reg:CC FLAGS_REG))]
7192   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7193   "#")
7194
7195 (define_split
7196   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7197         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7198                   (match_operand:TI 2 "x86_64_general_operand" "")))
7199    (clobber (reg:CC FLAGS_REG))]
7200   "TARGET_64BIT && reload_completed"
7201   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7202               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7203    (parallel [(set (match_dup 3)
7204                    (minus:DI (match_dup 4)
7205                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7206                                       (match_dup 5))))
7207               (clobber (reg:CC FLAGS_REG))])]
7208   "split_ti (operands+0, 1, operands+0, operands+3);
7209    split_ti (operands+1, 1, operands+1, operands+4);
7210    split_ti (operands+2, 1, operands+2, operands+5);")
7211
7212 ;; %%% splits for subsidi3
7213
7214 (define_expand "subdi3"
7215   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7216                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7217                              (match_operand:DI 2 "x86_64_general_operand" "")))
7218               (clobber (reg:CC FLAGS_REG))])]
7219   ""
7220   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7221
7222 (define_insn "*subdi3_1"
7223   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7224         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7225                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7226    (clobber (reg:CC FLAGS_REG))]
7227   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7228   "#")
7229
7230 (define_split
7231   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7232         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7233                   (match_operand:DI 2 "general_operand" "")))
7234    (clobber (reg:CC FLAGS_REG))]
7235   "!TARGET_64BIT && reload_completed"
7236   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7237               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7238    (parallel [(set (match_dup 3)
7239                    (minus:SI (match_dup 4)
7240                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7241                                       (match_dup 5))))
7242               (clobber (reg:CC FLAGS_REG))])]
7243   "split_di (operands+0, 1, operands+0, operands+3);
7244    split_di (operands+1, 1, operands+1, operands+4);
7245    split_di (operands+2, 1, operands+2, operands+5);")
7246
7247 (define_insn "subdi3_carry_rex64"
7248   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7249           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7250             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7251                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7252    (clobber (reg:CC FLAGS_REG))]
7253   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7254   "sbb{q}\t{%2, %0|%0, %2}"
7255   [(set_attr "type" "alu")
7256    (set_attr "pent_pair" "pu")
7257    (set_attr "mode" "DI")])
7258
7259 (define_insn "*subdi_1_rex64"
7260   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7261         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7262                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7263    (clobber (reg:CC FLAGS_REG))]
7264   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7265   "sub{q}\t{%2, %0|%0, %2}"
7266   [(set_attr "type" "alu")
7267    (set_attr "mode" "DI")])
7268
7269 (define_insn "*subdi_2_rex64"
7270   [(set (reg FLAGS_REG)
7271         (compare
7272           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7273                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7274           (const_int 0)))
7275    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7276         (minus:DI (match_dup 1) (match_dup 2)))]
7277   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7278    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7279   "sub{q}\t{%2, %0|%0, %2}"
7280   [(set_attr "type" "alu")
7281    (set_attr "mode" "DI")])
7282
7283 (define_insn "*subdi_3_rex63"
7284   [(set (reg FLAGS_REG)
7285         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7286                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7287    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7288         (minus:DI (match_dup 1) (match_dup 2)))]
7289   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7290    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7291   "sub{q}\t{%2, %0|%0, %2}"
7292   [(set_attr "type" "alu")
7293    (set_attr "mode" "DI")])
7294
7295 (define_insn "subqi3_carry"
7296   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7297           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7298             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7299                (match_operand:QI 2 "general_operand" "qi,qm"))))
7300    (clobber (reg:CC FLAGS_REG))]
7301   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7302   "sbb{b}\t{%2, %0|%0, %2}"
7303   [(set_attr "type" "alu")
7304    (set_attr "pent_pair" "pu")
7305    (set_attr "mode" "QI")])
7306
7307 (define_insn "subhi3_carry"
7308   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7309           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7310             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7311                (match_operand:HI 2 "general_operand" "ri,rm"))))
7312    (clobber (reg:CC FLAGS_REG))]
7313   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7314   "sbb{w}\t{%2, %0|%0, %2}"
7315   [(set_attr "type" "alu")
7316    (set_attr "pent_pair" "pu")
7317    (set_attr "mode" "HI")])
7318
7319 (define_insn "subsi3_carry"
7320   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7321           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7322             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7323                (match_operand:SI 2 "general_operand" "ri,rm"))))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7326   "sbb{l}\t{%2, %0|%0, %2}"
7327   [(set_attr "type" "alu")
7328    (set_attr "pent_pair" "pu")
7329    (set_attr "mode" "SI")])
7330
7331 (define_insn "subsi3_carry_zext"
7332   [(set (match_operand:DI 0 "register_operand" "=r")
7333           (zero_extend:DI
7334             (minus:SI (match_operand:SI 1 "register_operand" "0")
7335               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7336                  (match_operand:SI 2 "general_operand" "g")))))
7337    (clobber (reg:CC FLAGS_REG))]
7338   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339   "sbb{l}\t{%2, %k0|%k0, %2}"
7340   [(set_attr "type" "alu")
7341    (set_attr "pent_pair" "pu")
7342    (set_attr "mode" "SI")])
7343
7344 (define_expand "subsi3"
7345   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7346                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7347                              (match_operand:SI 2 "general_operand" "")))
7348               (clobber (reg:CC FLAGS_REG))])]
7349   ""
7350   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7351
7352 (define_insn "*subsi_1"
7353   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7354         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7355                   (match_operand:SI 2 "general_operand" "ri,rm")))
7356    (clobber (reg:CC FLAGS_REG))]
7357   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7358   "sub{l}\t{%2, %0|%0, %2}"
7359   [(set_attr "type" "alu")
7360    (set_attr "mode" "SI")])
7361
7362 (define_insn "*subsi_1_zext"
7363   [(set (match_operand:DI 0 "register_operand" "=r")
7364         (zero_extend:DI
7365           (minus:SI (match_operand:SI 1 "register_operand" "0")
7366                     (match_operand:SI 2 "general_operand" "g"))))
7367    (clobber (reg:CC FLAGS_REG))]
7368   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7369   "sub{l}\t{%2, %k0|%k0, %2}"
7370   [(set_attr "type" "alu")
7371    (set_attr "mode" "SI")])
7372
7373 (define_insn "*subsi_2"
7374   [(set (reg FLAGS_REG)
7375         (compare
7376           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7377                     (match_operand:SI 2 "general_operand" "ri,rm"))
7378           (const_int 0)))
7379    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7380         (minus:SI (match_dup 1) (match_dup 2)))]
7381   "ix86_match_ccmode (insn, CCGOCmode)
7382    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7383   "sub{l}\t{%2, %0|%0, %2}"
7384   [(set_attr "type" "alu")
7385    (set_attr "mode" "SI")])
7386
7387 (define_insn "*subsi_2_zext"
7388   [(set (reg FLAGS_REG)
7389         (compare
7390           (minus:SI (match_operand:SI 1 "register_operand" "0")
7391                     (match_operand:SI 2 "general_operand" "g"))
7392           (const_int 0)))
7393    (set (match_operand:DI 0 "register_operand" "=r")
7394         (zero_extend:DI
7395           (minus:SI (match_dup 1)
7396                     (match_dup 2))))]
7397   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7398    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7399   "sub{l}\t{%2, %k0|%k0, %2}"
7400   [(set_attr "type" "alu")
7401    (set_attr "mode" "SI")])
7402
7403 (define_insn "*subsi_3"
7404   [(set (reg FLAGS_REG)
7405         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7406                  (match_operand:SI 2 "general_operand" "ri,rm")))
7407    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7408         (minus:SI (match_dup 1) (match_dup 2)))]
7409   "ix86_match_ccmode (insn, CCmode)
7410    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7411   "sub{l}\t{%2, %0|%0, %2}"
7412   [(set_attr "type" "alu")
7413    (set_attr "mode" "SI")])
7414
7415 (define_insn "*subsi_3_zext"
7416   [(set (reg FLAGS_REG)
7417         (compare (match_operand:SI 1 "register_operand" "0")
7418                  (match_operand:SI 2 "general_operand" "g")))
7419    (set (match_operand:DI 0 "register_operand" "=r")
7420         (zero_extend:DI
7421           (minus:SI (match_dup 1)
7422                     (match_dup 2))))]
7423   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7424    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7425   "sub{l}\t{%2, %1|%1, %2}"
7426   [(set_attr "type" "alu")
7427    (set_attr "mode" "DI")])
7428
7429 (define_expand "subhi3"
7430   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7431                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7432                              (match_operand:HI 2 "general_operand" "")))
7433               (clobber (reg:CC FLAGS_REG))])]
7434   "TARGET_HIMODE_MATH"
7435   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7436
7437 (define_insn "*subhi_1"
7438   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7439         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7440                   (match_operand:HI 2 "general_operand" "ri,rm")))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7443   "sub{w}\t{%2, %0|%0, %2}"
7444   [(set_attr "type" "alu")
7445    (set_attr "mode" "HI")])
7446
7447 (define_insn "*subhi_2"
7448   [(set (reg FLAGS_REG)
7449         (compare
7450           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7451                     (match_operand:HI 2 "general_operand" "ri,rm"))
7452           (const_int 0)))
7453    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7454         (minus:HI (match_dup 1) (match_dup 2)))]
7455   "ix86_match_ccmode (insn, CCGOCmode)
7456    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7457   "sub{w}\t{%2, %0|%0, %2}"
7458   [(set_attr "type" "alu")
7459    (set_attr "mode" "HI")])
7460
7461 (define_insn "*subhi_3"
7462   [(set (reg FLAGS_REG)
7463         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7464                  (match_operand:HI 2 "general_operand" "ri,rm")))
7465    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7466         (minus:HI (match_dup 1) (match_dup 2)))]
7467   "ix86_match_ccmode (insn, CCmode)
7468    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7469   "sub{w}\t{%2, %0|%0, %2}"
7470   [(set_attr "type" "alu")
7471    (set_attr "mode" "HI")])
7472
7473 (define_expand "subqi3"
7474   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7475                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7476                              (match_operand:QI 2 "general_operand" "")))
7477               (clobber (reg:CC FLAGS_REG))])]
7478   "TARGET_QIMODE_MATH"
7479   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7480
7481 (define_insn "*subqi_1"
7482   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7483         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7484                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7485    (clobber (reg:CC FLAGS_REG))]
7486   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7487   "sub{b}\t{%2, %0|%0, %2}"
7488   [(set_attr "type" "alu")
7489    (set_attr "mode" "QI")])
7490
7491 (define_insn "*subqi_1_slp"
7492   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7493         (minus:QI (match_dup 0)
7494                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7495    (clobber (reg:CC FLAGS_REG))]
7496   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7497    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7498   "sub{b}\t{%1, %0|%0, %1}"
7499   [(set_attr "type" "alu1")
7500    (set_attr "mode" "QI")])
7501
7502 (define_insn "*subqi_2"
7503   [(set (reg FLAGS_REG)
7504         (compare
7505           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7506                     (match_operand:QI 2 "general_operand" "qi,qm"))
7507           (const_int 0)))
7508    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7509         (minus:HI (match_dup 1) (match_dup 2)))]
7510   "ix86_match_ccmode (insn, CCGOCmode)
7511    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7512   "sub{b}\t{%2, %0|%0, %2}"
7513   [(set_attr "type" "alu")
7514    (set_attr "mode" "QI")])
7515
7516 (define_insn "*subqi_3"
7517   [(set (reg FLAGS_REG)
7518         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7519                  (match_operand:QI 2 "general_operand" "qi,qm")))
7520    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7521         (minus:HI (match_dup 1) (match_dup 2)))]
7522   "ix86_match_ccmode (insn, CCmode)
7523    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7524   "sub{b}\t{%2, %0|%0, %2}"
7525   [(set_attr "type" "alu")
7526    (set_attr "mode" "QI")])
7527
7528 ;; The patterns that match these are at the end of this file.
7529
7530 (define_expand "subxf3"
7531   [(set (match_operand:XF 0 "register_operand" "")
7532         (minus:XF (match_operand:XF 1 "register_operand" "")
7533                   (match_operand:XF 2 "register_operand" "")))]
7534   "TARGET_80387"
7535   "")
7536
7537 (define_expand "sub<mode>3"
7538   [(set (match_operand:MODEF 0 "register_operand" "")
7539         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7540                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7541   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7542   "")
7543 \f
7544 ;; Multiply instructions
7545
7546 (define_expand "muldi3"
7547   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7548                    (mult:DI (match_operand:DI 1 "register_operand" "")
7549                             (match_operand:DI 2 "x86_64_general_operand" "")))
7550               (clobber (reg:CC FLAGS_REG))])]
7551   "TARGET_64BIT"
7552   "")
7553
7554 ;; On AMDFAM10
7555 ;; IMUL reg64, reg64, imm8      Direct
7556 ;; IMUL reg64, mem64, imm8      VectorPath
7557 ;; IMUL reg64, reg64, imm32     Direct
7558 ;; IMUL reg64, mem64, imm32     VectorPath
7559 ;; IMUL reg64, reg64            Direct
7560 ;; IMUL reg64, mem64            Direct
7561
7562 (define_insn "*muldi3_1_rex64"
7563   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7564         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7565                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT
7568    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7569   "@
7570    imul{q}\t{%2, %1, %0|%0, %1, %2}
7571    imul{q}\t{%2, %1, %0|%0, %1, %2}
7572    imul{q}\t{%2, %0|%0, %2}"
7573   [(set_attr "type" "imul")
7574    (set_attr "prefix_0f" "0,0,1")
7575    (set (attr "athlon_decode")
7576         (cond [(eq_attr "cpu" "athlon")
7577                   (const_string "vector")
7578                (eq_attr "alternative" "1")
7579                   (const_string "vector")
7580                (and (eq_attr "alternative" "2")
7581                     (match_operand 1 "memory_operand" ""))
7582                   (const_string "vector")]
7583               (const_string "direct")))
7584    (set (attr "amdfam10_decode")
7585         (cond [(and (eq_attr "alternative" "0,1")
7586                     (match_operand 1 "memory_operand" ""))
7587                   (const_string "vector")]
7588               (const_string "direct")))
7589    (set_attr "mode" "DI")])
7590
7591 (define_expand "mulsi3"
7592   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7593                    (mult:SI (match_operand:SI 1 "register_operand" "")
7594                             (match_operand:SI 2 "general_operand" "")))
7595               (clobber (reg:CC FLAGS_REG))])]
7596   ""
7597   "")
7598
7599 ;; On AMDFAM10
7600 ;; IMUL reg32, reg32, imm8      Direct
7601 ;; IMUL reg32, mem32, imm8      VectorPath
7602 ;; IMUL reg32, reg32, imm32     Direct
7603 ;; IMUL reg32, mem32, imm32     VectorPath
7604 ;; IMUL reg32, reg32            Direct
7605 ;; IMUL reg32, mem32            Direct
7606
7607 (define_insn "*mulsi3_1"
7608   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7609         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7610                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7611    (clobber (reg:CC FLAGS_REG))]
7612   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7613   "@
7614    imul{l}\t{%2, %1, %0|%0, %1, %2}
7615    imul{l}\t{%2, %1, %0|%0, %1, %2}
7616    imul{l}\t{%2, %0|%0, %2}"
7617   [(set_attr "type" "imul")
7618    (set_attr "prefix_0f" "0,0,1")
7619    (set (attr "athlon_decode")
7620         (cond [(eq_attr "cpu" "athlon")
7621                   (const_string "vector")
7622                (eq_attr "alternative" "1")
7623                   (const_string "vector")
7624                (and (eq_attr "alternative" "2")
7625                     (match_operand 1 "memory_operand" ""))
7626                   (const_string "vector")]
7627               (const_string "direct")))
7628    (set (attr "amdfam10_decode")
7629         (cond [(and (eq_attr "alternative" "0,1")
7630                     (match_operand 1 "memory_operand" ""))
7631                   (const_string "vector")]
7632               (const_string "direct")))
7633    (set_attr "mode" "SI")])
7634
7635 (define_insn "*mulsi3_1_zext"
7636   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7637         (zero_extend:DI
7638           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7639                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7640    (clobber (reg:CC FLAGS_REG))]
7641   "TARGET_64BIT
7642    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7643   "@
7644    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7645    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7646    imul{l}\t{%2, %k0|%k0, %2}"
7647   [(set_attr "type" "imul")
7648    (set_attr "prefix_0f" "0,0,1")
7649    (set (attr "athlon_decode")
7650         (cond [(eq_attr "cpu" "athlon")
7651                   (const_string "vector")
7652                (eq_attr "alternative" "1")
7653                   (const_string "vector")
7654                (and (eq_attr "alternative" "2")
7655                     (match_operand 1 "memory_operand" ""))
7656                   (const_string "vector")]
7657               (const_string "direct")))
7658    (set (attr "amdfam10_decode")
7659         (cond [(and (eq_attr "alternative" "0,1")
7660                     (match_operand 1 "memory_operand" ""))
7661                   (const_string "vector")]
7662               (const_string "direct")))
7663    (set_attr "mode" "SI")])
7664
7665 (define_expand "mulhi3"
7666   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7667                    (mult:HI (match_operand:HI 1 "register_operand" "")
7668                             (match_operand:HI 2 "general_operand" "")))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   "TARGET_HIMODE_MATH"
7671   "")
7672
7673 ;; On AMDFAM10
7674 ;; IMUL reg16, reg16, imm8      VectorPath
7675 ;; IMUL reg16, mem16, imm8      VectorPath
7676 ;; IMUL reg16, reg16, imm16     VectorPath
7677 ;; IMUL reg16, mem16, imm16     VectorPath
7678 ;; IMUL reg16, reg16            Direct
7679 ;; IMUL reg16, mem16            Direct
7680 (define_insn "*mulhi3_1"
7681   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7682         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7683                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7684    (clobber (reg:CC FLAGS_REG))]
7685   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7686   "@
7687    imul{w}\t{%2, %1, %0|%0, %1, %2}
7688    imul{w}\t{%2, %1, %0|%0, %1, %2}
7689    imul{w}\t{%2, %0|%0, %2}"
7690   [(set_attr "type" "imul")
7691    (set_attr "prefix_0f" "0,0,1")
7692    (set (attr "athlon_decode")
7693         (cond [(eq_attr "cpu" "athlon")
7694                   (const_string "vector")
7695                (eq_attr "alternative" "1,2")
7696                   (const_string "vector")]
7697               (const_string "direct")))
7698    (set (attr "amdfam10_decode")
7699         (cond [(eq_attr "alternative" "0,1")
7700                   (const_string "vector")]
7701               (const_string "direct")))
7702    (set_attr "mode" "HI")])
7703
7704 (define_expand "mulqi3"
7705   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7706                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7707                             (match_operand:QI 2 "register_operand" "")))
7708               (clobber (reg:CC FLAGS_REG))])]
7709   "TARGET_QIMODE_MATH"
7710   "")
7711
7712 ;;On AMDFAM10
7713 ;; MUL reg8     Direct
7714 ;; MUL mem8     Direct
7715
7716 (define_insn "*mulqi3_1"
7717   [(set (match_operand:QI 0 "register_operand" "=a")
7718         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7719                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7720    (clobber (reg:CC FLAGS_REG))]
7721   "TARGET_QIMODE_MATH
7722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7723   "mul{b}\t%2"
7724   [(set_attr "type" "imul")
7725    (set_attr "length_immediate" "0")
7726    (set (attr "athlon_decode")
7727      (if_then_else (eq_attr "cpu" "athlon")
7728         (const_string "vector")
7729         (const_string "direct")))
7730    (set_attr "amdfam10_decode" "direct")
7731    (set_attr "mode" "QI")])
7732
7733 (define_expand "umulqihi3"
7734   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7735                    (mult:HI (zero_extend:HI
7736                               (match_operand:QI 1 "nonimmediate_operand" ""))
7737                             (zero_extend:HI
7738                               (match_operand:QI 2 "register_operand" ""))))
7739               (clobber (reg:CC FLAGS_REG))])]
7740   "TARGET_QIMODE_MATH"
7741   "")
7742
7743 (define_insn "*umulqihi3_1"
7744   [(set (match_operand:HI 0 "register_operand" "=a")
7745         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7746                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7747    (clobber (reg:CC FLAGS_REG))]
7748   "TARGET_QIMODE_MATH
7749    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7750   "mul{b}\t%2"
7751   [(set_attr "type" "imul")
7752    (set_attr "length_immediate" "0")
7753    (set (attr "athlon_decode")
7754      (if_then_else (eq_attr "cpu" "athlon")
7755         (const_string "vector")
7756         (const_string "direct")))
7757    (set_attr "amdfam10_decode" "direct")
7758    (set_attr "mode" "QI")])
7759
7760 (define_expand "mulqihi3"
7761   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7762                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7763                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7764               (clobber (reg:CC FLAGS_REG))])]
7765   "TARGET_QIMODE_MATH"
7766   "")
7767
7768 (define_insn "*mulqihi3_insn"
7769   [(set (match_operand:HI 0 "register_operand" "=a")
7770         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7771                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "TARGET_QIMODE_MATH
7774    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7775   "imul{b}\t%2"
7776   [(set_attr "type" "imul")
7777    (set_attr "length_immediate" "0")
7778    (set (attr "athlon_decode")
7779      (if_then_else (eq_attr "cpu" "athlon")
7780         (const_string "vector")
7781         (const_string "direct")))
7782    (set_attr "amdfam10_decode" "direct")
7783    (set_attr "mode" "QI")])
7784
7785 (define_expand "umulditi3"
7786   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7787                    (mult:TI (zero_extend:TI
7788                               (match_operand:DI 1 "nonimmediate_operand" ""))
7789                             (zero_extend:TI
7790                               (match_operand:DI 2 "register_operand" ""))))
7791               (clobber (reg:CC FLAGS_REG))])]
7792   "TARGET_64BIT"
7793   "")
7794
7795 (define_insn "*umulditi3_insn"
7796   [(set (match_operand:TI 0 "register_operand" "=A")
7797         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7798                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_64BIT
7801    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7802   "mul{q}\t%2"
7803   [(set_attr "type" "imul")
7804    (set_attr "length_immediate" "0")
7805    (set (attr "athlon_decode")
7806      (if_then_else (eq_attr "cpu" "athlon")
7807         (const_string "vector")
7808         (const_string "double")))
7809    (set_attr "amdfam10_decode" "double")
7810    (set_attr "mode" "DI")])
7811
7812 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7813 (define_expand "umulsidi3"
7814   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7815                    (mult:DI (zero_extend:DI
7816                               (match_operand:SI 1 "nonimmediate_operand" ""))
7817                             (zero_extend:DI
7818                               (match_operand:SI 2 "register_operand" ""))))
7819               (clobber (reg:CC FLAGS_REG))])]
7820   "!TARGET_64BIT"
7821   "")
7822
7823 (define_insn "*umulsidi3_insn"
7824   [(set (match_operand:DI 0 "register_operand" "=A")
7825         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7826                  (zero_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   "mul{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 "mulditi3"
7841   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7842                    (mult:TI (sign_extend:TI
7843                               (match_operand:DI 1 "nonimmediate_operand" ""))
7844                             (sign_extend:TI
7845                               (match_operand:DI 2 "register_operand" ""))))
7846               (clobber (reg:CC FLAGS_REG))])]
7847   "TARGET_64BIT"
7848   "")
7849
7850 (define_insn "*mulditi3_insn"
7851   [(set (match_operand:TI 0 "register_operand" "=A")
7852         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7853                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7854    (clobber (reg:CC FLAGS_REG))]
7855   "TARGET_64BIT
7856    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7857   "imul{q}\t%2"
7858   [(set_attr "type" "imul")
7859    (set_attr "length_immediate" "0")
7860    (set (attr "athlon_decode")
7861      (if_then_else (eq_attr "cpu" "athlon")
7862         (const_string "vector")
7863         (const_string "double")))
7864    (set_attr "amdfam10_decode" "double")
7865    (set_attr "mode" "DI")])
7866
7867 (define_expand "mulsidi3"
7868   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7869                    (mult:DI (sign_extend:DI
7870                               (match_operand:SI 1 "nonimmediate_operand" ""))
7871                             (sign_extend:DI
7872                               (match_operand:SI 2 "register_operand" ""))))
7873               (clobber (reg:CC FLAGS_REG))])]
7874   "!TARGET_64BIT"
7875   "")
7876
7877 (define_insn "*mulsidi3_insn"
7878   [(set (match_operand:DI 0 "register_operand" "=A")
7879         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7880                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7881    (clobber (reg:CC FLAGS_REG))]
7882   "!TARGET_64BIT
7883    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7884   "imul{l}\t%2"
7885   [(set_attr "type" "imul")
7886    (set_attr "length_immediate" "0")
7887    (set (attr "athlon_decode")
7888      (if_then_else (eq_attr "cpu" "athlon")
7889         (const_string "vector")
7890         (const_string "double")))
7891    (set_attr "amdfam10_decode" "double")
7892    (set_attr "mode" "SI")])
7893
7894 (define_expand "umuldi3_highpart"
7895   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7896                    (truncate:DI
7897                      (lshiftrt:TI
7898                        (mult:TI (zero_extend:TI
7899                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7900                                 (zero_extend:TI
7901                                   (match_operand:DI 2 "register_operand" "")))
7902                        (const_int 64))))
7903               (clobber (match_scratch:DI 3 ""))
7904               (clobber (reg:CC FLAGS_REG))])]
7905   "TARGET_64BIT"
7906   "")
7907
7908 (define_insn "*umuldi3_highpart_rex64"
7909   [(set (match_operand:DI 0 "register_operand" "=d")
7910         (truncate:DI
7911           (lshiftrt:TI
7912             (mult:TI (zero_extend:TI
7913                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7914                      (zero_extend:TI
7915                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7916             (const_int 64))))
7917    (clobber (match_scratch:DI 3 "=1"))
7918    (clobber (reg:CC FLAGS_REG))]
7919   "TARGET_64BIT
7920    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7921   "mul{q}\t%2"
7922   [(set_attr "type" "imul")
7923    (set_attr "length_immediate" "0")
7924    (set (attr "athlon_decode")
7925      (if_then_else (eq_attr "cpu" "athlon")
7926         (const_string "vector")
7927         (const_string "double")))
7928    (set_attr "amdfam10_decode" "double")
7929    (set_attr "mode" "DI")])
7930
7931 (define_expand "umulsi3_highpart"
7932   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7933                    (truncate:SI
7934                      (lshiftrt:DI
7935                        (mult:DI (zero_extend:DI
7936                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7937                                 (zero_extend:DI
7938                                   (match_operand:SI 2 "register_operand" "")))
7939                        (const_int 32))))
7940               (clobber (match_scratch:SI 3 ""))
7941               (clobber (reg:CC FLAGS_REG))])]
7942   ""
7943   "")
7944
7945 (define_insn "*umulsi3_highpart_insn"
7946   [(set (match_operand:SI 0 "register_operand" "=d")
7947         (truncate:SI
7948           (lshiftrt:DI
7949             (mult:DI (zero_extend:DI
7950                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7951                      (zero_extend:DI
7952                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7953             (const_int 32))))
7954    (clobber (match_scratch:SI 3 "=1"))
7955    (clobber (reg:CC FLAGS_REG))]
7956   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957   "mul{l}\t%2"
7958   [(set_attr "type" "imul")
7959    (set_attr "length_immediate" "0")
7960    (set (attr "athlon_decode")
7961      (if_then_else (eq_attr "cpu" "athlon")
7962         (const_string "vector")
7963         (const_string "double")))
7964    (set_attr "amdfam10_decode" "double")
7965    (set_attr "mode" "SI")])
7966
7967 (define_insn "*umulsi3_highpart_zext"
7968   [(set (match_operand:DI 0 "register_operand" "=d")
7969         (zero_extend:DI (truncate:SI
7970           (lshiftrt:DI
7971             (mult:DI (zero_extend:DI
7972                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7973                      (zero_extend:DI
7974                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7975             (const_int 32)))))
7976    (clobber (match_scratch:SI 3 "=1"))
7977    (clobber (reg:CC FLAGS_REG))]
7978   "TARGET_64BIT
7979    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7980   "mul{l}\t%2"
7981   [(set_attr "type" "imul")
7982    (set_attr "length_immediate" "0")
7983    (set (attr "athlon_decode")
7984      (if_then_else (eq_attr "cpu" "athlon")
7985         (const_string "vector")
7986         (const_string "double")))
7987    (set_attr "amdfam10_decode" "double")
7988    (set_attr "mode" "SI")])
7989
7990 (define_expand "smuldi3_highpart"
7991   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7992                    (truncate:DI
7993                      (lshiftrt:TI
7994                        (mult:TI (sign_extend:TI
7995                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7996                                 (sign_extend:TI
7997                                   (match_operand:DI 2 "register_operand" "")))
7998                        (const_int 64))))
7999               (clobber (match_scratch:DI 3 ""))
8000               (clobber (reg:CC FLAGS_REG))])]
8001   "TARGET_64BIT"
8002   "")
8003
8004 (define_insn "*smuldi3_highpart_rex64"
8005   [(set (match_operand:DI 0 "register_operand" "=d")
8006         (truncate:DI
8007           (lshiftrt:TI
8008             (mult:TI (sign_extend:TI
8009                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8010                      (sign_extend:TI
8011                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8012             (const_int 64))))
8013    (clobber (match_scratch:DI 3 "=1"))
8014    (clobber (reg:CC FLAGS_REG))]
8015   "TARGET_64BIT
8016    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8017   "imul{q}\t%2"
8018   [(set_attr "type" "imul")
8019    (set (attr "athlon_decode")
8020      (if_then_else (eq_attr "cpu" "athlon")
8021         (const_string "vector")
8022         (const_string "double")))
8023    (set_attr "amdfam10_decode" "double")
8024    (set_attr "mode" "DI")])
8025
8026 (define_expand "smulsi3_highpart"
8027   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8028                    (truncate:SI
8029                      (lshiftrt:DI
8030                        (mult:DI (sign_extend:DI
8031                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8032                                 (sign_extend:DI
8033                                   (match_operand:SI 2 "register_operand" "")))
8034                        (const_int 32))))
8035               (clobber (match_scratch:SI 3 ""))
8036               (clobber (reg:CC FLAGS_REG))])]
8037   ""
8038   "")
8039
8040 (define_insn "*smulsi3_highpart_insn"
8041   [(set (match_operand:SI 0 "register_operand" "=d")
8042         (truncate:SI
8043           (lshiftrt:DI
8044             (mult:DI (sign_extend:DI
8045                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8046                      (sign_extend:DI
8047                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8048             (const_int 32))))
8049    (clobber (match_scratch:SI 3 "=1"))
8050    (clobber (reg:CC FLAGS_REG))]
8051   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8052   "imul{l}\t%2"
8053   [(set_attr "type" "imul")
8054    (set (attr "athlon_decode")
8055      (if_then_else (eq_attr "cpu" "athlon")
8056         (const_string "vector")
8057         (const_string "double")))
8058    (set_attr "amdfam10_decode" "double")
8059    (set_attr "mode" "SI")])
8060
8061 (define_insn "*smulsi3_highpart_zext"
8062   [(set (match_operand:DI 0 "register_operand" "=d")
8063         (zero_extend:DI (truncate:SI
8064           (lshiftrt:DI
8065             (mult:DI (sign_extend:DI
8066                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8067                      (sign_extend:DI
8068                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8069             (const_int 32)))))
8070    (clobber (match_scratch:SI 3 "=1"))
8071    (clobber (reg:CC FLAGS_REG))]
8072   "TARGET_64BIT
8073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8074   "imul{l}\t%2"
8075   [(set_attr "type" "imul")
8076    (set (attr "athlon_decode")
8077      (if_then_else (eq_attr "cpu" "athlon")
8078         (const_string "vector")
8079         (const_string "double")))
8080    (set_attr "amdfam10_decode" "double")
8081    (set_attr "mode" "SI")])
8082
8083 ;; The patterns that match these are at the end of this file.
8084
8085 (define_expand "mulxf3"
8086   [(set (match_operand:XF 0 "register_operand" "")
8087         (mult:XF (match_operand:XF 1 "register_operand" "")
8088                  (match_operand:XF 2 "register_operand" "")))]
8089   "TARGET_80387"
8090   "")
8091
8092 (define_expand "mul<mode>3"
8093   [(set (match_operand:MODEF 0 "register_operand" "")
8094         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8095                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8096   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8097   "")
8098
8099 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8100
8101 \f
8102 ;; Divide instructions
8103
8104 (define_insn "divqi3"
8105   [(set (match_operand:QI 0 "register_operand" "=a")
8106         (div:QI (match_operand:HI 1 "register_operand" "0")
8107                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "TARGET_QIMODE_MATH"
8110   "idiv{b}\t%2"
8111   [(set_attr "type" "idiv")
8112    (set_attr "mode" "QI")])
8113
8114 (define_insn "udivqi3"
8115   [(set (match_operand:QI 0 "register_operand" "=a")
8116         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8117                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8118    (clobber (reg:CC FLAGS_REG))]
8119   "TARGET_QIMODE_MATH"
8120   "div{b}\t%2"
8121   [(set_attr "type" "idiv")
8122    (set_attr "mode" "QI")])
8123
8124 ;; The patterns that match these are at the end of this file.
8125
8126 (define_expand "divxf3"
8127   [(set (match_operand:XF 0 "register_operand" "")
8128         (div:XF (match_operand:XF 1 "register_operand" "")
8129                 (match_operand:XF 2 "register_operand" "")))]
8130   "TARGET_80387"
8131   "")
8132
8133 (define_expand "divdf3"
8134   [(set (match_operand:DF 0 "register_operand" "")
8135         (div:DF (match_operand:DF 1 "register_operand" "")
8136                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8137    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8138    "")
8139
8140 (define_expand "divsf3"
8141   [(set (match_operand:SF 0 "register_operand" "")
8142         (div:SF (match_operand:SF 1 "register_operand" "")
8143                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8144   "TARGET_80387 || TARGET_SSE_MATH"
8145 {
8146   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8147       && flag_finite_math_only && !flag_trapping_math
8148       && flag_unsafe_math_optimizations)
8149     {
8150       ix86_emit_swdivsf (operands[0], operands[1],
8151                          operands[2], SFmode);
8152       DONE;
8153     }
8154 })
8155 \f
8156 ;; Remainder instructions.
8157
8158 (define_expand "divmoddi4"
8159   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8160                    (div:DI (match_operand:DI 1 "register_operand" "")
8161                            (match_operand:DI 2 "nonimmediate_operand" "")))
8162               (set (match_operand:DI 3 "register_operand" "")
8163                    (mod:DI (match_dup 1) (match_dup 2)))
8164               (clobber (reg:CC FLAGS_REG))])]
8165   "TARGET_64BIT"
8166   "")
8167
8168 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8169 ;; Penalize eax case slightly because it results in worse scheduling
8170 ;; of code.
8171 (define_insn "*divmoddi4_nocltd_rex64"
8172   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8173         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8174                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8175    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8176         (mod:DI (match_dup 2) (match_dup 3)))
8177    (clobber (reg:CC FLAGS_REG))]
8178   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8179   "#"
8180   [(set_attr "type" "multi")])
8181
8182 (define_insn "*divmoddi4_cltd_rex64"
8183   [(set (match_operand:DI 0 "register_operand" "=a")
8184         (div:DI (match_operand:DI 2 "register_operand" "a")
8185                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8186    (set (match_operand:DI 1 "register_operand" "=&d")
8187         (mod:DI (match_dup 2) (match_dup 3)))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8190   "#"
8191   [(set_attr "type" "multi")])
8192
8193 (define_insn "*divmoddi_noext_rex64"
8194   [(set (match_operand:DI 0 "register_operand" "=a")
8195         (div:DI (match_operand:DI 1 "register_operand" "0")
8196                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8197    (set (match_operand:DI 3 "register_operand" "=d")
8198         (mod:DI (match_dup 1) (match_dup 2)))
8199    (use (match_operand:DI 4 "register_operand" "3"))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_64BIT"
8202   "idiv{q}\t%2"
8203   [(set_attr "type" "idiv")
8204    (set_attr "mode" "DI")])
8205
8206 (define_split
8207   [(set (match_operand:DI 0 "register_operand" "")
8208         (div:DI (match_operand:DI 1 "register_operand" "")
8209                 (match_operand:DI 2 "nonimmediate_operand" "")))
8210    (set (match_operand:DI 3 "register_operand" "")
8211         (mod:DI (match_dup 1) (match_dup 2)))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "TARGET_64BIT && reload_completed"
8214   [(parallel [(set (match_dup 3)
8215                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8216               (clobber (reg:CC FLAGS_REG))])
8217    (parallel [(set (match_dup 0)
8218                    (div:DI (reg:DI 0) (match_dup 2)))
8219               (set (match_dup 3)
8220                    (mod:DI (reg:DI 0) (match_dup 2)))
8221               (use (match_dup 3))
8222               (clobber (reg:CC FLAGS_REG))])]
8223 {
8224   /* Avoid use of cltd in favor of a mov+shift.  */
8225   if (!TARGET_USE_CLTD && !optimize_size)
8226     {
8227       if (true_regnum (operands[1]))
8228         emit_move_insn (operands[0], operands[1]);
8229       else
8230         emit_move_insn (operands[3], operands[1]);
8231       operands[4] = operands[3];
8232     }
8233   else
8234     {
8235       gcc_assert (!true_regnum (operands[1]));
8236       operands[4] = operands[1];
8237     }
8238 })
8239
8240
8241 (define_expand "divmodsi4"
8242   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8243                    (div:SI (match_operand:SI 1 "register_operand" "")
8244                            (match_operand:SI 2 "nonimmediate_operand" "")))
8245               (set (match_operand:SI 3 "register_operand" "")
8246                    (mod:SI (match_dup 1) (match_dup 2)))
8247               (clobber (reg:CC FLAGS_REG))])]
8248   ""
8249   "")
8250
8251 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8252 ;; Penalize eax case slightly because it results in worse scheduling
8253 ;; of code.
8254 (define_insn "*divmodsi4_nocltd"
8255   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8256         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8257                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8258    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8259         (mod:SI (match_dup 2) (match_dup 3)))
8260    (clobber (reg:CC FLAGS_REG))]
8261   "!optimize_size && !TARGET_USE_CLTD"
8262   "#"
8263   [(set_attr "type" "multi")])
8264
8265 (define_insn "*divmodsi4_cltd"
8266   [(set (match_operand:SI 0 "register_operand" "=a")
8267         (div:SI (match_operand:SI 2 "register_operand" "a")
8268                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8269    (set (match_operand:SI 1 "register_operand" "=&d")
8270         (mod:SI (match_dup 2) (match_dup 3)))
8271    (clobber (reg:CC FLAGS_REG))]
8272   "optimize_size || TARGET_USE_CLTD"
8273   "#"
8274   [(set_attr "type" "multi")])
8275
8276 (define_insn "*divmodsi_noext"
8277   [(set (match_operand:SI 0 "register_operand" "=a")
8278         (div:SI (match_operand:SI 1 "register_operand" "0")
8279                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8280    (set (match_operand:SI 3 "register_operand" "=d")
8281         (mod:SI (match_dup 1) (match_dup 2)))
8282    (use (match_operand:SI 4 "register_operand" "3"))
8283    (clobber (reg:CC FLAGS_REG))]
8284   ""
8285   "idiv{l}\t%2"
8286   [(set_attr "type" "idiv")
8287    (set_attr "mode" "SI")])
8288
8289 (define_split
8290   [(set (match_operand:SI 0 "register_operand" "")
8291         (div:SI (match_operand:SI 1 "register_operand" "")
8292                 (match_operand:SI 2 "nonimmediate_operand" "")))
8293    (set (match_operand:SI 3 "register_operand" "")
8294         (mod:SI (match_dup 1) (match_dup 2)))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "reload_completed"
8297   [(parallel [(set (match_dup 3)
8298                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8299               (clobber (reg:CC FLAGS_REG))])
8300    (parallel [(set (match_dup 0)
8301                    (div:SI (reg:SI 0) (match_dup 2)))
8302               (set (match_dup 3)
8303                    (mod:SI (reg:SI 0) (match_dup 2)))
8304               (use (match_dup 3))
8305               (clobber (reg:CC FLAGS_REG))])]
8306 {
8307   /* Avoid use of cltd in favor of a mov+shift.  */
8308   if (!TARGET_USE_CLTD && !optimize_size)
8309     {
8310       if (true_regnum (operands[1]))
8311         emit_move_insn (operands[0], operands[1]);
8312       else
8313         emit_move_insn (operands[3], operands[1]);
8314       operands[4] = operands[3];
8315     }
8316   else
8317     {
8318       gcc_assert (!true_regnum (operands[1]));
8319       operands[4] = operands[1];
8320     }
8321 })
8322 ;; %%% Split me.
8323 (define_insn "divmodhi4"
8324   [(set (match_operand:HI 0 "register_operand" "=a")
8325         (div:HI (match_operand:HI 1 "register_operand" "0")
8326                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8327    (set (match_operand:HI 3 "register_operand" "=&d")
8328         (mod:HI (match_dup 1) (match_dup 2)))
8329    (clobber (reg:CC FLAGS_REG))]
8330   "TARGET_HIMODE_MATH"
8331   "cwtd\;idiv{w}\t%2"
8332   [(set_attr "type" "multi")
8333    (set_attr "length_immediate" "0")
8334    (set_attr "mode" "SI")])
8335
8336 (define_insn "udivmoddi4"
8337   [(set (match_operand:DI 0 "register_operand" "=a")
8338         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8339                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8340    (set (match_operand:DI 3 "register_operand" "=&d")
8341         (umod:DI (match_dup 1) (match_dup 2)))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "TARGET_64BIT"
8344   "xor{q}\t%3, %3\;div{q}\t%2"
8345   [(set_attr "type" "multi")
8346    (set_attr "length_immediate" "0")
8347    (set_attr "mode" "DI")])
8348
8349 (define_insn "*udivmoddi4_noext"
8350   [(set (match_operand:DI 0 "register_operand" "=a")
8351         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8352                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8353    (set (match_operand:DI 3 "register_operand" "=d")
8354         (umod:DI (match_dup 1) (match_dup 2)))
8355    (use (match_dup 3))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "TARGET_64BIT"
8358   "div{q}\t%2"
8359   [(set_attr "type" "idiv")
8360    (set_attr "mode" "DI")])
8361
8362 (define_split
8363   [(set (match_operand:DI 0 "register_operand" "")
8364         (udiv:DI (match_operand:DI 1 "register_operand" "")
8365                  (match_operand:DI 2 "nonimmediate_operand" "")))
8366    (set (match_operand:DI 3 "register_operand" "")
8367         (umod:DI (match_dup 1) (match_dup 2)))
8368    (clobber (reg:CC FLAGS_REG))]
8369   "TARGET_64BIT && reload_completed"
8370   [(set (match_dup 3) (const_int 0))
8371    (parallel [(set (match_dup 0)
8372                    (udiv:DI (match_dup 1) (match_dup 2)))
8373               (set (match_dup 3)
8374                    (umod:DI (match_dup 1) (match_dup 2)))
8375               (use (match_dup 3))
8376               (clobber (reg:CC FLAGS_REG))])]
8377   "")
8378
8379 (define_insn "udivmodsi4"
8380   [(set (match_operand:SI 0 "register_operand" "=a")
8381         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8382                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8383    (set (match_operand:SI 3 "register_operand" "=&d")
8384         (umod:SI (match_dup 1) (match_dup 2)))
8385    (clobber (reg:CC FLAGS_REG))]
8386   ""
8387   "xor{l}\t%3, %3\;div{l}\t%2"
8388   [(set_attr "type" "multi")
8389    (set_attr "length_immediate" "0")
8390    (set_attr "mode" "SI")])
8391
8392 (define_insn "*udivmodsi4_noext"
8393   [(set (match_operand:SI 0 "register_operand" "=a")
8394         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8395                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8396    (set (match_operand:SI 3 "register_operand" "=d")
8397         (umod:SI (match_dup 1) (match_dup 2)))
8398    (use (match_dup 3))
8399    (clobber (reg:CC FLAGS_REG))]
8400   ""
8401   "div{l}\t%2"
8402   [(set_attr "type" "idiv")
8403    (set_attr "mode" "SI")])
8404
8405 (define_split
8406   [(set (match_operand:SI 0 "register_operand" "")
8407         (udiv:SI (match_operand:SI 1 "register_operand" "")
8408                  (match_operand:SI 2 "nonimmediate_operand" "")))
8409    (set (match_operand:SI 3 "register_operand" "")
8410         (umod:SI (match_dup 1) (match_dup 2)))
8411    (clobber (reg:CC FLAGS_REG))]
8412   "reload_completed"
8413   [(set (match_dup 3) (const_int 0))
8414    (parallel [(set (match_dup 0)
8415                    (udiv:SI (match_dup 1) (match_dup 2)))
8416               (set (match_dup 3)
8417                    (umod:SI (match_dup 1) (match_dup 2)))
8418               (use (match_dup 3))
8419               (clobber (reg:CC FLAGS_REG))])]
8420   "")
8421
8422 (define_expand "udivmodhi4"
8423   [(set (match_dup 4) (const_int 0))
8424    (parallel [(set (match_operand:HI 0 "register_operand" "")
8425                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8426                             (match_operand:HI 2 "nonimmediate_operand" "")))
8427               (set (match_operand:HI 3 "register_operand" "")
8428                    (umod:HI (match_dup 1) (match_dup 2)))
8429               (use (match_dup 4))
8430               (clobber (reg:CC FLAGS_REG))])]
8431   "TARGET_HIMODE_MATH"
8432   "operands[4] = gen_reg_rtx (HImode);")
8433
8434 (define_insn "*udivmodhi_noext"
8435   [(set (match_operand:HI 0 "register_operand" "=a")
8436         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8437                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8438    (set (match_operand:HI 3 "register_operand" "=d")
8439         (umod:HI (match_dup 1) (match_dup 2)))
8440    (use (match_operand:HI 4 "register_operand" "3"))
8441    (clobber (reg:CC FLAGS_REG))]
8442   ""
8443   "div{w}\t%2"
8444   [(set_attr "type" "idiv")
8445    (set_attr "mode" "HI")])
8446
8447 ;; We cannot use div/idiv for double division, because it causes
8448 ;; "division by zero" on the overflow and that's not what we expect
8449 ;; from truncate.  Because true (non truncating) double division is
8450 ;; never generated, we can't create this insn anyway.
8451 ;
8452 ;(define_insn ""
8453 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8454 ;       (truncate:SI
8455 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8456 ;                  (zero_extend:DI
8457 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8458 ;   (set (match_operand:SI 3 "register_operand" "=d")
8459 ;       (truncate:SI
8460 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8461 ;   (clobber (reg:CC FLAGS_REG))]
8462 ;  ""
8463 ;  "div{l}\t{%2, %0|%0, %2}"
8464 ;  [(set_attr "type" "idiv")])
8465 \f
8466 ;;- Logical AND instructions
8467
8468 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8469 ;; Note that this excludes ah.
8470
8471 (define_insn "*testdi_1_rex64"
8472   [(set (reg FLAGS_REG)
8473         (compare
8474           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8475                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8476           (const_int 0)))]
8477   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8478    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8479   "@
8480    test{l}\t{%k1, %k0|%k0, %k1}
8481    test{l}\t{%k1, %k0|%k0, %k1}
8482    test{q}\t{%1, %0|%0, %1}
8483    test{q}\t{%1, %0|%0, %1}
8484    test{q}\t{%1, %0|%0, %1}"
8485   [(set_attr "type" "test")
8486    (set_attr "modrm" "0,1,0,1,1")
8487    (set_attr "mode" "SI,SI,DI,DI,DI")
8488    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8489
8490 (define_insn "testsi_1"
8491   [(set (reg FLAGS_REG)
8492         (compare
8493           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8494                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8495           (const_int 0)))]
8496   "ix86_match_ccmode (insn, CCNOmode)
8497    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8498   "test{l}\t{%1, %0|%0, %1}"
8499   [(set_attr "type" "test")
8500    (set_attr "modrm" "0,1,1")
8501    (set_attr "mode" "SI")
8502    (set_attr "pent_pair" "uv,np,uv")])
8503
8504 (define_expand "testsi_ccno_1"
8505   [(set (reg:CCNO FLAGS_REG)
8506         (compare:CCNO
8507           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8508                   (match_operand:SI 1 "nonmemory_operand" ""))
8509           (const_int 0)))]
8510   ""
8511   "")
8512
8513 (define_insn "*testhi_1"
8514   [(set (reg FLAGS_REG)
8515         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8516                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8517                  (const_int 0)))]
8518   "ix86_match_ccmode (insn, CCNOmode)
8519    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8520   "test{w}\t{%1, %0|%0, %1}"
8521   [(set_attr "type" "test")
8522    (set_attr "modrm" "0,1,1")
8523    (set_attr "mode" "HI")
8524    (set_attr "pent_pair" "uv,np,uv")])
8525
8526 (define_expand "testqi_ccz_1"
8527   [(set (reg:CCZ FLAGS_REG)
8528         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8529                              (match_operand:QI 1 "nonmemory_operand" ""))
8530                  (const_int 0)))]
8531   ""
8532   "")
8533
8534 (define_insn "*testqi_1_maybe_si"
8535   [(set (reg FLAGS_REG)
8536         (compare
8537           (and:QI
8538             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8539             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8540           (const_int 0)))]
8541    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8542     && ix86_match_ccmode (insn,
8543                          CONST_INT_P (operands[1])
8544                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8545 {
8546   if (which_alternative == 3)
8547     {
8548       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8549         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8550       return "test{l}\t{%1, %k0|%k0, %1}";
8551     }
8552   return "test{b}\t{%1, %0|%0, %1}";
8553 }
8554   [(set_attr "type" "test")
8555    (set_attr "modrm" "0,1,1,1")
8556    (set_attr "mode" "QI,QI,QI,SI")
8557    (set_attr "pent_pair" "uv,np,uv,np")])
8558
8559 (define_insn "*testqi_1"
8560   [(set (reg FLAGS_REG)
8561         (compare
8562           (and:QI
8563             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8564             (match_operand:QI 1 "general_operand" "n,n,qn"))
8565           (const_int 0)))]
8566   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8567    && ix86_match_ccmode (insn, CCNOmode)"
8568   "test{b}\t{%1, %0|%0, %1}"
8569   [(set_attr "type" "test")
8570    (set_attr "modrm" "0,1,1")
8571    (set_attr "mode" "QI")
8572    (set_attr "pent_pair" "uv,np,uv")])
8573
8574 (define_expand "testqi_ext_ccno_0"
8575   [(set (reg:CCNO FLAGS_REG)
8576         (compare:CCNO
8577           (and:SI
8578             (zero_extract:SI
8579               (match_operand 0 "ext_register_operand" "")
8580               (const_int 8)
8581               (const_int 8))
8582             (match_operand 1 "const_int_operand" ""))
8583           (const_int 0)))]
8584   ""
8585   "")
8586
8587 (define_insn "*testqi_ext_0"
8588   [(set (reg FLAGS_REG)
8589         (compare
8590           (and:SI
8591             (zero_extract:SI
8592               (match_operand 0 "ext_register_operand" "Q")
8593               (const_int 8)
8594               (const_int 8))
8595             (match_operand 1 "const_int_operand" "n"))
8596           (const_int 0)))]
8597   "ix86_match_ccmode (insn, CCNOmode)"
8598   "test{b}\t{%1, %h0|%h0, %1}"
8599   [(set_attr "type" "test")
8600    (set_attr "mode" "QI")
8601    (set_attr "length_immediate" "1")
8602    (set_attr "pent_pair" "np")])
8603
8604 (define_insn "*testqi_ext_1"
8605   [(set (reg FLAGS_REG)
8606         (compare
8607           (and:SI
8608             (zero_extract:SI
8609               (match_operand 0 "ext_register_operand" "Q")
8610               (const_int 8)
8611               (const_int 8))
8612             (zero_extend:SI
8613               (match_operand:QI 1 "general_operand" "Qm")))
8614           (const_int 0)))]
8615   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8616    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8617   "test{b}\t{%1, %h0|%h0, %1}"
8618   [(set_attr "type" "test")
8619    (set_attr "mode" "QI")])
8620
8621 (define_insn "*testqi_ext_1_rex64"
8622   [(set (reg FLAGS_REG)
8623         (compare
8624           (and:SI
8625             (zero_extract:SI
8626               (match_operand 0 "ext_register_operand" "Q")
8627               (const_int 8)
8628               (const_int 8))
8629             (zero_extend:SI
8630               (match_operand:QI 1 "register_operand" "Q")))
8631           (const_int 0)))]
8632   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8633   "test{b}\t{%1, %h0|%h0, %1}"
8634   [(set_attr "type" "test")
8635    (set_attr "mode" "QI")])
8636
8637 (define_insn "*testqi_ext_2"
8638   [(set (reg FLAGS_REG)
8639         (compare
8640           (and:SI
8641             (zero_extract:SI
8642               (match_operand 0 "ext_register_operand" "Q")
8643               (const_int 8)
8644               (const_int 8))
8645             (zero_extract:SI
8646               (match_operand 1 "ext_register_operand" "Q")
8647               (const_int 8)
8648               (const_int 8)))
8649           (const_int 0)))]
8650   "ix86_match_ccmode (insn, CCNOmode)"
8651   "test{b}\t{%h1, %h0|%h0, %h1}"
8652   [(set_attr "type" "test")
8653    (set_attr "mode" "QI")])
8654
8655 ;; Combine likes to form bit extractions for some tests.  Humor it.
8656 (define_insn "*testqi_ext_3"
8657   [(set (reg FLAGS_REG)
8658         (compare (zero_extract:SI
8659                    (match_operand 0 "nonimmediate_operand" "rm")
8660                    (match_operand:SI 1 "const_int_operand" "")
8661                    (match_operand:SI 2 "const_int_operand" ""))
8662                  (const_int 0)))]
8663   "ix86_match_ccmode (insn, CCNOmode)
8664    && INTVAL (operands[1]) > 0
8665    && INTVAL (operands[2]) >= 0
8666    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8667    && (GET_MODE (operands[0]) == SImode
8668        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8669        || GET_MODE (operands[0]) == HImode
8670        || GET_MODE (operands[0]) == QImode)"
8671   "#")
8672
8673 (define_insn "*testqi_ext_3_rex64"
8674   [(set (reg FLAGS_REG)
8675         (compare (zero_extract:DI
8676                    (match_operand 0 "nonimmediate_operand" "rm")
8677                    (match_operand:DI 1 "const_int_operand" "")
8678                    (match_operand:DI 2 "const_int_operand" ""))
8679                  (const_int 0)))]
8680   "TARGET_64BIT
8681    && ix86_match_ccmode (insn, CCNOmode)
8682    && INTVAL (operands[1]) > 0
8683    && INTVAL (operands[2]) >= 0
8684    /* Ensure that resulting mask is zero or sign extended operand.  */
8685    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8686        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8687            && INTVAL (operands[1]) > 32))
8688    && (GET_MODE (operands[0]) == SImode
8689        || GET_MODE (operands[0]) == DImode
8690        || GET_MODE (operands[0]) == HImode
8691        || GET_MODE (operands[0]) == QImode)"
8692   "#")
8693
8694 (define_split
8695   [(set (match_operand 0 "flags_reg_operand" "")
8696         (match_operator 1 "compare_operator"
8697           [(zero_extract
8698              (match_operand 2 "nonimmediate_operand" "")
8699              (match_operand 3 "const_int_operand" "")
8700              (match_operand 4 "const_int_operand" ""))
8701            (const_int 0)]))]
8702   "ix86_match_ccmode (insn, CCNOmode)"
8703   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8704 {
8705   rtx val = operands[2];
8706   HOST_WIDE_INT len = INTVAL (operands[3]);
8707   HOST_WIDE_INT pos = INTVAL (operands[4]);
8708   HOST_WIDE_INT mask;
8709   enum machine_mode mode, submode;
8710
8711   mode = GET_MODE (val);
8712   if (MEM_P (val))
8713     {
8714       /* ??? Combine likes to put non-volatile mem extractions in QImode
8715          no matter the size of the test.  So find a mode that works.  */
8716       if (! MEM_VOLATILE_P (val))
8717         {
8718           mode = smallest_mode_for_size (pos + len, MODE_INT);
8719           val = adjust_address (val, mode, 0);
8720         }
8721     }
8722   else if (GET_CODE (val) == SUBREG
8723            && (submode = GET_MODE (SUBREG_REG (val)),
8724                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8725            && pos + len <= GET_MODE_BITSIZE (submode))
8726     {
8727       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8728       mode = submode;
8729       val = SUBREG_REG (val);
8730     }
8731   else if (mode == HImode && pos + len <= 8)
8732     {
8733       /* Small HImode tests can be converted to QImode.  */
8734       mode = QImode;
8735       val = gen_lowpart (QImode, val);
8736     }
8737
8738   if (len == HOST_BITS_PER_WIDE_INT)
8739     mask = -1;
8740   else
8741     mask = ((HOST_WIDE_INT)1 << len) - 1;
8742   mask <<= pos;
8743
8744   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8745 })
8746
8747 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8748 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8749 ;; this is relatively important trick.
8750 ;; Do the conversion only post-reload to avoid limiting of the register class
8751 ;; to QI regs.
8752 (define_split
8753   [(set (match_operand 0 "flags_reg_operand" "")
8754         (match_operator 1 "compare_operator"
8755           [(and (match_operand 2 "register_operand" "")
8756                 (match_operand 3 "const_int_operand" ""))
8757            (const_int 0)]))]
8758    "reload_completed
8759     && QI_REG_P (operands[2])
8760     && GET_MODE (operands[2]) != QImode
8761     && ((ix86_match_ccmode (insn, CCZmode)
8762          && !(INTVAL (operands[3]) & ~(255 << 8)))
8763         || (ix86_match_ccmode (insn, CCNOmode)
8764             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8765   [(set (match_dup 0)
8766         (match_op_dup 1
8767           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8768                    (match_dup 3))
8769            (const_int 0)]))]
8770   "operands[2] = gen_lowpart (SImode, operands[2]);
8771    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8772
8773 (define_split
8774   [(set (match_operand 0 "flags_reg_operand" "")
8775         (match_operator 1 "compare_operator"
8776           [(and (match_operand 2 "nonimmediate_operand" "")
8777                 (match_operand 3 "const_int_operand" ""))
8778            (const_int 0)]))]
8779    "reload_completed
8780     && GET_MODE (operands[2]) != QImode
8781     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8782     && ((ix86_match_ccmode (insn, CCZmode)
8783          && !(INTVAL (operands[3]) & ~255))
8784         || (ix86_match_ccmode (insn, CCNOmode)
8785             && !(INTVAL (operands[3]) & ~127)))"
8786   [(set (match_dup 0)
8787         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8788                          (const_int 0)]))]
8789   "operands[2] = gen_lowpart (QImode, operands[2]);
8790    operands[3] = gen_lowpart (QImode, operands[3]);")
8791
8792
8793 ;; %%% This used to optimize known byte-wide and operations to memory,
8794 ;; and sometimes to QImode registers.  If this is considered useful,
8795 ;; it should be done with splitters.
8796
8797 (define_expand "anddi3"
8798   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8799         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8800                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8801    (clobber (reg:CC FLAGS_REG))]
8802   "TARGET_64BIT"
8803   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8804
8805 (define_insn "*anddi_1_rex64"
8806   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8807         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8808                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8809    (clobber (reg:CC FLAGS_REG))]
8810   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8811 {
8812   switch (get_attr_type (insn))
8813     {
8814     case TYPE_IMOVX:
8815       {
8816         enum machine_mode mode;
8817
8818         gcc_assert (CONST_INT_P (operands[2]));
8819         if (INTVAL (operands[2]) == 0xff)
8820           mode = QImode;
8821         else
8822           {
8823             gcc_assert (INTVAL (operands[2]) == 0xffff);
8824             mode = HImode;
8825           }
8826
8827         operands[1] = gen_lowpart (mode, operands[1]);
8828         if (mode == QImode)
8829           return "movz{bq|x}\t{%1,%0|%0, %1}";
8830         else
8831           return "movz{wq|x}\t{%1,%0|%0, %1}";
8832       }
8833
8834     default:
8835       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8836       if (get_attr_mode (insn) == MODE_SI)
8837         return "and{l}\t{%k2, %k0|%k0, %k2}";
8838       else
8839         return "and{q}\t{%2, %0|%0, %2}";
8840     }
8841 }
8842   [(set_attr "type" "alu,alu,alu,imovx")
8843    (set_attr "length_immediate" "*,*,*,0")
8844    (set_attr "mode" "SI,DI,DI,DI")])
8845
8846 (define_insn "*anddi_2"
8847   [(set (reg FLAGS_REG)
8848         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8849                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8850                  (const_int 0)))
8851    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8852         (and:DI (match_dup 1) (match_dup 2)))]
8853   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8854    && ix86_binary_operator_ok (AND, DImode, operands)"
8855   "@
8856    and{l}\t{%k2, %k0|%k0, %k2}
8857    and{q}\t{%2, %0|%0, %2}
8858    and{q}\t{%2, %0|%0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "SI,DI,DI")])
8861
8862 (define_expand "andsi3"
8863   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8864         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8865                 (match_operand:SI 2 "general_operand" "")))
8866    (clobber (reg:CC FLAGS_REG))]
8867   ""
8868   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8869
8870 (define_insn "*andsi_1"
8871   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8872         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8873                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8874    (clobber (reg:CC FLAGS_REG))]
8875   "ix86_binary_operator_ok (AND, SImode, operands)"
8876 {
8877   switch (get_attr_type (insn))
8878     {
8879     case TYPE_IMOVX:
8880       {
8881         enum machine_mode mode;
8882
8883         gcc_assert (CONST_INT_P (operands[2]));
8884         if (INTVAL (operands[2]) == 0xff)
8885           mode = QImode;
8886         else
8887           {
8888             gcc_assert (INTVAL (operands[2]) == 0xffff);
8889             mode = HImode;
8890           }
8891
8892         operands[1] = gen_lowpart (mode, operands[1]);
8893         if (mode == QImode)
8894           return "movz{bl|x}\t{%1,%0|%0, %1}";
8895         else
8896           return "movz{wl|x}\t{%1,%0|%0, %1}";
8897       }
8898
8899     default:
8900       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8901       return "and{l}\t{%2, %0|%0, %2}";
8902     }
8903 }
8904   [(set_attr "type" "alu,alu,imovx")
8905    (set_attr "length_immediate" "*,*,0")
8906    (set_attr "mode" "SI")])
8907
8908 (define_split
8909   [(set (match_operand 0 "register_operand" "")
8910         (and (match_dup 0)
8911              (const_int -65536)))
8912    (clobber (reg:CC FLAGS_REG))]
8913   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8914   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8915   "operands[1] = gen_lowpart (HImode, operands[0]);")
8916
8917 (define_split
8918   [(set (match_operand 0 "ext_register_operand" "")
8919         (and (match_dup 0)
8920              (const_int -256)))
8921    (clobber (reg:CC FLAGS_REG))]
8922   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8923   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8924   "operands[1] = gen_lowpart (QImode, operands[0]);")
8925
8926 (define_split
8927   [(set (match_operand 0 "ext_register_operand" "")
8928         (and (match_dup 0)
8929              (const_int -65281)))
8930    (clobber (reg:CC FLAGS_REG))]
8931   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8932   [(parallel [(set (zero_extract:SI (match_dup 0)
8933                                     (const_int 8)
8934                                     (const_int 8))
8935                    (xor:SI
8936                      (zero_extract:SI (match_dup 0)
8937                                       (const_int 8)
8938                                       (const_int 8))
8939                      (zero_extract:SI (match_dup 0)
8940                                       (const_int 8)
8941                                       (const_int 8))))
8942               (clobber (reg:CC FLAGS_REG))])]
8943   "operands[0] = gen_lowpart (SImode, operands[0]);")
8944
8945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8946 (define_insn "*andsi_1_zext"
8947   [(set (match_operand:DI 0 "register_operand" "=r")
8948         (zero_extend:DI
8949           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8950                   (match_operand:SI 2 "general_operand" "g"))))
8951    (clobber (reg:CC FLAGS_REG))]
8952   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8953   "and{l}\t{%2, %k0|%k0, %2}"
8954   [(set_attr "type" "alu")
8955    (set_attr "mode" "SI")])
8956
8957 (define_insn "*andsi_2"
8958   [(set (reg FLAGS_REG)
8959         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8960                          (match_operand:SI 2 "general_operand" "g,ri"))
8961                  (const_int 0)))
8962    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8963         (and:SI (match_dup 1) (match_dup 2)))]
8964   "ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (AND, SImode, operands)"
8966   "and{l}\t{%2, %0|%0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "mode" "SI")])
8969
8970 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8971 (define_insn "*andsi_2_zext"
8972   [(set (reg FLAGS_REG)
8973         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8974                          (match_operand:SI 2 "general_operand" "g"))
8975                  (const_int 0)))
8976    (set (match_operand:DI 0 "register_operand" "=r")
8977         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8978   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8979    && ix86_binary_operator_ok (AND, SImode, operands)"
8980   "and{l}\t{%2, %k0|%k0, %2}"
8981   [(set_attr "type" "alu")
8982    (set_attr "mode" "SI")])
8983
8984 (define_expand "andhi3"
8985   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8986         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8987                 (match_operand:HI 2 "general_operand" "")))
8988    (clobber (reg:CC FLAGS_REG))]
8989   "TARGET_HIMODE_MATH"
8990   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8991
8992 (define_insn "*andhi_1"
8993   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8994         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8995                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8996    (clobber (reg:CC FLAGS_REG))]
8997   "ix86_binary_operator_ok (AND, HImode, operands)"
8998 {
8999   switch (get_attr_type (insn))
9000     {
9001     case TYPE_IMOVX:
9002       gcc_assert (CONST_INT_P (operands[2]));
9003       gcc_assert (INTVAL (operands[2]) == 0xff);
9004       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9005
9006     default:
9007       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9008
9009       return "and{w}\t{%2, %0|%0, %2}";
9010     }
9011 }
9012   [(set_attr "type" "alu,alu,imovx")
9013    (set_attr "length_immediate" "*,*,0")
9014    (set_attr "mode" "HI,HI,SI")])
9015
9016 (define_insn "*andhi_2"
9017   [(set (reg FLAGS_REG)
9018         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9019                          (match_operand:HI 2 "general_operand" "g,ri"))
9020                  (const_int 0)))
9021    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9022         (and:HI (match_dup 1) (match_dup 2)))]
9023   "ix86_match_ccmode (insn, CCNOmode)
9024    && ix86_binary_operator_ok (AND, HImode, operands)"
9025   "and{w}\t{%2, %0|%0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "mode" "HI")])
9028
9029 (define_expand "andqi3"
9030   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9031         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9032                 (match_operand:QI 2 "general_operand" "")))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "TARGET_QIMODE_MATH"
9035   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9036
9037 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9038 (define_insn "*andqi_1"
9039   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9040         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9041                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "ix86_binary_operator_ok (AND, QImode, operands)"
9044   "@
9045    and{b}\t{%2, %0|%0, %2}
9046    and{b}\t{%2, %0|%0, %2}
9047    and{l}\t{%k2, %k0|%k0, %k2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "QI,QI,SI")])
9050
9051 (define_insn "*andqi_1_slp"
9052   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9053         (and:QI (match_dup 0)
9054                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9055    (clobber (reg:CC FLAGS_REG))]
9056   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9057    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9058   "and{b}\t{%1, %0|%0, %1}"
9059   [(set_attr "type" "alu1")
9060    (set_attr "mode" "QI")])
9061
9062 (define_insn "*andqi_2_maybe_si"
9063   [(set (reg FLAGS_REG)
9064         (compare (and:QI
9065                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9066                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9067                  (const_int 0)))
9068    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9069         (and:QI (match_dup 1) (match_dup 2)))]
9070   "ix86_binary_operator_ok (AND, QImode, operands)
9071    && ix86_match_ccmode (insn,
9072                          CONST_INT_P (operands[2])
9073                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9074 {
9075   if (which_alternative == 2)
9076     {
9077       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9078         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9079       return "and{l}\t{%2, %k0|%k0, %2}";
9080     }
9081   return "and{b}\t{%2, %0|%0, %2}";
9082 }
9083   [(set_attr "type" "alu")
9084    (set_attr "mode" "QI,QI,SI")])
9085
9086 (define_insn "*andqi_2"
9087   [(set (reg FLAGS_REG)
9088         (compare (and:QI
9089                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9090                    (match_operand:QI 2 "general_operand" "qim,qi"))
9091                  (const_int 0)))
9092    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9093         (and:QI (match_dup 1) (match_dup 2)))]
9094   "ix86_match_ccmode (insn, CCNOmode)
9095    && ix86_binary_operator_ok (AND, QImode, operands)"
9096   "and{b}\t{%2, %0|%0, %2}"
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "QI")])
9099
9100 (define_insn "*andqi_2_slp"
9101   [(set (reg FLAGS_REG)
9102         (compare (and:QI
9103                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9104                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9105                  (const_int 0)))
9106    (set (strict_low_part (match_dup 0))
9107         (and:QI (match_dup 0) (match_dup 1)))]
9108   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109    && ix86_match_ccmode (insn, CCNOmode)
9110    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9111   "and{b}\t{%1, %0|%0, %1}"
9112   [(set_attr "type" "alu1")
9113    (set_attr "mode" "QI")])
9114
9115 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9116 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9117 ;; for a QImode operand, which of course failed.
9118
9119 (define_insn "andqi_ext_0"
9120   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9121                          (const_int 8)
9122                          (const_int 8))
9123         (and:SI
9124           (zero_extract:SI
9125             (match_operand 1 "ext_register_operand" "0")
9126             (const_int 8)
9127             (const_int 8))
9128           (match_operand 2 "const_int_operand" "n")))
9129    (clobber (reg:CC FLAGS_REG))]
9130   ""
9131   "and{b}\t{%2, %h0|%h0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "length_immediate" "1")
9134    (set_attr "mode" "QI")])
9135
9136 ;; Generated by peephole translating test to and.  This shows up
9137 ;; often in fp comparisons.
9138
9139 (define_insn "*andqi_ext_0_cc"
9140   [(set (reg FLAGS_REG)
9141         (compare
9142           (and:SI
9143             (zero_extract:SI
9144               (match_operand 1 "ext_register_operand" "0")
9145               (const_int 8)
9146               (const_int 8))
9147             (match_operand 2 "const_int_operand" "n"))
9148           (const_int 0)))
9149    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9150                          (const_int 8)
9151                          (const_int 8))
9152         (and:SI
9153           (zero_extract:SI
9154             (match_dup 1)
9155             (const_int 8)
9156             (const_int 8))
9157           (match_dup 2)))]
9158   "ix86_match_ccmode (insn, CCNOmode)"
9159   "and{b}\t{%2, %h0|%h0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "length_immediate" "1")
9162    (set_attr "mode" "QI")])
9163
9164 (define_insn "*andqi_ext_1"
9165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9166                          (const_int 8)
9167                          (const_int 8))
9168         (and:SI
9169           (zero_extract:SI
9170             (match_operand 1 "ext_register_operand" "0")
9171             (const_int 8)
9172             (const_int 8))
9173           (zero_extend:SI
9174             (match_operand:QI 2 "general_operand" "Qm"))))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "!TARGET_64BIT"
9177   "and{b}\t{%2, %h0|%h0, %2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "0")
9180    (set_attr "mode" "QI")])
9181
9182 (define_insn "*andqi_ext_1_rex64"
9183   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9184                          (const_int 8)
9185                          (const_int 8))
9186         (and:SI
9187           (zero_extract:SI
9188             (match_operand 1 "ext_register_operand" "0")
9189             (const_int 8)
9190             (const_int 8))
9191           (zero_extend:SI
9192             (match_operand 2 "ext_register_operand" "Q"))))
9193    (clobber (reg:CC FLAGS_REG))]
9194   "TARGET_64BIT"
9195   "and{b}\t{%2, %h0|%h0, %2}"
9196   [(set_attr "type" "alu")
9197    (set_attr "length_immediate" "0")
9198    (set_attr "mode" "QI")])
9199
9200 (define_insn "*andqi_ext_2"
9201   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9202                          (const_int 8)
9203                          (const_int 8))
9204         (and:SI
9205           (zero_extract:SI
9206             (match_operand 1 "ext_register_operand" "%0")
9207             (const_int 8)
9208             (const_int 8))
9209           (zero_extract:SI
9210             (match_operand 2 "ext_register_operand" "Q")
9211             (const_int 8)
9212             (const_int 8))))
9213    (clobber (reg:CC FLAGS_REG))]
9214   ""
9215   "and{b}\t{%h2, %h0|%h0, %h2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "length_immediate" "0")
9218    (set_attr "mode" "QI")])
9219
9220 ;; Convert wide AND instructions with immediate operand to shorter QImode
9221 ;; equivalents when possible.
9222 ;; Don't do the splitting with memory operands, since it introduces risk
9223 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9224 ;; for size, but that can (should?) be handled by generic code instead.
9225 (define_split
9226   [(set (match_operand 0 "register_operand" "")
9227         (and (match_operand 1 "register_operand" "")
9228              (match_operand 2 "const_int_operand" "")))
9229    (clobber (reg:CC FLAGS_REG))]
9230    "reload_completed
9231     && QI_REG_P (operands[0])
9232     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9233     && !(~INTVAL (operands[2]) & ~(255 << 8))
9234     && GET_MODE (operands[0]) != QImode"
9235   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9236                    (and:SI (zero_extract:SI (match_dup 1)
9237                                             (const_int 8) (const_int 8))
9238                            (match_dup 2)))
9239               (clobber (reg:CC FLAGS_REG))])]
9240   "operands[0] = gen_lowpart (SImode, operands[0]);
9241    operands[1] = gen_lowpart (SImode, operands[1]);
9242    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9243
9244 ;; Since AND can be encoded with sign extended immediate, this is only
9245 ;; profitable when 7th bit is not set.
9246 (define_split
9247   [(set (match_operand 0 "register_operand" "")
9248         (and (match_operand 1 "general_operand" "")
9249              (match_operand 2 "const_int_operand" "")))
9250    (clobber (reg:CC FLAGS_REG))]
9251    "reload_completed
9252     && ANY_QI_REG_P (operands[0])
9253     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9254     && !(~INTVAL (operands[2]) & ~255)
9255     && !(INTVAL (operands[2]) & 128)
9256     && GET_MODE (operands[0]) != QImode"
9257   [(parallel [(set (strict_low_part (match_dup 0))
9258                    (and:QI (match_dup 1)
9259                            (match_dup 2)))
9260               (clobber (reg:CC FLAGS_REG))])]
9261   "operands[0] = gen_lowpart (QImode, operands[0]);
9262    operands[1] = gen_lowpart (QImode, operands[1]);
9263    operands[2] = gen_lowpart (QImode, operands[2]);")
9264 \f
9265 ;; Logical inclusive OR instructions
9266
9267 ;; %%% This used to optimize known byte-wide and operations to memory.
9268 ;; If this is considered useful, it should be done with splitters.
9269
9270 (define_expand "iordi3"
9271   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9272         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9273                 (match_operand:DI 2 "x86_64_general_operand" "")))
9274    (clobber (reg:CC FLAGS_REG))]
9275   "TARGET_64BIT"
9276   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9277
9278 (define_insn "*iordi_1_rex64"
9279   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9280         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9281                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9282    (clobber (reg:CC FLAGS_REG))]
9283   "TARGET_64BIT
9284    && ix86_binary_operator_ok (IOR, DImode, operands)"
9285   "or{q}\t{%2, %0|%0, %2}"
9286   [(set_attr "type" "alu")
9287    (set_attr "mode" "DI")])
9288
9289 (define_insn "*iordi_2_rex64"
9290   [(set (reg FLAGS_REG)
9291         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9292                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9293                  (const_int 0)))
9294    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9295         (ior:DI (match_dup 1) (match_dup 2)))]
9296   "TARGET_64BIT
9297    && ix86_match_ccmode (insn, CCNOmode)
9298    && ix86_binary_operator_ok (IOR, DImode, operands)"
9299   "or{q}\t{%2, %0|%0, %2}"
9300   [(set_attr "type" "alu")
9301    (set_attr "mode" "DI")])
9302
9303 (define_insn "*iordi_3_rex64"
9304   [(set (reg FLAGS_REG)
9305         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9306                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9307                  (const_int 0)))
9308    (clobber (match_scratch:DI 0 "=r"))]
9309   "TARGET_64BIT
9310    && ix86_match_ccmode (insn, CCNOmode)
9311    && ix86_binary_operator_ok (IOR, DImode, operands)"
9312   "or{q}\t{%2, %0|%0, %2}"
9313   [(set_attr "type" "alu")
9314    (set_attr "mode" "DI")])
9315
9316
9317 (define_expand "iorsi3"
9318   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9319         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9320                 (match_operand:SI 2 "general_operand" "")))
9321    (clobber (reg:CC FLAGS_REG))]
9322   ""
9323   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9324
9325 (define_insn "*iorsi_1"
9326   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9327         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9328                 (match_operand:SI 2 "general_operand" "ri,g")))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "ix86_binary_operator_ok (IOR, SImode, operands)"
9331   "or{l}\t{%2, %0|%0, %2}"
9332   [(set_attr "type" "alu")
9333    (set_attr "mode" "SI")])
9334
9335 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9336 (define_insn "*iorsi_1_zext"
9337   [(set (match_operand:DI 0 "register_operand" "=r")
9338         (zero_extend:DI
9339           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9340                   (match_operand:SI 2 "general_operand" "g"))))
9341    (clobber (reg:CC FLAGS_REG))]
9342   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9343   "or{l}\t{%2, %k0|%k0, %2}"
9344   [(set_attr "type" "alu")
9345    (set_attr "mode" "SI")])
9346
9347 (define_insn "*iorsi_1_zext_imm"
9348   [(set (match_operand:DI 0 "register_operand" "=r")
9349         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9350                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9351    (clobber (reg:CC FLAGS_REG))]
9352   "TARGET_64BIT"
9353   "or{l}\t{%2, %k0|%k0, %2}"
9354   [(set_attr "type" "alu")
9355    (set_attr "mode" "SI")])
9356
9357 (define_insn "*iorsi_2"
9358   [(set (reg FLAGS_REG)
9359         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9360                          (match_operand:SI 2 "general_operand" "g,ri"))
9361                  (const_int 0)))
9362    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9363         (ior:SI (match_dup 1) (match_dup 2)))]
9364   "ix86_match_ccmode (insn, CCNOmode)
9365    && ix86_binary_operator_ok (IOR, SImode, operands)"
9366   "or{l}\t{%2, %0|%0, %2}"
9367   [(set_attr "type" "alu")
9368    (set_attr "mode" "SI")])
9369
9370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9371 ;; ??? Special case for immediate operand is missing - it is tricky.
9372 (define_insn "*iorsi_2_zext"
9373   [(set (reg FLAGS_REG)
9374         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9375                          (match_operand:SI 2 "general_operand" "g"))
9376                  (const_int 0)))
9377    (set (match_operand:DI 0 "register_operand" "=r")
9378         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9379   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9380    && ix86_binary_operator_ok (IOR, SImode, operands)"
9381   "or{l}\t{%2, %k0|%k0, %2}"
9382   [(set_attr "type" "alu")
9383    (set_attr "mode" "SI")])
9384
9385 (define_insn "*iorsi_2_zext_imm"
9386   [(set (reg FLAGS_REG)
9387         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9388                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9389                  (const_int 0)))
9390    (set (match_operand:DI 0 "register_operand" "=r")
9391         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9392   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9393    && ix86_binary_operator_ok (IOR, SImode, operands)"
9394   "or{l}\t{%2, %k0|%k0, %2}"
9395   [(set_attr "type" "alu")
9396    (set_attr "mode" "SI")])
9397
9398 (define_insn "*iorsi_3"
9399   [(set (reg FLAGS_REG)
9400         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9401                          (match_operand:SI 2 "general_operand" "g"))
9402                  (const_int 0)))
9403    (clobber (match_scratch:SI 0 "=r"))]
9404   "ix86_match_ccmode (insn, CCNOmode)
9405    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9406   "or{l}\t{%2, %0|%0, %2}"
9407   [(set_attr "type" "alu")
9408    (set_attr "mode" "SI")])
9409
9410 (define_expand "iorhi3"
9411   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9412         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9413                 (match_operand:HI 2 "general_operand" "")))
9414    (clobber (reg:CC FLAGS_REG))]
9415   "TARGET_HIMODE_MATH"
9416   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9417
9418 (define_insn "*iorhi_1"
9419   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9420         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9421                 (match_operand:HI 2 "general_operand" "g,ri")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   "ix86_binary_operator_ok (IOR, HImode, operands)"
9424   "or{w}\t{%2, %0|%0, %2}"
9425   [(set_attr "type" "alu")
9426    (set_attr "mode" "HI")])
9427
9428 (define_insn "*iorhi_2"
9429   [(set (reg FLAGS_REG)
9430         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9431                          (match_operand:HI 2 "general_operand" "g,ri"))
9432                  (const_int 0)))
9433    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9434         (ior:HI (match_dup 1) (match_dup 2)))]
9435   "ix86_match_ccmode (insn, CCNOmode)
9436    && ix86_binary_operator_ok (IOR, HImode, operands)"
9437   "or{w}\t{%2, %0|%0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "mode" "HI")])
9440
9441 (define_insn "*iorhi_3"
9442   [(set (reg FLAGS_REG)
9443         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9444                          (match_operand:HI 2 "general_operand" "g"))
9445                  (const_int 0)))
9446    (clobber (match_scratch:HI 0 "=r"))]
9447   "ix86_match_ccmode (insn, CCNOmode)
9448    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9449   "or{w}\t{%2, %0|%0, %2}"
9450   [(set_attr "type" "alu")
9451    (set_attr "mode" "HI")])
9452
9453 (define_expand "iorqi3"
9454   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9455         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9456                 (match_operand:QI 2 "general_operand" "")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "TARGET_QIMODE_MATH"
9459   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9460
9461 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9462 (define_insn "*iorqi_1"
9463   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9464         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9465                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "ix86_binary_operator_ok (IOR, QImode, operands)"
9468   "@
9469    or{b}\t{%2, %0|%0, %2}
9470    or{b}\t{%2, %0|%0, %2}
9471    or{l}\t{%k2, %k0|%k0, %k2}"
9472   [(set_attr "type" "alu")
9473    (set_attr "mode" "QI,QI,SI")])
9474
9475 (define_insn "*iorqi_1_slp"
9476   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9477         (ior:QI (match_dup 0)
9478                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9479    (clobber (reg:CC FLAGS_REG))]
9480   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9481    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9482   "or{b}\t{%1, %0|%0, %1}"
9483   [(set_attr "type" "alu1")
9484    (set_attr "mode" "QI")])
9485
9486 (define_insn "*iorqi_2"
9487   [(set (reg FLAGS_REG)
9488         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9489                          (match_operand:QI 2 "general_operand" "qim,qi"))
9490                  (const_int 0)))
9491    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9492         (ior:QI (match_dup 1) (match_dup 2)))]
9493   "ix86_match_ccmode (insn, CCNOmode)
9494    && ix86_binary_operator_ok (IOR, QImode, operands)"
9495   "or{b}\t{%2, %0|%0, %2}"
9496   [(set_attr "type" "alu")
9497    (set_attr "mode" "QI")])
9498
9499 (define_insn "*iorqi_2_slp"
9500   [(set (reg FLAGS_REG)
9501         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9502                          (match_operand:QI 1 "general_operand" "qim,qi"))
9503                  (const_int 0)))
9504    (set (strict_low_part (match_dup 0))
9505         (ior:QI (match_dup 0) (match_dup 1)))]
9506   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9507    && ix86_match_ccmode (insn, CCNOmode)
9508    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9509   "or{b}\t{%1, %0|%0, %1}"
9510   [(set_attr "type" "alu1")
9511    (set_attr "mode" "QI")])
9512
9513 (define_insn "*iorqi_3"
9514   [(set (reg FLAGS_REG)
9515         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9516                          (match_operand:QI 2 "general_operand" "qim"))
9517                  (const_int 0)))
9518    (clobber (match_scratch:QI 0 "=q"))]
9519   "ix86_match_ccmode (insn, CCNOmode)
9520    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9521   "or{b}\t{%2, %0|%0, %2}"
9522   [(set_attr "type" "alu")
9523    (set_attr "mode" "QI")])
9524
9525 (define_insn "iorqi_ext_0"
9526   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9527                          (const_int 8)
9528                          (const_int 8))
9529         (ior:SI
9530           (zero_extract:SI
9531             (match_operand 1 "ext_register_operand" "0")
9532             (const_int 8)
9533             (const_int 8))
9534           (match_operand 2 "const_int_operand" "n")))
9535    (clobber (reg:CC FLAGS_REG))]
9536   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9537   "or{b}\t{%2, %h0|%h0, %2}"
9538   [(set_attr "type" "alu")
9539    (set_attr "length_immediate" "1")
9540    (set_attr "mode" "QI")])
9541
9542 (define_insn "*iorqi_ext_1"
9543   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9544                          (const_int 8)
9545                          (const_int 8))
9546         (ior:SI
9547           (zero_extract:SI
9548             (match_operand 1 "ext_register_operand" "0")
9549             (const_int 8)
9550             (const_int 8))
9551           (zero_extend:SI
9552             (match_operand:QI 2 "general_operand" "Qm"))))
9553    (clobber (reg:CC FLAGS_REG))]
9554   "!TARGET_64BIT
9555    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9556   "or{b}\t{%2, %h0|%h0, %2}"
9557   [(set_attr "type" "alu")
9558    (set_attr "length_immediate" "0")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*iorqi_ext_1_rex64"
9562   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9563                          (const_int 8)
9564                          (const_int 8))
9565         (ior:SI
9566           (zero_extract:SI
9567             (match_operand 1 "ext_register_operand" "0")
9568             (const_int 8)
9569             (const_int 8))
9570           (zero_extend:SI
9571             (match_operand 2 "ext_register_operand" "Q"))))
9572    (clobber (reg:CC FLAGS_REG))]
9573   "TARGET_64BIT
9574    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9575   "or{b}\t{%2, %h0|%h0, %2}"
9576   [(set_attr "type" "alu")
9577    (set_attr "length_immediate" "0")
9578    (set_attr "mode" "QI")])
9579
9580 (define_insn "*iorqi_ext_2"
9581   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9582                          (const_int 8)
9583                          (const_int 8))
9584         (ior:SI
9585           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9586                            (const_int 8)
9587                            (const_int 8))
9588           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9589                            (const_int 8)
9590                            (const_int 8))))
9591    (clobber (reg:CC FLAGS_REG))]
9592   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9593   "ior{b}\t{%h2, %h0|%h0, %h2}"
9594   [(set_attr "type" "alu")
9595    (set_attr "length_immediate" "0")
9596    (set_attr "mode" "QI")])
9597
9598 (define_split
9599   [(set (match_operand 0 "register_operand" "")
9600         (ior (match_operand 1 "register_operand" "")
9601              (match_operand 2 "const_int_operand" "")))
9602    (clobber (reg:CC FLAGS_REG))]
9603    "reload_completed
9604     && QI_REG_P (operands[0])
9605     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9606     && !(INTVAL (operands[2]) & ~(255 << 8))
9607     && GET_MODE (operands[0]) != QImode"
9608   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9609                    (ior:SI (zero_extract:SI (match_dup 1)
9610                                             (const_int 8) (const_int 8))
9611                            (match_dup 2)))
9612               (clobber (reg:CC FLAGS_REG))])]
9613   "operands[0] = gen_lowpart (SImode, operands[0]);
9614    operands[1] = gen_lowpart (SImode, operands[1]);
9615    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9616
9617 ;; Since OR can be encoded with sign extended immediate, this is only
9618 ;; profitable when 7th bit is set.
9619 (define_split
9620   [(set (match_operand 0 "register_operand" "")
9621         (ior (match_operand 1 "general_operand" "")
9622              (match_operand 2 "const_int_operand" "")))
9623    (clobber (reg:CC FLAGS_REG))]
9624    "reload_completed
9625     && ANY_QI_REG_P (operands[0])
9626     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9627     && !(INTVAL (operands[2]) & ~255)
9628     && (INTVAL (operands[2]) & 128)
9629     && GET_MODE (operands[0]) != QImode"
9630   [(parallel [(set (strict_low_part (match_dup 0))
9631                    (ior:QI (match_dup 1)
9632                            (match_dup 2)))
9633               (clobber (reg:CC FLAGS_REG))])]
9634   "operands[0] = gen_lowpart (QImode, operands[0]);
9635    operands[1] = gen_lowpart (QImode, operands[1]);
9636    operands[2] = gen_lowpart (QImode, operands[2]);")
9637 \f
9638 ;; Logical XOR instructions
9639
9640 ;; %%% This used to optimize known byte-wide and operations to memory.
9641 ;; If this is considered useful, it should be done with splitters.
9642
9643 (define_expand "xordi3"
9644   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9645         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9646                 (match_operand:DI 2 "x86_64_general_operand" "")))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "TARGET_64BIT"
9649   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9650
9651 (define_insn "*xordi_1_rex64"
9652   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9653         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9654                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9655    (clobber (reg:CC FLAGS_REG))]
9656   "TARGET_64BIT
9657    && ix86_binary_operator_ok (XOR, DImode, operands)"
9658   "@
9659    xor{q}\t{%2, %0|%0, %2}
9660    xor{q}\t{%2, %0|%0, %2}"
9661   [(set_attr "type" "alu")
9662    (set_attr "mode" "DI,DI")])
9663
9664 (define_insn "*xordi_2_rex64"
9665   [(set (reg FLAGS_REG)
9666         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9667                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9668                  (const_int 0)))
9669    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9670         (xor:DI (match_dup 1) (match_dup 2)))]
9671   "TARGET_64BIT
9672    && ix86_match_ccmode (insn, CCNOmode)
9673    && ix86_binary_operator_ok (XOR, DImode, operands)"
9674   "@
9675    xor{q}\t{%2, %0|%0, %2}
9676    xor{q}\t{%2, %0|%0, %2}"
9677   [(set_attr "type" "alu")
9678    (set_attr "mode" "DI,DI")])
9679
9680 (define_insn "*xordi_3_rex64"
9681   [(set (reg FLAGS_REG)
9682         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9683                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9684                  (const_int 0)))
9685    (clobber (match_scratch:DI 0 "=r"))]
9686   "TARGET_64BIT
9687    && ix86_match_ccmode (insn, CCNOmode)
9688    && ix86_binary_operator_ok (XOR, DImode, operands)"
9689   "xor{q}\t{%2, %0|%0, %2}"
9690   [(set_attr "type" "alu")
9691    (set_attr "mode" "DI")])
9692
9693 (define_expand "xorsi3"
9694   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9695         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9696                 (match_operand:SI 2 "general_operand" "")))
9697    (clobber (reg:CC FLAGS_REG))]
9698   ""
9699   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9700
9701 (define_insn "*xorsi_1"
9702   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9703         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9704                 (match_operand:SI 2 "general_operand" "ri,rm")))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "ix86_binary_operator_ok (XOR, SImode, operands)"
9707   "xor{l}\t{%2, %0|%0, %2}"
9708   [(set_attr "type" "alu")
9709    (set_attr "mode" "SI")])
9710
9711 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9712 ;; Add speccase for immediates
9713 (define_insn "*xorsi_1_zext"
9714   [(set (match_operand:DI 0 "register_operand" "=r")
9715         (zero_extend:DI
9716           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9717                   (match_operand:SI 2 "general_operand" "g"))))
9718    (clobber (reg:CC FLAGS_REG))]
9719   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9720   "xor{l}\t{%2, %k0|%k0, %2}"
9721   [(set_attr "type" "alu")
9722    (set_attr "mode" "SI")])
9723
9724 (define_insn "*xorsi_1_zext_imm"
9725   [(set (match_operand:DI 0 "register_operand" "=r")
9726         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9727                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9728    (clobber (reg:CC FLAGS_REG))]
9729   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9730   "xor{l}\t{%2, %k0|%k0, %2}"
9731   [(set_attr "type" "alu")
9732    (set_attr "mode" "SI")])
9733
9734 (define_insn "*xorsi_2"
9735   [(set (reg FLAGS_REG)
9736         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9737                          (match_operand:SI 2 "general_operand" "g,ri"))
9738                  (const_int 0)))
9739    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9740         (xor:SI (match_dup 1) (match_dup 2)))]
9741   "ix86_match_ccmode (insn, CCNOmode)
9742    && ix86_binary_operator_ok (XOR, SImode, operands)"
9743   "xor{l}\t{%2, %0|%0, %2}"
9744   [(set_attr "type" "alu")
9745    (set_attr "mode" "SI")])
9746
9747 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9748 ;; ??? Special case for immediate operand is missing - it is tricky.
9749 (define_insn "*xorsi_2_zext"
9750   [(set (reg FLAGS_REG)
9751         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9752                          (match_operand:SI 2 "general_operand" "g"))
9753                  (const_int 0)))
9754    (set (match_operand:DI 0 "register_operand" "=r")
9755         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9756   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9757    && ix86_binary_operator_ok (XOR, SImode, operands)"
9758   "xor{l}\t{%2, %k0|%k0, %2}"
9759   [(set_attr "type" "alu")
9760    (set_attr "mode" "SI")])
9761
9762 (define_insn "*xorsi_2_zext_imm"
9763   [(set (reg FLAGS_REG)
9764         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9765                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9766                  (const_int 0)))
9767    (set (match_operand:DI 0 "register_operand" "=r")
9768         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9769   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9770    && ix86_binary_operator_ok (XOR, SImode, operands)"
9771   "xor{l}\t{%2, %k0|%k0, %2}"
9772   [(set_attr "type" "alu")
9773    (set_attr "mode" "SI")])
9774
9775 (define_insn "*xorsi_3"
9776   [(set (reg FLAGS_REG)
9777         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9778                          (match_operand:SI 2 "general_operand" "g"))
9779                  (const_int 0)))
9780    (clobber (match_scratch:SI 0 "=r"))]
9781   "ix86_match_ccmode (insn, CCNOmode)
9782    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9783   "xor{l}\t{%2, %0|%0, %2}"
9784   [(set_attr "type" "alu")
9785    (set_attr "mode" "SI")])
9786
9787 (define_expand "xorhi3"
9788   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9789         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9790                 (match_operand:HI 2 "general_operand" "")))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "TARGET_HIMODE_MATH"
9793   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9794
9795 (define_insn "*xorhi_1"
9796   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9797         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9798                 (match_operand:HI 2 "general_operand" "g,ri")))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "ix86_binary_operator_ok (XOR, HImode, operands)"
9801   "xor{w}\t{%2, %0|%0, %2}"
9802   [(set_attr "type" "alu")
9803    (set_attr "mode" "HI")])
9804
9805 (define_insn "*xorhi_2"
9806   [(set (reg FLAGS_REG)
9807         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9808                          (match_operand:HI 2 "general_operand" "g,ri"))
9809                  (const_int 0)))
9810    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9811         (xor:HI (match_dup 1) (match_dup 2)))]
9812   "ix86_match_ccmode (insn, CCNOmode)
9813    && ix86_binary_operator_ok (XOR, HImode, operands)"
9814   "xor{w}\t{%2, %0|%0, %2}"
9815   [(set_attr "type" "alu")
9816    (set_attr "mode" "HI")])
9817
9818 (define_insn "*xorhi_3"
9819   [(set (reg FLAGS_REG)
9820         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9821                          (match_operand:HI 2 "general_operand" "g"))
9822                  (const_int 0)))
9823    (clobber (match_scratch:HI 0 "=r"))]
9824   "ix86_match_ccmode (insn, CCNOmode)
9825    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9826   "xor{w}\t{%2, %0|%0, %2}"
9827   [(set_attr "type" "alu")
9828    (set_attr "mode" "HI")])
9829
9830 (define_expand "xorqi3"
9831   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9832         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9833                 (match_operand:QI 2 "general_operand" "")))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "TARGET_QIMODE_MATH"
9836   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9837
9838 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9839 (define_insn "*xorqi_1"
9840   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9841         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9842                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9843    (clobber (reg:CC FLAGS_REG))]
9844   "ix86_binary_operator_ok (XOR, QImode, operands)"
9845   "@
9846    xor{b}\t{%2, %0|%0, %2}
9847    xor{b}\t{%2, %0|%0, %2}
9848    xor{l}\t{%k2, %k0|%k0, %k2}"
9849   [(set_attr "type" "alu")
9850    (set_attr "mode" "QI,QI,SI")])
9851
9852 (define_insn "*xorqi_1_slp"
9853   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9854         (xor:QI (match_dup 0)
9855                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9856    (clobber (reg:CC FLAGS_REG))]
9857   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9858    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9859   "xor{b}\t{%1, %0|%0, %1}"
9860   [(set_attr "type" "alu1")
9861    (set_attr "mode" "QI")])
9862
9863 (define_insn "xorqi_ext_0"
9864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9865                          (const_int 8)
9866                          (const_int 8))
9867         (xor:SI
9868           (zero_extract:SI
9869             (match_operand 1 "ext_register_operand" "0")
9870             (const_int 8)
9871             (const_int 8))
9872           (match_operand 2 "const_int_operand" "n")))
9873    (clobber (reg:CC FLAGS_REG))]
9874   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9875   "xor{b}\t{%2, %h0|%h0, %2}"
9876   [(set_attr "type" "alu")
9877    (set_attr "length_immediate" "1")
9878    (set_attr "mode" "QI")])
9879
9880 (define_insn "*xorqi_ext_1"
9881   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9882                          (const_int 8)
9883                          (const_int 8))
9884         (xor:SI
9885           (zero_extract:SI
9886             (match_operand 1 "ext_register_operand" "0")
9887             (const_int 8)
9888             (const_int 8))
9889           (zero_extend:SI
9890             (match_operand:QI 2 "general_operand" "Qm"))))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "!TARGET_64BIT
9893    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9894   "xor{b}\t{%2, %h0|%h0, %2}"
9895   [(set_attr "type" "alu")
9896    (set_attr "length_immediate" "0")
9897    (set_attr "mode" "QI")])
9898
9899 (define_insn "*xorqi_ext_1_rex64"
9900   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9901                          (const_int 8)
9902                          (const_int 8))
9903         (xor:SI
9904           (zero_extract:SI
9905             (match_operand 1 "ext_register_operand" "0")
9906             (const_int 8)
9907             (const_int 8))
9908           (zero_extend:SI
9909             (match_operand 2 "ext_register_operand" "Q"))))
9910    (clobber (reg:CC FLAGS_REG))]
9911   "TARGET_64BIT
9912    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9913   "xor{b}\t{%2, %h0|%h0, %2}"
9914   [(set_attr "type" "alu")
9915    (set_attr "length_immediate" "0")
9916    (set_attr "mode" "QI")])
9917
9918 (define_insn "*xorqi_ext_2"
9919   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9920                          (const_int 8)
9921                          (const_int 8))
9922         (xor:SI
9923           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9924                            (const_int 8)
9925                            (const_int 8))
9926           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9927                            (const_int 8)
9928                            (const_int 8))))
9929    (clobber (reg:CC FLAGS_REG))]
9930   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9931   "xor{b}\t{%h2, %h0|%h0, %h2}"
9932   [(set_attr "type" "alu")
9933    (set_attr "length_immediate" "0")
9934    (set_attr "mode" "QI")])
9935
9936 (define_insn "*xorqi_cc_1"
9937   [(set (reg FLAGS_REG)
9938         (compare
9939           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9940                   (match_operand:QI 2 "general_operand" "qim,qi"))
9941           (const_int 0)))
9942    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9943         (xor:QI (match_dup 1) (match_dup 2)))]
9944   "ix86_match_ccmode (insn, CCNOmode)
9945    && ix86_binary_operator_ok (XOR, QImode, operands)"
9946   "xor{b}\t{%2, %0|%0, %2}"
9947   [(set_attr "type" "alu")
9948    (set_attr "mode" "QI")])
9949
9950 (define_insn "*xorqi_2_slp"
9951   [(set (reg FLAGS_REG)
9952         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9953                          (match_operand:QI 1 "general_operand" "qim,qi"))
9954                  (const_int 0)))
9955    (set (strict_low_part (match_dup 0))
9956         (xor:QI (match_dup 0) (match_dup 1)))]
9957   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9958    && ix86_match_ccmode (insn, CCNOmode)
9959    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9960   "xor{b}\t{%1, %0|%0, %1}"
9961   [(set_attr "type" "alu1")
9962    (set_attr "mode" "QI")])
9963
9964 (define_insn "*xorqi_cc_2"
9965   [(set (reg FLAGS_REG)
9966         (compare
9967           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9968                   (match_operand:QI 2 "general_operand" "qim"))
9969           (const_int 0)))
9970    (clobber (match_scratch:QI 0 "=q"))]
9971   "ix86_match_ccmode (insn, CCNOmode)
9972    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9973   "xor{b}\t{%2, %0|%0, %2}"
9974   [(set_attr "type" "alu")
9975    (set_attr "mode" "QI")])
9976
9977 (define_insn "*xorqi_cc_ext_1"
9978   [(set (reg FLAGS_REG)
9979         (compare
9980           (xor:SI
9981             (zero_extract:SI
9982               (match_operand 1 "ext_register_operand" "0")
9983               (const_int 8)
9984               (const_int 8))
9985             (match_operand:QI 2 "general_operand" "qmn"))
9986           (const_int 0)))
9987    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9988                          (const_int 8)
9989                          (const_int 8))
9990         (xor:SI
9991           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9992           (match_dup 2)))]
9993   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9994   "xor{b}\t{%2, %h0|%h0, %2}"
9995   [(set_attr "type" "alu")
9996    (set_attr "mode" "QI")])
9997
9998 (define_insn "*xorqi_cc_ext_1_rex64"
9999   [(set (reg FLAGS_REG)
10000         (compare
10001           (xor:SI
10002             (zero_extract:SI
10003               (match_operand 1 "ext_register_operand" "0")
10004               (const_int 8)
10005               (const_int 8))
10006             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10007           (const_int 0)))
10008    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10009                          (const_int 8)
10010                          (const_int 8))
10011         (xor:SI
10012           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10013           (match_dup 2)))]
10014   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10015   "xor{b}\t{%2, %h0|%h0, %2}"
10016   [(set_attr "type" "alu")
10017    (set_attr "mode" "QI")])
10018
10019 (define_expand "xorqi_cc_ext_1"
10020   [(parallel [
10021      (set (reg:CCNO FLAGS_REG)
10022           (compare:CCNO
10023             (xor:SI
10024               (zero_extract:SI
10025                 (match_operand 1 "ext_register_operand" "")
10026                 (const_int 8)
10027                 (const_int 8))
10028               (match_operand:QI 2 "general_operand" ""))
10029             (const_int 0)))
10030      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10031                            (const_int 8)
10032                            (const_int 8))
10033           (xor:SI
10034             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10035             (match_dup 2)))])]
10036   ""
10037   "")
10038
10039 (define_split
10040   [(set (match_operand 0 "register_operand" "")
10041         (xor (match_operand 1 "register_operand" "")
10042              (match_operand 2 "const_int_operand" "")))
10043    (clobber (reg:CC FLAGS_REG))]
10044    "reload_completed
10045     && QI_REG_P (operands[0])
10046     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10047     && !(INTVAL (operands[2]) & ~(255 << 8))
10048     && GET_MODE (operands[0]) != QImode"
10049   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10050                    (xor:SI (zero_extract:SI (match_dup 1)
10051                                             (const_int 8) (const_int 8))
10052                            (match_dup 2)))
10053               (clobber (reg:CC FLAGS_REG))])]
10054   "operands[0] = gen_lowpart (SImode, operands[0]);
10055    operands[1] = gen_lowpart (SImode, operands[1]);
10056    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10057
10058 ;; Since XOR can be encoded with sign extended immediate, this is only
10059 ;; profitable when 7th bit is set.
10060 (define_split
10061   [(set (match_operand 0 "register_operand" "")
10062         (xor (match_operand 1 "general_operand" "")
10063              (match_operand 2 "const_int_operand" "")))
10064    (clobber (reg:CC FLAGS_REG))]
10065    "reload_completed
10066     && ANY_QI_REG_P (operands[0])
10067     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10068     && !(INTVAL (operands[2]) & ~255)
10069     && (INTVAL (operands[2]) & 128)
10070     && GET_MODE (operands[0]) != QImode"
10071   [(parallel [(set (strict_low_part (match_dup 0))
10072                    (xor:QI (match_dup 1)
10073                            (match_dup 2)))
10074               (clobber (reg:CC FLAGS_REG))])]
10075   "operands[0] = gen_lowpart (QImode, operands[0]);
10076    operands[1] = gen_lowpart (QImode, operands[1]);
10077    operands[2] = gen_lowpart (QImode, operands[2]);")
10078 \f
10079 ;; Negation instructions
10080
10081 (define_expand "negti2"
10082   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10083                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10084               (clobber (reg:CC FLAGS_REG))])]
10085   "TARGET_64BIT"
10086   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10087
10088 (define_insn "*negti2_1"
10089   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10090         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10091    (clobber (reg:CC FLAGS_REG))]
10092   "TARGET_64BIT
10093    && ix86_unary_operator_ok (NEG, TImode, operands)"
10094   "#")
10095
10096 (define_split
10097   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10098         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10099    (clobber (reg:CC FLAGS_REG))]
10100   "TARGET_64BIT && reload_completed"
10101   [(parallel
10102     [(set (reg:CCZ FLAGS_REG)
10103           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10104      (set (match_dup 0) (neg:DI (match_dup 2)))])
10105    (parallel
10106     [(set (match_dup 1)
10107           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10108                             (match_dup 3))
10109                    (const_int 0)))
10110      (clobber (reg:CC FLAGS_REG))])
10111    (parallel
10112     [(set (match_dup 1)
10113           (neg:DI (match_dup 1)))
10114      (clobber (reg:CC FLAGS_REG))])]
10115   "split_ti (operands+1, 1, operands+2, operands+3);
10116    split_ti (operands+0, 1, operands+0, operands+1);")
10117
10118 (define_expand "negdi2"
10119   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10120                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10121               (clobber (reg:CC FLAGS_REG))])]
10122   ""
10123   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10124
10125 (define_insn "*negdi2_1"
10126   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10127         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10128    (clobber (reg:CC FLAGS_REG))]
10129   "!TARGET_64BIT
10130    && ix86_unary_operator_ok (NEG, DImode, operands)"
10131   "#")
10132
10133 (define_split
10134   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10135         (neg:DI (match_operand:DI 1 "general_operand" "")))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "!TARGET_64BIT && reload_completed"
10138   [(parallel
10139     [(set (reg:CCZ FLAGS_REG)
10140           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10141      (set (match_dup 0) (neg:SI (match_dup 2)))])
10142    (parallel
10143     [(set (match_dup 1)
10144           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10145                             (match_dup 3))
10146                    (const_int 0)))
10147      (clobber (reg:CC FLAGS_REG))])
10148    (parallel
10149     [(set (match_dup 1)
10150           (neg:SI (match_dup 1)))
10151      (clobber (reg:CC FLAGS_REG))])]
10152   "split_di (operands+1, 1, operands+2, operands+3);
10153    split_di (operands+0, 1, operands+0, operands+1);")
10154
10155 (define_insn "*negdi2_1_rex64"
10156   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10157         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10158    (clobber (reg:CC FLAGS_REG))]
10159   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10160   "neg{q}\t%0"
10161   [(set_attr "type" "negnot")
10162    (set_attr "mode" "DI")])
10163
10164 ;; The problem with neg is that it does not perform (compare x 0),
10165 ;; it really performs (compare 0 x), which leaves us with the zero
10166 ;; flag being the only useful item.
10167
10168 (define_insn "*negdi2_cmpz_rex64"
10169   [(set (reg:CCZ FLAGS_REG)
10170         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10171                      (const_int 0)))
10172    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10173         (neg:DI (match_dup 1)))]
10174   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10175   "neg{q}\t%0"
10176   [(set_attr "type" "negnot")
10177    (set_attr "mode" "DI")])
10178
10179
10180 (define_expand "negsi2"
10181   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10182                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10183               (clobber (reg:CC FLAGS_REG))])]
10184   ""
10185   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10186
10187 (define_insn "*negsi2_1"
10188   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10189         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10190    (clobber (reg:CC FLAGS_REG))]
10191   "ix86_unary_operator_ok (NEG, SImode, operands)"
10192   "neg{l}\t%0"
10193   [(set_attr "type" "negnot")
10194    (set_attr "mode" "SI")])
10195
10196 ;; Combine is quite creative about this pattern.
10197 (define_insn "*negsi2_1_zext"
10198   [(set (match_operand:DI 0 "register_operand" "=r")
10199         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10200                                         (const_int 32)))
10201                      (const_int 32)))
10202    (clobber (reg:CC FLAGS_REG))]
10203   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10204   "neg{l}\t%k0"
10205   [(set_attr "type" "negnot")
10206    (set_attr "mode" "SI")])
10207
10208 ;; The problem with neg is that it does not perform (compare x 0),
10209 ;; it really performs (compare 0 x), which leaves us with the zero
10210 ;; flag being the only useful item.
10211
10212 (define_insn "*negsi2_cmpz"
10213   [(set (reg:CCZ FLAGS_REG)
10214         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10215                      (const_int 0)))
10216    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10217         (neg:SI (match_dup 1)))]
10218   "ix86_unary_operator_ok (NEG, SImode, operands)"
10219   "neg{l}\t%0"
10220   [(set_attr "type" "negnot")
10221    (set_attr "mode" "SI")])
10222
10223 (define_insn "*negsi2_cmpz_zext"
10224   [(set (reg:CCZ FLAGS_REG)
10225         (compare:CCZ (lshiftrt:DI
10226                        (neg:DI (ashift:DI
10227                                  (match_operand:DI 1 "register_operand" "0")
10228                                  (const_int 32)))
10229                        (const_int 32))
10230                      (const_int 0)))
10231    (set (match_operand:DI 0 "register_operand" "=r")
10232         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10233                                         (const_int 32)))
10234                      (const_int 32)))]
10235   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10236   "neg{l}\t%k0"
10237   [(set_attr "type" "negnot")
10238    (set_attr "mode" "SI")])
10239
10240 (define_expand "neghi2"
10241   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10242                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10243               (clobber (reg:CC FLAGS_REG))])]
10244   "TARGET_HIMODE_MATH"
10245   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10246
10247 (define_insn "*neghi2_1"
10248   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10249         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10250    (clobber (reg:CC FLAGS_REG))]
10251   "ix86_unary_operator_ok (NEG, HImode, operands)"
10252   "neg{w}\t%0"
10253   [(set_attr "type" "negnot")
10254    (set_attr "mode" "HI")])
10255
10256 (define_insn "*neghi2_cmpz"
10257   [(set (reg:CCZ FLAGS_REG)
10258         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10259                      (const_int 0)))
10260    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10261         (neg:HI (match_dup 1)))]
10262   "ix86_unary_operator_ok (NEG, HImode, operands)"
10263   "neg{w}\t%0"
10264   [(set_attr "type" "negnot")
10265    (set_attr "mode" "HI")])
10266
10267 (define_expand "negqi2"
10268   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10269                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10270               (clobber (reg:CC FLAGS_REG))])]
10271   "TARGET_QIMODE_MATH"
10272   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10273
10274 (define_insn "*negqi2_1"
10275   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10276         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "ix86_unary_operator_ok (NEG, QImode, operands)"
10279   "neg{b}\t%0"
10280   [(set_attr "type" "negnot")
10281    (set_attr "mode" "QI")])
10282
10283 (define_insn "*negqi2_cmpz"
10284   [(set (reg:CCZ FLAGS_REG)
10285         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10286                      (const_int 0)))
10287    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10288         (neg:QI (match_dup 1)))]
10289   "ix86_unary_operator_ok (NEG, QImode, operands)"
10290   "neg{b}\t%0"
10291   [(set_attr "type" "negnot")
10292    (set_attr "mode" "QI")])
10293
10294 ;; Changing of sign for FP values is doable using integer unit too.
10295
10296 (define_expand "neg<mode>2"
10297   [(set (match_operand:X87MODEF 0 "register_operand" "")
10298         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10299   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10300   "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10301
10302 (define_expand "abs<mode>2"
10303   [(set (match_operand:X87MODEF 0 "register_operand" "")
10304         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10305   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10306   "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10307
10308 (define_insn "*absneg<mode>2_mixed"
10309   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10310         (match_operator:MODEF 3 "absneg_operator"
10311           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10312    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10313    (clobber (reg:CC FLAGS_REG))]
10314   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10315   "#")
10316
10317 (define_insn "*absneg<mode>2_sse"
10318   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10319         (match_operator:MODEF 3 "absneg_operator"
10320           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10321    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10322    (clobber (reg:CC FLAGS_REG))]
10323   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10324   "#")
10325
10326 (define_insn "*absneg<mode>2_i387"
10327   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10328         (match_operator:X87MODEF 3 "absneg_operator"
10329           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10330    (use (match_operand 2 "" ""))
10331    (clobber (reg:CC FLAGS_REG))]
10332   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10333   "#")
10334
10335 (define_expand "negtf2"
10336   [(set (match_operand:TF 0 "register_operand" "")
10337         (neg:TF (match_operand:TF 1 "register_operand" "")))]
10338   "TARGET_64BIT"
10339   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10340
10341 (define_expand "abstf2"
10342   [(set (match_operand:TF 0 "register_operand" "")
10343         (abs:TF (match_operand:TF 1 "register_operand" "")))]
10344   "TARGET_64BIT"
10345   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10346
10347 (define_insn "*absnegtf2_sse"
10348   [(set (match_operand:TF 0 "register_operand" "=x,x")
10349         (match_operator:TF 3 "absneg_operator"
10350           [(match_operand:TF 1 "register_operand" "0,x")]))
10351    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10352    (clobber (reg:CC FLAGS_REG))]
10353   "TARGET_64BIT"
10354   "#")
10355
10356 ;; Splitters for fp abs and neg.
10357
10358 (define_split
10359   [(set (match_operand 0 "fp_register_operand" "")
10360         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10361    (use (match_operand 2 "" ""))
10362    (clobber (reg:CC FLAGS_REG))]
10363   "reload_completed"
10364   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10365
10366 (define_split
10367   [(set (match_operand 0 "register_operand" "")
10368         (match_operator 3 "absneg_operator"
10369           [(match_operand 1 "register_operand" "")]))
10370    (use (match_operand 2 "nonimmediate_operand" ""))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "reload_completed && SSE_REG_P (operands[0])"
10373   [(set (match_dup 0) (match_dup 3))]
10374 {
10375   enum machine_mode mode = GET_MODE (operands[0]);
10376   enum machine_mode vmode = GET_MODE (operands[2]);
10377   rtx tmp;
10378
10379   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10380   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10381   if (operands_match_p (operands[0], operands[2]))
10382     {
10383       tmp = operands[1];
10384       operands[1] = operands[2];
10385       operands[2] = tmp;
10386     }
10387   if (GET_CODE (operands[3]) == ABS)
10388     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10389   else
10390     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10391   operands[3] = tmp;
10392 })
10393
10394 (define_split
10395   [(set (match_operand:SF 0 "register_operand" "")
10396         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10397    (use (match_operand:V4SF 2 "" ""))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "reload_completed"
10400   [(parallel [(set (match_dup 0) (match_dup 1))
10401               (clobber (reg:CC FLAGS_REG))])]
10402 {
10403   rtx tmp;
10404   operands[0] = gen_lowpart (SImode, operands[0]);
10405   if (GET_CODE (operands[1]) == ABS)
10406     {
10407       tmp = gen_int_mode (0x7fffffff, SImode);
10408       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10409     }
10410   else
10411     {
10412       tmp = gen_int_mode (0x80000000, SImode);
10413       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10414     }
10415   operands[1] = tmp;
10416 })
10417
10418 (define_split
10419   [(set (match_operand:DF 0 "register_operand" "")
10420         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10421    (use (match_operand 2 "" ""))
10422    (clobber (reg:CC FLAGS_REG))]
10423   "reload_completed"
10424   [(parallel [(set (match_dup 0) (match_dup 1))
10425               (clobber (reg:CC FLAGS_REG))])]
10426 {
10427   rtx tmp;
10428   if (TARGET_64BIT)
10429     {
10430       tmp = gen_lowpart (DImode, operands[0]);
10431       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10432       operands[0] = tmp;
10433
10434       if (GET_CODE (operands[1]) == ABS)
10435         tmp = const0_rtx;
10436       else
10437         tmp = gen_rtx_NOT (DImode, tmp);
10438     }
10439   else
10440     {
10441       operands[0] = gen_highpart (SImode, operands[0]);
10442       if (GET_CODE (operands[1]) == ABS)
10443         {
10444           tmp = gen_int_mode (0x7fffffff, SImode);
10445           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10446         }
10447       else
10448         {
10449           tmp = gen_int_mode (0x80000000, SImode);
10450           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10451         }
10452     }
10453   operands[1] = tmp;
10454 })
10455
10456 (define_split
10457   [(set (match_operand:XF 0 "register_operand" "")
10458         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10459    (use (match_operand 2 "" ""))
10460    (clobber (reg:CC FLAGS_REG))]
10461   "reload_completed"
10462   [(parallel [(set (match_dup 0) (match_dup 1))
10463               (clobber (reg:CC FLAGS_REG))])]
10464 {
10465   rtx tmp;
10466   operands[0] = gen_rtx_REG (SImode,
10467                              true_regnum (operands[0])
10468                              + (TARGET_64BIT ? 1 : 2));
10469   if (GET_CODE (operands[1]) == ABS)
10470     {
10471       tmp = GEN_INT (0x7fff);
10472       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10473     }
10474   else
10475     {
10476       tmp = GEN_INT (0x8000);
10477       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10478     }
10479   operands[1] = tmp;
10480 })
10481
10482 ;; Conditionalize these after reload. If they match before reload, we
10483 ;; lose the clobber and ability to use integer instructions.
10484
10485 (define_insn "*neg<mode>2_1"
10486   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10487         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10488   "TARGET_80387
10489    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10490   "fchs"
10491   [(set_attr "type" "fsgn")
10492    (set_attr "mode" "<MODE>")])
10493
10494 (define_insn "*abs<mode>2_1"
10495   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10496         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10497   "TARGET_80387
10498    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10499   "fabs"
10500   [(set_attr "type" "fsgn")
10501    (set_attr "mode" "<MODE>")])
10502
10503 (define_insn "*negextendsfdf2"
10504   [(set (match_operand:DF 0 "register_operand" "=f")
10505         (neg:DF (float_extend:DF
10506                   (match_operand:SF 1 "register_operand" "0"))))]
10507   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10508   "fchs"
10509   [(set_attr "type" "fsgn")
10510    (set_attr "mode" "DF")])
10511
10512 (define_insn "*negextenddfxf2"
10513   [(set (match_operand:XF 0 "register_operand" "=f")
10514         (neg:XF (float_extend:XF
10515                   (match_operand:DF 1 "register_operand" "0"))))]
10516   "TARGET_80387"
10517   "fchs"
10518   [(set_attr "type" "fsgn")
10519    (set_attr "mode" "XF")])
10520
10521 (define_insn "*negextendsfxf2"
10522   [(set (match_operand:XF 0 "register_operand" "=f")
10523         (neg:XF (float_extend:XF
10524                   (match_operand:SF 1 "register_operand" "0"))))]
10525   "TARGET_80387"
10526   "fchs"
10527   [(set_attr "type" "fsgn")
10528    (set_attr "mode" "XF")])
10529
10530 (define_insn "*absextendsfdf2"
10531   [(set (match_operand:DF 0 "register_operand" "=f")
10532         (abs:DF (float_extend:DF
10533                   (match_operand:SF 1 "register_operand" "0"))))]
10534   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10535   "fabs"
10536   [(set_attr "type" "fsgn")
10537    (set_attr "mode" "DF")])
10538
10539 (define_insn "*absextenddfxf2"
10540   [(set (match_operand:XF 0 "register_operand" "=f")
10541         (abs:XF (float_extend:XF
10542           (match_operand:DF 1 "register_operand" "0"))))]
10543   "TARGET_80387"
10544   "fabs"
10545   [(set_attr "type" "fsgn")
10546    (set_attr "mode" "XF")])
10547
10548 (define_insn "*absextendsfxf2"
10549   [(set (match_operand:XF 0 "register_operand" "=f")
10550         (abs:XF (float_extend:XF
10551           (match_operand:SF 1 "register_operand" "0"))))]
10552   "TARGET_80387"
10553   "fabs"
10554   [(set_attr "type" "fsgn")
10555    (set_attr "mode" "XF")])
10556
10557 ;; Copysign instructions
10558
10559 (define_mode_iterator CSGNMODE [SF DF TF])
10560 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10561
10562 (define_expand "copysign<mode>3"
10563   [(match_operand:CSGNMODE 0 "register_operand" "")
10564    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10565    (match_operand:CSGNMODE 2 "register_operand" "")]
10566   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10567    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10568 {
10569   ix86_expand_copysign (operands);
10570   DONE;
10571 })
10572
10573 (define_insn_and_split "copysign<mode>3_const"
10574   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10575         (unspec:CSGNMODE
10576           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10577            (match_operand:CSGNMODE 2 "register_operand" "0")
10578            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10579           UNSPEC_COPYSIGN))]
10580   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10581    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10582   "#"
10583   "&& reload_completed"
10584   [(const_int 0)]
10585 {
10586   ix86_split_copysign_const (operands);
10587   DONE;
10588 })
10589
10590 (define_insn "copysign<mode>3_var"
10591   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10592         (unspec:CSGNMODE
10593           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10594            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10595            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10596            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10597           UNSPEC_COPYSIGN))
10598    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10599   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10600    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10601   "#")
10602
10603 (define_split
10604   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10605         (unspec:CSGNMODE
10606           [(match_operand:CSGNMODE 2 "register_operand" "")
10607            (match_operand:CSGNMODE 3 "register_operand" "")
10608            (match_operand:<CSGNVMODE> 4 "" "")
10609            (match_operand:<CSGNVMODE> 5 "" "")]
10610           UNSPEC_COPYSIGN))
10611    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10612   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10613     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10614    && reload_completed"
10615   [(const_int 0)]
10616 {
10617   ix86_split_copysign_var (operands);
10618   DONE;
10619 })
10620 \f
10621 ;; One complement instructions
10622
10623 (define_expand "one_cmpldi2"
10624   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10625         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10626   "TARGET_64BIT"
10627   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10628
10629 (define_insn "*one_cmpldi2_1_rex64"
10630   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10631         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10632   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10633   "not{q}\t%0"
10634   [(set_attr "type" "negnot")
10635    (set_attr "mode" "DI")])
10636
10637 (define_insn "*one_cmpldi2_2_rex64"
10638   [(set (reg FLAGS_REG)
10639         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10640                  (const_int 0)))
10641    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10642         (not:DI (match_dup 1)))]
10643   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10644    && ix86_unary_operator_ok (NOT, DImode, operands)"
10645   "#"
10646   [(set_attr "type" "alu1")
10647    (set_attr "mode" "DI")])
10648
10649 (define_split
10650   [(set (match_operand 0 "flags_reg_operand" "")
10651         (match_operator 2 "compare_operator"
10652           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10653            (const_int 0)]))
10654    (set (match_operand:DI 1 "nonimmediate_operand" "")
10655         (not:DI (match_dup 3)))]
10656   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10657   [(parallel [(set (match_dup 0)
10658                    (match_op_dup 2
10659                      [(xor:DI (match_dup 3) (const_int -1))
10660                       (const_int 0)]))
10661               (set (match_dup 1)
10662                    (xor:DI (match_dup 3) (const_int -1)))])]
10663   "")
10664
10665 (define_expand "one_cmplsi2"
10666   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10667         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10668   ""
10669   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10670
10671 (define_insn "*one_cmplsi2_1"
10672   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10673         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10674   "ix86_unary_operator_ok (NOT, SImode, operands)"
10675   "not{l}\t%0"
10676   [(set_attr "type" "negnot")
10677    (set_attr "mode" "SI")])
10678
10679 ;; ??? Currently never generated - xor is used instead.
10680 (define_insn "*one_cmplsi2_1_zext"
10681   [(set (match_operand:DI 0 "register_operand" "=r")
10682         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10683   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10684   "not{l}\t%k0"
10685   [(set_attr "type" "negnot")
10686    (set_attr "mode" "SI")])
10687
10688 (define_insn "*one_cmplsi2_2"
10689   [(set (reg FLAGS_REG)
10690         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10691                  (const_int 0)))
10692    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10693         (not:SI (match_dup 1)))]
10694   "ix86_match_ccmode (insn, CCNOmode)
10695    && ix86_unary_operator_ok (NOT, SImode, operands)"
10696   "#"
10697   [(set_attr "type" "alu1")
10698    (set_attr "mode" "SI")])
10699
10700 (define_split
10701   [(set (match_operand 0 "flags_reg_operand" "")
10702         (match_operator 2 "compare_operator"
10703           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10704            (const_int 0)]))
10705    (set (match_operand:SI 1 "nonimmediate_operand" "")
10706         (not:SI (match_dup 3)))]
10707   "ix86_match_ccmode (insn, CCNOmode)"
10708   [(parallel [(set (match_dup 0)
10709                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10710                                     (const_int 0)]))
10711               (set (match_dup 1)
10712                    (xor:SI (match_dup 3) (const_int -1)))])]
10713   "")
10714
10715 ;; ??? Currently never generated - xor is used instead.
10716 (define_insn "*one_cmplsi2_2_zext"
10717   [(set (reg FLAGS_REG)
10718         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10719                  (const_int 0)))
10720    (set (match_operand:DI 0 "register_operand" "=r")
10721         (zero_extend:DI (not:SI (match_dup 1))))]
10722   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10723    && ix86_unary_operator_ok (NOT, SImode, operands)"
10724   "#"
10725   [(set_attr "type" "alu1")
10726    (set_attr "mode" "SI")])
10727
10728 (define_split
10729   [(set (match_operand 0 "flags_reg_operand" "")
10730         (match_operator 2 "compare_operator"
10731           [(not:SI (match_operand:SI 3 "register_operand" ""))
10732            (const_int 0)]))
10733    (set (match_operand:DI 1 "register_operand" "")
10734         (zero_extend:DI (not:SI (match_dup 3))))]
10735   "ix86_match_ccmode (insn, CCNOmode)"
10736   [(parallel [(set (match_dup 0)
10737                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10738                                     (const_int 0)]))
10739               (set (match_dup 1)
10740                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10741   "")
10742
10743 (define_expand "one_cmplhi2"
10744   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10745         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10746   "TARGET_HIMODE_MATH"
10747   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10748
10749 (define_insn "*one_cmplhi2_1"
10750   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10751         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10752   "ix86_unary_operator_ok (NOT, HImode, operands)"
10753   "not{w}\t%0"
10754   [(set_attr "type" "negnot")
10755    (set_attr "mode" "HI")])
10756
10757 (define_insn "*one_cmplhi2_2"
10758   [(set (reg FLAGS_REG)
10759         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10760                  (const_int 0)))
10761    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10762         (not:HI (match_dup 1)))]
10763   "ix86_match_ccmode (insn, CCNOmode)
10764    && ix86_unary_operator_ok (NEG, HImode, operands)"
10765   "#"
10766   [(set_attr "type" "alu1")
10767    (set_attr "mode" "HI")])
10768
10769 (define_split
10770   [(set (match_operand 0 "flags_reg_operand" "")
10771         (match_operator 2 "compare_operator"
10772           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10773            (const_int 0)]))
10774    (set (match_operand:HI 1 "nonimmediate_operand" "")
10775         (not:HI (match_dup 3)))]
10776   "ix86_match_ccmode (insn, CCNOmode)"
10777   [(parallel [(set (match_dup 0)
10778                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10779                                     (const_int 0)]))
10780               (set (match_dup 1)
10781                    (xor:HI (match_dup 3) (const_int -1)))])]
10782   "")
10783
10784 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10785 (define_expand "one_cmplqi2"
10786   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10787         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10788   "TARGET_QIMODE_MATH"
10789   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10790
10791 (define_insn "*one_cmplqi2_1"
10792   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10793         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10794   "ix86_unary_operator_ok (NOT, QImode, operands)"
10795   "@
10796    not{b}\t%0
10797    not{l}\t%k0"
10798   [(set_attr "type" "negnot")
10799    (set_attr "mode" "QI,SI")])
10800
10801 (define_insn "*one_cmplqi2_2"
10802   [(set (reg FLAGS_REG)
10803         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10804                  (const_int 0)))
10805    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10806         (not:QI (match_dup 1)))]
10807   "ix86_match_ccmode (insn, CCNOmode)
10808    && ix86_unary_operator_ok (NOT, QImode, operands)"
10809   "#"
10810   [(set_attr "type" "alu1")
10811    (set_attr "mode" "QI")])
10812
10813 (define_split
10814   [(set (match_operand 0 "flags_reg_operand" "")
10815         (match_operator 2 "compare_operator"
10816           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10817            (const_int 0)]))
10818    (set (match_operand:QI 1 "nonimmediate_operand" "")
10819         (not:QI (match_dup 3)))]
10820   "ix86_match_ccmode (insn, CCNOmode)"
10821   [(parallel [(set (match_dup 0)
10822                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10823                                     (const_int 0)]))
10824               (set (match_dup 1)
10825                    (xor:QI (match_dup 3) (const_int -1)))])]
10826   "")
10827 \f
10828 ;; Arithmetic shift instructions
10829
10830 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10831 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10832 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10833 ;; from the assembler input.
10834 ;;
10835 ;; This instruction shifts the target reg/mem as usual, but instead of
10836 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10837 ;; is a left shift double, bits are taken from the high order bits of
10838 ;; reg, else if the insn is a shift right double, bits are taken from the
10839 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10840 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10841 ;;
10842 ;; Since sh[lr]d does not change the `reg' operand, that is done
10843 ;; separately, making all shifts emit pairs of shift double and normal
10844 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10845 ;; support a 63 bit shift, each shift where the count is in a reg expands
10846 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10847 ;;
10848 ;; If the shift count is a constant, we need never emit more than one
10849 ;; shift pair, instead using moves and sign extension for counts greater
10850 ;; than 31.
10851
10852 (define_expand "ashlti3"
10853   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10854                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10855                               (match_operand:QI 2 "nonmemory_operand" "")))
10856               (clobber (reg:CC FLAGS_REG))])]
10857   "TARGET_64BIT"
10858 {
10859   if (! immediate_operand (operands[2], QImode))
10860     {
10861       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10862       DONE;
10863     }
10864   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10865   DONE;
10866 })
10867
10868 (define_insn "ashlti3_1"
10869   [(set (match_operand:TI 0 "register_operand" "=r")
10870         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10871                    (match_operand:QI 2 "register_operand" "c")))
10872    (clobber (match_scratch:DI 3 "=&r"))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "TARGET_64BIT"
10875   "#"
10876   [(set_attr "type" "multi")])
10877
10878 ;; This pattern must be defined before *ashlti3_2 to prevent
10879 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10880
10881 (define_insn "sse2_ashlti3"
10882   [(set (match_operand:TI 0 "register_operand" "=x")
10883         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10884                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10885   "TARGET_SSE2"
10886 {
10887   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10888   return "pslldq\t{%2, %0|%0, %2}";
10889 }
10890   [(set_attr "type" "sseishft")
10891    (set_attr "prefix_data16" "1")
10892    (set_attr "mode" "TI")])
10893
10894 (define_insn "*ashlti3_2"
10895   [(set (match_operand:TI 0 "register_operand" "=r")
10896         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10897                    (match_operand:QI 2 "immediate_operand" "O")))
10898    (clobber (reg:CC FLAGS_REG))]
10899   "TARGET_64BIT"
10900   "#"
10901   [(set_attr "type" "multi")])
10902
10903 (define_split
10904   [(set (match_operand:TI 0 "register_operand" "")
10905         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10906                    (match_operand:QI 2 "register_operand" "")))
10907    (clobber (match_scratch:DI 3 ""))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "TARGET_64BIT && reload_completed"
10910   [(const_int 0)]
10911   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10912
10913 (define_split
10914   [(set (match_operand:TI 0 "register_operand" "")
10915         (ashift:TI (match_operand:TI 1 "register_operand" "")
10916                    (match_operand:QI 2 "immediate_operand" "")))
10917    (clobber (reg:CC FLAGS_REG))]
10918   "TARGET_64BIT && reload_completed"
10919   [(const_int 0)]
10920   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10921
10922 (define_insn "x86_64_shld"
10923   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10924         (ior:DI (ashift:DI (match_dup 0)
10925                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10926                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10927                   (minus:QI (const_int 64) (match_dup 2)))))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "TARGET_64BIT"
10930   "@
10931    shld{q}\t{%2, %1, %0|%0, %1, %2}
10932    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10933   [(set_attr "type" "ishift")
10934    (set_attr "prefix_0f" "1")
10935    (set_attr "mode" "DI")
10936    (set_attr "athlon_decode" "vector")
10937    (set_attr "amdfam10_decode" "vector")])
10938
10939 (define_expand "x86_64_shift_adj"
10940   [(set (reg:CCZ FLAGS_REG)
10941         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10942                              (const_int 64))
10943                      (const_int 0)))
10944    (set (match_operand:DI 0 "register_operand" "")
10945         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10946                          (match_operand:DI 1 "register_operand" "")
10947                          (match_dup 0)))
10948    (set (match_dup 1)
10949         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10950                          (match_operand:DI 3 "register_operand" "r")
10951                          (match_dup 1)))]
10952   "TARGET_64BIT"
10953   "")
10954
10955 (define_expand "ashldi3"
10956   [(set (match_operand:DI 0 "shiftdi_operand" "")
10957         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10958                    (match_operand:QI 2 "nonmemory_operand" "")))]
10959   ""
10960   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10961
10962 (define_insn "*ashldi3_1_rex64"
10963   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10964         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10965                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10966    (clobber (reg:CC FLAGS_REG))]
10967   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10968 {
10969   switch (get_attr_type (insn))
10970     {
10971     case TYPE_ALU:
10972       gcc_assert (operands[2] == const1_rtx);
10973       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10974       return "add{q}\t%0, %0";
10975
10976     case TYPE_LEA:
10977       gcc_assert (CONST_INT_P (operands[2]));
10978       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10979       operands[1] = gen_rtx_MULT (DImode, operands[1],
10980                                   GEN_INT (1 << INTVAL (operands[2])));
10981       return "lea{q}\t{%a1, %0|%0, %a1}";
10982
10983     default:
10984       if (REG_P (operands[2]))
10985         return "sal{q}\t{%b2, %0|%0, %b2}";
10986       else if (operands[2] == const1_rtx
10987                && (TARGET_SHIFT1 || optimize_size))
10988         return "sal{q}\t%0";
10989       else
10990         return "sal{q}\t{%2, %0|%0, %2}";
10991     }
10992 }
10993   [(set (attr "type")
10994      (cond [(eq_attr "alternative" "1")
10995               (const_string "lea")
10996             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10997                           (const_int 0))
10998                       (match_operand 0 "register_operand" ""))
10999                  (match_operand 2 "const1_operand" ""))
11000               (const_string "alu")
11001            ]
11002            (const_string "ishift")))
11003    (set_attr "mode" "DI")])
11004
11005 ;; Convert lea to the lea pattern to avoid flags dependency.
11006 (define_split
11007   [(set (match_operand:DI 0 "register_operand" "")
11008         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11009                    (match_operand:QI 2 "immediate_operand" "")))
11010    (clobber (reg:CC FLAGS_REG))]
11011   "TARGET_64BIT && reload_completed
11012    && true_regnum (operands[0]) != true_regnum (operands[1])"
11013   [(set (match_dup 0)
11014         (mult:DI (match_dup 1)
11015                  (match_dup 2)))]
11016   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11017
11018 ;; This pattern can't accept a variable shift count, since shifts by
11019 ;; zero don't affect the flags.  We assume that shifts by constant
11020 ;; zero are optimized away.
11021 (define_insn "*ashldi3_cmp_rex64"
11022   [(set (reg FLAGS_REG)
11023         (compare
11024           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11025                      (match_operand:QI 2 "immediate_operand" "e"))
11026           (const_int 0)))
11027    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11028         (ashift:DI (match_dup 1) (match_dup 2)))]
11029   "TARGET_64BIT
11030    && (optimize_size
11031        || !TARGET_PARTIAL_FLAG_REG_STALL
11032        || (operands[2] == const1_rtx
11033            && (TARGET_SHIFT1
11034                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11035    && ix86_match_ccmode (insn, CCGOCmode)
11036    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11037 {
11038   switch (get_attr_type (insn))
11039     {
11040     case TYPE_ALU:
11041       gcc_assert (operands[2] == const1_rtx);
11042       return "add{q}\t%0, %0";
11043
11044     default:
11045       if (REG_P (operands[2]))
11046         return "sal{q}\t{%b2, %0|%0, %b2}";
11047       else if (operands[2] == const1_rtx
11048                && (TARGET_SHIFT1 || optimize_size))
11049         return "sal{q}\t%0";
11050       else
11051         return "sal{q}\t{%2, %0|%0, %2}";
11052     }
11053 }
11054   [(set (attr "type")
11055      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11056                           (const_int 0))
11057                       (match_operand 0 "register_operand" ""))
11058                  (match_operand 2 "const1_operand" ""))
11059               (const_string "alu")
11060            ]
11061            (const_string "ishift")))
11062    (set_attr "mode" "DI")])
11063
11064 (define_insn "*ashldi3_cconly_rex64"
11065   [(set (reg FLAGS_REG)
11066         (compare
11067           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11068                      (match_operand:QI 2 "immediate_operand" "e"))
11069           (const_int 0)))
11070    (clobber (match_scratch:DI 0 "=r"))]
11071   "TARGET_64BIT
11072    && (optimize_size
11073        || !TARGET_PARTIAL_FLAG_REG_STALL
11074        || (operands[2] == const1_rtx
11075            && (TARGET_SHIFT1
11076                || TARGET_DOUBLE_WITH_ADD)))
11077    && ix86_match_ccmode (insn, CCGOCmode)
11078    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11079 {
11080   switch (get_attr_type (insn))
11081     {
11082     case TYPE_ALU:
11083       gcc_assert (operands[2] == const1_rtx);
11084       return "add{q}\t%0, %0";
11085
11086     default:
11087       if (REG_P (operands[2]))
11088         return "sal{q}\t{%b2, %0|%0, %b2}";
11089       else if (operands[2] == const1_rtx
11090                && (TARGET_SHIFT1 || optimize_size))
11091         return "sal{q}\t%0";
11092       else
11093         return "sal{q}\t{%2, %0|%0, %2}";
11094     }
11095 }
11096   [(set (attr "type")
11097      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11098                           (const_int 0))
11099                       (match_operand 0 "register_operand" ""))
11100                  (match_operand 2 "const1_operand" ""))
11101               (const_string "alu")
11102            ]
11103            (const_string "ishift")))
11104    (set_attr "mode" "DI")])
11105
11106 (define_insn "*ashldi3_1"
11107   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11108         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11109                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11110    (clobber (reg:CC FLAGS_REG))]
11111   "!TARGET_64BIT"
11112   "#"
11113   [(set_attr "type" "multi")])
11114
11115 ;; By default we don't ask for a scratch register, because when DImode
11116 ;; values are manipulated, registers are already at a premium.  But if
11117 ;; we have one handy, we won't turn it away.
11118 (define_peephole2
11119   [(match_scratch:SI 3 "r")
11120    (parallel [(set (match_operand:DI 0 "register_operand" "")
11121                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11122                               (match_operand:QI 2 "nonmemory_operand" "")))
11123               (clobber (reg:CC FLAGS_REG))])
11124    (match_dup 3)]
11125   "!TARGET_64BIT && TARGET_CMOVE"
11126   [(const_int 0)]
11127   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11128
11129 (define_split
11130   [(set (match_operand:DI 0 "register_operand" "")
11131         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11132                    (match_operand:QI 2 "nonmemory_operand" "")))
11133    (clobber (reg:CC FLAGS_REG))]
11134   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11135                      ? epilogue_completed : reload_completed)"
11136   [(const_int 0)]
11137   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11138
11139 (define_insn "x86_shld_1"
11140   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11141         (ior:SI (ashift:SI (match_dup 0)
11142                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11143                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11144                   (minus:QI (const_int 32) (match_dup 2)))))
11145    (clobber (reg:CC FLAGS_REG))]
11146   ""
11147   "@
11148    shld{l}\t{%2, %1, %0|%0, %1, %2}
11149    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11150   [(set_attr "type" "ishift")
11151    (set_attr "prefix_0f" "1")
11152    (set_attr "mode" "SI")
11153    (set_attr "pent_pair" "np")
11154    (set_attr "athlon_decode" "vector")
11155    (set_attr "amdfam10_decode" "vector")])
11156
11157 (define_expand "x86_shift_adj_1"
11158   [(set (reg:CCZ FLAGS_REG)
11159         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11160                              (const_int 32))
11161                      (const_int 0)))
11162    (set (match_operand:SI 0 "register_operand" "")
11163         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11164                          (match_operand:SI 1 "register_operand" "")
11165                          (match_dup 0)))
11166    (set (match_dup 1)
11167         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11168                          (match_operand:SI 3 "register_operand" "r")
11169                          (match_dup 1)))]
11170   "TARGET_CMOVE"
11171   "")
11172
11173 (define_expand "x86_shift_adj_2"
11174   [(use (match_operand:SI 0 "register_operand" ""))
11175    (use (match_operand:SI 1 "register_operand" ""))
11176    (use (match_operand:QI 2 "register_operand" ""))]
11177   ""
11178 {
11179   rtx label = gen_label_rtx ();
11180   rtx tmp;
11181
11182   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11183
11184   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11185   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11186   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11187                               gen_rtx_LABEL_REF (VOIDmode, label),
11188                               pc_rtx);
11189   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11190   JUMP_LABEL (tmp) = label;
11191
11192   emit_move_insn (operands[0], operands[1]);
11193   ix86_expand_clear (operands[1]);
11194
11195   emit_label (label);
11196   LABEL_NUSES (label) = 1;
11197
11198   DONE;
11199 })
11200
11201 (define_expand "ashlsi3"
11202   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11203         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11204                    (match_operand:QI 2 "nonmemory_operand" "")))
11205    (clobber (reg:CC FLAGS_REG))]
11206   ""
11207   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11208
11209 (define_insn "*ashlsi3_1"
11210   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11211         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11212                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11213    (clobber (reg:CC FLAGS_REG))]
11214   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11215 {
11216   switch (get_attr_type (insn))
11217     {
11218     case TYPE_ALU:
11219       gcc_assert (operands[2] == const1_rtx);
11220       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11221       return "add{l}\t%0, %0";
11222
11223     case TYPE_LEA:
11224       return "#";
11225
11226     default:
11227       if (REG_P (operands[2]))
11228         return "sal{l}\t{%b2, %0|%0, %b2}";
11229       else if (operands[2] == const1_rtx
11230                && (TARGET_SHIFT1 || optimize_size))
11231         return "sal{l}\t%0";
11232       else
11233         return "sal{l}\t{%2, %0|%0, %2}";
11234     }
11235 }
11236   [(set (attr "type")
11237      (cond [(eq_attr "alternative" "1")
11238               (const_string "lea")
11239             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11240                           (const_int 0))
11241                       (match_operand 0 "register_operand" ""))
11242                  (match_operand 2 "const1_operand" ""))
11243               (const_string "alu")
11244            ]
11245            (const_string "ishift")))
11246    (set_attr "mode" "SI")])
11247
11248 ;; Convert lea to the lea pattern to avoid flags dependency.
11249 (define_split
11250   [(set (match_operand 0 "register_operand" "")
11251         (ashift (match_operand 1 "index_register_operand" "")
11252                 (match_operand:QI 2 "const_int_operand" "")))
11253    (clobber (reg:CC FLAGS_REG))]
11254   "reload_completed
11255    && true_regnum (operands[0]) != true_regnum (operands[1])
11256    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11257   [(const_int 0)]
11258 {
11259   rtx pat;
11260   enum machine_mode mode = GET_MODE (operands[0]);
11261
11262   if (GET_MODE_SIZE (mode) < 4)
11263     operands[0] = gen_lowpart (SImode, operands[0]);
11264   if (mode != Pmode)
11265     operands[1] = gen_lowpart (Pmode, operands[1]);
11266   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11267
11268   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11269   if (Pmode != SImode)
11270     pat = gen_rtx_SUBREG (SImode, pat, 0);
11271   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11272   DONE;
11273 })
11274
11275 ;; Rare case of shifting RSP is handled by generating move and shift
11276 (define_split
11277   [(set (match_operand 0 "register_operand" "")
11278         (ashift (match_operand 1 "register_operand" "")
11279                 (match_operand:QI 2 "const_int_operand" "")))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "reload_completed
11282    && true_regnum (operands[0]) != true_regnum (operands[1])"
11283   [(const_int 0)]
11284 {
11285   rtx pat, clob;
11286   emit_move_insn (operands[0], operands[1]);
11287   pat = gen_rtx_SET (VOIDmode, operands[0],
11288                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11289                                      operands[0], operands[2]));
11290   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11291   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11292   DONE;
11293 })
11294
11295 (define_insn "*ashlsi3_1_zext"
11296   [(set (match_operand:DI 0 "register_operand" "=r,r")
11297         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11298                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11299    (clobber (reg:CC FLAGS_REG))]
11300   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11301 {
11302   switch (get_attr_type (insn))
11303     {
11304     case TYPE_ALU:
11305       gcc_assert (operands[2] == const1_rtx);
11306       return "add{l}\t%k0, %k0";
11307
11308     case TYPE_LEA:
11309       return "#";
11310
11311     default:
11312       if (REG_P (operands[2]))
11313         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11314       else if (operands[2] == const1_rtx
11315                && (TARGET_SHIFT1 || optimize_size))
11316         return "sal{l}\t%k0";
11317       else
11318         return "sal{l}\t{%2, %k0|%k0, %2}";
11319     }
11320 }
11321   [(set (attr "type")
11322      (cond [(eq_attr "alternative" "1")
11323               (const_string "lea")
11324             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325                      (const_int 0))
11326                  (match_operand 2 "const1_operand" ""))
11327               (const_string "alu")
11328            ]
11329            (const_string "ishift")))
11330    (set_attr "mode" "SI")])
11331
11332 ;; Convert lea to the lea pattern to avoid flags dependency.
11333 (define_split
11334   [(set (match_operand:DI 0 "register_operand" "")
11335         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11336                                 (match_operand:QI 2 "const_int_operand" ""))))
11337    (clobber (reg:CC FLAGS_REG))]
11338   "TARGET_64BIT && reload_completed
11339    && true_regnum (operands[0]) != true_regnum (operands[1])"
11340   [(set (match_dup 0) (zero_extend:DI
11341                         (subreg:SI (mult:SI (match_dup 1)
11342                                             (match_dup 2)) 0)))]
11343 {
11344   operands[1] = gen_lowpart (Pmode, operands[1]);
11345   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11346 })
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags.  We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashlsi3_cmp"
11352   [(set (reg FLAGS_REG)
11353         (compare
11354           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11356           (const_int 0)))
11357    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358         (ashift:SI (match_dup 1) (match_dup 2)))]
11359    "(optimize_size
11360      || !TARGET_PARTIAL_FLAG_REG_STALL
11361      || (operands[2] == const1_rtx
11362          && (TARGET_SHIFT1
11363              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11364    && ix86_match_ccmode (insn, CCGOCmode)
11365    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11366 {
11367   switch (get_attr_type (insn))
11368     {
11369     case TYPE_ALU:
11370       gcc_assert (operands[2] == const1_rtx);
11371       return "add{l}\t%0, %0";
11372
11373     default:
11374       if (REG_P (operands[2]))
11375         return "sal{l}\t{%b2, %0|%0, %b2}";
11376       else if (operands[2] == const1_rtx
11377                && (TARGET_SHIFT1 || optimize_size))
11378         return "sal{l}\t%0";
11379       else
11380         return "sal{l}\t{%2, %0|%0, %2}";
11381     }
11382 }
11383   [(set (attr "type")
11384      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11385                           (const_int 0))
11386                       (match_operand 0 "register_operand" ""))
11387                  (match_operand 2 "const1_operand" ""))
11388               (const_string "alu")
11389            ]
11390            (const_string "ishift")))
11391    (set_attr "mode" "SI")])
11392
11393 (define_insn "*ashlsi3_cconly"
11394   [(set (reg FLAGS_REG)
11395         (compare
11396           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11397                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11398           (const_int 0)))
11399    (clobber (match_scratch:SI 0 "=r"))]
11400   "(optimize_size
11401     || !TARGET_PARTIAL_FLAG_REG_STALL
11402     || (operands[2] == const1_rtx
11403         && (TARGET_SHIFT1
11404             || TARGET_DOUBLE_WITH_ADD)))
11405    && ix86_match_ccmode (insn, CCGOCmode)
11406    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11407 {
11408   switch (get_attr_type (insn))
11409     {
11410     case TYPE_ALU:
11411       gcc_assert (operands[2] == const1_rtx);
11412       return "add{l}\t%0, %0";
11413
11414     default:
11415       if (REG_P (operands[2]))
11416         return "sal{l}\t{%b2, %0|%0, %b2}";
11417       else if (operands[2] == const1_rtx
11418                && (TARGET_SHIFT1 || optimize_size))
11419         return "sal{l}\t%0";
11420       else
11421         return "sal{l}\t{%2, %0|%0, %2}";
11422     }
11423 }
11424   [(set (attr "type")
11425      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11426                           (const_int 0))
11427                       (match_operand 0 "register_operand" ""))
11428                  (match_operand 2 "const1_operand" ""))
11429               (const_string "alu")
11430            ]
11431            (const_string "ishift")))
11432    (set_attr "mode" "SI")])
11433
11434 (define_insn "*ashlsi3_cmp_zext"
11435   [(set (reg FLAGS_REG)
11436         (compare
11437           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11438                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11439           (const_int 0)))
11440    (set (match_operand:DI 0 "register_operand" "=r")
11441         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11442   "TARGET_64BIT
11443    && (optimize_size
11444        || !TARGET_PARTIAL_FLAG_REG_STALL
11445        || (operands[2] == const1_rtx
11446            && (TARGET_SHIFT1
11447                || TARGET_DOUBLE_WITH_ADD)))
11448    && ix86_match_ccmode (insn, CCGOCmode)
11449    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11450 {
11451   switch (get_attr_type (insn))
11452     {
11453     case TYPE_ALU:
11454       gcc_assert (operands[2] == const1_rtx);
11455       return "add{l}\t%k0, %k0";
11456
11457     default:
11458       if (REG_P (operands[2]))
11459         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11460       else if (operands[2] == const1_rtx
11461                && (TARGET_SHIFT1 || optimize_size))
11462         return "sal{l}\t%k0";
11463       else
11464         return "sal{l}\t{%2, %k0|%k0, %2}";
11465     }
11466 }
11467   [(set (attr "type")
11468      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11469                      (const_int 0))
11470                  (match_operand 2 "const1_operand" ""))
11471               (const_string "alu")
11472            ]
11473            (const_string "ishift")))
11474    (set_attr "mode" "SI")])
11475
11476 (define_expand "ashlhi3"
11477   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11478         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11479                    (match_operand:QI 2 "nonmemory_operand" "")))
11480    (clobber (reg:CC FLAGS_REG))]
11481   "TARGET_HIMODE_MATH"
11482   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11483
11484 (define_insn "*ashlhi3_1_lea"
11485   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11486         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11487                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "!TARGET_PARTIAL_REG_STALL
11490    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11491 {
11492   switch (get_attr_type (insn))
11493     {
11494     case TYPE_LEA:
11495       return "#";
11496     case TYPE_ALU:
11497       gcc_assert (operands[2] == const1_rtx);
11498       return "add{w}\t%0, %0";
11499
11500     default:
11501       if (REG_P (operands[2]))
11502         return "sal{w}\t{%b2, %0|%0, %b2}";
11503       else if (operands[2] == const1_rtx
11504                && (TARGET_SHIFT1 || optimize_size))
11505         return "sal{w}\t%0";
11506       else
11507         return "sal{w}\t{%2, %0|%0, %2}";
11508     }
11509 }
11510   [(set (attr "type")
11511      (cond [(eq_attr "alternative" "1")
11512               (const_string "lea")
11513             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11514                           (const_int 0))
11515                       (match_operand 0 "register_operand" ""))
11516                  (match_operand 2 "const1_operand" ""))
11517               (const_string "alu")
11518            ]
11519            (const_string "ishift")))
11520    (set_attr "mode" "HI,SI")])
11521
11522 (define_insn "*ashlhi3_1"
11523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11524         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11525                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "TARGET_PARTIAL_REG_STALL
11528    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11529 {
11530   switch (get_attr_type (insn))
11531     {
11532     case TYPE_ALU:
11533       gcc_assert (operands[2] == const1_rtx);
11534       return "add{w}\t%0, %0";
11535
11536     default:
11537       if (REG_P (operands[2]))
11538         return "sal{w}\t{%b2, %0|%0, %b2}";
11539       else if (operands[2] == const1_rtx
11540                && (TARGET_SHIFT1 || optimize_size))
11541         return "sal{w}\t%0";
11542       else
11543         return "sal{w}\t{%2, %0|%0, %2}";
11544     }
11545 }
11546   [(set (attr "type")
11547      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11548                           (const_int 0))
11549                       (match_operand 0 "register_operand" ""))
11550                  (match_operand 2 "const1_operand" ""))
11551               (const_string "alu")
11552            ]
11553            (const_string "ishift")))
11554    (set_attr "mode" "HI")])
11555
11556 ;; This pattern can't accept a variable shift count, since shifts by
11557 ;; zero don't affect the flags.  We assume that shifts by constant
11558 ;; zero are optimized away.
11559 (define_insn "*ashlhi3_cmp"
11560   [(set (reg FLAGS_REG)
11561         (compare
11562           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11563                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11564           (const_int 0)))
11565    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11566         (ashift:HI (match_dup 1) (match_dup 2)))]
11567   "(optimize_size
11568     || !TARGET_PARTIAL_FLAG_REG_STALL
11569     || (operands[2] == const1_rtx
11570         && (TARGET_SHIFT1
11571             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11572    && ix86_match_ccmode (insn, CCGOCmode)
11573    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11574 {
11575   switch (get_attr_type (insn))
11576     {
11577     case TYPE_ALU:
11578       gcc_assert (operands[2] == const1_rtx);
11579       return "add{w}\t%0, %0";
11580
11581     default:
11582       if (REG_P (operands[2]))
11583         return "sal{w}\t{%b2, %0|%0, %b2}";
11584       else if (operands[2] == const1_rtx
11585                && (TARGET_SHIFT1 || optimize_size))
11586         return "sal{w}\t%0";
11587       else
11588         return "sal{w}\t{%2, %0|%0, %2}";
11589     }
11590 }
11591   [(set (attr "type")
11592      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11593                           (const_int 0))
11594                       (match_operand 0 "register_operand" ""))
11595                  (match_operand 2 "const1_operand" ""))
11596               (const_string "alu")
11597            ]
11598            (const_string "ishift")))
11599    (set_attr "mode" "HI")])
11600
11601 (define_insn "*ashlhi3_cconly"
11602   [(set (reg FLAGS_REG)
11603         (compare
11604           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11605                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606           (const_int 0)))
11607    (clobber (match_scratch:HI 0 "=r"))]
11608   "(optimize_size
11609     || !TARGET_PARTIAL_FLAG_REG_STALL
11610     || (operands[2] == const1_rtx
11611         && (TARGET_SHIFT1
11612             || TARGET_DOUBLE_WITH_ADD)))
11613    && ix86_match_ccmode (insn, CCGOCmode)
11614    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11615 {
11616   switch (get_attr_type (insn))
11617     {
11618     case TYPE_ALU:
11619       gcc_assert (operands[2] == const1_rtx);
11620       return "add{w}\t%0, %0";
11621
11622     default:
11623       if (REG_P (operands[2]))
11624         return "sal{w}\t{%b2, %0|%0, %b2}";
11625       else if (operands[2] == const1_rtx
11626                && (TARGET_SHIFT1 || optimize_size))
11627         return "sal{w}\t%0";
11628       else
11629         return "sal{w}\t{%2, %0|%0, %2}";
11630     }
11631 }
11632   [(set (attr "type")
11633      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634                           (const_int 0))
11635                       (match_operand 0 "register_operand" ""))
11636                  (match_operand 2 "const1_operand" ""))
11637               (const_string "alu")
11638            ]
11639            (const_string "ishift")))
11640    (set_attr "mode" "HI")])
11641
11642 (define_expand "ashlqi3"
11643   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11644         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11645                    (match_operand:QI 2 "nonmemory_operand" "")))
11646    (clobber (reg:CC FLAGS_REG))]
11647   "TARGET_QIMODE_MATH"
11648   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11649
11650 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11651
11652 (define_insn "*ashlqi3_1_lea"
11653   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11654         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11655                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "!TARGET_PARTIAL_REG_STALL
11658    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11659 {
11660   switch (get_attr_type (insn))
11661     {
11662     case TYPE_LEA:
11663       return "#";
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 [(eq_attr "alternative" "2")
11698               (const_string "lea")
11699             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700                           (const_int 0))
11701                       (match_operand 0 "register_operand" ""))
11702                  (match_operand 2 "const1_operand" ""))
11703               (const_string "alu")
11704            ]
11705            (const_string "ishift")))
11706    (set_attr "mode" "QI,SI,SI")])
11707
11708 (define_insn "*ashlqi3_1"
11709   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11710         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11711                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11712    (clobber (reg:CC FLAGS_REG))]
11713   "TARGET_PARTIAL_REG_STALL
11714    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11715 {
11716   switch (get_attr_type (insn))
11717     {
11718     case TYPE_ALU:
11719       gcc_assert (operands[2] == const1_rtx);
11720       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11721         return "add{l}\t%k0, %k0";
11722       else
11723         return "add{b}\t%0, %0";
11724
11725     default:
11726       if (REG_P (operands[2]))
11727         {
11728           if (get_attr_mode (insn) == MODE_SI)
11729             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11730           else
11731             return "sal{b}\t{%b2, %0|%0, %b2}";
11732         }
11733       else if (operands[2] == const1_rtx
11734                && (TARGET_SHIFT1 || optimize_size))
11735         {
11736           if (get_attr_mode (insn) == MODE_SI)
11737             return "sal{l}\t%0";
11738           else
11739             return "sal{b}\t%0";
11740         }
11741       else
11742         {
11743           if (get_attr_mode (insn) == MODE_SI)
11744             return "sal{l}\t{%2, %k0|%k0, %2}";
11745           else
11746             return "sal{b}\t{%2, %0|%0, %2}";
11747         }
11748     }
11749 }
11750   [(set (attr "type")
11751      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11752                           (const_int 0))
11753                       (match_operand 0 "register_operand" ""))
11754                  (match_operand 2 "const1_operand" ""))
11755               (const_string "alu")
11756            ]
11757            (const_string "ishift")))
11758    (set_attr "mode" "QI,SI")])
11759
11760 ;; This pattern can't accept a variable shift count, since shifts by
11761 ;; zero don't affect the flags.  We assume that shifts by constant
11762 ;; zero are optimized away.
11763 (define_insn "*ashlqi3_cmp"
11764   [(set (reg FLAGS_REG)
11765         (compare
11766           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11767                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11768           (const_int 0)))
11769    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11770         (ashift:QI (match_dup 1) (match_dup 2)))]
11771   "(optimize_size
11772     || !TARGET_PARTIAL_FLAG_REG_STALL
11773     || (operands[2] == const1_rtx
11774         && (TARGET_SHIFT1
11775             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11776    && ix86_match_ccmode (insn, CCGOCmode)
11777    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11778 {
11779   switch (get_attr_type (insn))
11780     {
11781     case TYPE_ALU:
11782       gcc_assert (operands[2] == const1_rtx);
11783       return "add{b}\t%0, %0";
11784
11785     default:
11786       if (REG_P (operands[2]))
11787         return "sal{b}\t{%b2, %0|%0, %b2}";
11788       else if (operands[2] == const1_rtx
11789                && (TARGET_SHIFT1 || optimize_size))
11790         return "sal{b}\t%0";
11791       else
11792         return "sal{b}\t{%2, %0|%0, %2}";
11793     }
11794 }
11795   [(set (attr "type")
11796      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11797                           (const_int 0))
11798                       (match_operand 0 "register_operand" ""))
11799                  (match_operand 2 "const1_operand" ""))
11800               (const_string "alu")
11801            ]
11802            (const_string "ishift")))
11803    (set_attr "mode" "QI")])
11804
11805 (define_insn "*ashlqi3_cconly"
11806   [(set (reg FLAGS_REG)
11807         (compare
11808           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11809                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810           (const_int 0)))
11811    (clobber (match_scratch:QI 0 "=q"))]
11812   "(optimize_size
11813     || !TARGET_PARTIAL_FLAG_REG_STALL
11814     || (operands[2] == const1_rtx
11815         && (TARGET_SHIFT1
11816             || TARGET_DOUBLE_WITH_ADD)))
11817    && ix86_match_ccmode (insn, CCGOCmode)
11818    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11819 {
11820   switch (get_attr_type (insn))
11821     {
11822     case TYPE_ALU:
11823       gcc_assert (operands[2] == const1_rtx);
11824       return "add{b}\t%0, %0";
11825
11826     default:
11827       if (REG_P (operands[2]))
11828         return "sal{b}\t{%b2, %0|%0, %b2}";
11829       else if (operands[2] == const1_rtx
11830                && (TARGET_SHIFT1 || optimize_size))
11831         return "sal{b}\t%0";
11832       else
11833         return "sal{b}\t{%2, %0|%0, %2}";
11834     }
11835 }
11836   [(set (attr "type")
11837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11838                           (const_int 0))
11839                       (match_operand 0 "register_operand" ""))
11840                  (match_operand 2 "const1_operand" ""))
11841               (const_string "alu")
11842            ]
11843            (const_string "ishift")))
11844    (set_attr "mode" "QI")])
11845
11846 ;; See comment above `ashldi3' about how this works.
11847
11848 (define_expand "ashrti3"
11849   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11850                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11851                                 (match_operand:QI 2 "nonmemory_operand" "")))
11852               (clobber (reg:CC FLAGS_REG))])]
11853   "TARGET_64BIT"
11854 {
11855   if (! immediate_operand (operands[2], QImode))
11856     {
11857       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11858       DONE;
11859     }
11860   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11861   DONE;
11862 })
11863
11864 (define_insn "ashrti3_1"
11865   [(set (match_operand:TI 0 "register_operand" "=r")
11866         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11867                      (match_operand:QI 2 "register_operand" "c")))
11868    (clobber (match_scratch:DI 3 "=&r"))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "TARGET_64BIT"
11871   "#"
11872   [(set_attr "type" "multi")])
11873
11874 (define_insn "*ashrti3_2"
11875   [(set (match_operand:TI 0 "register_operand" "=r")
11876         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11877                      (match_operand:QI 2 "immediate_operand" "O")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_64BIT"
11880   "#"
11881   [(set_attr "type" "multi")])
11882
11883 (define_split
11884   [(set (match_operand:TI 0 "register_operand" "")
11885         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11886                      (match_operand:QI 2 "register_operand" "")))
11887    (clobber (match_scratch:DI 3 ""))
11888    (clobber (reg:CC FLAGS_REG))]
11889   "TARGET_64BIT && reload_completed"
11890   [(const_int 0)]
11891   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11892
11893 (define_split
11894   [(set (match_operand:TI 0 "register_operand" "")
11895         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11896                      (match_operand:QI 2 "immediate_operand" "")))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "TARGET_64BIT && reload_completed"
11899   [(const_int 0)]
11900   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11901
11902 (define_insn "x86_64_shrd"
11903   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11904         (ior:DI (ashiftrt:DI (match_dup 0)
11905                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11906                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11907                   (minus:QI (const_int 64) (match_dup 2)))))
11908    (clobber (reg:CC FLAGS_REG))]
11909   "TARGET_64BIT"
11910   "@
11911    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11912    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11913   [(set_attr "type" "ishift")
11914    (set_attr "prefix_0f" "1")
11915    (set_attr "mode" "DI")
11916    (set_attr "athlon_decode" "vector")
11917    (set_attr "amdfam10_decode" "vector")])
11918
11919 (define_expand "ashrdi3"
11920   [(set (match_operand:DI 0 "shiftdi_operand" "")
11921         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11922                      (match_operand:QI 2 "nonmemory_operand" "")))]
11923   ""
11924   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11925
11926 (define_insn "*ashrdi3_63_rex64"
11927   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11928         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11929                      (match_operand:DI 2 "const_int_operand" "i,i")))
11930    (clobber (reg:CC FLAGS_REG))]
11931   "TARGET_64BIT && INTVAL (operands[2]) == 63
11932    && (TARGET_USE_CLTD || optimize_size)
11933    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11934   "@
11935    {cqto|cqo}
11936    sar{q}\t{%2, %0|%0, %2}"
11937   [(set_attr "type" "imovx,ishift")
11938    (set_attr "prefix_0f" "0,*")
11939    (set_attr "length_immediate" "0,*")
11940    (set_attr "modrm" "0,1")
11941    (set_attr "mode" "DI")])
11942
11943 (define_insn "*ashrdi3_1_one_bit_rex64"
11944   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11945         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11946                      (match_operand:QI 2 "const1_operand" "")))
11947    (clobber (reg:CC FLAGS_REG))]
11948   "TARGET_64BIT
11949    && (TARGET_SHIFT1 || optimize_size)
11950    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11951   "sar{q}\t%0"
11952   [(set_attr "type" "ishift")
11953    (set (attr "length")
11954      (if_then_else (match_operand:DI 0 "register_operand" "")
11955         (const_string "2")
11956         (const_string "*")))])
11957
11958 (define_insn "*ashrdi3_1_rex64"
11959   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11960         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11961                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11962    (clobber (reg:CC FLAGS_REG))]
11963   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11964   "@
11965    sar{q}\t{%2, %0|%0, %2}
11966    sar{q}\t{%b2, %0|%0, %b2}"
11967   [(set_attr "type" "ishift")
11968    (set_attr "mode" "DI")])
11969
11970 ;; This pattern can't accept a variable shift count, since shifts by
11971 ;; zero don't affect the flags.  We assume that shifts by constant
11972 ;; zero are optimized away.
11973 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11974   [(set (reg FLAGS_REG)
11975         (compare
11976           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11977                        (match_operand:QI 2 "const1_operand" ""))
11978           (const_int 0)))
11979    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11980         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11981   "TARGET_64BIT
11982    && (TARGET_SHIFT1 || optimize_size)
11983    && ix86_match_ccmode (insn, CCGOCmode)
11984    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11985   "sar{q}\t%0"
11986   [(set_attr "type" "ishift")
11987    (set (attr "length")
11988      (if_then_else (match_operand:DI 0 "register_operand" "")
11989         (const_string "2")
11990         (const_string "*")))])
11991
11992 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11993   [(set (reg FLAGS_REG)
11994         (compare
11995           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11996                        (match_operand:QI 2 "const1_operand" ""))
11997           (const_int 0)))
11998    (clobber (match_scratch:DI 0 "=r"))]
11999   "TARGET_64BIT
12000    && (TARGET_SHIFT1 || optimize_size)
12001    && ix86_match_ccmode (insn, CCGOCmode)
12002    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12003   "sar{q}\t%0"
12004   [(set_attr "type" "ishift")
12005    (set_attr "length" "2")])
12006
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags.  We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*ashrdi3_cmp_rex64"
12011   [(set (reg FLAGS_REG)
12012         (compare
12013           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12014                        (match_operand:QI 2 "const_int_operand" "n"))
12015           (const_int 0)))
12016    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12017         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12018   "TARGET_64BIT
12019    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12020    && ix86_match_ccmode (insn, CCGOCmode)
12021    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12022   "sar{q}\t{%2, %0|%0, %2}"
12023   [(set_attr "type" "ishift")
12024    (set_attr "mode" "DI")])
12025
12026 (define_insn "*ashrdi3_cconly_rex64"
12027   [(set (reg FLAGS_REG)
12028         (compare
12029           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12030                        (match_operand:QI 2 "const_int_operand" "n"))
12031           (const_int 0)))
12032    (clobber (match_scratch:DI 0 "=r"))]
12033   "TARGET_64BIT
12034    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12035    && ix86_match_ccmode (insn, CCGOCmode)
12036    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12037   "sar{q}\t{%2, %0|%0, %2}"
12038   [(set_attr "type" "ishift")
12039    (set_attr "mode" "DI")])
12040
12041 (define_insn "*ashrdi3_1"
12042   [(set (match_operand:DI 0 "register_operand" "=r")
12043         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12044                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12045    (clobber (reg:CC FLAGS_REG))]
12046   "!TARGET_64BIT"
12047   "#"
12048   [(set_attr "type" "multi")])
12049
12050 ;; By default we don't ask for a scratch register, because when DImode
12051 ;; values are manipulated, registers are already at a premium.  But if
12052 ;; we have one handy, we won't turn it away.
12053 (define_peephole2
12054   [(match_scratch:SI 3 "r")
12055    (parallel [(set (match_operand:DI 0 "register_operand" "")
12056                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12057                                 (match_operand:QI 2 "nonmemory_operand" "")))
12058               (clobber (reg:CC FLAGS_REG))])
12059    (match_dup 3)]
12060   "!TARGET_64BIT && TARGET_CMOVE"
12061   [(const_int 0)]
12062   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12063
12064 (define_split
12065   [(set (match_operand:DI 0 "register_operand" "")
12066         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12067                      (match_operand:QI 2 "nonmemory_operand" "")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12070                      ? epilogue_completed : reload_completed)"
12071   [(const_int 0)]
12072   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12073
12074 (define_insn "x86_shrd_1"
12075   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12076         (ior:SI (ashiftrt:SI (match_dup 0)
12077                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12078                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12079                   (minus:QI (const_int 32) (match_dup 2)))))
12080    (clobber (reg:CC FLAGS_REG))]
12081   ""
12082   "@
12083    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12084    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12085   [(set_attr "type" "ishift")
12086    (set_attr "prefix_0f" "1")
12087    (set_attr "pent_pair" "np")
12088    (set_attr "mode" "SI")])
12089
12090 (define_expand "x86_shift_adj_3"
12091   [(use (match_operand:SI 0 "register_operand" ""))
12092    (use (match_operand:SI 1 "register_operand" ""))
12093    (use (match_operand:QI 2 "register_operand" ""))]
12094   ""
12095 {
12096   rtx label = gen_label_rtx ();
12097   rtx tmp;
12098
12099   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12100
12101   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12102   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12103   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12104                               gen_rtx_LABEL_REF (VOIDmode, label),
12105                               pc_rtx);
12106   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12107   JUMP_LABEL (tmp) = label;
12108
12109   emit_move_insn (operands[0], operands[1]);
12110   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12111
12112   emit_label (label);
12113   LABEL_NUSES (label) = 1;
12114
12115   DONE;
12116 })
12117
12118 (define_insn "ashrsi3_31"
12119   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12120         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12121                      (match_operand:SI 2 "const_int_operand" "i,i")))
12122    (clobber (reg:CC FLAGS_REG))]
12123   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12124    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12125   "@
12126    {cltd|cdq}
12127    sar{l}\t{%2, %0|%0, %2}"
12128   [(set_attr "type" "imovx,ishift")
12129    (set_attr "prefix_0f" "0,*")
12130    (set_attr "length_immediate" "0,*")
12131    (set_attr "modrm" "0,1")
12132    (set_attr "mode" "SI")])
12133
12134 (define_insn "*ashrsi3_31_zext"
12135   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12136         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12137                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12140    && INTVAL (operands[2]) == 31
12141    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12142   "@
12143    {cltd|cdq}
12144    sar{l}\t{%2, %k0|%k0, %2}"
12145   [(set_attr "type" "imovx,ishift")
12146    (set_attr "prefix_0f" "0,*")
12147    (set_attr "length_immediate" "0,*")
12148    (set_attr "modrm" "0,1")
12149    (set_attr "mode" "SI")])
12150
12151 (define_expand "ashrsi3"
12152   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12153         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12154                      (match_operand:QI 2 "nonmemory_operand" "")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   ""
12157   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12158
12159 (define_insn "*ashrsi3_1_one_bit"
12160   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12161         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162                      (match_operand:QI 2 "const1_operand" "")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "(TARGET_SHIFT1 || optimize_size)
12165    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12166   "sar{l}\t%0"
12167   [(set_attr "type" "ishift")
12168    (set (attr "length")
12169      (if_then_else (match_operand:SI 0 "register_operand" "")
12170         (const_string "2")
12171         (const_string "*")))])
12172
12173 (define_insn "*ashrsi3_1_one_bit_zext"
12174   [(set (match_operand:DI 0 "register_operand" "=r")
12175         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12176                                      (match_operand:QI 2 "const1_operand" ""))))
12177    (clobber (reg:CC FLAGS_REG))]
12178   "TARGET_64BIT
12179    && (TARGET_SHIFT1 || optimize_size)
12180    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181   "sar{l}\t%k0"
12182   [(set_attr "type" "ishift")
12183    (set_attr "length" "2")])
12184
12185 (define_insn "*ashrsi3_1"
12186   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12191   "@
12192    sar{l}\t{%2, %0|%0, %2}
12193    sar{l}\t{%b2, %0|%0, %b2}"
12194   [(set_attr "type" "ishift")
12195    (set_attr "mode" "SI")])
12196
12197 (define_insn "*ashrsi3_1_zext"
12198   [(set (match_operand:DI 0 "register_operand" "=r,r")
12199         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12200                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12203   "@
12204    sar{l}\t{%2, %k0|%k0, %2}
12205    sar{l}\t{%b2, %k0|%k0, %b2}"
12206   [(set_attr "type" "ishift")
12207    (set_attr "mode" "SI")])
12208
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags.  We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*ashrsi3_one_bit_cmp"
12213   [(set (reg FLAGS_REG)
12214         (compare
12215           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12216                        (match_operand:QI 2 "const1_operand" ""))
12217           (const_int 0)))
12218    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12219         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12220   "(TARGET_SHIFT1 || optimize_size)
12221    && ix86_match_ccmode (insn, CCGOCmode)
12222    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12223   "sar{l}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand:SI 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*ashrsi3_one_bit_cconly"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (clobber (match_scratch:SI 0 "=r"))]
12237   "(TARGET_SHIFT1 || optimize_size)
12238    && ix86_match_ccmode (insn, CCGOCmode)
12239    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12240   "sar{l}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12243
12244 (define_insn "*ashrsi3_one_bit_cmp_zext"
12245   [(set (reg FLAGS_REG)
12246         (compare
12247           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12248                        (match_operand:QI 2 "const1_operand" ""))
12249           (const_int 0)))
12250    (set (match_operand:DI 0 "register_operand" "=r")
12251         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12252   "TARGET_64BIT
12253    && (TARGET_SHIFT1 || optimize_size)
12254    && ix86_match_ccmode (insn, CCmode)
12255    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12256   "sar{l}\t%k0"
12257   [(set_attr "type" "ishift")
12258    (set_attr "length" "2")])
12259
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags.  We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*ashrsi3_cmp"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12271   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12272    && ix86_match_ccmode (insn, CCGOCmode)
12273    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12274   "sar{l}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "SI")])
12277
12278 (define_insn "*ashrsi3_cconly"
12279   [(set (reg FLAGS_REG)
12280         (compare
12281           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12283           (const_int 0)))
12284    (clobber (match_scratch:SI 0 "=r"))]
12285   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12286    && ix86_match_ccmode (insn, CCGOCmode)
12287    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12288   "sar{l}\t{%2, %0|%0, %2}"
12289   [(set_attr "type" "ishift")
12290    (set_attr "mode" "SI")])
12291
12292 (define_insn "*ashrsi3_cmp_zext"
12293   [(set (reg FLAGS_REG)
12294         (compare
12295           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12297           (const_int 0)))
12298    (set (match_operand:DI 0 "register_operand" "=r")
12299         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12300   "TARGET_64BIT
12301    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12302    && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12304   "sar{l}\t{%2, %k0|%k0, %2}"
12305   [(set_attr "type" "ishift")
12306    (set_attr "mode" "SI")])
12307
12308 (define_expand "ashrhi3"
12309   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12311                      (match_operand:QI 2 "nonmemory_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "TARGET_HIMODE_MATH"
12314   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12315
12316 (define_insn "*ashrhi3_1_one_bit"
12317   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12318         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12319                      (match_operand:QI 2 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "(TARGET_SHIFT1 || optimize_size)
12322    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12323   "sar{w}\t%0"
12324   [(set_attr "type" "ishift")
12325    (set (attr "length")
12326      (if_then_else (match_operand 0 "register_operand" "")
12327         (const_string "2")
12328         (const_string "*")))])
12329
12330 (define_insn "*ashrhi3_1"
12331   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12332         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12333                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12336   "@
12337    sar{w}\t{%2, %0|%0, %2}
12338    sar{w}\t{%b2, %0|%0, %b2}"
12339   [(set_attr "type" "ishift")
12340    (set_attr "mode" "HI")])
12341
12342 ;; This pattern can't accept a variable shift count, since shifts by
12343 ;; zero don't affect the flags.  We assume that shifts by constant
12344 ;; zero are optimized away.
12345 (define_insn "*ashrhi3_one_bit_cmp"
12346   [(set (reg FLAGS_REG)
12347         (compare
12348           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12349                        (match_operand:QI 2 "const1_operand" ""))
12350           (const_int 0)))
12351    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12352         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12353   "(TARGET_SHIFT1 || optimize_size)
12354    && ix86_match_ccmode (insn, CCGOCmode)
12355    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12356   "sar{w}\t%0"
12357   [(set_attr "type" "ishift")
12358    (set (attr "length")
12359      (if_then_else (match_operand 0 "register_operand" "")
12360         (const_string "2")
12361         (const_string "*")))])
12362
12363 (define_insn "*ashrhi3_one_bit_cconly"
12364   [(set (reg FLAGS_REG)
12365         (compare
12366           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12367                        (match_operand:QI 2 "const1_operand" ""))
12368           (const_int 0)))
12369    (clobber (match_scratch:HI 0 "=r"))]
12370   "(TARGET_SHIFT1 || optimize_size)
12371    && ix86_match_ccmode (insn, CCGOCmode)
12372    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12373   "sar{w}\t%0"
12374   [(set_attr "type" "ishift")
12375    (set_attr "length" "2")])
12376
12377 ;; This pattern can't accept a variable shift count, since shifts by
12378 ;; zero don't affect the flags.  We assume that shifts by constant
12379 ;; zero are optimized away.
12380 (define_insn "*ashrhi3_cmp"
12381   [(set (reg FLAGS_REG)
12382         (compare
12383           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385           (const_int 0)))
12386    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12387         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12388   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12389    && ix86_match_ccmode (insn, CCGOCmode)
12390    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12391   "sar{w}\t{%2, %0|%0, %2}"
12392   [(set_attr "type" "ishift")
12393    (set_attr "mode" "HI")])
12394
12395 (define_insn "*ashrhi3_cconly"
12396   [(set (reg FLAGS_REG)
12397         (compare
12398           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12399                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12400           (const_int 0)))
12401    (clobber (match_scratch:HI 0 "=r"))]
12402   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12403    && ix86_match_ccmode (insn, CCGOCmode)
12404    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12405   "sar{w}\t{%2, %0|%0, %2}"
12406   [(set_attr "type" "ishift")
12407    (set_attr "mode" "HI")])
12408
12409 (define_expand "ashrqi3"
12410   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12411         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12412                      (match_operand:QI 2 "nonmemory_operand" "")))
12413    (clobber (reg:CC FLAGS_REG))]
12414   "TARGET_QIMODE_MATH"
12415   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12416
12417 (define_insn "*ashrqi3_1_one_bit"
12418   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12419         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420                      (match_operand:QI 2 "const1_operand" "")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "(TARGET_SHIFT1 || optimize_size)
12423    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12424   "sar{b}\t%0"
12425   [(set_attr "type" "ishift")
12426    (set (attr "length")
12427      (if_then_else (match_operand 0 "register_operand" "")
12428         (const_string "2")
12429         (const_string "*")))])
12430
12431 (define_insn "*ashrqi3_1_one_bit_slp"
12432   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12433         (ashiftrt:QI (match_dup 0)
12434                      (match_operand:QI 1 "const1_operand" "")))
12435    (clobber (reg:CC FLAGS_REG))]
12436   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12437    && (TARGET_SHIFT1 || optimize_size)
12438    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12439   "sar{b}\t%0"
12440   [(set_attr "type" "ishift1")
12441    (set (attr "length")
12442      (if_then_else (match_operand 0 "register_operand" "")
12443         (const_string "2")
12444         (const_string "*")))])
12445
12446 (define_insn "*ashrqi3_1"
12447   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12448         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12449                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12452   "@
12453    sar{b}\t{%2, %0|%0, %2}
12454    sar{b}\t{%b2, %0|%0, %b2}"
12455   [(set_attr "type" "ishift")
12456    (set_attr "mode" "QI")])
12457
12458 (define_insn "*ashrqi3_1_slp"
12459   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12460         (ashiftrt:QI (match_dup 0)
12461                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12462    (clobber (reg:CC FLAGS_REG))]
12463   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12464    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12465   "@
12466    sar{b}\t{%1, %0|%0, %1}
12467    sar{b}\t{%b1, %0|%0, %b1}"
12468   [(set_attr "type" "ishift1")
12469    (set_attr "mode" "QI")])
12470
12471 ;; This pattern can't accept a variable shift count, since shifts by
12472 ;; zero don't affect the flags.  We assume that shifts by constant
12473 ;; zero are optimized away.
12474 (define_insn "*ashrqi3_one_bit_cmp"
12475   [(set (reg FLAGS_REG)
12476         (compare
12477           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12478                        (match_operand:QI 2 "const1_operand" "I"))
12479           (const_int 0)))
12480    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12481         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12482   "(TARGET_SHIFT1 || optimize_size)
12483    && ix86_match_ccmode (insn, CCGOCmode)
12484    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12485   "sar{b}\t%0"
12486   [(set_attr "type" "ishift")
12487    (set (attr "length")
12488      (if_then_else (match_operand 0 "register_operand" "")
12489         (const_string "2")
12490         (const_string "*")))])
12491
12492 (define_insn "*ashrqi3_one_bit_cconly"
12493   [(set (reg FLAGS_REG)
12494         (compare
12495           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12496                        (match_operand:QI 2 "const1_operand" "I"))
12497           (const_int 0)))
12498    (clobber (match_scratch:QI 0 "=q"))]
12499   "(TARGET_SHIFT1 || optimize_size)
12500    && ix86_match_ccmode (insn, CCGOCmode)
12501    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12502   "sar{b}\t%0"
12503   [(set_attr "type" "ishift")
12504    (set_attr "length" "2")])
12505
12506 ;; This pattern can't accept a variable shift count, since shifts by
12507 ;; zero don't affect the flags.  We assume that shifts by constant
12508 ;; zero are optimized away.
12509 (define_insn "*ashrqi3_cmp"
12510   [(set (reg FLAGS_REG)
12511         (compare
12512           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12513                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12514           (const_int 0)))
12515    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12516         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12517   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12518    && ix86_match_ccmode (insn, CCGOCmode)
12519    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12520   "sar{b}\t{%2, %0|%0, %2}"
12521   [(set_attr "type" "ishift")
12522    (set_attr "mode" "QI")])
12523
12524 (define_insn "*ashrqi3_cconly"
12525   [(set (reg FLAGS_REG)
12526         (compare
12527           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12529           (const_int 0)))
12530    (clobber (match_scratch:QI 0 "=q"))]
12531   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12532    && ix86_match_ccmode (insn, CCGOCmode)
12533    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12534   "sar{b}\t{%2, %0|%0, %2}"
12535   [(set_attr "type" "ishift")
12536    (set_attr "mode" "QI")])
12537
12538 \f
12539 ;; Logical shift instructions
12540
12541 ;; See comment above `ashldi3' about how this works.
12542
12543 (define_expand "lshrti3"
12544   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12545                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12546                                 (match_operand:QI 2 "nonmemory_operand" "")))
12547               (clobber (reg:CC FLAGS_REG))])]
12548   "TARGET_64BIT"
12549 {
12550   if (! immediate_operand (operands[2], QImode))
12551     {
12552       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12553       DONE;
12554     }
12555   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12556   DONE;
12557 })
12558
12559 (define_insn "lshrti3_1"
12560   [(set (match_operand:TI 0 "register_operand" "=r")
12561         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12562                      (match_operand:QI 2 "register_operand" "c")))
12563    (clobber (match_scratch:DI 3 "=&r"))
12564    (clobber (reg:CC FLAGS_REG))]
12565   "TARGET_64BIT"
12566   "#"
12567   [(set_attr "type" "multi")])
12568
12569 ;; This pattern must be defined before *lshrti3_2 to prevent
12570 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12571
12572 (define_insn "sse2_lshrti3"
12573   [(set (match_operand:TI 0 "register_operand" "=x")
12574         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12575                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12576   "TARGET_SSE2"
12577 {
12578   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12579   return "psrldq\t{%2, %0|%0, %2}";
12580 }
12581   [(set_attr "type" "sseishft")
12582    (set_attr "prefix_data16" "1")
12583    (set_attr "mode" "TI")])
12584
12585 (define_insn "*lshrti3_2"
12586   [(set (match_operand:TI 0 "register_operand" "=r")
12587         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12588                      (match_operand:QI 2 "immediate_operand" "O")))
12589    (clobber (reg:CC FLAGS_REG))]
12590   "TARGET_64BIT"
12591   "#"
12592   [(set_attr "type" "multi")])
12593
12594 (define_split
12595   [(set (match_operand:TI 0 "register_operand" "")
12596         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12597                      (match_operand:QI 2 "register_operand" "")))
12598    (clobber (match_scratch:DI 3 ""))
12599    (clobber (reg:CC FLAGS_REG))]
12600   "TARGET_64BIT && reload_completed"
12601   [(const_int 0)]
12602   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12603
12604 (define_split
12605   [(set (match_operand:TI 0 "register_operand" "")
12606         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12607                      (match_operand:QI 2 "immediate_operand" "")))
12608    (clobber (reg:CC FLAGS_REG))]
12609   "TARGET_64BIT && reload_completed"
12610   [(const_int 0)]
12611   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12612
12613 (define_expand "lshrdi3"
12614   [(set (match_operand:DI 0 "shiftdi_operand" "")
12615         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12616                      (match_operand:QI 2 "nonmemory_operand" "")))]
12617   ""
12618   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12619
12620 (define_insn "*lshrdi3_1_one_bit_rex64"
12621   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12622         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12623                      (match_operand:QI 2 "const1_operand" "")))
12624    (clobber (reg:CC FLAGS_REG))]
12625   "TARGET_64BIT
12626    && (TARGET_SHIFT1 || optimize_size)
12627    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12628   "shr{q}\t%0"
12629   [(set_attr "type" "ishift")
12630    (set (attr "length")
12631      (if_then_else (match_operand:DI 0 "register_operand" "")
12632         (const_string "2")
12633         (const_string "*")))])
12634
12635 (define_insn "*lshrdi3_1_rex64"
12636   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12637         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12638                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12639    (clobber (reg:CC FLAGS_REG))]
12640   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12641   "@
12642    shr{q}\t{%2, %0|%0, %2}
12643    shr{q}\t{%b2, %0|%0, %b2}"
12644   [(set_attr "type" "ishift")
12645    (set_attr "mode" "DI")])
12646
12647 ;; This pattern can't accept a variable shift count, since shifts by
12648 ;; zero don't affect the flags.  We assume that shifts by constant
12649 ;; zero are optimized away.
12650 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12651   [(set (reg FLAGS_REG)
12652         (compare
12653           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12654                        (match_operand:QI 2 "const1_operand" ""))
12655           (const_int 0)))
12656    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12657         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12658   "TARGET_64BIT
12659    && (TARGET_SHIFT1 || optimize_size)
12660    && ix86_match_ccmode (insn, CCGOCmode)
12661    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12662   "shr{q}\t%0"
12663   [(set_attr "type" "ishift")
12664    (set (attr "length")
12665      (if_then_else (match_operand:DI 0 "register_operand" "")
12666         (const_string "2")
12667         (const_string "*")))])
12668
12669 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12670   [(set (reg FLAGS_REG)
12671         (compare
12672           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12673                        (match_operand:QI 2 "const1_operand" ""))
12674           (const_int 0)))
12675    (clobber (match_scratch:DI 0 "=r"))]
12676   "TARGET_64BIT
12677    && (TARGET_SHIFT1 || optimize_size)
12678    && ix86_match_ccmode (insn, CCGOCmode)
12679    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12680   "shr{q}\t%0"
12681   [(set_attr "type" "ishift")
12682    (set_attr "length" "2")])
12683
12684 ;; This pattern can't accept a variable shift count, since shifts by
12685 ;; zero don't affect the flags.  We assume that shifts by constant
12686 ;; zero are optimized away.
12687 (define_insn "*lshrdi3_cmp_rex64"
12688   [(set (reg FLAGS_REG)
12689         (compare
12690           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12691                        (match_operand:QI 2 "const_int_operand" "e"))
12692           (const_int 0)))
12693    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12694         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12695   "TARGET_64BIT
12696    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12697    && ix86_match_ccmode (insn, CCGOCmode)
12698    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12699   "shr{q}\t{%2, %0|%0, %2}"
12700   [(set_attr "type" "ishift")
12701    (set_attr "mode" "DI")])
12702
12703 (define_insn "*lshrdi3_cconly_rex64"
12704   [(set (reg FLAGS_REG)
12705         (compare
12706           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12707                        (match_operand:QI 2 "const_int_operand" "e"))
12708           (const_int 0)))
12709    (clobber (match_scratch:DI 0 "=r"))]
12710   "TARGET_64BIT
12711    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12712    && ix86_match_ccmode (insn, CCGOCmode)
12713    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12714   "shr{q}\t{%2, %0|%0, %2}"
12715   [(set_attr "type" "ishift")
12716    (set_attr "mode" "DI")])
12717
12718 (define_insn "*lshrdi3_1"
12719   [(set (match_operand:DI 0 "register_operand" "=r")
12720         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12721                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12722    (clobber (reg:CC FLAGS_REG))]
12723   "!TARGET_64BIT"
12724   "#"
12725   [(set_attr "type" "multi")])
12726
12727 ;; By default we don't ask for a scratch register, because when DImode
12728 ;; values are manipulated, registers are already at a premium.  But if
12729 ;; we have one handy, we won't turn it away.
12730 (define_peephole2
12731   [(match_scratch:SI 3 "r")
12732    (parallel [(set (match_operand:DI 0 "register_operand" "")
12733                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12734                                 (match_operand:QI 2 "nonmemory_operand" "")))
12735               (clobber (reg:CC FLAGS_REG))])
12736    (match_dup 3)]
12737   "!TARGET_64BIT && TARGET_CMOVE"
12738   [(const_int 0)]
12739   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12740
12741 (define_split
12742   [(set (match_operand:DI 0 "register_operand" "")
12743         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12744                      (match_operand:QI 2 "nonmemory_operand" "")))
12745    (clobber (reg:CC FLAGS_REG))]
12746   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12747                      ? epilogue_completed : reload_completed)"
12748   [(const_int 0)]
12749   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12750
12751 (define_expand "lshrsi3"
12752   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12753         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12754                      (match_operand:QI 2 "nonmemory_operand" "")))
12755    (clobber (reg:CC FLAGS_REG))]
12756   ""
12757   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12758
12759 (define_insn "*lshrsi3_1_one_bit"
12760   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12761         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12762                      (match_operand:QI 2 "const1_operand" "")))
12763    (clobber (reg:CC FLAGS_REG))]
12764   "(TARGET_SHIFT1 || optimize_size)
12765    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12766   "shr{l}\t%0"
12767   [(set_attr "type" "ishift")
12768    (set (attr "length")
12769      (if_then_else (match_operand:SI 0 "register_operand" "")
12770         (const_string "2")
12771         (const_string "*")))])
12772
12773 (define_insn "*lshrsi3_1_one_bit_zext"
12774   [(set (match_operand:DI 0 "register_operand" "=r")
12775         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12776                      (match_operand:QI 2 "const1_operand" "")))
12777    (clobber (reg:CC FLAGS_REG))]
12778   "TARGET_64BIT
12779    && (TARGET_SHIFT1 || optimize_size)
12780    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781   "shr{l}\t%k0"
12782   [(set_attr "type" "ishift")
12783    (set_attr "length" "2")])
12784
12785 (define_insn "*lshrsi3_1"
12786   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12787         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12788                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12789    (clobber (reg:CC FLAGS_REG))]
12790   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12791   "@
12792    shr{l}\t{%2, %0|%0, %2}
12793    shr{l}\t{%b2, %0|%0, %b2}"
12794   [(set_attr "type" "ishift")
12795    (set_attr "mode" "SI")])
12796
12797 (define_insn "*lshrsi3_1_zext"
12798   [(set (match_operand:DI 0 "register_operand" "=r,r")
12799         (zero_extend:DI
12800           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12801                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12802    (clobber (reg:CC FLAGS_REG))]
12803   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12804   "@
12805    shr{l}\t{%2, %k0|%k0, %2}
12806    shr{l}\t{%b2, %k0|%k0, %b2}"
12807   [(set_attr "type" "ishift")
12808    (set_attr "mode" "SI")])
12809
12810 ;; This pattern can't accept a variable shift count, since shifts by
12811 ;; zero don't affect the flags.  We assume that shifts by constant
12812 ;; zero are optimized away.
12813 (define_insn "*lshrsi3_one_bit_cmp"
12814   [(set (reg FLAGS_REG)
12815         (compare
12816           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12817                        (match_operand:QI 2 "const1_operand" ""))
12818           (const_int 0)))
12819    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12820         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12821   "(TARGET_SHIFT1 || optimize_size)
12822    && ix86_match_ccmode (insn, CCGOCmode)
12823    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12824   "shr{l}\t%0"
12825   [(set_attr "type" "ishift")
12826    (set (attr "length")
12827      (if_then_else (match_operand:SI 0 "register_operand" "")
12828         (const_string "2")
12829         (const_string "*")))])
12830
12831 (define_insn "*lshrsi3_one_bit_cconly"
12832   [(set (reg FLAGS_REG)
12833         (compare
12834           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12835                        (match_operand:QI 2 "const1_operand" ""))
12836           (const_int 0)))
12837    (clobber (match_scratch:SI 0 "=r"))]
12838   "(TARGET_SHIFT1 || optimize_size)
12839    && ix86_match_ccmode (insn, CCGOCmode)
12840    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12841   "shr{l}\t%0"
12842   [(set_attr "type" "ishift")
12843    (set_attr "length" "2")])
12844
12845 (define_insn "*lshrsi3_cmp_one_bit_zext"
12846   [(set (reg FLAGS_REG)
12847         (compare
12848           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12849                        (match_operand:QI 2 "const1_operand" ""))
12850           (const_int 0)))
12851    (set (match_operand:DI 0 "register_operand" "=r")
12852         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12853   "TARGET_64BIT
12854    && (TARGET_SHIFT1 || optimize_size)
12855    && ix86_match_ccmode (insn, CCGOCmode)
12856    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12857   "shr{l}\t%k0"
12858   [(set_attr "type" "ishift")
12859    (set_attr "length" "2")])
12860
12861 ;; This pattern can't accept a variable shift count, since shifts by
12862 ;; zero don't affect the flags.  We assume that shifts by constant
12863 ;; zero are optimized away.
12864 (define_insn "*lshrsi3_cmp"
12865   [(set (reg FLAGS_REG)
12866         (compare
12867           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12868                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12869           (const_int 0)))
12870    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12871         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12872   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12873    && ix86_match_ccmode (insn, CCGOCmode)
12874    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12875   "shr{l}\t{%2, %0|%0, %2}"
12876   [(set_attr "type" "ishift")
12877    (set_attr "mode" "SI")])
12878
12879 (define_insn "*lshrsi3_cconly"
12880   [(set (reg FLAGS_REG)
12881       (compare
12882         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12883                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12884         (const_int 0)))
12885    (clobber (match_scratch:SI 0 "=r"))]
12886   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12887    && ix86_match_ccmode (insn, CCGOCmode)
12888    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12889   "shr{l}\t{%2, %0|%0, %2}"
12890   [(set_attr "type" "ishift")
12891    (set_attr "mode" "SI")])
12892
12893 (define_insn "*lshrsi3_cmp_zext"
12894   [(set (reg FLAGS_REG)
12895         (compare
12896           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12897                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12898           (const_int 0)))
12899    (set (match_operand:DI 0 "register_operand" "=r")
12900         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12901   "TARGET_64BIT
12902    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12903    && ix86_match_ccmode (insn, CCGOCmode)
12904    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12905   "shr{l}\t{%2, %k0|%k0, %2}"
12906   [(set_attr "type" "ishift")
12907    (set_attr "mode" "SI")])
12908
12909 (define_expand "lshrhi3"
12910   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12911         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12912                      (match_operand:QI 2 "nonmemory_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_HIMODE_MATH"
12915   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12916
12917 (define_insn "*lshrhi3_1_one_bit"
12918   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12919         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12920                      (match_operand:QI 2 "const1_operand" "")))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "(TARGET_SHIFT1 || optimize_size)
12923    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12924   "shr{w}\t%0"
12925   [(set_attr "type" "ishift")
12926    (set (attr "length")
12927      (if_then_else (match_operand 0 "register_operand" "")
12928         (const_string "2")
12929         (const_string "*")))])
12930
12931 (define_insn "*lshrhi3_1"
12932   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12933         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12934                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937   "@
12938    shr{w}\t{%2, %0|%0, %2}
12939    shr{w}\t{%b2, %0|%0, %b2}"
12940   [(set_attr "type" "ishift")
12941    (set_attr "mode" "HI")])
12942
12943 ;; This pattern can't accept a variable shift count, since shifts by
12944 ;; zero don't affect the flags.  We assume that shifts by constant
12945 ;; zero are optimized away.
12946 (define_insn "*lshrhi3_one_bit_cmp"
12947   [(set (reg FLAGS_REG)
12948         (compare
12949           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12950                        (match_operand:QI 2 "const1_operand" ""))
12951           (const_int 0)))
12952    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12953         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12954   "(TARGET_SHIFT1 || optimize_size)
12955    && ix86_match_ccmode (insn, CCGOCmode)
12956    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12957   "shr{w}\t%0"
12958   [(set_attr "type" "ishift")
12959    (set (attr "length")
12960      (if_then_else (match_operand:SI 0 "register_operand" "")
12961         (const_string "2")
12962         (const_string "*")))])
12963
12964 (define_insn "*lshrhi3_one_bit_cconly"
12965   [(set (reg FLAGS_REG)
12966         (compare
12967           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12968                        (match_operand:QI 2 "const1_operand" ""))
12969           (const_int 0)))
12970    (clobber (match_scratch:HI 0 "=r"))]
12971   "(TARGET_SHIFT1 || optimize_size)
12972    && ix86_match_ccmode (insn, CCGOCmode)
12973    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12974   "shr{w}\t%0"
12975   [(set_attr "type" "ishift")
12976    (set_attr "length" "2")])
12977
12978 ;; This pattern can't accept a variable shift count, since shifts by
12979 ;; zero don't affect the flags.  We assume that shifts by constant
12980 ;; zero are optimized away.
12981 (define_insn "*lshrhi3_cmp"
12982   [(set (reg FLAGS_REG)
12983         (compare
12984           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12985                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12986           (const_int 0)))
12987    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12988         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12989   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12990    && ix86_match_ccmode (insn, CCGOCmode)
12991    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12992   "shr{w}\t{%2, %0|%0, %2}"
12993   [(set_attr "type" "ishift")
12994    (set_attr "mode" "HI")])
12995
12996 (define_insn "*lshrhi3_cconly"
12997   [(set (reg FLAGS_REG)
12998         (compare
12999           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13000                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13001           (const_int 0)))
13002    (clobber (match_scratch:HI 0 "=r"))]
13003   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13004    && ix86_match_ccmode (insn, CCGOCmode)
13005    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13006   "shr{w}\t{%2, %0|%0, %2}"
13007   [(set_attr "type" "ishift")
13008    (set_attr "mode" "HI")])
13009
13010 (define_expand "lshrqi3"
13011   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13012         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13013                      (match_operand:QI 2 "nonmemory_operand" "")))
13014    (clobber (reg:CC FLAGS_REG))]
13015   "TARGET_QIMODE_MATH"
13016   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13017
13018 (define_insn "*lshrqi3_1_one_bit"
13019   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13021                      (match_operand:QI 2 "const1_operand" "")))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "(TARGET_SHIFT1 || optimize_size)
13024    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13025   "shr{b}\t%0"
13026   [(set_attr "type" "ishift")
13027    (set (attr "length")
13028      (if_then_else (match_operand 0 "register_operand" "")
13029         (const_string "2")
13030         (const_string "*")))])
13031
13032 (define_insn "*lshrqi3_1_one_bit_slp"
13033   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13034         (lshiftrt:QI (match_dup 0)
13035                      (match_operand:QI 1 "const1_operand" "")))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13038    && (TARGET_SHIFT1 || optimize_size)"
13039   "shr{b}\t%0"
13040   [(set_attr "type" "ishift1")
13041    (set (attr "length")
13042      (if_then_else (match_operand 0 "register_operand" "")
13043         (const_string "2")
13044         (const_string "*")))])
13045
13046 (define_insn "*lshrqi3_1"
13047   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13048         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13049                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13050    (clobber (reg:CC FLAGS_REG))]
13051   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13052   "@
13053    shr{b}\t{%2, %0|%0, %2}
13054    shr{b}\t{%b2, %0|%0, %b2}"
13055   [(set_attr "type" "ishift")
13056    (set_attr "mode" "QI")])
13057
13058 (define_insn "*lshrqi3_1_slp"
13059   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13060         (lshiftrt:QI (match_dup 0)
13061                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13062    (clobber (reg:CC FLAGS_REG))]
13063   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13064    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13065   "@
13066    shr{b}\t{%1, %0|%0, %1}
13067    shr{b}\t{%b1, %0|%0, %b1}"
13068   [(set_attr "type" "ishift1")
13069    (set_attr "mode" "QI")])
13070
13071 ;; This pattern can't accept a variable shift count, since shifts by
13072 ;; zero don't affect the flags.  We assume that shifts by constant
13073 ;; zero are optimized away.
13074 (define_insn "*lshrqi2_one_bit_cmp"
13075   [(set (reg FLAGS_REG)
13076         (compare
13077           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13078                        (match_operand:QI 2 "const1_operand" ""))
13079           (const_int 0)))
13080    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13081         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13082   "(TARGET_SHIFT1 || optimize_size)
13083    && ix86_match_ccmode (insn, CCGOCmode)
13084    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13085   "shr{b}\t%0"
13086   [(set_attr "type" "ishift")
13087    (set (attr "length")
13088      (if_then_else (match_operand:SI 0 "register_operand" "")
13089         (const_string "2")
13090         (const_string "*")))])
13091
13092 (define_insn "*lshrqi2_one_bit_cconly"
13093   [(set (reg FLAGS_REG)
13094         (compare
13095           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13096                        (match_operand:QI 2 "const1_operand" ""))
13097           (const_int 0)))
13098    (clobber (match_scratch:QI 0 "=q"))]
13099   "(TARGET_SHIFT1 || optimize_size)
13100    && ix86_match_ccmode (insn, CCGOCmode)
13101    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13102   "shr{b}\t%0"
13103   [(set_attr "type" "ishift")
13104    (set_attr "length" "2")])
13105
13106 ;; This pattern can't accept a variable shift count, since shifts by
13107 ;; zero don't affect the flags.  We assume that shifts by constant
13108 ;; zero are optimized away.
13109 (define_insn "*lshrqi2_cmp"
13110   [(set (reg FLAGS_REG)
13111         (compare
13112           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13113                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13114           (const_int 0)))
13115    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13116         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13117   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13118    && ix86_match_ccmode (insn, CCGOCmode)
13119    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13120   "shr{b}\t{%2, %0|%0, %2}"
13121   [(set_attr "type" "ishift")
13122    (set_attr "mode" "QI")])
13123
13124 (define_insn "*lshrqi2_cconly"
13125   [(set (reg FLAGS_REG)
13126         (compare
13127           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13128                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13129           (const_int 0)))
13130    (clobber (match_scratch:QI 0 "=q"))]
13131   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13132    && ix86_match_ccmode (insn, CCGOCmode)
13133    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13134   "shr{b}\t{%2, %0|%0, %2}"
13135   [(set_attr "type" "ishift")
13136    (set_attr "mode" "QI")])
13137 \f
13138 ;; Rotate instructions
13139
13140 (define_expand "rotldi3"
13141   [(set (match_operand:DI 0 "shiftdi_operand" "")
13142         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13143                    (match_operand:QI 2 "nonmemory_operand" "")))
13144    (clobber (reg:CC FLAGS_REG))]
13145  ""
13146 {
13147   if (TARGET_64BIT)
13148     {
13149       ix86_expand_binary_operator (ROTATE, DImode, operands);
13150       DONE;
13151     }
13152   if (!const_1_to_31_operand (operands[2], VOIDmode))
13153     FAIL;
13154   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13155   DONE;
13156 })
13157
13158 ;; Implement rotation using two double-precision shift instructions
13159 ;; and a scratch register.
13160 (define_insn_and_split "ix86_rotldi3"
13161  [(set (match_operand:DI 0 "register_operand" "=r")
13162        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13163                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13164   (clobber (reg:CC FLAGS_REG))
13165   (clobber (match_scratch:SI 3 "=&r"))]
13166  "!TARGET_64BIT"
13167  ""
13168  "&& reload_completed"
13169  [(set (match_dup 3) (match_dup 4))
13170   (parallel
13171    [(set (match_dup 4)
13172          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13173                  (lshiftrt:SI (match_dup 5)
13174                               (minus:QI (const_int 32) (match_dup 2)))))
13175     (clobber (reg:CC FLAGS_REG))])
13176   (parallel
13177    [(set (match_dup 5)
13178          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13179                  (lshiftrt:SI (match_dup 3)
13180                               (minus:QI (const_int 32) (match_dup 2)))))
13181     (clobber (reg:CC FLAGS_REG))])]
13182  "split_di (operands, 1, operands + 4, operands + 5);")
13183
13184 (define_insn "*rotlsi3_1_one_bit_rex64"
13185   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13186         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13187                    (match_operand:QI 2 "const1_operand" "")))
13188    (clobber (reg:CC FLAGS_REG))]
13189   "TARGET_64BIT
13190    && (TARGET_SHIFT1 || optimize_size)
13191    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13192   "rol{q}\t%0"
13193   [(set_attr "type" "rotate")
13194    (set (attr "length")
13195      (if_then_else (match_operand:DI 0 "register_operand" "")
13196         (const_string "2")
13197         (const_string "*")))])
13198
13199 (define_insn "*rotldi3_1_rex64"
13200   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13201         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13202                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13203    (clobber (reg:CC FLAGS_REG))]
13204   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13205   "@
13206    rol{q}\t{%2, %0|%0, %2}
13207    rol{q}\t{%b2, %0|%0, %b2}"
13208   [(set_attr "type" "rotate")
13209    (set_attr "mode" "DI")])
13210
13211 (define_expand "rotlsi3"
13212   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13213         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13214                    (match_operand:QI 2 "nonmemory_operand" "")))
13215    (clobber (reg:CC FLAGS_REG))]
13216   ""
13217   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13218
13219 (define_insn "*rotlsi3_1_one_bit"
13220   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13221         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13222                    (match_operand:QI 2 "const1_operand" "")))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "(TARGET_SHIFT1 || optimize_size)
13225    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13226   "rol{l}\t%0"
13227   [(set_attr "type" "rotate")
13228    (set (attr "length")
13229      (if_then_else (match_operand:SI 0 "register_operand" "")
13230         (const_string "2")
13231         (const_string "*")))])
13232
13233 (define_insn "*rotlsi3_1_one_bit_zext"
13234   [(set (match_operand:DI 0 "register_operand" "=r")
13235         (zero_extend:DI
13236           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13237                      (match_operand:QI 2 "const1_operand" ""))))
13238    (clobber (reg:CC FLAGS_REG))]
13239   "TARGET_64BIT
13240    && (TARGET_SHIFT1 || optimize_size)
13241    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13242   "rol{l}\t%k0"
13243   [(set_attr "type" "rotate")
13244    (set_attr "length" "2")])
13245
13246 (define_insn "*rotlsi3_1"
13247   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13248         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13249                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13250    (clobber (reg:CC FLAGS_REG))]
13251   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13252   "@
13253    rol{l}\t{%2, %0|%0, %2}
13254    rol{l}\t{%b2, %0|%0, %b2}"
13255   [(set_attr "type" "rotate")
13256    (set_attr "mode" "SI")])
13257
13258 (define_insn "*rotlsi3_1_zext"
13259   [(set (match_operand:DI 0 "register_operand" "=r,r")
13260         (zero_extend:DI
13261           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13262                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13263    (clobber (reg:CC FLAGS_REG))]
13264   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13265   "@
13266    rol{l}\t{%2, %k0|%k0, %2}
13267    rol{l}\t{%b2, %k0|%k0, %b2}"
13268   [(set_attr "type" "rotate")
13269    (set_attr "mode" "SI")])
13270
13271 (define_expand "rotlhi3"
13272   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13273         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13274                    (match_operand:QI 2 "nonmemory_operand" "")))
13275    (clobber (reg:CC FLAGS_REG))]
13276   "TARGET_HIMODE_MATH"
13277   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13278
13279 (define_insn "*rotlhi3_1_one_bit"
13280   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13281         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13282                    (match_operand:QI 2 "const1_operand" "")))
13283    (clobber (reg:CC FLAGS_REG))]
13284   "(TARGET_SHIFT1 || optimize_size)
13285    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13286   "rol{w}\t%0"
13287   [(set_attr "type" "rotate")
13288    (set (attr "length")
13289      (if_then_else (match_operand 0 "register_operand" "")
13290         (const_string "2")
13291         (const_string "*")))])
13292
13293 (define_insn "*rotlhi3_1"
13294   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13295         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13296                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13297    (clobber (reg:CC FLAGS_REG))]
13298   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13299   "@
13300    rol{w}\t{%2, %0|%0, %2}
13301    rol{w}\t{%b2, %0|%0, %b2}"
13302   [(set_attr "type" "rotate")
13303    (set_attr "mode" "HI")])
13304
13305 (define_split
13306  [(set (match_operand:HI 0 "register_operand" "")
13307        (rotate:HI (match_dup 0) (const_int 8)))
13308   (clobber (reg:CC FLAGS_REG))]
13309  "reload_completed"
13310  [(parallel [(set (strict_low_part (match_dup 0))
13311                   (bswap:HI (match_dup 0)))
13312              (clobber (reg:CC FLAGS_REG))])]
13313  "")
13314
13315 (define_expand "rotlqi3"
13316   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13317         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13318                    (match_operand:QI 2 "nonmemory_operand" "")))
13319    (clobber (reg:CC FLAGS_REG))]
13320   "TARGET_QIMODE_MATH"
13321   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13322
13323 (define_insn "*rotlqi3_1_one_bit_slp"
13324   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13325         (rotate:QI (match_dup 0)
13326                    (match_operand:QI 1 "const1_operand" "")))
13327    (clobber (reg:CC FLAGS_REG))]
13328   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13329    && (TARGET_SHIFT1 || optimize_size)"
13330   "rol{b}\t%0"
13331   [(set_attr "type" "rotate1")
13332    (set (attr "length")
13333      (if_then_else (match_operand 0 "register_operand" "")
13334         (const_string "2")
13335         (const_string "*")))])
13336
13337 (define_insn "*rotlqi3_1_one_bit"
13338   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13339         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13340                    (match_operand:QI 2 "const1_operand" "")))
13341    (clobber (reg:CC FLAGS_REG))]
13342   "(TARGET_SHIFT1 || optimize_size)
13343    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13344   "rol{b}\t%0"
13345   [(set_attr "type" "rotate")
13346    (set (attr "length")
13347      (if_then_else (match_operand 0 "register_operand" "")
13348         (const_string "2")
13349         (const_string "*")))])
13350
13351 (define_insn "*rotlqi3_1_slp"
13352   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13353         (rotate:QI (match_dup 0)
13354                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13355    (clobber (reg:CC FLAGS_REG))]
13356   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13357    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13358   "@
13359    rol{b}\t{%1, %0|%0, %1}
13360    rol{b}\t{%b1, %0|%0, %b1}"
13361   [(set_attr "type" "rotate1")
13362    (set_attr "mode" "QI")])
13363
13364 (define_insn "*rotlqi3_1"
13365   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13366         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13367                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13368    (clobber (reg:CC FLAGS_REG))]
13369   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13370   "@
13371    rol{b}\t{%2, %0|%0, %2}
13372    rol{b}\t{%b2, %0|%0, %b2}"
13373   [(set_attr "type" "rotate")
13374    (set_attr "mode" "QI")])
13375
13376 (define_expand "rotrdi3"
13377   [(set (match_operand:DI 0 "shiftdi_operand" "")
13378         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13379                    (match_operand:QI 2 "nonmemory_operand" "")))
13380    (clobber (reg:CC FLAGS_REG))]
13381  ""
13382 {
13383   if (TARGET_64BIT)
13384     {
13385       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13386       DONE;
13387     }
13388   if (!const_1_to_31_operand (operands[2], VOIDmode))
13389     FAIL;
13390   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13391   DONE;
13392 })
13393
13394 ;; Implement rotation using two double-precision shift instructions
13395 ;; and a scratch register.
13396 (define_insn_and_split "ix86_rotrdi3"
13397  [(set (match_operand:DI 0 "register_operand" "=r")
13398        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13399                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13400   (clobber (reg:CC FLAGS_REG))
13401   (clobber (match_scratch:SI 3 "=&r"))]
13402  "!TARGET_64BIT"
13403  ""
13404  "&& reload_completed"
13405  [(set (match_dup 3) (match_dup 4))
13406   (parallel
13407    [(set (match_dup 4)
13408          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13409                  (ashift:SI (match_dup 5)
13410                             (minus:QI (const_int 32) (match_dup 2)))))
13411     (clobber (reg:CC FLAGS_REG))])
13412   (parallel
13413    [(set (match_dup 5)
13414          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13415                  (ashift:SI (match_dup 3)
13416                             (minus:QI (const_int 32) (match_dup 2)))))
13417     (clobber (reg:CC FLAGS_REG))])]
13418  "split_di (operands, 1, operands + 4, operands + 5);")
13419
13420 (define_insn "*rotrdi3_1_one_bit_rex64"
13421   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13422         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13423                      (match_operand:QI 2 "const1_operand" "")))
13424    (clobber (reg:CC FLAGS_REG))]
13425   "TARGET_64BIT
13426    && (TARGET_SHIFT1 || optimize_size)
13427    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13428   "ror{q}\t%0"
13429   [(set_attr "type" "rotate")
13430    (set (attr "length")
13431      (if_then_else (match_operand:DI 0 "register_operand" "")
13432         (const_string "2")
13433         (const_string "*")))])
13434
13435 (define_insn "*rotrdi3_1_rex64"
13436   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13437         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13438                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13439    (clobber (reg:CC FLAGS_REG))]
13440   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13441   "@
13442    ror{q}\t{%2, %0|%0, %2}
13443    ror{q}\t{%b2, %0|%0, %b2}"
13444   [(set_attr "type" "rotate")
13445    (set_attr "mode" "DI")])
13446
13447 (define_expand "rotrsi3"
13448   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13449         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13450                      (match_operand:QI 2 "nonmemory_operand" "")))
13451    (clobber (reg:CC FLAGS_REG))]
13452   ""
13453   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13454
13455 (define_insn "*rotrsi3_1_one_bit"
13456   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13457         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13458                      (match_operand:QI 2 "const1_operand" "")))
13459    (clobber (reg:CC FLAGS_REG))]
13460   "(TARGET_SHIFT1 || optimize_size)
13461    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13462   "ror{l}\t%0"
13463   [(set_attr "type" "rotate")
13464    (set (attr "length")
13465      (if_then_else (match_operand:SI 0 "register_operand" "")
13466         (const_string "2")
13467         (const_string "*")))])
13468
13469 (define_insn "*rotrsi3_1_one_bit_zext"
13470   [(set (match_operand:DI 0 "register_operand" "=r")
13471         (zero_extend:DI
13472           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13473                        (match_operand:QI 2 "const1_operand" ""))))
13474    (clobber (reg:CC FLAGS_REG))]
13475   "TARGET_64BIT
13476    && (TARGET_SHIFT1 || optimize_size)
13477    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13478   "ror{l}\t%k0"
13479   [(set_attr "type" "rotate")
13480    (set (attr "length")
13481      (if_then_else (match_operand:SI 0 "register_operand" "")
13482         (const_string "2")
13483         (const_string "*")))])
13484
13485 (define_insn "*rotrsi3_1"
13486   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13487         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13488                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13489    (clobber (reg:CC FLAGS_REG))]
13490   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13491   "@
13492    ror{l}\t{%2, %0|%0, %2}
13493    ror{l}\t{%b2, %0|%0, %b2}"
13494   [(set_attr "type" "rotate")
13495    (set_attr "mode" "SI")])
13496
13497 (define_insn "*rotrsi3_1_zext"
13498   [(set (match_operand:DI 0 "register_operand" "=r,r")
13499         (zero_extend:DI
13500           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13501                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13502    (clobber (reg:CC FLAGS_REG))]
13503   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13504   "@
13505    ror{l}\t{%2, %k0|%k0, %2}
13506    ror{l}\t{%b2, %k0|%k0, %b2}"
13507   [(set_attr "type" "rotate")
13508    (set_attr "mode" "SI")])
13509
13510 (define_expand "rotrhi3"
13511   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13512         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13513                      (match_operand:QI 2 "nonmemory_operand" "")))
13514    (clobber (reg:CC FLAGS_REG))]
13515   "TARGET_HIMODE_MATH"
13516   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13517
13518 (define_insn "*rotrhi3_one_bit"
13519   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13520         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13521                      (match_operand:QI 2 "const1_operand" "")))
13522    (clobber (reg:CC FLAGS_REG))]
13523   "(TARGET_SHIFT1 || optimize_size)
13524    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13525   "ror{w}\t%0"
13526   [(set_attr "type" "rotate")
13527    (set (attr "length")
13528      (if_then_else (match_operand 0 "register_operand" "")
13529         (const_string "2")
13530         (const_string "*")))])
13531
13532 (define_insn "*rotrhi3_1"
13533   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13534         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13535                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13536    (clobber (reg:CC FLAGS_REG))]
13537   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13538   "@
13539    ror{w}\t{%2, %0|%0, %2}
13540    ror{w}\t{%b2, %0|%0, %b2}"
13541   [(set_attr "type" "rotate")
13542    (set_attr "mode" "HI")])
13543
13544 (define_split
13545  [(set (match_operand:HI 0 "register_operand" "")
13546        (rotatert:HI (match_dup 0) (const_int 8)))
13547   (clobber (reg:CC FLAGS_REG))]
13548  "reload_completed"
13549  [(parallel [(set (strict_low_part (match_dup 0))
13550                   (bswap:HI (match_dup 0)))
13551              (clobber (reg:CC FLAGS_REG))])]
13552  "")
13553
13554 (define_expand "rotrqi3"
13555   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13556         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13557                      (match_operand:QI 2 "nonmemory_operand" "")))
13558    (clobber (reg:CC FLAGS_REG))]
13559   "TARGET_QIMODE_MATH"
13560   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13561
13562 (define_insn "*rotrqi3_1_one_bit"
13563   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13564         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13565                      (match_operand:QI 2 "const1_operand" "")))
13566    (clobber (reg:CC FLAGS_REG))]
13567   "(TARGET_SHIFT1 || optimize_size)
13568    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13569   "ror{b}\t%0"
13570   [(set_attr "type" "rotate")
13571    (set (attr "length")
13572      (if_then_else (match_operand 0 "register_operand" "")
13573         (const_string "2")
13574         (const_string "*")))])
13575
13576 (define_insn "*rotrqi3_1_one_bit_slp"
13577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13578         (rotatert:QI (match_dup 0)
13579                      (match_operand:QI 1 "const1_operand" "")))
13580    (clobber (reg:CC FLAGS_REG))]
13581   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13582    && (TARGET_SHIFT1 || optimize_size)"
13583   "ror{b}\t%0"
13584   [(set_attr "type" "rotate1")
13585    (set (attr "length")
13586      (if_then_else (match_operand 0 "register_operand" "")
13587         (const_string "2")
13588         (const_string "*")))])
13589
13590 (define_insn "*rotrqi3_1"
13591   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13592         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13593                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13594    (clobber (reg:CC FLAGS_REG))]
13595   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13596   "@
13597    ror{b}\t{%2, %0|%0, %2}
13598    ror{b}\t{%b2, %0|%0, %b2}"
13599   [(set_attr "type" "rotate")
13600    (set_attr "mode" "QI")])
13601
13602 (define_insn "*rotrqi3_1_slp"
13603   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13604         (rotatert:QI (match_dup 0)
13605                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13606    (clobber (reg:CC FLAGS_REG))]
13607   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13608    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13609   "@
13610    ror{b}\t{%1, %0|%0, %1}
13611    ror{b}\t{%b1, %0|%0, %b1}"
13612   [(set_attr "type" "rotate1")
13613    (set_attr "mode" "QI")])
13614 \f
13615 ;; Bit set / bit test instructions
13616
13617 (define_expand "extv"
13618   [(set (match_operand:SI 0 "register_operand" "")
13619         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13620                          (match_operand:SI 2 "const8_operand" "")
13621                          (match_operand:SI 3 "const8_operand" "")))]
13622   ""
13623 {
13624   /* Handle extractions from %ah et al.  */
13625   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13626     FAIL;
13627
13628   /* From mips.md: extract_bit_field doesn't verify that our source
13629      matches the predicate, so check it again here.  */
13630   if (! ext_register_operand (operands[1], VOIDmode))
13631     FAIL;
13632 })
13633
13634 (define_expand "extzv"
13635   [(set (match_operand:SI 0 "register_operand" "")
13636         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13637                          (match_operand:SI 2 "const8_operand" "")
13638                          (match_operand:SI 3 "const8_operand" "")))]
13639   ""
13640 {
13641   /* Handle extractions from %ah et al.  */
13642   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13643     FAIL;
13644
13645   /* From mips.md: extract_bit_field doesn't verify that our source
13646      matches the predicate, so check it again here.  */
13647   if (! ext_register_operand (operands[1], VOIDmode))
13648     FAIL;
13649 })
13650
13651 (define_expand "insv"
13652   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13653                       (match_operand 1 "const8_operand" "")
13654                       (match_operand 2 "const8_operand" ""))
13655         (match_operand 3 "register_operand" ""))]
13656   ""
13657 {
13658   /* Handle insertions to %ah et al.  */
13659   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13660     FAIL;
13661
13662   /* From mips.md: insert_bit_field doesn't verify that our source
13663      matches the predicate, so check it again here.  */
13664   if (! ext_register_operand (operands[0], VOIDmode))
13665     FAIL;
13666
13667   if (TARGET_64BIT)
13668     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13669   else
13670     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13671
13672   DONE;
13673 })
13674
13675 ;; %%% bts, btr, btc, bt.
13676 ;; In general these instructions are *slow* when applied to memory,
13677 ;; since they enforce atomic operation.  When applied to registers,
13678 ;; it depends on the cpu implementation.  They're never faster than
13679 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13680 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13681 ;; within the instruction itself, so operating on bits in the high
13682 ;; 32-bits of a register becomes easier.
13683 ;;
13684 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13685 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13686 ;; negdf respectively, so they can never be disabled entirely.
13687
13688 (define_insn "*btsq"
13689   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13690                          (const_int 1)
13691                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13692         (const_int 1))
13693    (clobber (reg:CC FLAGS_REG))]
13694   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13695   "bts{q} %1,%0"
13696   [(set_attr "type" "alu1")])
13697
13698 (define_insn "*btrq"
13699   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13700                          (const_int 1)
13701                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13702         (const_int 0))
13703    (clobber (reg:CC FLAGS_REG))]
13704   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13705   "btr{q} %1,%0"
13706   [(set_attr "type" "alu1")])
13707
13708 (define_insn "*btcq"
13709   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13710                          (const_int 1)
13711                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13712         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13713    (clobber (reg:CC FLAGS_REG))]
13714   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13715   "btc{q} %1,%0"
13716   [(set_attr "type" "alu1")])
13717
13718 ;; Allow Nocona to avoid these instructions if a register is available.
13719
13720 (define_peephole2
13721   [(match_scratch:DI 2 "r")
13722    (parallel [(set (zero_extract:DI
13723                      (match_operand:DI 0 "register_operand" "")
13724                      (const_int 1)
13725                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13726                    (const_int 1))
13727               (clobber (reg:CC FLAGS_REG))])]
13728   "TARGET_64BIT && !TARGET_USE_BT"
13729   [(const_int 0)]
13730 {
13731   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13732   rtx op1;
13733
13734   if (HOST_BITS_PER_WIDE_INT >= 64)
13735     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13736   else if (i < HOST_BITS_PER_WIDE_INT)
13737     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13738   else
13739     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13740
13741   op1 = immed_double_const (lo, hi, DImode);
13742   if (i >= 31)
13743     {
13744       emit_move_insn (operands[2], op1);
13745       op1 = operands[2];
13746     }
13747
13748   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13749   DONE;
13750 })
13751
13752 (define_peephole2
13753   [(match_scratch:DI 2 "r")
13754    (parallel [(set (zero_extract:DI
13755                      (match_operand:DI 0 "register_operand" "")
13756                      (const_int 1)
13757                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13758                    (const_int 0))
13759               (clobber (reg:CC FLAGS_REG))])]
13760   "TARGET_64BIT && !TARGET_USE_BT"
13761   [(const_int 0)]
13762 {
13763   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13764   rtx op1;
13765
13766   if (HOST_BITS_PER_WIDE_INT >= 64)
13767     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13768   else if (i < HOST_BITS_PER_WIDE_INT)
13769     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13770   else
13771     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13772
13773   op1 = immed_double_const (~lo, ~hi, DImode);
13774   if (i >= 32)
13775     {
13776       emit_move_insn (operands[2], op1);
13777       op1 = operands[2];
13778     }
13779
13780   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13781   DONE;
13782 })
13783
13784 (define_peephole2
13785   [(match_scratch:DI 2 "r")
13786    (parallel [(set (zero_extract:DI
13787                      (match_operand:DI 0 "register_operand" "")
13788                      (const_int 1)
13789                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13790               (not:DI (zero_extract:DI
13791                         (match_dup 0) (const_int 1) (match_dup 1))))
13792               (clobber (reg:CC FLAGS_REG))])]
13793   "TARGET_64BIT && !TARGET_USE_BT"
13794   [(const_int 0)]
13795 {
13796   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13797   rtx op1;
13798
13799   if (HOST_BITS_PER_WIDE_INT >= 64)
13800     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13801   else if (i < HOST_BITS_PER_WIDE_INT)
13802     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13803   else
13804     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13805
13806   op1 = immed_double_const (lo, hi, DImode);
13807   if (i >= 31)
13808     {
13809       emit_move_insn (operands[2], op1);
13810       op1 = operands[2];
13811     }
13812
13813   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13814   DONE;
13815 })
13816 \f
13817 ;; Store-flag instructions.
13818
13819 ;; For all sCOND expanders, also expand the compare or test insn that
13820 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13821
13822 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13823 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13824 ;; way, which can later delete the movzx if only QImode is needed.
13825
13826 (define_expand "s<code>"
13827   [(set (match_operand:QI 0 "register_operand" "")
13828         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13829   ""
13830   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13831
13832 (define_expand "s<code>"
13833   [(set (match_operand:QI 0 "register_operand" "")
13834         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13835   "TARGET_80387 || TARGET_SSE"
13836   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13837
13838 (define_insn "*setcc_1"
13839   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13840         (match_operator:QI 1 "ix86_comparison_operator"
13841           [(reg FLAGS_REG) (const_int 0)]))]
13842   ""
13843   "set%C1\t%0"
13844   [(set_attr "type" "setcc")
13845    (set_attr "mode" "QI")])
13846
13847 (define_insn "*setcc_2"
13848   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13849         (match_operator:QI 1 "ix86_comparison_operator"
13850           [(reg FLAGS_REG) (const_int 0)]))]
13851   ""
13852   "set%C1\t%0"
13853   [(set_attr "type" "setcc")
13854    (set_attr "mode" "QI")])
13855
13856 ;; In general it is not safe to assume too much about CCmode registers,
13857 ;; so simplify-rtx stops when it sees a second one.  Under certain
13858 ;; conditions this is safe on x86, so help combine not create
13859 ;;
13860 ;;      seta    %al
13861 ;;      testb   %al, %al
13862 ;;      sete    %al
13863
13864 (define_split
13865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13866         (ne:QI (match_operator 1 "ix86_comparison_operator"
13867                  [(reg FLAGS_REG) (const_int 0)])
13868             (const_int 0)))]
13869   ""
13870   [(set (match_dup 0) (match_dup 1))]
13871 {
13872   PUT_MODE (operands[1], QImode);
13873 })
13874
13875 (define_split
13876   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13877         (ne:QI (match_operator 1 "ix86_comparison_operator"
13878                  [(reg FLAGS_REG) (const_int 0)])
13879             (const_int 0)))]
13880   ""
13881   [(set (match_dup 0) (match_dup 1))]
13882 {
13883   PUT_MODE (operands[1], QImode);
13884 })
13885
13886 (define_split
13887   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13888         (eq:QI (match_operator 1 "ix86_comparison_operator"
13889                  [(reg FLAGS_REG) (const_int 0)])
13890             (const_int 0)))]
13891   ""
13892   [(set (match_dup 0) (match_dup 1))]
13893 {
13894   rtx new_op1 = copy_rtx (operands[1]);
13895   operands[1] = new_op1;
13896   PUT_MODE (new_op1, QImode);
13897   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13898                                              GET_MODE (XEXP (new_op1, 0))));
13899
13900   /* Make sure that (a) the CCmode we have for the flags is strong
13901      enough for the reversed compare or (b) we have a valid FP compare.  */
13902   if (! ix86_comparison_operator (new_op1, VOIDmode))
13903     FAIL;
13904 })
13905
13906 (define_split
13907   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13908         (eq:QI (match_operator 1 "ix86_comparison_operator"
13909                  [(reg FLAGS_REG) (const_int 0)])
13910             (const_int 0)))]
13911   ""
13912   [(set (match_dup 0) (match_dup 1))]
13913 {
13914   rtx new_op1 = copy_rtx (operands[1]);
13915   operands[1] = new_op1;
13916   PUT_MODE (new_op1, QImode);
13917   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13918                                              GET_MODE (XEXP (new_op1, 0))));
13919
13920   /* Make sure that (a) the CCmode we have for the flags is strong
13921      enough for the reversed compare or (b) we have a valid FP compare.  */
13922   if (! ix86_comparison_operator (new_op1, VOIDmode))
13923     FAIL;
13924 })
13925
13926 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13927 ;; subsequent logical operations are used to imitate conditional moves.
13928 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13929 ;; it directly.
13930
13931 (define_insn "*sse_setcc<mode>"
13932   [(set (match_operand:MODEF 0 "register_operand" "=x")
13933         (match_operator:MODEF 1 "sse_comparison_operator"
13934           [(match_operand:MODEF 2 "register_operand" "0")
13935            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13936   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13937   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13938   [(set_attr "type" "ssecmp")
13939    (set_attr "mode" "<MODE>")])
13940
13941 (define_insn "*sse5_setcc<mode>"
13942   [(set (match_operand:MODEF 0 "register_operand" "=x")
13943         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13944           [(match_operand:MODEF 2 "register_operand" "x")
13945            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13946   "TARGET_SSE5"
13947   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13948   [(set_attr "type" "sse4arg")
13949    (set_attr "mode" "<MODE>")])
13950
13951 \f
13952 ;; Basic conditional jump instructions.
13953 ;; We ignore the overflow flag for signed branch instructions.
13954
13955 ;; For all bCOND expanders, also expand the compare or test insn that
13956 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13957
13958 (define_expand "b<code>"
13959   [(set (pc)
13960         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13961                                    (const_int 0))
13962                       (label_ref (match_operand 0 ""))
13963                       (pc)))]
13964   ""
13965   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13966
13967 (define_expand "b<code>"
13968   [(set (pc)
13969         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13970                                   (const_int 0))
13971                       (label_ref (match_operand 0 ""))
13972                       (pc)))]
13973   "TARGET_80387 || TARGET_SSE_MATH"
13974   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13975
13976 (define_insn "*jcc_1"
13977   [(set (pc)
13978         (if_then_else (match_operator 1 "ix86_comparison_operator"
13979                                       [(reg FLAGS_REG) (const_int 0)])
13980                       (label_ref (match_operand 0 "" ""))
13981                       (pc)))]
13982   ""
13983   "%+j%C1\t%l0"
13984   [(set_attr "type" "ibr")
13985    (set_attr "modrm" "0")
13986    (set (attr "length")
13987            (if_then_else (and (ge (minus (match_dup 0) (pc))
13988                                   (const_int -126))
13989                               (lt (minus (match_dup 0) (pc))
13990                                   (const_int 128)))
13991              (const_int 2)
13992              (const_int 6)))])
13993
13994 (define_insn "*jcc_2"
13995   [(set (pc)
13996         (if_then_else (match_operator 1 "ix86_comparison_operator"
13997                                       [(reg FLAGS_REG) (const_int 0)])
13998                       (pc)
13999                       (label_ref (match_operand 0 "" ""))))]
14000   ""
14001   "%+j%c1\t%l0"
14002   [(set_attr "type" "ibr")
14003    (set_attr "modrm" "0")
14004    (set (attr "length")
14005            (if_then_else (and (ge (minus (match_dup 0) (pc))
14006                                   (const_int -126))
14007                               (lt (minus (match_dup 0) (pc))
14008                                   (const_int 128)))
14009              (const_int 2)
14010              (const_int 6)))])
14011
14012 ;; In general it is not safe to assume too much about CCmode registers,
14013 ;; so simplify-rtx stops when it sees a second one.  Under certain
14014 ;; conditions this is safe on x86, so help combine not create
14015 ;;
14016 ;;      seta    %al
14017 ;;      testb   %al, %al
14018 ;;      je      Lfoo
14019
14020 (define_split
14021   [(set (pc)
14022         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14023                                       [(reg FLAGS_REG) (const_int 0)])
14024                           (const_int 0))
14025                       (label_ref (match_operand 1 "" ""))
14026                       (pc)))]
14027   ""
14028   [(set (pc)
14029         (if_then_else (match_dup 0)
14030                       (label_ref (match_dup 1))
14031                       (pc)))]
14032 {
14033   PUT_MODE (operands[0], VOIDmode);
14034 })
14035
14036 (define_split
14037   [(set (pc)
14038         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14039                                       [(reg FLAGS_REG) (const_int 0)])
14040                           (const_int 0))
14041                       (label_ref (match_operand 1 "" ""))
14042                       (pc)))]
14043   ""
14044   [(set (pc)
14045         (if_then_else (match_dup 0)
14046                       (label_ref (match_dup 1))
14047                       (pc)))]
14048 {
14049   rtx new_op0 = copy_rtx (operands[0]);
14050   operands[0] = new_op0;
14051   PUT_MODE (new_op0, VOIDmode);
14052   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14053                                              GET_MODE (XEXP (new_op0, 0))));
14054
14055   /* Make sure that (a) the CCmode we have for the flags is strong
14056      enough for the reversed compare or (b) we have a valid FP compare.  */
14057   if (! ix86_comparison_operator (new_op0, VOIDmode))
14058     FAIL;
14059 })
14060
14061 ;; Define combination compare-and-branch fp compare instructions to use
14062 ;; during early optimization.  Splitting the operation apart early makes
14063 ;; for bad code when we want to reverse the operation.
14064
14065 (define_insn "*fp_jcc_1_mixed"
14066   [(set (pc)
14067         (if_then_else (match_operator 0 "comparison_operator"
14068                         [(match_operand 1 "register_operand" "f,x")
14069                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14070           (label_ref (match_operand 3 "" ""))
14071           (pc)))
14072    (clobber (reg:CCFP FPSR_REG))
14073    (clobber (reg:CCFP FLAGS_REG))]
14074   "TARGET_MIX_SSE_I387
14075    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14076    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14077    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14078   "#")
14079
14080 (define_insn "*fp_jcc_1_sse"
14081   [(set (pc)
14082         (if_then_else (match_operator 0 "comparison_operator"
14083                         [(match_operand 1 "register_operand" "x")
14084                          (match_operand 2 "nonimmediate_operand" "xm")])
14085           (label_ref (match_operand 3 "" ""))
14086           (pc)))
14087    (clobber (reg:CCFP FPSR_REG))
14088    (clobber (reg:CCFP FLAGS_REG))]
14089   "TARGET_SSE_MATH
14090    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14091    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14092    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14093   "#")
14094
14095 (define_insn "*fp_jcc_1_387"
14096   [(set (pc)
14097         (if_then_else (match_operator 0 "comparison_operator"
14098                         [(match_operand 1 "register_operand" "f")
14099                          (match_operand 2 "register_operand" "f")])
14100           (label_ref (match_operand 3 "" ""))
14101           (pc)))
14102    (clobber (reg:CCFP FPSR_REG))
14103    (clobber (reg:CCFP FLAGS_REG))]
14104   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14105    && TARGET_CMOVE
14106    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14107    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14108   "#")
14109
14110 (define_insn "*fp_jcc_2_mixed"
14111   [(set (pc)
14112         (if_then_else (match_operator 0 "comparison_operator"
14113                         [(match_operand 1 "register_operand" "f,x")
14114                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14115           (pc)
14116           (label_ref (match_operand 3 "" ""))))
14117    (clobber (reg:CCFP FPSR_REG))
14118    (clobber (reg:CCFP FLAGS_REG))]
14119   "TARGET_MIX_SSE_I387
14120    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14121    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14122    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14123   "#")
14124
14125 (define_insn "*fp_jcc_2_sse"
14126   [(set (pc)
14127         (if_then_else (match_operator 0 "comparison_operator"
14128                         [(match_operand 1 "register_operand" "x")
14129                          (match_operand 2 "nonimmediate_operand" "xm")])
14130           (pc)
14131           (label_ref (match_operand 3 "" ""))))
14132    (clobber (reg:CCFP FPSR_REG))
14133    (clobber (reg:CCFP FLAGS_REG))]
14134   "TARGET_SSE_MATH
14135    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14136    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14137    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14138   "#")
14139
14140 (define_insn "*fp_jcc_2_387"
14141   [(set (pc)
14142         (if_then_else (match_operator 0 "comparison_operator"
14143                         [(match_operand 1 "register_operand" "f")
14144                          (match_operand 2 "register_operand" "f")])
14145           (pc)
14146           (label_ref (match_operand 3 "" ""))))
14147    (clobber (reg:CCFP FPSR_REG))
14148    (clobber (reg:CCFP FLAGS_REG))]
14149   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14150    && TARGET_CMOVE
14151    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14152    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14153   "#")
14154
14155 (define_insn "*fp_jcc_3_387"
14156   [(set (pc)
14157         (if_then_else (match_operator 0 "comparison_operator"
14158                         [(match_operand 1 "register_operand" "f")
14159                          (match_operand 2 "nonimmediate_operand" "fm")])
14160           (label_ref (match_operand 3 "" ""))
14161           (pc)))
14162    (clobber (reg:CCFP FPSR_REG))
14163    (clobber (reg:CCFP FLAGS_REG))
14164    (clobber (match_scratch:HI 4 "=a"))]
14165   "TARGET_80387
14166    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14167    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14168    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14169    && SELECT_CC_MODE (GET_CODE (operands[0]),
14170                       operands[1], operands[2]) == CCFPmode
14171    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14172   "#")
14173
14174 (define_insn "*fp_jcc_4_387"
14175   [(set (pc)
14176         (if_then_else (match_operator 0 "comparison_operator"
14177                         [(match_operand 1 "register_operand" "f")
14178                          (match_operand 2 "nonimmediate_operand" "fm")])
14179           (pc)
14180           (label_ref (match_operand 3 "" ""))))
14181    (clobber (reg:CCFP FPSR_REG))
14182    (clobber (reg:CCFP FLAGS_REG))
14183    (clobber (match_scratch:HI 4 "=a"))]
14184   "TARGET_80387
14185    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14186    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14187    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14188    && SELECT_CC_MODE (GET_CODE (operands[0]),
14189                       operands[1], operands[2]) == CCFPmode
14190    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14191   "#")
14192
14193 (define_insn "*fp_jcc_5_387"
14194   [(set (pc)
14195         (if_then_else (match_operator 0 "comparison_operator"
14196                         [(match_operand 1 "register_operand" "f")
14197                          (match_operand 2 "register_operand" "f")])
14198           (label_ref (match_operand 3 "" ""))
14199           (pc)))
14200    (clobber (reg:CCFP FPSR_REG))
14201    (clobber (reg:CCFP FLAGS_REG))
14202    (clobber (match_scratch:HI 4 "=a"))]
14203   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14204    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14205    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14206   "#")
14207
14208 (define_insn "*fp_jcc_6_387"
14209   [(set (pc)
14210         (if_then_else (match_operator 0 "comparison_operator"
14211                         [(match_operand 1 "register_operand" "f")
14212                          (match_operand 2 "register_operand" "f")])
14213           (pc)
14214           (label_ref (match_operand 3 "" ""))))
14215    (clobber (reg:CCFP FPSR_REG))
14216    (clobber (reg:CCFP FLAGS_REG))
14217    (clobber (match_scratch:HI 4 "=a"))]
14218   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14219    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14220    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14221   "#")
14222
14223 (define_insn "*fp_jcc_7_387"
14224   [(set (pc)
14225         (if_then_else (match_operator 0 "comparison_operator"
14226                         [(match_operand 1 "register_operand" "f")
14227                          (match_operand 2 "const0_operand" "X")])
14228           (label_ref (match_operand 3 "" ""))
14229           (pc)))
14230    (clobber (reg:CCFP FPSR_REG))
14231    (clobber (reg:CCFP FLAGS_REG))
14232    (clobber (match_scratch:HI 4 "=a"))]
14233   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14234    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14235    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14236    && SELECT_CC_MODE (GET_CODE (operands[0]),
14237                       operands[1], operands[2]) == CCFPmode
14238    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14239   "#")
14240
14241 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14242 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14243 ;; with a precedence over other operators and is always put in the first
14244 ;; place. Swap condition and operands to match ficom instruction.
14245
14246 (define_insn "*fp_jcc_8<mode>_387"
14247   [(set (pc)
14248         (if_then_else (match_operator 0 "comparison_operator"
14249                         [(match_operator 1 "float_operator"
14250                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14251                            (match_operand 3 "register_operand" "f,f")])
14252           (label_ref (match_operand 4 "" ""))
14253           (pc)))
14254    (clobber (reg:CCFP FPSR_REG))
14255    (clobber (reg:CCFP FLAGS_REG))
14256    (clobber (match_scratch:HI 5 "=a,a"))]
14257   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14258    && TARGET_USE_<MODE>MODE_FIOP
14259    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14260    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14261    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14262    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14263   "#")
14264
14265 (define_split
14266   [(set (pc)
14267         (if_then_else (match_operator 0 "comparison_operator"
14268                         [(match_operand 1 "register_operand" "")
14269                          (match_operand 2 "nonimmediate_operand" "")])
14270           (match_operand 3 "" "")
14271           (match_operand 4 "" "")))
14272    (clobber (reg:CCFP FPSR_REG))
14273    (clobber (reg:CCFP FLAGS_REG))]
14274   "reload_completed"
14275   [(const_int 0)]
14276 {
14277   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14278                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14279   DONE;
14280 })
14281
14282 (define_split
14283   [(set (pc)
14284         (if_then_else (match_operator 0 "comparison_operator"
14285                         [(match_operand 1 "register_operand" "")
14286                          (match_operand 2 "general_operand" "")])
14287           (match_operand 3 "" "")
14288           (match_operand 4 "" "")))
14289    (clobber (reg:CCFP FPSR_REG))
14290    (clobber (reg:CCFP FLAGS_REG))
14291    (clobber (match_scratch:HI 5 "=a"))]
14292   "reload_completed"
14293   [(const_int 0)]
14294 {
14295   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14296                         operands[3], operands[4], operands[5], NULL_RTX);
14297   DONE;
14298 })
14299
14300 (define_split
14301   [(set (pc)
14302         (if_then_else (match_operator 0 "comparison_operator"
14303                         [(match_operator 1 "float_operator"
14304                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14305                            (match_operand 3 "register_operand" "")])
14306           (match_operand 4 "" "")
14307           (match_operand 5 "" "")))
14308    (clobber (reg:CCFP FPSR_REG))
14309    (clobber (reg:CCFP FLAGS_REG))
14310    (clobber (match_scratch:HI 6 "=a"))]
14311   "reload_completed"
14312   [(const_int 0)]
14313 {
14314   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14315   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14316                         operands[3], operands[7],
14317                         operands[4], operands[5], operands[6], NULL_RTX);
14318   DONE;
14319 })
14320
14321 ;; %%% Kill this when reload knows how to do it.
14322 (define_split
14323   [(set (pc)
14324         (if_then_else (match_operator 0 "comparison_operator"
14325                         [(match_operator 1 "float_operator"
14326                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14327                            (match_operand 3 "register_operand" "")])
14328           (match_operand 4 "" "")
14329           (match_operand 5 "" "")))
14330    (clobber (reg:CCFP FPSR_REG))
14331    (clobber (reg:CCFP FLAGS_REG))
14332    (clobber (match_scratch:HI 6 "=a"))]
14333   "reload_completed"
14334   [(const_int 0)]
14335 {
14336   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14337   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14338   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14339                         operands[3], operands[7],
14340                         operands[4], operands[5], operands[6], operands[2]);
14341   DONE;
14342 })
14343 \f
14344 ;; Unconditional and other jump instructions
14345
14346 (define_insn "jump"
14347   [(set (pc)
14348         (label_ref (match_operand 0 "" "")))]
14349   ""
14350   "jmp\t%l0"
14351   [(set_attr "type" "ibr")
14352    (set (attr "length")
14353            (if_then_else (and (ge (minus (match_dup 0) (pc))
14354                                   (const_int -126))
14355                               (lt (minus (match_dup 0) (pc))
14356                                   (const_int 128)))
14357              (const_int 2)
14358              (const_int 5)))
14359    (set_attr "modrm" "0")])
14360
14361 (define_expand "indirect_jump"
14362   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14363   ""
14364   "")
14365
14366 (define_insn "*indirect_jump"
14367   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14368   "!TARGET_64BIT"
14369   "jmp\t%A0"
14370   [(set_attr "type" "ibr")
14371    (set_attr "length_immediate" "0")])
14372
14373 (define_insn "*indirect_jump_rtx64"
14374   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14375   "TARGET_64BIT"
14376   "jmp\t%A0"
14377   [(set_attr "type" "ibr")
14378    (set_attr "length_immediate" "0")])
14379
14380 (define_expand "tablejump"
14381   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14382               (use (label_ref (match_operand 1 "" "")))])]
14383   ""
14384 {
14385   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14386      relative.  Convert the relative address to an absolute address.  */
14387   if (flag_pic)
14388     {
14389       rtx op0, op1;
14390       enum rtx_code code;
14391
14392       /* We can't use @GOTOFF for text labels on VxWorks;
14393          see gotoff_operand.  */
14394       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14395         {
14396           code = PLUS;
14397           op0 = operands[0];
14398           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14399         }
14400       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14401         {
14402           code = PLUS;
14403           op0 = operands[0];
14404           op1 = pic_offset_table_rtx;
14405         }
14406       else
14407         {
14408           code = MINUS;
14409           op0 = pic_offset_table_rtx;
14410           op1 = operands[0];
14411         }
14412
14413       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14414                                          OPTAB_DIRECT);
14415     }
14416 })
14417
14418 (define_insn "*tablejump_1"
14419   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14420    (use (label_ref (match_operand 1 "" "")))]
14421   "!TARGET_64BIT"
14422   "jmp\t%A0"
14423   [(set_attr "type" "ibr")
14424    (set_attr "length_immediate" "0")])
14425
14426 (define_insn "*tablejump_1_rtx64"
14427   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14428    (use (label_ref (match_operand 1 "" "")))]
14429   "TARGET_64BIT"
14430   "jmp\t%A0"
14431   [(set_attr "type" "ibr")
14432    (set_attr "length_immediate" "0")])
14433 \f
14434 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14435
14436 (define_peephole2
14437   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14438    (set (match_operand:QI 1 "register_operand" "")
14439         (match_operator:QI 2 "ix86_comparison_operator"
14440           [(reg FLAGS_REG) (const_int 0)]))
14441    (set (match_operand 3 "q_regs_operand" "")
14442         (zero_extend (match_dup 1)))]
14443   "(peep2_reg_dead_p (3, operands[1])
14444     || operands_match_p (operands[1], operands[3]))
14445    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14446   [(set (match_dup 4) (match_dup 0))
14447    (set (strict_low_part (match_dup 5))
14448         (match_dup 2))]
14449 {
14450   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14451   operands[5] = gen_lowpart (QImode, operands[3]);
14452   ix86_expand_clear (operands[3]);
14453 })
14454
14455 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14456
14457 (define_peephole2
14458   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14459    (set (match_operand:QI 1 "register_operand" "")
14460         (match_operator:QI 2 "ix86_comparison_operator"
14461           [(reg FLAGS_REG) (const_int 0)]))
14462    (parallel [(set (match_operand 3 "q_regs_operand" "")
14463                    (zero_extend (match_dup 1)))
14464               (clobber (reg:CC FLAGS_REG))])]
14465   "(peep2_reg_dead_p (3, operands[1])
14466     || operands_match_p (operands[1], operands[3]))
14467    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14468   [(set (match_dup 4) (match_dup 0))
14469    (set (strict_low_part (match_dup 5))
14470         (match_dup 2))]
14471 {
14472   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14473   operands[5] = gen_lowpart (QImode, operands[3]);
14474   ix86_expand_clear (operands[3]);
14475 })
14476 \f
14477 ;; Call instructions.
14478
14479 ;; The predicates normally associated with named expanders are not properly
14480 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14481 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14482
14483 ;; Call subroutine returning no value.
14484
14485 (define_expand "call_pop"
14486   [(parallel [(call (match_operand:QI 0 "" "")
14487                     (match_operand:SI 1 "" ""))
14488               (set (reg:SI SP_REG)
14489                    (plus:SI (reg:SI SP_REG)
14490                             (match_operand:SI 3 "" "")))])]
14491   "!TARGET_64BIT"
14492 {
14493   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14494   DONE;
14495 })
14496
14497 (define_insn "*call_pop_0"
14498   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14499          (match_operand:SI 1 "" ""))
14500    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14501                             (match_operand:SI 2 "immediate_operand" "")))]
14502   "!TARGET_64BIT"
14503 {
14504   if (SIBLING_CALL_P (insn))
14505     return "jmp\t%P0";
14506   else
14507     return "call\t%P0";
14508 }
14509   [(set_attr "type" "call")])
14510
14511 (define_insn "*call_pop_1"
14512   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14513          (match_operand:SI 1 "" ""))
14514    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14515                             (match_operand:SI 2 "immediate_operand" "i")))]
14516   "!TARGET_64BIT"
14517 {
14518   if (constant_call_address_operand (operands[0], Pmode))
14519     {
14520       if (SIBLING_CALL_P (insn))
14521         return "jmp\t%P0";
14522       else
14523         return "call\t%P0";
14524     }
14525   if (SIBLING_CALL_P (insn))
14526     return "jmp\t%A0";
14527   else
14528     return "call\t%A0";
14529 }
14530   [(set_attr "type" "call")])
14531
14532 (define_expand "call"
14533   [(call (match_operand:QI 0 "" "")
14534          (match_operand 1 "" ""))
14535    (use (match_operand 2 "" ""))]
14536   ""
14537 {
14538   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14539   DONE;
14540 })
14541
14542 (define_expand "sibcall"
14543   [(call (match_operand:QI 0 "" "")
14544          (match_operand 1 "" ""))
14545    (use (match_operand 2 "" ""))]
14546   ""
14547 {
14548   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14549   DONE;
14550 })
14551
14552 (define_insn "*call_0"
14553   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14554          (match_operand 1 "" ""))]
14555   ""
14556 {
14557   if (SIBLING_CALL_P (insn))
14558     return "jmp\t%P0";
14559   else
14560     return "call\t%P0";
14561 }
14562   [(set_attr "type" "call")])
14563
14564 (define_insn "*call_1"
14565   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14566          (match_operand 1 "" ""))]
14567   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14568 {
14569   if (constant_call_address_operand (operands[0], Pmode))
14570     return "call\t%P0";
14571   return "call\t%A0";
14572 }
14573   [(set_attr "type" "call")])
14574
14575 (define_insn "*sibcall_1"
14576   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14577          (match_operand 1 "" ""))]
14578   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14579 {
14580   if (constant_call_address_operand (operands[0], Pmode))
14581     return "jmp\t%P0";
14582   return "jmp\t%A0";
14583 }
14584   [(set_attr "type" "call")])
14585
14586 (define_insn "*call_1_rex64"
14587   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14588          (match_operand 1 "" ""))]
14589   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14590    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14591 {
14592   if (constant_call_address_operand (operands[0], Pmode))
14593     return "call\t%P0";
14594   return "call\t%A0";
14595 }
14596   [(set_attr "type" "call")])
14597
14598 (define_insn "*call_1_rex64_large"
14599   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14600          (match_operand 1 "" ""))]
14601   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14602   "call\t%A0"
14603   [(set_attr "type" "call")])
14604
14605 (define_insn "*sibcall_1_rex64"
14606   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14607          (match_operand 1 "" ""))]
14608   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14609   "jmp\t%P0"
14610   [(set_attr "type" "call")])
14611
14612 (define_insn "*sibcall_1_rex64_v"
14613   [(call (mem:QI (reg:DI R11_REG))
14614          (match_operand 0 "" ""))]
14615   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14616   "jmp\t{*%%}r11"
14617   [(set_attr "type" "call")])
14618
14619
14620 ;; Call subroutine, returning value in operand 0
14621
14622 (define_expand "call_value_pop"
14623   [(parallel [(set (match_operand 0 "" "")
14624                    (call (match_operand:QI 1 "" "")
14625                          (match_operand:SI 2 "" "")))
14626               (set (reg:SI SP_REG)
14627                    (plus:SI (reg:SI SP_REG)
14628                             (match_operand:SI 4 "" "")))])]
14629   "!TARGET_64BIT"
14630 {
14631   ix86_expand_call (operands[0], operands[1], operands[2],
14632                     operands[3], operands[4], 0);
14633   DONE;
14634 })
14635
14636 (define_expand "call_value"
14637   [(set (match_operand 0 "" "")
14638         (call (match_operand:QI 1 "" "")
14639               (match_operand:SI 2 "" "")))
14640    (use (match_operand:SI 3 "" ""))]
14641   ;; Operand 2 not used on the i386.
14642   ""
14643 {
14644   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14645   DONE;
14646 })
14647
14648 (define_expand "sibcall_value"
14649   [(set (match_operand 0 "" "")
14650         (call (match_operand:QI 1 "" "")
14651               (match_operand:SI 2 "" "")))
14652    (use (match_operand:SI 3 "" ""))]
14653   ;; Operand 2 not used on the i386.
14654   ""
14655 {
14656   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14657   DONE;
14658 })
14659
14660 ;; Call subroutine returning any type.
14661
14662 (define_expand "untyped_call"
14663   [(parallel [(call (match_operand 0 "" "")
14664                     (const_int 0))
14665               (match_operand 1 "" "")
14666               (match_operand 2 "" "")])]
14667   ""
14668 {
14669   int i;
14670
14671   /* In order to give reg-stack an easier job in validating two
14672      coprocessor registers as containing a possible return value,
14673      simply pretend the untyped call returns a complex long double
14674      value.  */
14675
14676   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14677                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14678                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14679                     NULL, 0);
14680
14681   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14682     {
14683       rtx set = XVECEXP (operands[2], 0, i);
14684       emit_move_insn (SET_DEST (set), SET_SRC (set));
14685     }
14686
14687   /* The optimizer does not know that the call sets the function value
14688      registers we stored in the result block.  We avoid problems by
14689      claiming that all hard registers are used and clobbered at this
14690      point.  */
14691   emit_insn (gen_blockage ());
14692
14693   DONE;
14694 })
14695 \f
14696 ;; Prologue and epilogue instructions
14697
14698 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14699 ;; all of memory.  This blocks insns from being moved across this point.
14700
14701 (define_insn "blockage"
14702   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14703   ""
14704   ""
14705   [(set_attr "length" "0")])
14706
14707 ;; As USE insns aren't meaningful after reload, this is used instead
14708 ;; to prevent deleting instructions setting registers for PIC code
14709 (define_insn "prologue_use"
14710   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14711   ""
14712   ""
14713   [(set_attr "length" "0")])
14714
14715 ;; Insn emitted into the body of a function to return from a function.
14716 ;; This is only done if the function's epilogue is known to be simple.
14717 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14718
14719 (define_expand "return"
14720   [(return)]
14721   "ix86_can_use_return_insn_p ()"
14722 {
14723   if (current_function_pops_args)
14724     {
14725       rtx popc = GEN_INT (current_function_pops_args);
14726       emit_jump_insn (gen_return_pop_internal (popc));
14727       DONE;
14728     }
14729 })
14730
14731 (define_insn "return_internal"
14732   [(return)]
14733   "reload_completed"
14734   "ret"
14735   [(set_attr "length" "1")
14736    (set_attr "length_immediate" "0")
14737    (set_attr "modrm" "0")])
14738
14739 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14740 ;; instruction Athlon and K8 have.
14741
14742 (define_insn "return_internal_long"
14743   [(return)
14744    (unspec [(const_int 0)] UNSPEC_REP)]
14745   "reload_completed"
14746   "rep\;ret"
14747   [(set_attr "length" "1")
14748    (set_attr "length_immediate" "0")
14749    (set_attr "prefix_rep" "1")
14750    (set_attr "modrm" "0")])
14751
14752 (define_insn "return_pop_internal"
14753   [(return)
14754    (use (match_operand:SI 0 "const_int_operand" ""))]
14755   "reload_completed"
14756   "ret\t%0"
14757   [(set_attr "length" "3")
14758    (set_attr "length_immediate" "2")
14759    (set_attr "modrm" "0")])
14760
14761 (define_insn "return_indirect_internal"
14762   [(return)
14763    (use (match_operand:SI 0 "register_operand" "r"))]
14764   "reload_completed"
14765   "jmp\t%A0"
14766   [(set_attr "type" "ibr")
14767    (set_attr "length_immediate" "0")])
14768
14769 (define_insn "nop"
14770   [(const_int 0)]
14771   ""
14772   "nop"
14773   [(set_attr "length" "1")
14774    (set_attr "length_immediate" "0")
14775    (set_attr "modrm" "0")])
14776
14777 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14778 ;; branch prediction penalty for the third jump in a 16-byte
14779 ;; block on K8.
14780
14781 (define_insn "align"
14782   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14783   ""
14784 {
14785 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14786   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14787 #else
14788   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14789      The align insn is used to avoid 3 jump instructions in the row to improve
14790      branch prediction and the benefits hardly outweigh the cost of extra 8
14791      nops on the average inserted by full alignment pseudo operation.  */
14792 #endif
14793   return "";
14794 }
14795   [(set_attr "length" "16")])
14796
14797 (define_expand "prologue"
14798   [(const_int 0)]
14799   ""
14800   "ix86_expand_prologue (); DONE;")
14801
14802 (define_insn "set_got"
14803   [(set (match_operand:SI 0 "register_operand" "=r")
14804         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14805    (clobber (reg:CC FLAGS_REG))]
14806   "!TARGET_64BIT"
14807   { return output_set_got (operands[0], NULL_RTX); }
14808   [(set_attr "type" "multi")
14809    (set_attr "length" "12")])
14810
14811 (define_insn "set_got_labelled"
14812   [(set (match_operand:SI 0 "register_operand" "=r")
14813         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14814          UNSPEC_SET_GOT))
14815    (clobber (reg:CC FLAGS_REG))]
14816   "!TARGET_64BIT"
14817   { return output_set_got (operands[0], operands[1]); }
14818   [(set_attr "type" "multi")
14819    (set_attr "length" "12")])
14820
14821 (define_insn "set_got_rex64"
14822   [(set (match_operand:DI 0 "register_operand" "=r")
14823         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14824   "TARGET_64BIT"
14825   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14826   [(set_attr "type" "lea")
14827    (set_attr "length" "6")])
14828
14829 (define_insn "set_rip_rex64"
14830   [(set (match_operand:DI 0 "register_operand" "=r")
14831         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14832   "TARGET_64BIT"
14833   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14834   [(set_attr "type" "lea")
14835    (set_attr "length" "6")])
14836
14837 (define_insn "set_got_offset_rex64"
14838   [(set (match_operand:DI 0 "register_operand" "=r")
14839         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14840   "TARGET_64BIT"
14841   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14842   [(set_attr "type" "imov")
14843    (set_attr "length" "11")])
14844
14845 (define_expand "epilogue"
14846   [(const_int 0)]
14847   ""
14848   "ix86_expand_epilogue (1); DONE;")
14849
14850 (define_expand "sibcall_epilogue"
14851   [(const_int 0)]
14852   ""
14853   "ix86_expand_epilogue (0); DONE;")
14854
14855 (define_expand "eh_return"
14856   [(use (match_operand 0 "register_operand" ""))]
14857   ""
14858 {
14859   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14860
14861   /* Tricky bit: we write the address of the handler to which we will
14862      be returning into someone else's stack frame, one word below the
14863      stack address we wish to restore.  */
14864   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14865   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14866   tmp = gen_rtx_MEM (Pmode, tmp);
14867   emit_move_insn (tmp, ra);
14868
14869   if (Pmode == SImode)
14870     emit_jump_insn (gen_eh_return_si (sa));
14871   else
14872     emit_jump_insn (gen_eh_return_di (sa));
14873   emit_barrier ();
14874   DONE;
14875 })
14876
14877 (define_insn_and_split "eh_return_si"
14878   [(set (pc)
14879         (unspec [(match_operand:SI 0 "register_operand" "c")]
14880                  UNSPEC_EH_RETURN))]
14881   "!TARGET_64BIT"
14882   "#"
14883   "reload_completed"
14884   [(const_int 0)]
14885   "ix86_expand_epilogue (2); DONE;")
14886
14887 (define_insn_and_split "eh_return_di"
14888   [(set (pc)
14889         (unspec [(match_operand:DI 0 "register_operand" "c")]
14890                  UNSPEC_EH_RETURN))]
14891   "TARGET_64BIT"
14892   "#"
14893   "reload_completed"
14894   [(const_int 0)]
14895   "ix86_expand_epilogue (2); DONE;")
14896
14897 (define_insn "leave"
14898   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14899    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14900    (clobber (mem:BLK (scratch)))]
14901   "!TARGET_64BIT"
14902   "leave"
14903   [(set_attr "type" "leave")])
14904
14905 (define_insn "leave_rex64"
14906   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14907    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14908    (clobber (mem:BLK (scratch)))]
14909   "TARGET_64BIT"
14910   "leave"
14911   [(set_attr "type" "leave")])
14912 \f
14913 (define_expand "ffssi2"
14914   [(parallel
14915      [(set (match_operand:SI 0 "register_operand" "")
14916            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14917       (clobber (match_scratch:SI 2 ""))
14918       (clobber (reg:CC FLAGS_REG))])]
14919   ""
14920 {
14921   if (TARGET_CMOVE)
14922     {
14923       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14924       DONE;
14925     }
14926 })
14927
14928 (define_expand "ffs_cmove"
14929   [(set (match_dup 2) (const_int -1))
14930    (parallel [(set (reg:CCZ FLAGS_REG)
14931                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14932                                 (const_int 0)))
14933               (set (match_operand:SI 0 "nonimmediate_operand" "")
14934                    (ctz:SI (match_dup 1)))])
14935    (set (match_dup 0) (if_then_else:SI
14936                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14937                         (match_dup 2)
14938                         (match_dup 0)))
14939    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14940               (clobber (reg:CC FLAGS_REG))])]
14941   "TARGET_CMOVE"
14942   "operands[2] = gen_reg_rtx (SImode);")
14943
14944 (define_insn_and_split "*ffs_no_cmove"
14945   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14946         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14947    (clobber (match_scratch:SI 2 "=&q"))
14948    (clobber (reg:CC FLAGS_REG))]
14949   "!TARGET_CMOVE"
14950   "#"
14951   "&& reload_completed"
14952   [(parallel [(set (reg:CCZ FLAGS_REG)
14953                    (compare:CCZ (match_dup 1) (const_int 0)))
14954               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14955    (set (strict_low_part (match_dup 3))
14956         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14957    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14958               (clobber (reg:CC FLAGS_REG))])
14959    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14960               (clobber (reg:CC FLAGS_REG))])
14961    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14962               (clobber (reg:CC FLAGS_REG))])]
14963 {
14964   operands[3] = gen_lowpart (QImode, operands[2]);
14965   ix86_expand_clear (operands[2]);
14966 })
14967
14968 (define_insn "*ffssi_1"
14969   [(set (reg:CCZ FLAGS_REG)
14970         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14971                      (const_int 0)))
14972    (set (match_operand:SI 0 "register_operand" "=r")
14973         (ctz:SI (match_dup 1)))]
14974   ""
14975   "bsf{l}\t{%1, %0|%0, %1}"
14976   [(set_attr "prefix_0f" "1")])
14977
14978 (define_expand "ffsdi2"
14979   [(set (match_dup 2) (const_int -1))
14980    (parallel [(set (reg:CCZ FLAGS_REG)
14981                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
14982                                 (const_int 0)))
14983               (set (match_operand:DI 0 "nonimmediate_operand" "")
14984                    (ctz:DI (match_dup 1)))])
14985    (set (match_dup 0) (if_then_else:DI
14986                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14987                         (match_dup 2)
14988                         (match_dup 0)))
14989    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14990               (clobber (reg:CC FLAGS_REG))])]
14991   "TARGET_64BIT"
14992   "operands[2] = gen_reg_rtx (DImode);")
14993
14994 (define_insn "*ffsdi_1"
14995   [(set (reg:CCZ FLAGS_REG)
14996         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14997                      (const_int 0)))
14998    (set (match_operand:DI 0 "register_operand" "=r")
14999         (ctz:DI (match_dup 1)))]
15000   "TARGET_64BIT"
15001   "bsf{q}\t{%1, %0|%0, %1}"
15002   [(set_attr "prefix_0f" "1")])
15003
15004 (define_insn "ctzsi2"
15005   [(set (match_operand:SI 0 "register_operand" "=r")
15006         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15007    (clobber (reg:CC FLAGS_REG))]
15008   ""
15009   "bsf{l}\t{%1, %0|%0, %1}"
15010   [(set_attr "prefix_0f" "1")])
15011
15012 (define_insn "ctzdi2"
15013   [(set (match_operand:DI 0 "register_operand" "=r")
15014         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15015    (clobber (reg:CC FLAGS_REG))]
15016   "TARGET_64BIT"
15017   "bsf{q}\t{%1, %0|%0, %1}"
15018   [(set_attr "prefix_0f" "1")])
15019
15020 (define_expand "clzsi2"
15021   [(parallel
15022      [(set (match_operand:SI 0 "register_operand" "")
15023            (minus:SI (const_int 31)
15024                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15025       (clobber (reg:CC FLAGS_REG))])
15026    (parallel
15027      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15028       (clobber (reg:CC FLAGS_REG))])]
15029   ""
15030 {
15031   if (TARGET_ABM)
15032     {
15033       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15034       DONE;
15035     }
15036 })
15037
15038 (define_insn "clzsi2_abm"
15039   [(set (match_operand:SI 0 "register_operand" "=r")
15040         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15041    (clobber (reg:CC FLAGS_REG))]
15042   "TARGET_ABM"
15043   "lzcnt{l}\t{%1, %0|%0, %1}"
15044   [(set_attr "prefix_rep" "1")
15045    (set_attr "type" "bitmanip")
15046    (set_attr "mode" "SI")])
15047
15048 (define_insn "*bsr"
15049   [(set (match_operand:SI 0 "register_operand" "=r")
15050         (minus:SI (const_int 31)
15051                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15052    (clobber (reg:CC FLAGS_REG))]
15053   ""
15054   "bsr{l}\t{%1, %0|%0, %1}"
15055   [(set_attr "prefix_0f" "1")
15056    (set_attr "mode" "SI")])
15057
15058 (define_insn "popcountsi2"
15059   [(set (match_operand:SI 0 "register_operand" "=r")
15060         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15061    (clobber (reg:CC FLAGS_REG))]
15062   "TARGET_POPCNT"
15063   "popcnt{l}\t{%1, %0|%0, %1}"
15064   [(set_attr "prefix_rep" "1")
15065    (set_attr "type" "bitmanip")
15066    (set_attr "mode" "SI")])
15067
15068 (define_insn "*popcountsi2_cmp"
15069   [(set (reg FLAGS_REG)
15070         (compare
15071           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15072           (const_int 0)))
15073    (set (match_operand:SI 0 "register_operand" "=r")
15074         (popcount:SI (match_dup 1)))]
15075   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15076   "popcnt{l}\t{%1, %0|%0, %1}"
15077   [(set_attr "prefix_rep" "1")
15078    (set_attr "type" "bitmanip")
15079    (set_attr "mode" "SI")])
15080
15081 (define_insn "*popcountsi2_cmp_zext"
15082   [(set (reg FLAGS_REG)
15083         (compare
15084           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15085           (const_int 0)))
15086    (set (match_operand:DI 0 "register_operand" "=r")
15087         (zero_extend:DI(popcount:SI (match_dup 1))))]
15088   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15089   "popcnt{l}\t{%1, %0|%0, %1}"
15090   [(set_attr "prefix_rep" "1")
15091    (set_attr "type" "bitmanip")
15092    (set_attr "mode" "SI")])
15093
15094 (define_expand "bswapsi2"
15095   [(set (match_operand:SI 0 "register_operand" "")
15096         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15097   ""
15098 {
15099   if (!TARGET_BSWAP)
15100     {
15101       rtx x = operands[0];
15102
15103       emit_move_insn (x, operands[1]);
15104       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15105       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15106       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15107       DONE;
15108     }
15109 })
15110
15111 (define_insn "*bswapsi_1"
15112   [(set (match_operand:SI 0 "register_operand" "=r")
15113         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15114   "TARGET_BSWAP"
15115   "bswap\t%0"
15116   [(set_attr "prefix_0f" "1")
15117    (set_attr "length" "2")])
15118
15119 (define_insn "*bswaphi_lowpart_1"
15120   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15121         (bswap:HI (match_dup 0)))
15122    (clobber (reg:CC FLAGS_REG))]
15123   "TARGET_USE_XCHGB || optimize_size"
15124   "@
15125     xchg{b}\t{%h0, %b0|%b0, %h0}
15126     rol{w}\t{$8, %0|%0, 8}"
15127   [(set_attr "length" "2,4")
15128    (set_attr "mode" "QI,HI")])
15129
15130 (define_insn "bswaphi_lowpart"
15131   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15132         (bswap:HI (match_dup 0)))
15133    (clobber (reg:CC FLAGS_REG))]
15134   ""
15135   "rol{w}\t{$8, %0|%0, 8}"
15136   [(set_attr "length" "4")
15137    (set_attr "mode" "HI")])
15138
15139 (define_insn "bswapdi2"
15140   [(set (match_operand:DI 0 "register_operand" "=r")
15141         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15142   "TARGET_64BIT"
15143   "bswap\t%0"
15144   [(set_attr "prefix_0f" "1")
15145    (set_attr "length" "3")])
15146
15147 (define_expand "clzdi2"
15148   [(parallel
15149      [(set (match_operand:DI 0 "register_operand" "")
15150            (minus:DI (const_int 63)
15151                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15152       (clobber (reg:CC FLAGS_REG))])
15153    (parallel
15154      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15155       (clobber (reg:CC FLAGS_REG))])]
15156   "TARGET_64BIT"
15157 {
15158   if (TARGET_ABM)
15159     {
15160       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15161       DONE;
15162     }
15163 })
15164
15165 (define_insn "clzdi2_abm"
15166   [(set (match_operand:DI 0 "register_operand" "=r")
15167         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15168    (clobber (reg:CC FLAGS_REG))]
15169   "TARGET_64BIT && TARGET_ABM"
15170   "lzcnt{q}\t{%1, %0|%0, %1}"
15171   [(set_attr "prefix_rep" "1")
15172    (set_attr "type" "bitmanip")
15173    (set_attr "mode" "DI")])
15174
15175 (define_insn "*bsr_rex64"
15176   [(set (match_operand:DI 0 "register_operand" "=r")
15177         (minus:DI (const_int 63)
15178                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15179    (clobber (reg:CC FLAGS_REG))]
15180   "TARGET_64BIT"
15181   "bsr{q}\t{%1, %0|%0, %1}"
15182   [(set_attr "prefix_0f" "1")
15183    (set_attr "mode" "DI")])
15184
15185 (define_insn "popcountdi2"
15186   [(set (match_operand:DI 0 "register_operand" "=r")
15187         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15188    (clobber (reg:CC FLAGS_REG))]
15189   "TARGET_64BIT && TARGET_POPCNT"
15190   "popcnt{q}\t{%1, %0|%0, %1}"
15191   [(set_attr "prefix_rep" "1")
15192    (set_attr "type" "bitmanip")
15193    (set_attr "mode" "DI")])
15194
15195 (define_insn "*popcountdi2_cmp"
15196   [(set (reg FLAGS_REG)
15197         (compare
15198           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15199           (const_int 0)))
15200    (set (match_operand:DI 0 "register_operand" "=r")
15201         (popcount:DI (match_dup 1)))]
15202   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15203   "popcnt{q}\t{%1, %0|%0, %1}"
15204   [(set_attr "prefix_rep" "1")
15205    (set_attr "type" "bitmanip")
15206    (set_attr "mode" "DI")])
15207
15208 (define_expand "clzhi2"
15209   [(parallel
15210      [(set (match_operand:HI 0 "register_operand" "")
15211            (minus:HI (const_int 15)
15212                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15213       (clobber (reg:CC FLAGS_REG))])
15214    (parallel
15215      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15216       (clobber (reg:CC FLAGS_REG))])]
15217   ""
15218 {
15219   if (TARGET_ABM)
15220     {
15221       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15222       DONE;
15223     }
15224 })
15225
15226 (define_insn "clzhi2_abm"
15227   [(set (match_operand:HI 0 "register_operand" "=r")
15228         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15229    (clobber (reg:CC FLAGS_REG))]
15230   "TARGET_ABM"
15231   "lzcnt{w}\t{%1, %0|%0, %1}"
15232   [(set_attr "prefix_rep" "1")
15233    (set_attr "type" "bitmanip")
15234    (set_attr "mode" "HI")])
15235
15236 (define_insn "*bsrhi"
15237   [(set (match_operand:HI 0 "register_operand" "=r")
15238         (minus:HI (const_int 15)
15239                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15240    (clobber (reg:CC FLAGS_REG))]
15241   ""
15242   "bsr{w}\t{%1, %0|%0, %1}"
15243   [(set_attr "prefix_0f" "1")
15244    (set_attr "mode" "HI")])
15245
15246 (define_insn "popcounthi2"
15247   [(set (match_operand:HI 0 "register_operand" "=r")
15248         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15249    (clobber (reg:CC FLAGS_REG))]
15250   "TARGET_POPCNT"
15251   "popcnt{w}\t{%1, %0|%0, %1}"
15252   [(set_attr "prefix_rep" "1")
15253    (set_attr "type" "bitmanip")
15254    (set_attr "mode" "HI")])
15255
15256 (define_insn "*popcounthi2_cmp"
15257   [(set (reg FLAGS_REG)
15258         (compare
15259           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15260           (const_int 0)))
15261    (set (match_operand:HI 0 "register_operand" "=r")
15262         (popcount:HI (match_dup 1)))]
15263   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15264   "popcnt{w}\t{%1, %0|%0, %1}"
15265   [(set_attr "prefix_rep" "1")
15266    (set_attr "type" "bitmanip")
15267    (set_attr "mode" "HI")])
15268
15269 (define_expand "paritydi2"
15270   [(set (match_operand:DI 0 "register_operand" "")
15271         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15272   "! TARGET_POPCNT"
15273 {
15274   rtx scratch = gen_reg_rtx (QImode);
15275   rtx cond;
15276
15277   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15278                                 NULL_RTX, operands[1]));
15279
15280   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15281                          gen_rtx_REG (CCmode, FLAGS_REG),
15282                          const0_rtx);
15283   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15284
15285   if (TARGET_64BIT)
15286     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15287   else
15288     {
15289       rtx tmp = gen_reg_rtx (SImode);
15290
15291       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15292       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15293     }
15294   DONE;
15295 })
15296
15297 (define_insn_and_split "paritydi2_cmp"
15298   [(set (reg:CC FLAGS_REG)
15299         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15300    (clobber (match_scratch:DI 0 "=r"))
15301    (clobber (match_scratch:SI 1 "=&r"))
15302    (clobber (match_scratch:HI 2 "=Q"))]
15303   "! TARGET_POPCNT"
15304   "#"
15305   "&& reload_completed"
15306   [(parallel
15307      [(set (match_dup 1)
15308            (xor:SI (match_dup 1) (match_dup 4)))
15309       (clobber (reg:CC FLAGS_REG))])
15310    (parallel
15311      [(set (reg:CC FLAGS_REG)
15312            (parity:CC (match_dup 1)))
15313       (clobber (match_dup 1))
15314       (clobber (match_dup 2))])]
15315 {
15316   operands[4] = gen_lowpart (SImode, operands[3]);
15317
15318   if (TARGET_64BIT)
15319     {
15320       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15321       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15322     }
15323   else
15324     operands[1] = gen_highpart (SImode, operands[3]);
15325 })
15326
15327 (define_expand "paritysi2"
15328   [(set (match_operand:SI 0 "register_operand" "")
15329         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15330   "! TARGET_POPCNT"
15331 {
15332   rtx scratch = gen_reg_rtx (QImode);
15333   rtx cond;
15334
15335   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15336
15337   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15338                          gen_rtx_REG (CCmode, FLAGS_REG),
15339                          const0_rtx);
15340   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15341
15342   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15343   DONE;
15344 })
15345
15346 (define_insn_and_split "paritysi2_cmp"
15347   [(set (reg:CC FLAGS_REG)
15348         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15349    (clobber (match_scratch:SI 0 "=r"))
15350    (clobber (match_scratch:HI 1 "=&Q"))]
15351   "! TARGET_POPCNT"
15352   "#"
15353   "&& reload_completed"
15354   [(parallel
15355      [(set (match_dup 1)
15356            (xor:HI (match_dup 1) (match_dup 3)))
15357       (clobber (reg:CC FLAGS_REG))])
15358    (parallel
15359      [(set (reg:CC FLAGS_REG)
15360            (parity:CC (match_dup 1)))
15361       (clobber (match_dup 1))])]
15362 {
15363   operands[3] = gen_lowpart (HImode, operands[2]);
15364
15365   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15366   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15367 })
15368
15369 (define_insn "*parityhi2_cmp"
15370   [(set (reg:CC FLAGS_REG)
15371         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15372    (clobber (match_scratch:HI 0 "=Q"))]
15373   "! TARGET_POPCNT"
15374   "xor{b}\t{%h0, %b0|%b0, %h0}"
15375   [(set_attr "length" "2")
15376    (set_attr "mode" "HI")])
15377
15378 (define_insn "*parityqi2_cmp"
15379   [(set (reg:CC FLAGS_REG)
15380         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15381   "! TARGET_POPCNT"
15382   "test{b}\t%0, %0"
15383   [(set_attr "length" "2")
15384    (set_attr "mode" "QI")])
15385 \f
15386 ;; Thread-local storage patterns for ELF.
15387 ;;
15388 ;; Note that these code sequences must appear exactly as shown
15389 ;; in order to allow linker relaxation.
15390
15391 (define_insn "*tls_global_dynamic_32_gnu"
15392   [(set (match_operand:SI 0 "register_operand" "=a")
15393         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15394                     (match_operand:SI 2 "tls_symbolic_operand" "")
15395                     (match_operand:SI 3 "call_insn_operand" "")]
15396                     UNSPEC_TLS_GD))
15397    (clobber (match_scratch:SI 4 "=d"))
15398    (clobber (match_scratch:SI 5 "=c"))
15399    (clobber (reg:CC FLAGS_REG))]
15400   "!TARGET_64BIT && TARGET_GNU_TLS"
15401   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15402   [(set_attr "type" "multi")
15403    (set_attr "length" "12")])
15404
15405 (define_insn "*tls_global_dynamic_32_sun"
15406   [(set (match_operand:SI 0 "register_operand" "=a")
15407         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15408                     (match_operand:SI 2 "tls_symbolic_operand" "")
15409                     (match_operand:SI 3 "call_insn_operand" "")]
15410                     UNSPEC_TLS_GD))
15411    (clobber (match_scratch:SI 4 "=d"))
15412    (clobber (match_scratch:SI 5 "=c"))
15413    (clobber (reg:CC FLAGS_REG))]
15414   "!TARGET_64BIT && TARGET_SUN_TLS"
15415   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15416         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15417   [(set_attr "type" "multi")
15418    (set_attr "length" "14")])
15419
15420 (define_expand "tls_global_dynamic_32"
15421   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15422                    (unspec:SI
15423                     [(match_dup 2)
15424                      (match_operand:SI 1 "tls_symbolic_operand" "")
15425                      (match_dup 3)]
15426                     UNSPEC_TLS_GD))
15427               (clobber (match_scratch:SI 4 ""))
15428               (clobber (match_scratch:SI 5 ""))
15429               (clobber (reg:CC FLAGS_REG))])]
15430   ""
15431 {
15432   if (flag_pic)
15433     operands[2] = pic_offset_table_rtx;
15434   else
15435     {
15436       operands[2] = gen_reg_rtx (Pmode);
15437       emit_insn (gen_set_got (operands[2]));
15438     }
15439   if (TARGET_GNU2_TLS)
15440     {
15441        emit_insn (gen_tls_dynamic_gnu2_32
15442                   (operands[0], operands[1], operands[2]));
15443        DONE;
15444     }
15445   operands[3] = ix86_tls_get_addr ();
15446 })
15447
15448 (define_insn "*tls_global_dynamic_64"
15449   [(set (match_operand:DI 0 "register_operand" "=a")
15450         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15451                  (match_operand:DI 3 "" "")))
15452    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15453               UNSPEC_TLS_GD)]
15454   "TARGET_64BIT"
15455   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15456   [(set_attr "type" "multi")
15457    (set_attr "length" "16")])
15458
15459 (define_expand "tls_global_dynamic_64"
15460   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15461                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15462               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15463                          UNSPEC_TLS_GD)])]
15464   ""
15465 {
15466   if (TARGET_GNU2_TLS)
15467     {
15468        emit_insn (gen_tls_dynamic_gnu2_64
15469                   (operands[0], operands[1]));
15470        DONE;
15471     }
15472   operands[2] = ix86_tls_get_addr ();
15473 })
15474
15475 (define_insn "*tls_local_dynamic_base_32_gnu"
15476   [(set (match_operand:SI 0 "register_operand" "=a")
15477         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15478                     (match_operand:SI 2 "call_insn_operand" "")]
15479                    UNSPEC_TLS_LD_BASE))
15480    (clobber (match_scratch:SI 3 "=d"))
15481    (clobber (match_scratch:SI 4 "=c"))
15482    (clobber (reg:CC FLAGS_REG))]
15483   "!TARGET_64BIT && TARGET_GNU_TLS"
15484   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15485   [(set_attr "type" "multi")
15486    (set_attr "length" "11")])
15487
15488 (define_insn "*tls_local_dynamic_base_32_sun"
15489   [(set (match_operand:SI 0 "register_operand" "=a")
15490         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15491                     (match_operand:SI 2 "call_insn_operand" "")]
15492                    UNSPEC_TLS_LD_BASE))
15493    (clobber (match_scratch:SI 3 "=d"))
15494    (clobber (match_scratch:SI 4 "=c"))
15495    (clobber (reg:CC FLAGS_REG))]
15496   "!TARGET_64BIT && TARGET_SUN_TLS"
15497   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15498         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15499   [(set_attr "type" "multi")
15500    (set_attr "length" "13")])
15501
15502 (define_expand "tls_local_dynamic_base_32"
15503   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15504                    (unspec:SI [(match_dup 1) (match_dup 2)]
15505                               UNSPEC_TLS_LD_BASE))
15506               (clobber (match_scratch:SI 3 ""))
15507               (clobber (match_scratch:SI 4 ""))
15508               (clobber (reg:CC FLAGS_REG))])]
15509   ""
15510 {
15511   if (flag_pic)
15512     operands[1] = pic_offset_table_rtx;
15513   else
15514     {
15515       operands[1] = gen_reg_rtx (Pmode);
15516       emit_insn (gen_set_got (operands[1]));
15517     }
15518   if (TARGET_GNU2_TLS)
15519     {
15520        emit_insn (gen_tls_dynamic_gnu2_32
15521                   (operands[0], ix86_tls_module_base (), operands[1]));
15522        DONE;
15523     }
15524   operands[2] = ix86_tls_get_addr ();
15525 })
15526
15527 (define_insn "*tls_local_dynamic_base_64"
15528   [(set (match_operand:DI 0 "register_operand" "=a")
15529         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15530                  (match_operand:DI 2 "" "")))
15531    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15532   "TARGET_64BIT"
15533   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15534   [(set_attr "type" "multi")
15535    (set_attr "length" "12")])
15536
15537 (define_expand "tls_local_dynamic_base_64"
15538   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15539                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15540               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15541   ""
15542 {
15543   if (TARGET_GNU2_TLS)
15544     {
15545        emit_insn (gen_tls_dynamic_gnu2_64
15546                   (operands[0], ix86_tls_module_base ()));
15547        DONE;
15548     }
15549   operands[1] = ix86_tls_get_addr ();
15550 })
15551
15552 ;; Local dynamic of a single variable is a lose.  Show combine how
15553 ;; to convert that back to global dynamic.
15554
15555 (define_insn_and_split "*tls_local_dynamic_32_once"
15556   [(set (match_operand:SI 0 "register_operand" "=a")
15557         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15558                              (match_operand:SI 2 "call_insn_operand" "")]
15559                             UNSPEC_TLS_LD_BASE)
15560                  (const:SI (unspec:SI
15561                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15562                             UNSPEC_DTPOFF))))
15563    (clobber (match_scratch:SI 4 "=d"))
15564    (clobber (match_scratch:SI 5 "=c"))
15565    (clobber (reg:CC FLAGS_REG))]
15566   ""
15567   "#"
15568   ""
15569   [(parallel [(set (match_dup 0)
15570                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15571                               UNSPEC_TLS_GD))
15572               (clobber (match_dup 4))
15573               (clobber (match_dup 5))
15574               (clobber (reg:CC FLAGS_REG))])]
15575   "")
15576
15577 ;; Load and add the thread base pointer from %gs:0.
15578
15579 (define_insn "*load_tp_si"
15580   [(set (match_operand:SI 0 "register_operand" "=r")
15581         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15582   "!TARGET_64BIT"
15583   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15584   [(set_attr "type" "imov")
15585    (set_attr "modrm" "0")
15586    (set_attr "length" "7")
15587    (set_attr "memory" "load")
15588    (set_attr "imm_disp" "false")])
15589
15590 (define_insn "*add_tp_si"
15591   [(set (match_operand:SI 0 "register_operand" "=r")
15592         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15593                  (match_operand:SI 1 "register_operand" "0")))
15594    (clobber (reg:CC FLAGS_REG))]
15595   "!TARGET_64BIT"
15596   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15597   [(set_attr "type" "alu")
15598    (set_attr "modrm" "0")
15599    (set_attr "length" "7")
15600    (set_attr "memory" "load")
15601    (set_attr "imm_disp" "false")])
15602
15603 (define_insn "*load_tp_di"
15604   [(set (match_operand:DI 0 "register_operand" "=r")
15605         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15606   "TARGET_64BIT"
15607   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15608   [(set_attr "type" "imov")
15609    (set_attr "modrm" "0")
15610    (set_attr "length" "7")
15611    (set_attr "memory" "load")
15612    (set_attr "imm_disp" "false")])
15613
15614 (define_insn "*add_tp_di"
15615   [(set (match_operand:DI 0 "register_operand" "=r")
15616         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15617                  (match_operand:DI 1 "register_operand" "0")))
15618    (clobber (reg:CC FLAGS_REG))]
15619   "TARGET_64BIT"
15620   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15621   [(set_attr "type" "alu")
15622    (set_attr "modrm" "0")
15623    (set_attr "length" "7")
15624    (set_attr "memory" "load")
15625    (set_attr "imm_disp" "false")])
15626
15627 ;; GNU2 TLS patterns can be split.
15628
15629 (define_expand "tls_dynamic_gnu2_32"
15630   [(set (match_dup 3)
15631         (plus:SI (match_operand:SI 2 "register_operand" "")
15632                  (const:SI
15633                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15634                              UNSPEC_TLSDESC))))
15635    (parallel
15636     [(set (match_operand:SI 0 "register_operand" "")
15637           (unspec:SI [(match_dup 1) (match_dup 3)
15638                       (match_dup 2) (reg:SI SP_REG)]
15639                       UNSPEC_TLSDESC))
15640      (clobber (reg:CC FLAGS_REG))])]
15641   "!TARGET_64BIT && TARGET_GNU2_TLS"
15642 {
15643   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15644   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15645 })
15646
15647 (define_insn "*tls_dynamic_lea_32"
15648   [(set (match_operand:SI 0 "register_operand" "=r")
15649         (plus:SI (match_operand:SI 1 "register_operand" "b")
15650                  (const:SI
15651                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15652                               UNSPEC_TLSDESC))))]
15653   "!TARGET_64BIT && TARGET_GNU2_TLS"
15654   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15655   [(set_attr "type" "lea")
15656    (set_attr "mode" "SI")
15657    (set_attr "length" "6")
15658    (set_attr "length_address" "4")])
15659
15660 (define_insn "*tls_dynamic_call_32"
15661   [(set (match_operand:SI 0 "register_operand" "=a")
15662         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15663                     (match_operand:SI 2 "register_operand" "0")
15664                     ;; we have to make sure %ebx still points to the GOT
15665                     (match_operand:SI 3 "register_operand" "b")
15666                     (reg:SI SP_REG)]
15667                    UNSPEC_TLSDESC))
15668    (clobber (reg:CC FLAGS_REG))]
15669   "!TARGET_64BIT && TARGET_GNU2_TLS"
15670   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15671   [(set_attr "type" "call")
15672    (set_attr "length" "2")
15673    (set_attr "length_address" "0")])
15674
15675 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15676   [(set (match_operand:SI 0 "register_operand" "=&a")
15677         (plus:SI
15678          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15679                      (match_operand:SI 4 "" "")
15680                      (match_operand:SI 2 "register_operand" "b")
15681                      (reg:SI SP_REG)]
15682                     UNSPEC_TLSDESC)
15683          (const:SI (unspec:SI
15684                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15685                     UNSPEC_DTPOFF))))
15686    (clobber (reg:CC FLAGS_REG))]
15687   "!TARGET_64BIT && TARGET_GNU2_TLS"
15688   "#"
15689   ""
15690   [(set (match_dup 0) (match_dup 5))]
15691 {
15692   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15693   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15694 })
15695
15696 (define_expand "tls_dynamic_gnu2_64"
15697   [(set (match_dup 2)
15698         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15699                    UNSPEC_TLSDESC))
15700    (parallel
15701     [(set (match_operand:DI 0 "register_operand" "")
15702           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15703                      UNSPEC_TLSDESC))
15704      (clobber (reg:CC FLAGS_REG))])]
15705   "TARGET_64BIT && TARGET_GNU2_TLS"
15706 {
15707   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15708   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15709 })
15710
15711 (define_insn "*tls_dynamic_lea_64"
15712   [(set (match_operand:DI 0 "register_operand" "=r")
15713         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15714                    UNSPEC_TLSDESC))]
15715   "TARGET_64BIT && TARGET_GNU2_TLS"
15716   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15717   [(set_attr "type" "lea")
15718    (set_attr "mode" "DI")
15719    (set_attr "length" "7")
15720    (set_attr "length_address" "4")])
15721
15722 (define_insn "*tls_dynamic_call_64"
15723   [(set (match_operand:DI 0 "register_operand" "=a")
15724         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15725                     (match_operand:DI 2 "register_operand" "0")
15726                     (reg:DI SP_REG)]
15727                    UNSPEC_TLSDESC))
15728    (clobber (reg:CC FLAGS_REG))]
15729   "TARGET_64BIT && TARGET_GNU2_TLS"
15730   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15731   [(set_attr "type" "call")
15732    (set_attr "length" "2")
15733    (set_attr "length_address" "0")])
15734
15735 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15736   [(set (match_operand:DI 0 "register_operand" "=&a")
15737         (plus:DI
15738          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15739                      (match_operand:DI 3 "" "")
15740                      (reg:DI SP_REG)]
15741                     UNSPEC_TLSDESC)
15742          (const:DI (unspec:DI
15743                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15744                     UNSPEC_DTPOFF))))
15745    (clobber (reg:CC FLAGS_REG))]
15746   "TARGET_64BIT && TARGET_GNU2_TLS"
15747   "#"
15748   ""
15749   [(set (match_dup 0) (match_dup 4))]
15750 {
15751   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15752   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15753 })
15754
15755 ;;
15756 \f
15757 ;; These patterns match the binary 387 instructions for addM3, subM3,
15758 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15759 ;; SFmode.  The first is the normal insn, the second the same insn but
15760 ;; with one operand a conversion, and the third the same insn but with
15761 ;; the other operand a conversion.  The conversion may be SFmode or
15762 ;; SImode if the target mode DFmode, but only SImode if the target mode
15763 ;; is SFmode.
15764
15765 ;; Gcc is slightly more smart about handling normal two address instructions
15766 ;; so use special patterns for add and mull.
15767
15768 (define_insn "*fop_sf_comm_mixed"
15769   [(set (match_operand:SF 0 "register_operand" "=f,x")
15770         (match_operator:SF 3 "binary_fp_operator"
15771                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15772                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15773   "TARGET_MIX_SSE_I387
15774    && COMMUTATIVE_ARITH_P (operands[3])
15775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15776   "* return output_387_binary_op (insn, operands);"
15777   [(set (attr "type")
15778         (if_then_else (eq_attr "alternative" "1")
15779            (if_then_else (match_operand:SF 3 "mult_operator" "")
15780               (const_string "ssemul")
15781               (const_string "sseadd"))
15782            (if_then_else (match_operand:SF 3 "mult_operator" "")
15783               (const_string "fmul")
15784               (const_string "fop"))))
15785    (set_attr "mode" "SF")])
15786
15787 (define_insn "*fop_sf_comm_sse"
15788   [(set (match_operand:SF 0 "register_operand" "=x")
15789         (match_operator:SF 3 "binary_fp_operator"
15790                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15791                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15792   "TARGET_SSE_MATH
15793    && COMMUTATIVE_ARITH_P (operands[3])
15794    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15795   "* return output_387_binary_op (insn, operands);"
15796   [(set (attr "type")
15797         (if_then_else (match_operand:SF 3 "mult_operator" "")
15798            (const_string "ssemul")
15799            (const_string "sseadd")))
15800    (set_attr "mode" "SF")])
15801
15802 (define_insn "*fop_sf_comm_i387"
15803   [(set (match_operand:SF 0 "register_operand" "=f")
15804         (match_operator:SF 3 "binary_fp_operator"
15805                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15806                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15807   "TARGET_80387
15808    && COMMUTATIVE_ARITH_P (operands[3])
15809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15810   "* return output_387_binary_op (insn, operands);"
15811   [(set (attr "type")
15812         (if_then_else (match_operand:SF 3 "mult_operator" "")
15813            (const_string "fmul")
15814            (const_string "fop")))
15815    (set_attr "mode" "SF")])
15816
15817 (define_insn "*fop_sf_1_mixed"
15818   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15819         (match_operator:SF 3 "binary_fp_operator"
15820                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15821                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15822   "TARGET_MIX_SSE_I387
15823    && !COMMUTATIVE_ARITH_P (operands[3])
15824    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15825   "* return output_387_binary_op (insn, operands);"
15826   [(set (attr "type")
15827         (cond [(and (eq_attr "alternative" "2")
15828                     (match_operand:SF 3 "mult_operator" ""))
15829                  (const_string "ssemul")
15830                (and (eq_attr "alternative" "2")
15831                     (match_operand:SF 3 "div_operator" ""))
15832                  (const_string "ssediv")
15833                (eq_attr "alternative" "2")
15834                  (const_string "sseadd")
15835                (match_operand:SF 3 "mult_operator" "")
15836                  (const_string "fmul")
15837                (match_operand:SF 3 "div_operator" "")
15838                  (const_string "fdiv")
15839               ]
15840               (const_string "fop")))
15841    (set_attr "mode" "SF")])
15842
15843 (define_insn "*rcpsf2_sse"
15844   [(set (match_operand:SF 0 "register_operand" "=x")
15845         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15846                    UNSPEC_RCP))]
15847   "TARGET_SSE_MATH"
15848   "rcpss\t{%1, %0|%0, %1}"
15849   [(set_attr "type" "sse")
15850    (set_attr "mode" "SF")])
15851
15852 (define_insn "*fop_sf_1_sse"
15853   [(set (match_operand:SF 0 "register_operand" "=x")
15854         (match_operator:SF 3 "binary_fp_operator"
15855                         [(match_operand:SF 1 "register_operand" "0")
15856                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15857   "TARGET_SSE_MATH
15858    && !COMMUTATIVE_ARITH_P (operands[3])"
15859   "* return output_387_binary_op (insn, operands);"
15860   [(set (attr "type")
15861         (cond [(match_operand:SF 3 "mult_operator" "")
15862                  (const_string "ssemul")
15863                (match_operand:SF 3 "div_operator" "")
15864                  (const_string "ssediv")
15865               ]
15866               (const_string "sseadd")))
15867    (set_attr "mode" "SF")])
15868
15869 ;; This pattern is not fully shadowed by the pattern above.
15870 (define_insn "*fop_sf_1_i387"
15871   [(set (match_operand:SF 0 "register_operand" "=f,f")
15872         (match_operator:SF 3 "binary_fp_operator"
15873                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15874                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15875   "TARGET_80387 && !TARGET_SSE_MATH
15876    && !COMMUTATIVE_ARITH_P (operands[3])
15877    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15878   "* return output_387_binary_op (insn, operands);"
15879   [(set (attr "type")
15880         (cond [(match_operand:SF 3 "mult_operator" "")
15881                  (const_string "fmul")
15882                (match_operand:SF 3 "div_operator" "")
15883                  (const_string "fdiv")
15884               ]
15885               (const_string "fop")))
15886    (set_attr "mode" "SF")])
15887
15888 ;; ??? Add SSE splitters for these!
15889 (define_insn "*fop_sf_2<mode>_i387"
15890   [(set (match_operand:SF 0 "register_operand" "=f,f")
15891         (match_operator:SF 3 "binary_fp_operator"
15892           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15893            (match_operand:SF 2 "register_operand" "0,0")]))]
15894   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15895   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15896   [(set (attr "type")
15897         (cond [(match_operand:SF 3 "mult_operator" "")
15898                  (const_string "fmul")
15899                (match_operand:SF 3 "div_operator" "")
15900                  (const_string "fdiv")
15901               ]
15902               (const_string "fop")))
15903    (set_attr "fp_int_src" "true")
15904    (set_attr "mode" "<MODE>")])
15905
15906 (define_insn "*fop_sf_3<mode>_i387"
15907   [(set (match_operand:SF 0 "register_operand" "=f,f")
15908         (match_operator:SF 3 "binary_fp_operator"
15909           [(match_operand:SF 1 "register_operand" "0,0")
15910            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15911   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15912   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15913   [(set (attr "type")
15914         (cond [(match_operand:SF 3 "mult_operator" "")
15915                  (const_string "fmul")
15916                (match_operand:SF 3 "div_operator" "")
15917                  (const_string "fdiv")
15918               ]
15919               (const_string "fop")))
15920    (set_attr "fp_int_src" "true")
15921    (set_attr "mode" "<MODE>")])
15922
15923 (define_insn "*fop_df_comm_mixed"
15924   [(set (match_operand:DF 0 "register_operand" "=f,x")
15925         (match_operator:DF 3 "binary_fp_operator"
15926           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15927            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15928   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15929    && COMMUTATIVE_ARITH_P (operands[3])
15930    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15931   "* return output_387_binary_op (insn, operands);"
15932   [(set (attr "type")
15933         (if_then_else (eq_attr "alternative" "1")
15934            (if_then_else (match_operand:DF 3 "mult_operator" "")
15935               (const_string "ssemul")
15936               (const_string "sseadd"))
15937            (if_then_else (match_operand:DF 3 "mult_operator" "")
15938               (const_string "fmul")
15939               (const_string "fop"))))
15940    (set_attr "mode" "DF")])
15941
15942 (define_insn "*fop_df_comm_sse"
15943   [(set (match_operand:DF 0 "register_operand" "=x")
15944         (match_operator:DF 3 "binary_fp_operator"
15945           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15946            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15947   "TARGET_SSE2 && TARGET_SSE_MATH
15948    && COMMUTATIVE_ARITH_P (operands[3])
15949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15950   "* return output_387_binary_op (insn, operands);"
15951   [(set (attr "type")
15952         (if_then_else (match_operand:DF 3 "mult_operator" "")
15953            (const_string "ssemul")
15954            (const_string "sseadd")))
15955    (set_attr "mode" "DF")])
15956
15957 (define_insn "*fop_df_comm_i387"
15958   [(set (match_operand:DF 0 "register_operand" "=f")
15959         (match_operator:DF 3 "binary_fp_operator"
15960                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15961                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15962   "TARGET_80387
15963    && COMMUTATIVE_ARITH_P (operands[3])
15964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15965   "* return output_387_binary_op (insn, operands);"
15966   [(set (attr "type")
15967         (if_then_else (match_operand:DF 3 "mult_operator" "")
15968            (const_string "fmul")
15969            (const_string "fop")))
15970    (set_attr "mode" "DF")])
15971
15972 (define_insn "*fop_df_1_mixed"
15973   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15974         (match_operator:DF 3 "binary_fp_operator"
15975           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15976            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15977   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15978    && !COMMUTATIVE_ARITH_P (operands[3])
15979    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15980   "* return output_387_binary_op (insn, operands);"
15981   [(set (attr "type")
15982         (cond [(and (eq_attr "alternative" "2")
15983                     (match_operand:DF 3 "mult_operator" ""))
15984                  (const_string "ssemul")
15985                (and (eq_attr "alternative" "2")
15986                     (match_operand:DF 3 "div_operator" ""))
15987                  (const_string "ssediv")
15988                (eq_attr "alternative" "2")
15989                  (const_string "sseadd")
15990                (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 "mode" "DF")])
15997
15998 (define_insn "*fop_df_1_sse"
15999   [(set (match_operand:DF 0 "register_operand" "=x")
16000         (match_operator:DF 3 "binary_fp_operator"
16001           [(match_operand:DF 1 "register_operand" "0")
16002            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16003   "TARGET_SSE2 && TARGET_SSE_MATH
16004    && !COMMUTATIVE_ARITH_P (operands[3])"
16005   "* return output_387_binary_op (insn, operands);"
16006   [(set_attr "mode" "DF")
16007    (set (attr "type")
16008         (cond [(match_operand:DF 3 "mult_operator" "")
16009                  (const_string "ssemul")
16010                (match_operand:DF 3 "div_operator" "")
16011                  (const_string "ssediv")
16012               ]
16013               (const_string "sseadd")))])
16014
16015 ;; This pattern is not fully shadowed by the pattern above.
16016 (define_insn "*fop_df_1_i387"
16017   [(set (match_operand:DF 0 "register_operand" "=f,f")
16018         (match_operator:DF 3 "binary_fp_operator"
16019                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16020                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16021   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16022    && !COMMUTATIVE_ARITH_P (operands[3])
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" "DF")])
16033
16034 ;; ??? Add SSE splitters for these!
16035 (define_insn "*fop_df_2<mode>_i387"
16036   [(set (match_operand:DF 0 "register_operand" "=f,f")
16037         (match_operator:DF 3 "binary_fp_operator"
16038            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16039             (match_operand:DF 2 "register_operand" "0,0")]))]
16040   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16041    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16042   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16043   [(set (attr "type")
16044         (cond [(match_operand:DF 3 "mult_operator" "")
16045                  (const_string "fmul")
16046                (match_operand:DF 3 "div_operator" "")
16047                  (const_string "fdiv")
16048               ]
16049               (const_string "fop")))
16050    (set_attr "fp_int_src" "true")
16051    (set_attr "mode" "<MODE>")])
16052
16053 (define_insn "*fop_df_3<mode>_i387"
16054   [(set (match_operand:DF 0 "register_operand" "=f,f")
16055         (match_operator:DF 3 "binary_fp_operator"
16056            [(match_operand:DF 1 "register_operand" "0,0")
16057             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16058   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16059    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16060   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16061   [(set (attr "type")
16062         (cond [(match_operand:DF 3 "mult_operator" "")
16063                  (const_string "fmul")
16064                (match_operand:DF 3 "div_operator" "")
16065                  (const_string "fdiv")
16066               ]
16067               (const_string "fop")))
16068    (set_attr "fp_int_src" "true")
16069    (set_attr "mode" "<MODE>")])
16070
16071 (define_insn "*fop_df_4_i387"
16072   [(set (match_operand:DF 0 "register_operand" "=f,f")
16073         (match_operator:DF 3 "binary_fp_operator"
16074            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16075             (match_operand:DF 2 "register_operand" "0,f")]))]
16076   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16077    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16078   "* return output_387_binary_op (insn, operands);"
16079   [(set (attr "type")
16080         (cond [(match_operand:DF 3 "mult_operator" "")
16081                  (const_string "fmul")
16082                (match_operand:DF 3 "div_operator" "")
16083                  (const_string "fdiv")
16084               ]
16085               (const_string "fop")))
16086    (set_attr "mode" "SF")])
16087
16088 (define_insn "*fop_df_5_i387"
16089   [(set (match_operand:DF 0 "register_operand" "=f,f")
16090         (match_operator:DF 3 "binary_fp_operator"
16091           [(match_operand:DF 1 "register_operand" "0,f")
16092            (float_extend:DF
16093             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16094   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16095   "* return output_387_binary_op (insn, operands);"
16096   [(set (attr "type")
16097         (cond [(match_operand:DF 3 "mult_operator" "")
16098                  (const_string "fmul")
16099                (match_operand:DF 3 "div_operator" "")
16100                  (const_string "fdiv")
16101               ]
16102               (const_string "fop")))
16103    (set_attr "mode" "SF")])
16104
16105 (define_insn "*fop_df_6_i387"
16106   [(set (match_operand:DF 0 "register_operand" "=f,f")
16107         (match_operator:DF 3 "binary_fp_operator"
16108           [(float_extend:DF
16109             (match_operand:SF 1 "register_operand" "0,f"))
16110            (float_extend:DF
16111             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16112   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16113   "* return output_387_binary_op (insn, operands);"
16114   [(set (attr "type")
16115         (cond [(match_operand:DF 3 "mult_operator" "")
16116                  (const_string "fmul")
16117                (match_operand:DF 3 "div_operator" "")
16118                  (const_string "fdiv")
16119               ]
16120               (const_string "fop")))
16121    (set_attr "mode" "SF")])
16122
16123 (define_insn "*fop_xf_comm_i387"
16124   [(set (match_operand:XF 0 "register_operand" "=f")
16125         (match_operator:XF 3 "binary_fp_operator"
16126                         [(match_operand:XF 1 "register_operand" "%0")
16127                          (match_operand:XF 2 "register_operand" "f")]))]
16128   "TARGET_80387
16129    && COMMUTATIVE_ARITH_P (operands[3])"
16130   "* return output_387_binary_op (insn, operands);"
16131   [(set (attr "type")
16132         (if_then_else (match_operand:XF 3 "mult_operator" "")
16133            (const_string "fmul")
16134            (const_string "fop")))
16135    (set_attr "mode" "XF")])
16136
16137 (define_insn "*fop_xf_1_i387"
16138   [(set (match_operand:XF 0 "register_operand" "=f,f")
16139         (match_operator:XF 3 "binary_fp_operator"
16140                         [(match_operand:XF 1 "register_operand" "0,f")
16141                          (match_operand:XF 2 "register_operand" "f,0")]))]
16142   "TARGET_80387
16143    && !COMMUTATIVE_ARITH_P (operands[3])"
16144   "* return output_387_binary_op (insn, operands);"
16145   [(set (attr "type")
16146         (cond [(match_operand:XF 3 "mult_operator" "")
16147                  (const_string "fmul")
16148                (match_operand:XF 3 "div_operator" "")
16149                  (const_string "fdiv")
16150               ]
16151               (const_string "fop")))
16152    (set_attr "mode" "XF")])
16153
16154 (define_insn "*fop_xf_2<mode>_i387"
16155   [(set (match_operand:XF 0 "register_operand" "=f,f")
16156         (match_operator:XF 3 "binary_fp_operator"
16157            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16158             (match_operand:XF 2 "register_operand" "0,0")]))]
16159   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16160   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16161   [(set (attr "type")
16162         (cond [(match_operand:XF 3 "mult_operator" "")
16163                  (const_string "fmul")
16164                (match_operand:XF 3 "div_operator" "")
16165                  (const_string "fdiv")
16166               ]
16167               (const_string "fop")))
16168    (set_attr "fp_int_src" "true")
16169    (set_attr "mode" "<MODE>")])
16170
16171 (define_insn "*fop_xf_3<mode>_i387"
16172   [(set (match_operand:XF 0 "register_operand" "=f,f")
16173         (match_operator:XF 3 "binary_fp_operator"
16174           [(match_operand:XF 1 "register_operand" "0,0")
16175            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16176   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16177   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16178   [(set (attr "type")
16179         (cond [(match_operand:XF 3 "mult_operator" "")
16180                  (const_string "fmul")
16181                (match_operand:XF 3 "div_operator" "")
16182                  (const_string "fdiv")
16183               ]
16184               (const_string "fop")))
16185    (set_attr "fp_int_src" "true")
16186    (set_attr "mode" "<MODE>")])
16187
16188 (define_insn "*fop_xf_4_i387"
16189   [(set (match_operand:XF 0 "register_operand" "=f,f")
16190         (match_operator:XF 3 "binary_fp_operator"
16191            [(float_extend:XF
16192               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16193             (match_operand:XF 2 "register_operand" "0,f")]))]
16194   "TARGET_80387"
16195   "* return output_387_binary_op (insn, operands);"
16196   [(set (attr "type")
16197         (cond [(match_operand:XF 3 "mult_operator" "")
16198                  (const_string "fmul")
16199                (match_operand:XF 3 "div_operator" "")
16200                  (const_string "fdiv")
16201               ]
16202               (const_string "fop")))
16203    (set_attr "mode" "SF")])
16204
16205 (define_insn "*fop_xf_5_i387"
16206   [(set (match_operand:XF 0 "register_operand" "=f,f")
16207         (match_operator:XF 3 "binary_fp_operator"
16208           [(match_operand:XF 1 "register_operand" "0,f")
16209            (float_extend:XF
16210              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16211   "TARGET_80387"
16212   "* return output_387_binary_op (insn, operands);"
16213   [(set (attr "type")
16214         (cond [(match_operand:XF 3 "mult_operator" "")
16215                  (const_string "fmul")
16216                (match_operand:XF 3 "div_operator" "")
16217                  (const_string "fdiv")
16218               ]
16219               (const_string "fop")))
16220    (set_attr "mode" "SF")])
16221
16222 (define_insn "*fop_xf_6_i387"
16223   [(set (match_operand:XF 0 "register_operand" "=f,f")
16224         (match_operator:XF 3 "binary_fp_operator"
16225           [(float_extend:XF
16226              (match_operand:MODEF 1 "register_operand" "0,f"))
16227            (float_extend:XF
16228              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16229   "TARGET_80387"
16230   "* return output_387_binary_op (insn, operands);"
16231   [(set (attr "type")
16232         (cond [(match_operand:XF 3 "mult_operator" "")
16233                  (const_string "fmul")
16234                (match_operand:XF 3 "div_operator" "")
16235                  (const_string "fdiv")
16236               ]
16237               (const_string "fop")))
16238    (set_attr "mode" "SF")])
16239
16240 (define_split
16241   [(set (match_operand 0 "register_operand" "")
16242         (match_operator 3 "binary_fp_operator"
16243            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16244             (match_operand 2 "register_operand" "")]))]
16245   "reload_completed
16246    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16247   [(const_int 0)]
16248 {
16249   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16250   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16251   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16252                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16253                                           GET_MODE (operands[3]),
16254                                           operands[4],
16255                                           operands[2])));
16256   ix86_free_from_memory (GET_MODE (operands[1]));
16257   DONE;
16258 })
16259
16260 (define_split
16261   [(set (match_operand 0 "register_operand" "")
16262         (match_operator 3 "binary_fp_operator"
16263            [(match_operand 1 "register_operand" "")
16264             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16265   "reload_completed
16266    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16267   [(const_int 0)]
16268 {
16269   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16270   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16271   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16272                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16273                                           GET_MODE (operands[3]),
16274                                           operands[1],
16275                                           operands[4])));
16276   ix86_free_from_memory (GET_MODE (operands[2]));
16277   DONE;
16278 })
16279 \f
16280 ;; FPU special functions.
16281
16282 ;; This pattern implements a no-op XFmode truncation for
16283 ;; all fancy i386 XFmode math functions.
16284
16285 (define_insn "truncxf<mode>2_i387_noop_unspec"
16286   [(set (match_operand:MODEF 0 "register_operand" "=f")
16287         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16288         UNSPEC_TRUNC_NOOP))]
16289   "TARGET_USE_FANCY_MATH_387"
16290   "* return output_387_reg_move (insn, operands);"
16291   [(set_attr "type" "fmov")
16292    (set_attr "mode" "<MODE>")])
16293
16294 (define_insn "sqrtxf2"
16295   [(set (match_operand:XF 0 "register_operand" "=f")
16296         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16297   "TARGET_USE_FANCY_MATH_387"
16298   "fsqrt"
16299   [(set_attr "type" "fpspc")
16300    (set_attr "mode" "XF")
16301    (set_attr "athlon_decode" "direct")
16302    (set_attr "amdfam10_decode" "direct")])
16303
16304 (define_insn "sqrt_extend<mode>xf2_i387"
16305   [(set (match_operand:XF 0 "register_operand" "=f")
16306         (sqrt:XF
16307           (float_extend:XF
16308             (match_operand:MODEF 1 "register_operand" "0"))))]
16309   "TARGET_USE_FANCY_MATH_387"
16310   "fsqrt"
16311   [(set_attr "type" "fpspc")
16312    (set_attr "mode" "XF")
16313    (set_attr "athlon_decode" "direct")
16314    (set_attr "amdfam10_decode" "direct")])
16315
16316 (define_insn "*rsqrtsf2_sse"
16317   [(set (match_operand:SF 0 "register_operand" "=x")
16318         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16319                    UNSPEC_RSQRT))]
16320   "TARGET_SSE_MATH"
16321   "rsqrtss\t{%1, %0|%0, %1}"
16322   [(set_attr "type" "sse")
16323    (set_attr "mode" "SF")])
16324
16325 (define_expand "rsqrtsf2"
16326   [(set (match_operand:SF 0 "register_operand" "")
16327         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16328                    UNSPEC_RSQRT))]
16329   "TARGET_SSE_MATH"
16330 {
16331   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16332   DONE;
16333 })
16334
16335 (define_insn "*sqrt<mode>2_sse"
16336   [(set (match_operand:MODEF 0 "register_operand" "=x")
16337         (sqrt:MODEF
16338           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16339   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16340   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16341   [(set_attr "type" "sse")
16342    (set_attr "mode" "<MODE>")
16343    (set_attr "athlon_decode" "*")
16344    (set_attr "amdfam10_decode" "*")])
16345
16346 (define_expand "sqrt<mode>2"
16347   [(set (match_operand:MODEF 0 "register_operand" "")
16348         (sqrt:MODEF
16349           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16350   "TARGET_USE_FANCY_MATH_387
16351    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16352 {
16353   if (<MODE>mode == SFmode
16354       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16355       && flag_finite_math_only && !flag_trapping_math
16356       && flag_unsafe_math_optimizations)
16357     {
16358       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16359       DONE;
16360     }
16361
16362   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16363     {
16364       rtx op0 = gen_reg_rtx (XFmode);
16365       rtx op1 = force_reg (<MODE>mode, operands[1]);
16366
16367       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16368       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16369       DONE;
16370    }
16371 })
16372
16373 (define_insn "fpremxf4_i387"
16374   [(set (match_operand:XF 0 "register_operand" "=f")
16375         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16376                     (match_operand:XF 3 "register_operand" "1")]
16377                    UNSPEC_FPREM_F))
16378    (set (match_operand:XF 1 "register_operand" "=u")
16379         (unspec:XF [(match_dup 2) (match_dup 3)]
16380                    UNSPEC_FPREM_U))
16381    (set (reg:CCFP FPSR_REG)
16382         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16383                      UNSPEC_C2_FLAG))]
16384   "TARGET_USE_FANCY_MATH_387"
16385   "fprem"
16386   [(set_attr "type" "fpspc")
16387    (set_attr "mode" "XF")])
16388
16389 (define_expand "fmodxf3"
16390   [(use (match_operand:XF 0 "register_operand" ""))
16391    (use (match_operand:XF 1 "register_operand" ""))
16392    (use (match_operand:XF 2 "register_operand" ""))]
16393   "TARGET_USE_FANCY_MATH_387"
16394 {
16395   rtx label = gen_label_rtx ();
16396
16397   rtx op2;
16398
16399   if (rtx_equal_p (operands[1], operands[2]))
16400     {
16401       op2 = gen_reg_rtx (XFmode);
16402       emit_move_insn (op2, operands[2]);
16403     }
16404   else
16405     op2 = operands[2];
16406
16407   emit_label (label);
16408   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16409   ix86_emit_fp_unordered_jump (label);
16410   LABEL_NUSES (label) = 1;
16411
16412   emit_move_insn (operands[0], operands[1]);
16413   DONE;
16414 })
16415
16416 (define_expand "fmod<mode>3"
16417   [(use (match_operand:MODEF 0 "register_operand" ""))
16418    (use (match_operand:MODEF 1 "general_operand" ""))
16419    (use (match_operand:MODEF 2 "general_operand" ""))]
16420   "TARGET_USE_FANCY_MATH_387"
16421 {
16422   rtx label = gen_label_rtx ();
16423
16424   rtx op1 = gen_reg_rtx (XFmode);
16425   rtx op2 = gen_reg_rtx (XFmode);
16426
16427   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16428   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16429
16430   emit_label (label);
16431   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16432   ix86_emit_fp_unordered_jump (label);
16433   LABEL_NUSES (label) = 1;
16434
16435   /* Truncate the result properly for strict SSE math.  */
16436   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16437       && !TARGET_MIX_SSE_I387)
16438     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16439   else
16440     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16441
16442   DONE;
16443 })
16444
16445 (define_insn "fprem1xf4_i387"
16446   [(set (match_operand:XF 0 "register_operand" "=f")
16447         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16448                     (match_operand:XF 3 "register_operand" "1")]
16449                    UNSPEC_FPREM1_F))
16450    (set (match_operand:XF 1 "register_operand" "=u")
16451         (unspec:XF [(match_dup 2) (match_dup 3)]
16452                    UNSPEC_FPREM1_U))
16453    (set (reg:CCFP FPSR_REG)
16454         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16455                      UNSPEC_C2_FLAG))]
16456   "TARGET_USE_FANCY_MATH_387"
16457   "fprem1"
16458   [(set_attr "type" "fpspc")
16459    (set_attr "mode" "XF")])
16460
16461 (define_expand "remainderxf3"
16462   [(use (match_operand:XF 0 "register_operand" ""))
16463    (use (match_operand:XF 1 "register_operand" ""))
16464    (use (match_operand:XF 2 "register_operand" ""))]
16465   "TARGET_USE_FANCY_MATH_387"
16466 {
16467   rtx label = gen_label_rtx ();
16468
16469   rtx op2;
16470
16471   if (rtx_equal_p (operands[1], operands[2]))
16472     {
16473       op2 = gen_reg_rtx (XFmode);
16474       emit_move_insn (op2, operands[2]);
16475     }
16476   else
16477     op2 = operands[2];
16478
16479   emit_label (label);
16480   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16481   ix86_emit_fp_unordered_jump (label);
16482   LABEL_NUSES (label) = 1;
16483
16484   emit_move_insn (operands[0], operands[1]);
16485   DONE;
16486 })
16487
16488 (define_expand "remainder<mode>3"
16489   [(use (match_operand:MODEF 0 "register_operand" ""))
16490    (use (match_operand:MODEF 1 "general_operand" ""))
16491    (use (match_operand:MODEF 2 "general_operand" ""))]
16492   "TARGET_USE_FANCY_MATH_387"
16493 {
16494   rtx label = gen_label_rtx ();
16495
16496   rtx op1 = gen_reg_rtx (XFmode);
16497   rtx op2 = gen_reg_rtx (XFmode);
16498
16499   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16500   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16501
16502   emit_label (label);
16503
16504   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16505   ix86_emit_fp_unordered_jump (label);
16506   LABEL_NUSES (label) = 1;
16507
16508   /* Truncate the result properly for strict SSE math.  */
16509   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16510       && !TARGET_MIX_SSE_I387)
16511     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16512   else
16513     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16514
16515   DONE;
16516 })
16517
16518 (define_insn "*sinxf2_i387"
16519   [(set (match_operand:XF 0 "register_operand" "=f")
16520         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16521   "TARGET_USE_FANCY_MATH_387
16522    && flag_unsafe_math_optimizations"
16523   "fsin"
16524   [(set_attr "type" "fpspc")
16525    (set_attr "mode" "XF")])
16526
16527 (define_insn "*sin_extend<mode>xf2_i387"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (unspec:XF [(float_extend:XF
16530                       (match_operand:MODEF 1 "register_operand" "0"))]
16531                    UNSPEC_SIN))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16534        || TARGET_MIX_SSE_I387)
16535    && flag_unsafe_math_optimizations"
16536   "fsin"
16537   [(set_attr "type" "fpspc")
16538    (set_attr "mode" "XF")])
16539
16540 (define_insn "*cosxf2_i387"
16541   [(set (match_operand:XF 0 "register_operand" "=f")
16542         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16543   "TARGET_USE_FANCY_MATH_387
16544    && flag_unsafe_math_optimizations"
16545   "fcos"
16546   [(set_attr "type" "fpspc")
16547    (set_attr "mode" "XF")])
16548
16549 (define_insn "*cos_extend<mode>xf2_i387"
16550   [(set (match_operand:XF 0 "register_operand" "=f")
16551         (unspec:XF [(float_extend:XF
16552                       (match_operand:MODEF 1 "register_operand" "0"))]
16553                    UNSPEC_COS))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16556        || TARGET_MIX_SSE_I387)
16557    && flag_unsafe_math_optimizations"
16558   "fcos"
16559   [(set_attr "type" "fpspc")
16560    (set_attr "mode" "XF")])
16561
16562 ;; When sincos pattern is defined, sin and cos builtin functions will be
16563 ;; expanded to sincos pattern with one of its outputs left unused.
16564 ;; CSE pass will figure out if two sincos patterns can be combined,
16565 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16566 ;; depending on the unused output.
16567
16568 (define_insn "sincosxf3"
16569   [(set (match_operand:XF 0 "register_operand" "=f")
16570         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16571                    UNSPEC_SINCOS_COS))
16572    (set (match_operand:XF 1 "register_operand" "=u")
16573         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16574   "TARGET_USE_FANCY_MATH_387
16575    && flag_unsafe_math_optimizations"
16576   "fsincos"
16577   [(set_attr "type" "fpspc")
16578    (set_attr "mode" "XF")])
16579
16580 (define_split
16581   [(set (match_operand:XF 0 "register_operand" "")
16582         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16583                    UNSPEC_SINCOS_COS))
16584    (set (match_operand:XF 1 "register_operand" "")
16585         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16586   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16587    && !(reload_completed || reload_in_progress)"
16588   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16589   "")
16590
16591 (define_split
16592   [(set (match_operand:XF 0 "register_operand" "")
16593         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16594                    UNSPEC_SINCOS_COS))
16595    (set (match_operand:XF 1 "register_operand" "")
16596         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16597   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16598    && !(reload_completed || reload_in_progress)"
16599   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16600   "")
16601
16602 (define_insn "sincos_extend<mode>xf3_i387"
16603   [(set (match_operand:XF 0 "register_operand" "=f")
16604         (unspec:XF [(float_extend:XF
16605                       (match_operand:MODEF 2 "register_operand" "0"))]
16606                    UNSPEC_SINCOS_COS))
16607    (set (match_operand:XF 1 "register_operand" "=u")
16608         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16611        || TARGET_MIX_SSE_I387)
16612    && flag_unsafe_math_optimizations"
16613   "fsincos"
16614   [(set_attr "type" "fpspc")
16615    (set_attr "mode" "XF")])
16616
16617 (define_split
16618   [(set (match_operand:XF 0 "register_operand" "")
16619         (unspec:XF [(float_extend:XF
16620                       (match_operand:MODEF 2 "register_operand" ""))]
16621                    UNSPEC_SINCOS_COS))
16622    (set (match_operand:XF 1 "register_operand" "")
16623         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16624   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16625    && !(reload_completed || reload_in_progress)"
16626   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16627   "")
16628
16629 (define_split
16630   [(set (match_operand:XF 0 "register_operand" "")
16631         (unspec:XF [(float_extend:XF
16632                       (match_operand:MODEF 2 "register_operand" ""))]
16633                    UNSPEC_SINCOS_COS))
16634    (set (match_operand:XF 1 "register_operand" "")
16635         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16636   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16637    && !(reload_completed || reload_in_progress)"
16638   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16639   "")
16640
16641 (define_expand "sincos<mode>3"
16642   [(use (match_operand:MODEF 0 "register_operand" ""))
16643    (use (match_operand:MODEF 1 "register_operand" ""))
16644    (use (match_operand:MODEF 2 "register_operand" ""))]
16645   "TARGET_USE_FANCY_MATH_387
16646    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16647        || TARGET_MIX_SSE_I387)
16648    && flag_unsafe_math_optimizations"
16649 {
16650   rtx op0 = gen_reg_rtx (XFmode);
16651   rtx op1 = gen_reg_rtx (XFmode);
16652
16653   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16654   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16655   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16656   DONE;
16657 })
16658
16659 (define_insn "fptanxf4_i387"
16660   [(set (match_operand:XF 0 "register_operand" "=f")
16661         (match_operand:XF 3 "const_double_operand" "F"))
16662    (set (match_operand:XF 1 "register_operand" "=u")
16663         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16664                    UNSPEC_TAN))]
16665   "TARGET_USE_FANCY_MATH_387
16666    && flag_unsafe_math_optimizations
16667    && standard_80387_constant_p (operands[3]) == 2"
16668   "fptan"
16669   [(set_attr "type" "fpspc")
16670    (set_attr "mode" "XF")])
16671
16672 (define_insn "fptan_extend<mode>xf4_i387"
16673   [(set (match_operand:MODEF 0 "register_operand" "=f")
16674         (match_operand:MODEF 3 "const_double_operand" "F"))
16675    (set (match_operand:XF 1 "register_operand" "=u")
16676         (unspec:XF [(float_extend:XF
16677                       (match_operand:MODEF 2 "register_operand" "0"))]
16678                    UNSPEC_TAN))]
16679   "TARGET_USE_FANCY_MATH_387
16680    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16681        || TARGET_MIX_SSE_I387)
16682    && flag_unsafe_math_optimizations
16683    && standard_80387_constant_p (operands[3]) == 2"
16684   "fptan"
16685   [(set_attr "type" "fpspc")
16686    (set_attr "mode" "XF")])
16687
16688 (define_expand "tanxf2"
16689   [(use (match_operand:XF 0 "register_operand" ""))
16690    (use (match_operand:XF 1 "register_operand" ""))]
16691   "TARGET_USE_FANCY_MATH_387
16692    && flag_unsafe_math_optimizations"
16693 {
16694   rtx one = gen_reg_rtx (XFmode);
16695   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16696
16697   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16698   DONE;
16699 })
16700
16701 (define_expand "tan<mode>2"
16702   [(use (match_operand:MODEF 0 "register_operand" ""))
16703    (use (match_operand:MODEF 1 "register_operand" ""))]
16704   "TARGET_USE_FANCY_MATH_387
16705    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16706        || TARGET_MIX_SSE_I387)
16707    && flag_unsafe_math_optimizations"
16708 {
16709   rtx op0 = gen_reg_rtx (XFmode);
16710
16711   rtx one = gen_reg_rtx (<MODE>mode);
16712   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16713
16714   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16715                                              operands[1], op2));
16716   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16717   DONE;
16718 })
16719
16720 (define_insn "*fpatanxf3_i387"
16721   [(set (match_operand:XF 0 "register_operand" "=f")
16722         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16723                     (match_operand:XF 2 "register_operand" "u")]
16724                    UNSPEC_FPATAN))
16725    (clobber (match_scratch:XF 3 "=2"))]
16726   "TARGET_USE_FANCY_MATH_387
16727    && flag_unsafe_math_optimizations"
16728   "fpatan"
16729   [(set_attr "type" "fpspc")
16730    (set_attr "mode" "XF")])
16731
16732 (define_insn "fpatan_extend<mode>xf3_i387"
16733   [(set (match_operand:XF 0 "register_operand" "=f")
16734         (unspec:XF [(float_extend:XF
16735                       (match_operand:MODEF 1 "register_operand" "0"))
16736                     (float_extend:XF
16737                       (match_operand:MODEF 2 "register_operand" "u"))]
16738                    UNSPEC_FPATAN))
16739    (clobber (match_scratch:XF 3 "=2"))]
16740   "TARGET_USE_FANCY_MATH_387
16741    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16742        || TARGET_MIX_SSE_I387)
16743    && flag_unsafe_math_optimizations"
16744   "fpatan"
16745   [(set_attr "type" "fpspc")
16746    (set_attr "mode" "XF")])
16747
16748 (define_expand "atan2xf3"
16749   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16750                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16751                                (match_operand:XF 1 "register_operand" "")]
16752                               UNSPEC_FPATAN))
16753               (clobber (match_scratch:XF 3 ""))])]
16754   "TARGET_USE_FANCY_MATH_387
16755    && flag_unsafe_math_optimizations"
16756   "")
16757
16758 (define_expand "atan2<mode>3"
16759   [(use (match_operand:MODEF 0 "register_operand" ""))
16760    (use (match_operand:MODEF 1 "register_operand" ""))
16761    (use (match_operand:MODEF 2 "register_operand" ""))]
16762   "TARGET_USE_FANCY_MATH_387
16763    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16764        || TARGET_MIX_SSE_I387)
16765    && flag_unsafe_math_optimizations"
16766 {
16767   rtx op0 = gen_reg_rtx (XFmode);
16768
16769   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16770   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16771   DONE;
16772 })
16773
16774 (define_expand "atanxf2"
16775   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16776                    (unspec:XF [(match_dup 2)
16777                                (match_operand:XF 1 "register_operand" "")]
16778                               UNSPEC_FPATAN))
16779               (clobber (match_scratch:XF 3 ""))])]
16780   "TARGET_USE_FANCY_MATH_387
16781    && flag_unsafe_math_optimizations"
16782 {
16783   operands[2] = gen_reg_rtx (XFmode);
16784   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16785 })
16786
16787 (define_expand "atan<mode>2"
16788   [(use (match_operand:MODEF 0 "register_operand" ""))
16789    (use (match_operand:MODEF 1 "register_operand" ""))]
16790   "TARGET_USE_FANCY_MATH_387
16791    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16792        || TARGET_MIX_SSE_I387)
16793    && flag_unsafe_math_optimizations"
16794 {
16795   rtx op0 = gen_reg_rtx (XFmode);
16796
16797   rtx op2 = gen_reg_rtx (<MODE>mode);
16798   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16799
16800   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16801   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16802   DONE;
16803 })
16804
16805 (define_expand "asinxf2"
16806   [(set (match_dup 2)
16807         (mult:XF (match_operand:XF 1 "register_operand" "")
16808                  (match_dup 1)))
16809    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16810    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16811    (parallel [(set (match_operand:XF 0 "register_operand" "")
16812                    (unspec:XF [(match_dup 5) (match_dup 1)]
16813                               UNSPEC_FPATAN))
16814               (clobber (match_scratch:XF 6 ""))])]
16815   "TARGET_USE_FANCY_MATH_387
16816    && flag_unsafe_math_optimizations && !optimize_size"
16817 {
16818   int i;
16819
16820   for (i = 2; i < 6; i++)
16821     operands[i] = gen_reg_rtx (XFmode);
16822
16823   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16824 })
16825
16826 (define_expand "asin<mode>2"
16827   [(use (match_operand:MODEF 0 "register_operand" ""))
16828    (use (match_operand:MODEF 1 "general_operand" ""))]
16829  "TARGET_USE_FANCY_MATH_387
16830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831        || TARGET_MIX_SSE_I387)
16832    && flag_unsafe_math_optimizations && !optimize_size"
16833 {
16834   rtx op0 = gen_reg_rtx (XFmode);
16835   rtx op1 = gen_reg_rtx (XFmode);
16836
16837   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16838   emit_insn (gen_asinxf2 (op0, op1));
16839   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16840   DONE;
16841 })
16842
16843 (define_expand "acosxf2"
16844   [(set (match_dup 2)
16845         (mult:XF (match_operand:XF 1 "register_operand" "")
16846                  (match_dup 1)))
16847    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16848    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16849    (parallel [(set (match_operand:XF 0 "register_operand" "")
16850                    (unspec:XF [(match_dup 1) (match_dup 5)]
16851                               UNSPEC_FPATAN))
16852               (clobber (match_scratch:XF 6 ""))])]
16853   "TARGET_USE_FANCY_MATH_387
16854    && flag_unsafe_math_optimizations && !optimize_size"
16855 {
16856   int i;
16857
16858   for (i = 2; i < 6; i++)
16859     operands[i] = gen_reg_rtx (XFmode);
16860
16861   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16862 })
16863
16864 (define_expand "acos<mode>2"
16865   [(use (match_operand:MODEF 0 "register_operand" ""))
16866    (use (match_operand:MODEF 1 "general_operand" ""))]
16867  "TARGET_USE_FANCY_MATH_387
16868    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16869        || TARGET_MIX_SSE_I387)
16870    && flag_unsafe_math_optimizations && !optimize_size"
16871 {
16872   rtx op0 = gen_reg_rtx (XFmode);
16873   rtx op1 = gen_reg_rtx (XFmode);
16874
16875   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16876   emit_insn (gen_acosxf2 (op0, op1));
16877   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16878   DONE;
16879 })
16880
16881 (define_insn "fyl2xxf3_i387"
16882   [(set (match_operand:XF 0 "register_operand" "=f")
16883         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16884                     (match_operand:XF 2 "register_operand" "u")]
16885                    UNSPEC_FYL2X))
16886    (clobber (match_scratch:XF 3 "=2"))]
16887   "TARGET_USE_FANCY_MATH_387
16888    && flag_unsafe_math_optimizations"
16889   "fyl2x"
16890   [(set_attr "type" "fpspc")
16891    (set_attr "mode" "XF")])
16892
16893 (define_insn "fyl2x_extend<mode>xf3_i387"
16894   [(set (match_operand:XF 0 "register_operand" "=f")
16895         (unspec:XF [(float_extend:XF
16896                       (match_operand:MODEF 1 "register_operand" "0"))
16897                     (match_operand:XF 2 "register_operand" "u")]
16898                    UNSPEC_FYL2X))
16899    (clobber (match_scratch:XF 3 "=2"))]
16900   "TARGET_USE_FANCY_MATH_387
16901    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16902        || TARGET_MIX_SSE_I387)
16903    && flag_unsafe_math_optimizations"
16904   "fyl2x"
16905   [(set_attr "type" "fpspc")
16906    (set_attr "mode" "XF")])
16907
16908 (define_expand "logxf2"
16909   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16910                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16911                                (match_dup 2)] UNSPEC_FYL2X))
16912               (clobber (match_scratch:XF 3 ""))])]
16913   "TARGET_USE_FANCY_MATH_387
16914    && flag_unsafe_math_optimizations"
16915 {
16916   operands[2] = gen_reg_rtx (XFmode);
16917   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16918 })
16919
16920 (define_expand "log<mode>2"
16921   [(use (match_operand:MODEF 0 "register_operand" ""))
16922    (use (match_operand:MODEF 1 "register_operand" ""))]
16923   "TARGET_USE_FANCY_MATH_387
16924    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925        || TARGET_MIX_SSE_I387)
16926    && flag_unsafe_math_optimizations"
16927 {
16928   rtx op0 = gen_reg_rtx (XFmode);
16929
16930   rtx op2 = gen_reg_rtx (XFmode);
16931   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16932
16933   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16934   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16935   DONE;
16936 })
16937
16938 (define_expand "log10xf2"
16939   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16940                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16941                                (match_dup 2)] UNSPEC_FYL2X))
16942               (clobber (match_scratch:XF 3 ""))])]
16943   "TARGET_USE_FANCY_MATH_387
16944    && flag_unsafe_math_optimizations"
16945 {
16946   operands[2] = gen_reg_rtx (XFmode);
16947   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16948 })
16949
16950 (define_expand "log10<mode>2"
16951   [(use (match_operand:MODEF 0 "register_operand" ""))
16952    (use (match_operand:MODEF 1 "register_operand" ""))]
16953   "TARGET_USE_FANCY_MATH_387
16954    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16955        || TARGET_MIX_SSE_I387)
16956    && flag_unsafe_math_optimizations"
16957 {
16958   rtx op0 = gen_reg_rtx (XFmode);
16959
16960   rtx op2 = gen_reg_rtx (XFmode);
16961   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16962
16963   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16964   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16965   DONE;
16966 })
16967
16968 (define_expand "log2xf2"
16969   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16970                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16971                                (match_dup 2)] UNSPEC_FYL2X))
16972               (clobber (match_scratch:XF 3 ""))])]
16973   "TARGET_USE_FANCY_MATH_387
16974    && flag_unsafe_math_optimizations"
16975 {
16976   operands[2] = gen_reg_rtx (XFmode);
16977   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16978 })
16979
16980 (define_expand "log2<mode>2"
16981   [(use (match_operand:MODEF 0 "register_operand" ""))
16982    (use (match_operand:MODEF 1 "register_operand" ""))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16985        || TARGET_MIX_SSE_I387)
16986    && flag_unsafe_math_optimizations"
16987 {
16988   rtx op0 = gen_reg_rtx (XFmode);
16989
16990   rtx op2 = gen_reg_rtx (XFmode);
16991   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16992
16993   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16994   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16995   DONE;
16996 })
16997
16998 (define_insn "fyl2xp1xf3_i387"
16999   [(set (match_operand:XF 0 "register_operand" "=f")
17000         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17001                     (match_operand:XF 2 "register_operand" "u")]
17002                    UNSPEC_FYL2XP1))
17003    (clobber (match_scratch:XF 3 "=2"))]
17004   "TARGET_USE_FANCY_MATH_387
17005    && flag_unsafe_math_optimizations"
17006   "fyl2xp1"
17007   [(set_attr "type" "fpspc")
17008    (set_attr "mode" "XF")])
17009
17010 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17011   [(set (match_operand:XF 0 "register_operand" "=f")
17012         (unspec:XF [(float_extend:XF
17013                       (match_operand:MODEF 1 "register_operand" "0"))
17014                     (match_operand:XF 2 "register_operand" "u")]
17015                    UNSPEC_FYL2XP1))
17016    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2xp1"
17022   [(set_attr "type" "fpspc")
17023    (set_attr "mode" "XF")])
17024
17025 (define_expand "log1pxf2"
17026   [(use (match_operand:XF 0 "register_operand" ""))
17027    (use (match_operand:XF 1 "register_operand" ""))]
17028   "TARGET_USE_FANCY_MATH_387
17029    && flag_unsafe_math_optimizations && !optimize_size"
17030 {
17031   ix86_emit_i387_log1p (operands[0], operands[1]);
17032   DONE;
17033 })
17034
17035 (define_expand "log1p<mode>2"
17036   [(use (match_operand:MODEF 0 "register_operand" ""))
17037    (use (match_operand:MODEF 1 "register_operand" ""))]
17038   "TARGET_USE_FANCY_MATH_387
17039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17040        || TARGET_MIX_SSE_I387)
17041    && flag_unsafe_math_optimizations && !optimize_size"
17042 {
17043   rtx op0 = gen_reg_rtx (XFmode);
17044
17045   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17046
17047   ix86_emit_i387_log1p (op0, operands[1]);
17048   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17049   DONE;
17050 })
17051
17052 (define_insn "fxtractxf3_i387"
17053   [(set (match_operand:XF 0 "register_operand" "=f")
17054         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17055                    UNSPEC_XTRACT_FRACT))
17056    (set (match_operand:XF 1 "register_operand" "=u")
17057         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17058   "TARGET_USE_FANCY_MATH_387
17059    && flag_unsafe_math_optimizations"
17060   "fxtract"
17061   [(set_attr "type" "fpspc")
17062    (set_attr "mode" "XF")])
17063
17064 (define_insn "fxtract_extend<mode>xf3_i387"
17065   [(set (match_operand:XF 0 "register_operand" "=f")
17066         (unspec:XF [(float_extend:XF
17067                       (match_operand:MODEF 2 "register_operand" "0"))]
17068                    UNSPEC_XTRACT_FRACT))
17069    (set (match_operand:XF 1 "register_operand" "=u")
17070         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17073        || TARGET_MIX_SSE_I387)
17074    && flag_unsafe_math_optimizations"
17075   "fxtract"
17076   [(set_attr "type" "fpspc")
17077    (set_attr "mode" "XF")])
17078
17079 (define_expand "logbxf2"
17080   [(parallel [(set (match_dup 2)
17081                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17082                               UNSPEC_XTRACT_FRACT))
17083               (set (match_operand:XF 0 "register_operand" "")
17084                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17085   "TARGET_USE_FANCY_MATH_387
17086    && flag_unsafe_math_optimizations"
17087 {
17088   operands[2] = gen_reg_rtx (XFmode);
17089 })
17090
17091 (define_expand "logb<mode>2"
17092   [(use (match_operand:MODEF 0 "register_operand" ""))
17093    (use (match_operand:MODEF 1 "register_operand" ""))]
17094   "TARGET_USE_FANCY_MATH_387
17095    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17096        || TARGET_MIX_SSE_I387)
17097    && flag_unsafe_math_optimizations"
17098 {
17099   rtx op0 = gen_reg_rtx (XFmode);
17100   rtx op1 = gen_reg_rtx (XFmode);
17101
17102   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17103   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17104   DONE;
17105 })
17106
17107 (define_expand "ilogbxf2"
17108   [(use (match_operand:SI 0 "register_operand" ""))
17109    (use (match_operand:XF 1 "register_operand" ""))]
17110   "TARGET_USE_FANCY_MATH_387
17111    && flag_unsafe_math_optimizations && !optimize_size"
17112 {
17113   rtx op0 = gen_reg_rtx (XFmode);
17114   rtx op1 = gen_reg_rtx (XFmode);
17115
17116   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17117   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17118   DONE;
17119 })
17120
17121 (define_expand "ilogb<mode>2"
17122   [(use (match_operand:SI 0 "register_operand" ""))
17123    (use (match_operand:MODEF 1 "register_operand" ""))]
17124   "TARGET_USE_FANCY_MATH_387
17125    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17126        || TARGET_MIX_SSE_I387)
17127    && flag_unsafe_math_optimizations && !optimize_size"
17128 {
17129   rtx op0 = gen_reg_rtx (XFmode);
17130   rtx op1 = gen_reg_rtx (XFmode);
17131
17132   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17133   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17134   DONE;
17135 })
17136
17137 (define_insn "*f2xm1xf2_i387"
17138   [(set (match_operand:XF 0 "register_operand" "=f")
17139         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17140                    UNSPEC_F2XM1))]
17141   "TARGET_USE_FANCY_MATH_387
17142    && flag_unsafe_math_optimizations"
17143   "f2xm1"
17144   [(set_attr "type" "fpspc")
17145    (set_attr "mode" "XF")])
17146
17147 (define_insn "*fscalexf4_i387"
17148   [(set (match_operand:XF 0 "register_operand" "=f")
17149         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17150                     (match_operand:XF 3 "register_operand" "1")]
17151                    UNSPEC_FSCALE_FRACT))
17152    (set (match_operand:XF 1 "register_operand" "=u")
17153         (unspec:XF [(match_dup 2) (match_dup 3)]
17154                    UNSPEC_FSCALE_EXP))]
17155   "TARGET_USE_FANCY_MATH_387
17156    && flag_unsafe_math_optimizations"
17157   "fscale"
17158   [(set_attr "type" "fpspc")
17159    (set_attr "mode" "XF")])
17160
17161 (define_expand "expNcorexf3"
17162   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17163                                (match_operand:XF 2 "register_operand" "")))
17164    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17165    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17166    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17167    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17168    (parallel [(set (match_operand:XF 0 "register_operand" "")
17169                    (unspec:XF [(match_dup 8) (match_dup 4)]
17170                               UNSPEC_FSCALE_FRACT))
17171               (set (match_dup 9)
17172                    (unspec:XF [(match_dup 8) (match_dup 4)]
17173                               UNSPEC_FSCALE_EXP))])]
17174   "TARGET_USE_FANCY_MATH_387
17175    && flag_unsafe_math_optimizations && !optimize_size"
17176 {
17177   int i;
17178
17179   for (i = 3; i < 10; i++)
17180     operands[i] = gen_reg_rtx (XFmode);
17181
17182   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17183 })
17184
17185 (define_expand "expxf2"
17186   [(use (match_operand:XF 0 "register_operand" ""))
17187    (use (match_operand:XF 1 "register_operand" ""))]
17188   "TARGET_USE_FANCY_MATH_387
17189    && flag_unsafe_math_optimizations && !optimize_size"
17190 {
17191   rtx op2 = gen_reg_rtx (XFmode);
17192   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17193
17194   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17195   DONE;
17196 })
17197
17198 (define_expand "exp<mode>2"
17199   [(use (match_operand:MODEF 0 "register_operand" ""))
17200    (use (match_operand:MODEF 1 "general_operand" ""))]
17201  "TARGET_USE_FANCY_MATH_387
17202    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17203        || TARGET_MIX_SSE_I387)
17204    && flag_unsafe_math_optimizations && !optimize_size"
17205 {
17206   rtx op0 = gen_reg_rtx (XFmode);
17207   rtx op1 = gen_reg_rtx (XFmode);
17208
17209   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17210   emit_insn (gen_expxf2 (op0, op1));
17211   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17212   DONE;
17213 })
17214
17215 (define_expand "exp10xf2"
17216   [(use (match_operand:XF 0 "register_operand" ""))
17217    (use (match_operand:XF 1 "register_operand" ""))]
17218   "TARGET_USE_FANCY_MATH_387
17219    && flag_unsafe_math_optimizations && !optimize_size"
17220 {
17221   rtx op2 = gen_reg_rtx (XFmode);
17222   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17223
17224   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17225   DONE;
17226 })
17227
17228 (define_expand "exp10<mode>2"
17229   [(use (match_operand:MODEF 0 "register_operand" ""))
17230    (use (match_operand:MODEF 1 "general_operand" ""))]
17231  "TARGET_USE_FANCY_MATH_387
17232    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17233        || TARGET_MIX_SSE_I387)
17234    && flag_unsafe_math_optimizations && !optimize_size"
17235 {
17236   rtx op0 = gen_reg_rtx (XFmode);
17237   rtx op1 = gen_reg_rtx (XFmode);
17238
17239   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17240   emit_insn (gen_exp10xf2 (op0, op1));
17241   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17242   DONE;
17243 })
17244
17245 (define_expand "exp2xf2"
17246   [(use (match_operand:XF 0 "register_operand" ""))
17247    (use (match_operand:XF 1 "register_operand" ""))]
17248   "TARGET_USE_FANCY_MATH_387
17249    && flag_unsafe_math_optimizations && !optimize_size"
17250 {
17251   rtx op2 = gen_reg_rtx (XFmode);
17252   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17253
17254   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17255   DONE;
17256 })
17257
17258 (define_expand "exp2<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_exp2xf2 (op0, op1));
17271   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17272   DONE;
17273 })
17274
17275 (define_expand "expm1xf2"
17276   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17277                                (match_dup 2)))
17278    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17279    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17280    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17281    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17282    (parallel [(set (match_dup 7)
17283                    (unspec:XF [(match_dup 6) (match_dup 4)]
17284                               UNSPEC_FSCALE_FRACT))
17285               (set (match_dup 8)
17286                    (unspec:XF [(match_dup 6) (match_dup 4)]
17287                               UNSPEC_FSCALE_EXP))])
17288    (parallel [(set (match_dup 10)
17289                    (unspec:XF [(match_dup 9) (match_dup 8)]
17290                               UNSPEC_FSCALE_FRACT))
17291               (set (match_dup 11)
17292                    (unspec:XF [(match_dup 9) (match_dup 8)]
17293                               UNSPEC_FSCALE_EXP))])
17294    (set (match_dup 12) (minus:XF (match_dup 10)
17295                                  (float_extend:XF (match_dup 13))))
17296    (set (match_operand:XF 0 "register_operand" "")
17297         (plus:XF (match_dup 12) (match_dup 7)))]
17298   "TARGET_USE_FANCY_MATH_387
17299    && flag_unsafe_math_optimizations && !optimize_size"
17300 {
17301   int i;
17302
17303   for (i = 2; i < 13; i++)
17304     operands[i] = gen_reg_rtx (XFmode);
17305
17306   operands[13]
17307     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17308
17309   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17310 })
17311
17312 (define_expand "expm1<mode>2"
17313   [(use (match_operand:MODEF 0 "register_operand" ""))
17314    (use (match_operand:MODEF 1 "general_operand" ""))]
17315  "TARGET_USE_FANCY_MATH_387
17316    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17317        || TARGET_MIX_SSE_I387)
17318    && flag_unsafe_math_optimizations && !optimize_size"
17319 {
17320   rtx op0 = gen_reg_rtx (XFmode);
17321   rtx op1 = gen_reg_rtx (XFmode);
17322
17323   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17324   emit_insn (gen_expm1xf2 (op0, op1));
17325   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17326   DONE;
17327 })
17328
17329 (define_expand "ldexpxf3"
17330   [(set (match_dup 3)
17331         (float:XF (match_operand:SI 2 "register_operand" "")))
17332    (parallel [(set (match_operand:XF 0 " register_operand" "")
17333                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17334                                (match_dup 3)]
17335                               UNSPEC_FSCALE_FRACT))
17336               (set (match_dup 4)
17337                    (unspec:XF [(match_dup 1) (match_dup 3)]
17338                               UNSPEC_FSCALE_EXP))])]
17339   "TARGET_USE_FANCY_MATH_387
17340    && flag_unsafe_math_optimizations && !optimize_size"
17341 {
17342   operands[3] = gen_reg_rtx (XFmode);
17343   operands[4] = gen_reg_rtx (XFmode);
17344 })
17345
17346 (define_expand "ldexp<mode>3"
17347   [(use (match_operand:MODEF 0 "register_operand" ""))
17348    (use (match_operand:MODEF 1 "general_operand" ""))
17349    (use (match_operand:SI 2 "register_operand" ""))]
17350  "TARGET_USE_FANCY_MATH_387
17351    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17352        || TARGET_MIX_SSE_I387)
17353    && flag_unsafe_math_optimizations && !optimize_size"
17354 {
17355   rtx op0 = gen_reg_rtx (XFmode);
17356   rtx op1 = gen_reg_rtx (XFmode);
17357
17358   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17359   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17360   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17361   DONE;
17362 })
17363
17364 (define_expand "scalbxf3"
17365   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17366                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17367                                (match_operand:XF 2 "register_operand" "")]
17368                               UNSPEC_FSCALE_FRACT))
17369               (set (match_dup 3)
17370                    (unspec:XF [(match_dup 1) (match_dup 2)]
17371                               UNSPEC_FSCALE_EXP))])]
17372   "TARGET_USE_FANCY_MATH_387
17373    && flag_unsafe_math_optimizations && !optimize_size"
17374 {
17375   operands[3] = gen_reg_rtx (XFmode);
17376 })
17377
17378 (define_expand "scalb<mode>3"
17379   [(use (match_operand:MODEF 0 "register_operand" ""))
17380    (use (match_operand:MODEF 1 "general_operand" ""))
17381    (use (match_operand:MODEF 2 "register_operand" ""))]
17382  "TARGET_USE_FANCY_MATH_387
17383    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17384        || TARGET_MIX_SSE_I387)
17385    && flag_unsafe_math_optimizations && !optimize_size"
17386 {
17387   rtx op0 = gen_reg_rtx (XFmode);
17388   rtx op1 = gen_reg_rtx (XFmode);
17389   rtx op2 = gen_reg_rtx (XFmode);
17390
17391   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17392   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17393   emit_insn (gen_scalbxf3 (op0, op1, op2));
17394   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17395   DONE;
17396 })
17397 \f
17398
17399 (define_insn "sse4_1_round<mode>2"
17400   [(set (match_operand:MODEF 0 "register_operand" "=x")
17401         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17402                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17403                       UNSPEC_ROUND))]
17404   "TARGET_ROUND"
17405   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17406   [(set_attr "type" "ssecvt")
17407    (set_attr "prefix_extra" "1")
17408    (set_attr "mode" "<MODE>")])
17409
17410 (define_insn "rintxf2"
17411   [(set (match_operand:XF 0 "register_operand" "=f")
17412         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17413                    UNSPEC_FRNDINT))]
17414   "TARGET_USE_FANCY_MATH_387
17415    && flag_unsafe_math_optimizations"
17416   "frndint"
17417   [(set_attr "type" "fpspc")
17418    (set_attr "mode" "XF")])
17419
17420 (define_expand "rint<mode>2"
17421   [(use (match_operand:MODEF 0 "register_operand" ""))
17422    (use (match_operand:MODEF 1 "register_operand" ""))]
17423   "(TARGET_USE_FANCY_MATH_387
17424     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17425         || TARGET_MIX_SSE_I387)
17426     && flag_unsafe_math_optimizations)
17427    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17428        && !flag_trapping_math
17429        && (TARGET_ROUND || !optimize_size))"
17430 {
17431   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17432       && !flag_trapping_math
17433       && (TARGET_ROUND || !optimize_size))
17434     {
17435       if (TARGET_ROUND)
17436         emit_insn (gen_sse4_1_round<mode>2
17437                    (operands[0], operands[1], GEN_INT (0x04)));
17438       else
17439         ix86_expand_rint (operand0, operand1);
17440     }
17441   else
17442     {
17443       rtx op0 = gen_reg_rtx (XFmode);
17444       rtx op1 = gen_reg_rtx (XFmode);
17445
17446       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17447       emit_insn (gen_rintxf2 (op0, op1));
17448
17449       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17450     }
17451   DONE;
17452 })
17453
17454 (define_expand "round<mode>2"
17455   [(match_operand:MODEF 0 "register_operand" "")
17456    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17457   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17458    && !flag_trapping_math && !flag_rounding_math
17459    && !optimize_size"
17460 {
17461   if (TARGET_64BIT || (<MODE>mode != DFmode))
17462     ix86_expand_round (operand0, operand1);
17463   else
17464     ix86_expand_rounddf_32 (operand0, operand1);
17465   DONE;
17466 })
17467
17468 (define_insn_and_split "*fistdi2_1"
17469   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17470         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17471                    UNSPEC_FIST))]
17472   "TARGET_USE_FANCY_MATH_387
17473    && !(reload_completed || reload_in_progress)"
17474   "#"
17475   "&& 1"
17476   [(const_int 0)]
17477 {
17478   if (memory_operand (operands[0], VOIDmode))
17479     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17480   else
17481     {
17482       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17483       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17484                                          operands[2]));
17485     }
17486   DONE;
17487 }
17488   [(set_attr "type" "fpspc")
17489    (set_attr "mode" "DI")])
17490
17491 (define_insn "fistdi2"
17492   [(set (match_operand:DI 0 "memory_operand" "=m")
17493         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17494                    UNSPEC_FIST))
17495    (clobber (match_scratch:XF 2 "=&1f"))]
17496   "TARGET_USE_FANCY_MATH_387"
17497   "* return output_fix_trunc (insn, operands, 0);"
17498   [(set_attr "type" "fpspc")
17499    (set_attr "mode" "DI")])
17500
17501 (define_insn "fistdi2_with_temp"
17502   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17503         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17504                    UNSPEC_FIST))
17505    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17506    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17507   "TARGET_USE_FANCY_MATH_387"
17508   "#"
17509   [(set_attr "type" "fpspc")
17510    (set_attr "mode" "DI")])
17511
17512 (define_split
17513   [(set (match_operand:DI 0 "register_operand" "")
17514         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17515                    UNSPEC_FIST))
17516    (clobber (match_operand:DI 2 "memory_operand" ""))
17517    (clobber (match_scratch 3 ""))]
17518   "reload_completed"
17519   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17520               (clobber (match_dup 3))])
17521    (set (match_dup 0) (match_dup 2))]
17522   "")
17523
17524 (define_split
17525   [(set (match_operand:DI 0 "memory_operand" "")
17526         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17527                    UNSPEC_FIST))
17528    (clobber (match_operand:DI 2 "memory_operand" ""))
17529    (clobber (match_scratch 3 ""))]
17530   "reload_completed"
17531   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17532               (clobber (match_dup 3))])]
17533   "")
17534
17535 (define_insn_and_split "*fist<mode>2_1"
17536   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17537         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17538                            UNSPEC_FIST))]
17539   "TARGET_USE_FANCY_MATH_387
17540    && !(reload_completed || reload_in_progress)"
17541   "#"
17542   "&& 1"
17543   [(const_int 0)]
17544 {
17545   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17546   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17547                                         operands[2]));
17548   DONE;
17549 }
17550   [(set_attr "type" "fpspc")
17551    (set_attr "mode" "<MODE>")])
17552
17553 (define_insn "fist<mode>2"
17554   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17555         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17556                            UNSPEC_FIST))]
17557   "TARGET_USE_FANCY_MATH_387"
17558   "* return output_fix_trunc (insn, operands, 0);"
17559   [(set_attr "type" "fpspc")
17560    (set_attr "mode" "<MODE>")])
17561
17562 (define_insn "fist<mode>2_with_temp"
17563   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17564         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17565                            UNSPEC_FIST))
17566    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17567   "TARGET_USE_FANCY_MATH_387"
17568   "#"
17569   [(set_attr "type" "fpspc")
17570    (set_attr "mode" "<MODE>")])
17571
17572 (define_split
17573   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17574         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17575                            UNSPEC_FIST))
17576    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17577   "reload_completed"
17578   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17579    (set (match_dup 0) (match_dup 2))]
17580   "")
17581
17582 (define_split
17583   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17584         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17585                            UNSPEC_FIST))
17586    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17587   "reload_completed"
17588   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17589   "")
17590
17591 (define_expand "lrintxf<mode>2"
17592   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17593      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17594                       UNSPEC_FIST))]
17595   "TARGET_USE_FANCY_MATH_387"
17596   "")
17597
17598 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17599   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17600      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17601                         UNSPEC_FIX_NOTRUNC))]
17602   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17603    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17604   "")
17605
17606 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17607   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17608    (match_operand:MODEF 1 "register_operand" "")]
17609   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17610    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17611    && !flag_trapping_math && !flag_rounding_math
17612    && !optimize_size"
17613 {
17614   ix86_expand_lround (operand0, operand1);
17615   DONE;
17616 })
17617
17618 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17619 (define_insn_and_split "frndintxf2_floor"
17620   [(set (match_operand:XF 0 "register_operand" "")
17621         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17622          UNSPEC_FRNDINT_FLOOR))
17623    (clobber (reg:CC FLAGS_REG))]
17624   "TARGET_USE_FANCY_MATH_387
17625    && flag_unsafe_math_optimizations
17626    && !(reload_completed || reload_in_progress)"
17627   "#"
17628   "&& 1"
17629   [(const_int 0)]
17630 {
17631   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17632
17633   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17634   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17635
17636   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17637                                         operands[2], operands[3]));
17638   DONE;
17639 }
17640   [(set_attr "type" "frndint")
17641    (set_attr "i387_cw" "floor")
17642    (set_attr "mode" "XF")])
17643
17644 (define_insn "frndintxf2_floor_i387"
17645   [(set (match_operand:XF 0 "register_operand" "=f")
17646         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17647          UNSPEC_FRNDINT_FLOOR))
17648    (use (match_operand:HI 2 "memory_operand" "m"))
17649    (use (match_operand:HI 3 "memory_operand" "m"))]
17650   "TARGET_USE_FANCY_MATH_387
17651    && flag_unsafe_math_optimizations"
17652   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17653   [(set_attr "type" "frndint")
17654    (set_attr "i387_cw" "floor")
17655    (set_attr "mode" "XF")])
17656
17657 (define_expand "floorxf2"
17658   [(use (match_operand:XF 0 "register_operand" ""))
17659    (use (match_operand:XF 1 "register_operand" ""))]
17660   "TARGET_USE_FANCY_MATH_387
17661    && flag_unsafe_math_optimizations && !optimize_size"
17662 {
17663   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17664   DONE;
17665 })
17666
17667 (define_expand "floor<mode>2"
17668   [(use (match_operand:MODEF 0 "register_operand" ""))
17669    (use (match_operand:MODEF 1 "register_operand" ""))]
17670   "(TARGET_USE_FANCY_MATH_387
17671     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17672         || TARGET_MIX_SSE_I387)
17673     && flag_unsafe_math_optimizations && !optimize_size)
17674    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17675        && !flag_trapping_math
17676        && (TARGET_ROUND || !optimize_size))"
17677 {
17678   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17679       && !flag_trapping_math
17680       && (TARGET_ROUND || !optimize_size))
17681     {
17682       if (TARGET_ROUND)
17683         emit_insn (gen_sse4_1_round<mode>2
17684                    (operands[0], operands[1], GEN_INT (0x01)));
17685       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17686         ix86_expand_floorceil (operand0, operand1, true);
17687       else
17688         ix86_expand_floorceildf_32 (operand0, operand1, true);
17689     }
17690   else
17691     {
17692       rtx op0 = gen_reg_rtx (XFmode);
17693       rtx op1 = gen_reg_rtx (XFmode);
17694
17695       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17696       emit_insn (gen_frndintxf2_floor (op0, op1));
17697
17698       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17699     }
17700   DONE;
17701 })
17702
17703 (define_insn_and_split "*fist<mode>2_floor_1"
17704   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17705         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17706          UNSPEC_FIST_FLOOR))
17707    (clobber (reg:CC FLAGS_REG))]
17708   "TARGET_USE_FANCY_MATH_387
17709    && flag_unsafe_math_optimizations
17710    && !(reload_completed || reload_in_progress)"
17711   "#"
17712   "&& 1"
17713   [(const_int 0)]
17714 {
17715   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17716
17717   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17718   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17719   if (memory_operand (operands[0], VOIDmode))
17720     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17721                                       operands[2], operands[3]));
17722   else
17723     {
17724       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17725       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17726                                                   operands[2], operands[3],
17727                                                   operands[4]));
17728     }
17729   DONE;
17730 }
17731   [(set_attr "type" "fistp")
17732    (set_attr "i387_cw" "floor")
17733    (set_attr "mode" "<MODE>")])
17734
17735 (define_insn "fistdi2_floor"
17736   [(set (match_operand:DI 0 "memory_operand" "=m")
17737         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17738          UNSPEC_FIST_FLOOR))
17739    (use (match_operand:HI 2 "memory_operand" "m"))
17740    (use (match_operand:HI 3 "memory_operand" "m"))
17741    (clobber (match_scratch:XF 4 "=&1f"))]
17742   "TARGET_USE_FANCY_MATH_387
17743    && flag_unsafe_math_optimizations"
17744   "* return output_fix_trunc (insn, operands, 0);"
17745   [(set_attr "type" "fistp")
17746    (set_attr "i387_cw" "floor")
17747    (set_attr "mode" "DI")])
17748
17749 (define_insn "fistdi2_floor_with_temp"
17750   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17751         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17752          UNSPEC_FIST_FLOOR))
17753    (use (match_operand:HI 2 "memory_operand" "m,m"))
17754    (use (match_operand:HI 3 "memory_operand" "m,m"))
17755    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17756    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17757   "TARGET_USE_FANCY_MATH_387
17758    && flag_unsafe_math_optimizations"
17759   "#"
17760   [(set_attr "type" "fistp")
17761    (set_attr "i387_cw" "floor")
17762    (set_attr "mode" "DI")])
17763
17764 (define_split
17765   [(set (match_operand:DI 0 "register_operand" "")
17766         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17767          UNSPEC_FIST_FLOOR))
17768    (use (match_operand:HI 2 "memory_operand" ""))
17769    (use (match_operand:HI 3 "memory_operand" ""))
17770    (clobber (match_operand:DI 4 "memory_operand" ""))
17771    (clobber (match_scratch 5 ""))]
17772   "reload_completed"
17773   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17774               (use (match_dup 2))
17775               (use (match_dup 3))
17776               (clobber (match_dup 5))])
17777    (set (match_dup 0) (match_dup 4))]
17778   "")
17779
17780 (define_split
17781   [(set (match_operand:DI 0 "memory_operand" "")
17782         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17783          UNSPEC_FIST_FLOOR))
17784    (use (match_operand:HI 2 "memory_operand" ""))
17785    (use (match_operand:HI 3 "memory_operand" ""))
17786    (clobber (match_operand:DI 4 "memory_operand" ""))
17787    (clobber (match_scratch 5 ""))]
17788   "reload_completed"
17789   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17790               (use (match_dup 2))
17791               (use (match_dup 3))
17792               (clobber (match_dup 5))])]
17793   "")
17794
17795 (define_insn "fist<mode>2_floor"
17796   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17797         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17798          UNSPEC_FIST_FLOOR))
17799    (use (match_operand:HI 2 "memory_operand" "m"))
17800    (use (match_operand:HI 3 "memory_operand" "m"))]
17801   "TARGET_USE_FANCY_MATH_387
17802    && flag_unsafe_math_optimizations"
17803   "* return output_fix_trunc (insn, operands, 0);"
17804   [(set_attr "type" "fistp")
17805    (set_attr "i387_cw" "floor")
17806    (set_attr "mode" "<MODE>")])
17807
17808 (define_insn "fist<mode>2_floor_with_temp"
17809   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17810         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17811          UNSPEC_FIST_FLOOR))
17812    (use (match_operand:HI 2 "memory_operand" "m,m"))
17813    (use (match_operand:HI 3 "memory_operand" "m,m"))
17814    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17815   "TARGET_USE_FANCY_MATH_387
17816    && flag_unsafe_math_optimizations"
17817   "#"
17818   [(set_attr "type" "fistp")
17819    (set_attr "i387_cw" "floor")
17820    (set_attr "mode" "<MODE>")])
17821
17822 (define_split
17823   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17824         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17825          UNSPEC_FIST_FLOOR))
17826    (use (match_operand:HI 2 "memory_operand" ""))
17827    (use (match_operand:HI 3 "memory_operand" ""))
17828    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17829   "reload_completed"
17830   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17831                                   UNSPEC_FIST_FLOOR))
17832               (use (match_dup 2))
17833               (use (match_dup 3))])
17834    (set (match_dup 0) (match_dup 4))]
17835   "")
17836
17837 (define_split
17838   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17839         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17840          UNSPEC_FIST_FLOOR))
17841    (use (match_operand:HI 2 "memory_operand" ""))
17842    (use (match_operand:HI 3 "memory_operand" ""))
17843    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17844   "reload_completed"
17845   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17846                                   UNSPEC_FIST_FLOOR))
17847               (use (match_dup 2))
17848               (use (match_dup 3))])]
17849   "")
17850
17851 (define_expand "lfloorxf<mode>2"
17852   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17853                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17854                     UNSPEC_FIST_FLOOR))
17855               (clobber (reg:CC FLAGS_REG))])]
17856   "TARGET_USE_FANCY_MATH_387
17857    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17858    && flag_unsafe_math_optimizations"
17859   "")
17860
17861 (define_expand "lfloor<mode>di2"
17862   [(match_operand:DI 0 "nonimmediate_operand" "")
17863    (match_operand:MODEF 1 "register_operand" "")]
17864   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17865    && !flag_trapping_math
17866    && !optimize_size"
17867 {
17868   ix86_expand_lfloorceil (operand0, operand1, true);
17869   DONE;
17870 })
17871
17872 (define_expand "lfloor<mode>si2"
17873   [(match_operand:SI 0 "nonimmediate_operand" "")
17874    (match_operand:MODEF 1 "register_operand" "")]
17875   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17876    && !flag_trapping_math
17877    && (!optimize_size || !TARGET_64BIT)"
17878 {
17879   ix86_expand_lfloorceil (operand0, operand1, true);
17880   DONE;
17881 })
17882
17883 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17884 (define_insn_and_split "frndintxf2_ceil"
17885   [(set (match_operand:XF 0 "register_operand" "")
17886         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17887          UNSPEC_FRNDINT_CEIL))
17888    (clobber (reg:CC FLAGS_REG))]
17889   "TARGET_USE_FANCY_MATH_387
17890    && flag_unsafe_math_optimizations
17891    && !(reload_completed || reload_in_progress)"
17892   "#"
17893   "&& 1"
17894   [(const_int 0)]
17895 {
17896   ix86_optimize_mode_switching[I387_CEIL] = 1;
17897
17898   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17899   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17900
17901   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17902                                        operands[2], operands[3]));
17903   DONE;
17904 }
17905   [(set_attr "type" "frndint")
17906    (set_attr "i387_cw" "ceil")
17907    (set_attr "mode" "XF")])
17908
17909 (define_insn "frndintxf2_ceil_i387"
17910   [(set (match_operand:XF 0 "register_operand" "=f")
17911         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912          UNSPEC_FRNDINT_CEIL))
17913    (use (match_operand:HI 2 "memory_operand" "m"))
17914    (use (match_operand:HI 3 "memory_operand" "m"))]
17915   "TARGET_USE_FANCY_MATH_387
17916    && flag_unsafe_math_optimizations"
17917   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17918   [(set_attr "type" "frndint")
17919    (set_attr "i387_cw" "ceil")
17920    (set_attr "mode" "XF")])
17921
17922 (define_expand "ceilxf2"
17923   [(use (match_operand:XF 0 "register_operand" ""))
17924    (use (match_operand:XF 1 "register_operand" ""))]
17925   "TARGET_USE_FANCY_MATH_387
17926    && flag_unsafe_math_optimizations && !optimize_size"
17927 {
17928   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17929   DONE;
17930 })
17931
17932 (define_expand "ceil<mode>2"
17933   [(use (match_operand:MODEF 0 "register_operand" ""))
17934    (use (match_operand:MODEF 1 "register_operand" ""))]
17935   "(TARGET_USE_FANCY_MATH_387
17936     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17937         || TARGET_MIX_SSE_I387)
17938     && flag_unsafe_math_optimizations && !optimize_size)
17939    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17940        && !flag_trapping_math
17941        && (TARGET_ROUND || !optimize_size))"
17942 {
17943   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17944       && !flag_trapping_math
17945       && (TARGET_ROUND || !optimize_size))
17946     {
17947       if (TARGET_ROUND)
17948         emit_insn (gen_sse4_1_round<mode>2
17949                    (operands[0], operands[1], GEN_INT (0x02)));
17950       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17951         ix86_expand_floorceil (operand0, operand1, false);
17952       else
17953         ix86_expand_floorceildf_32 (operand0, operand1, false);
17954     }
17955   else
17956     {
17957       rtx op0 = gen_reg_rtx (XFmode);
17958       rtx op1 = gen_reg_rtx (XFmode);
17959
17960       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17961       emit_insn (gen_frndintxf2_ceil (op0, op1));
17962
17963       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17964     }
17965   DONE;
17966 })
17967
17968 (define_insn_and_split "*fist<mode>2_ceil_1"
17969   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17970         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17971          UNSPEC_FIST_CEIL))
17972    (clobber (reg:CC FLAGS_REG))]
17973   "TARGET_USE_FANCY_MATH_387
17974    && flag_unsafe_math_optimizations
17975    && !(reload_completed || reload_in_progress)"
17976   "#"
17977   "&& 1"
17978   [(const_int 0)]
17979 {
17980   ix86_optimize_mode_switching[I387_CEIL] = 1;
17981
17982   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17983   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17984   if (memory_operand (operands[0], VOIDmode))
17985     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17986                                      operands[2], operands[3]));
17987   else
17988     {
17989       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17990       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17991                                                  operands[2], operands[3],
17992                                                  operands[4]));
17993     }
17994   DONE;
17995 }
17996   [(set_attr "type" "fistp")
17997    (set_attr "i387_cw" "ceil")
17998    (set_attr "mode" "<MODE>")])
17999
18000 (define_insn "fistdi2_ceil"
18001   [(set (match_operand:DI 0 "memory_operand" "=m")
18002         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18003          UNSPEC_FIST_CEIL))
18004    (use (match_operand:HI 2 "memory_operand" "m"))
18005    (use (match_operand:HI 3 "memory_operand" "m"))
18006    (clobber (match_scratch:XF 4 "=&1f"))]
18007   "TARGET_USE_FANCY_MATH_387
18008    && flag_unsafe_math_optimizations"
18009   "* return output_fix_trunc (insn, operands, 0);"
18010   [(set_attr "type" "fistp")
18011    (set_attr "i387_cw" "ceil")
18012    (set_attr "mode" "DI")])
18013
18014 (define_insn "fistdi2_ceil_with_temp"
18015   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18016         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18017          UNSPEC_FIST_CEIL))
18018    (use (match_operand:HI 2 "memory_operand" "m,m"))
18019    (use (match_operand:HI 3 "memory_operand" "m,m"))
18020    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18021    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18022   "TARGET_USE_FANCY_MATH_387
18023    && flag_unsafe_math_optimizations"
18024   "#"
18025   [(set_attr "type" "fistp")
18026    (set_attr "i387_cw" "ceil")
18027    (set_attr "mode" "DI")])
18028
18029 (define_split
18030   [(set (match_operand:DI 0 "register_operand" "")
18031         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18032          UNSPEC_FIST_CEIL))
18033    (use (match_operand:HI 2 "memory_operand" ""))
18034    (use (match_operand:HI 3 "memory_operand" ""))
18035    (clobber (match_operand:DI 4 "memory_operand" ""))
18036    (clobber (match_scratch 5 ""))]
18037   "reload_completed"
18038   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18039               (use (match_dup 2))
18040               (use (match_dup 3))
18041               (clobber (match_dup 5))])
18042    (set (match_dup 0) (match_dup 4))]
18043   "")
18044
18045 (define_split
18046   [(set (match_operand:DI 0 "memory_operand" "")
18047         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18048          UNSPEC_FIST_CEIL))
18049    (use (match_operand:HI 2 "memory_operand" ""))
18050    (use (match_operand:HI 3 "memory_operand" ""))
18051    (clobber (match_operand:DI 4 "memory_operand" ""))
18052    (clobber (match_scratch 5 ""))]
18053   "reload_completed"
18054   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18055               (use (match_dup 2))
18056               (use (match_dup 3))
18057               (clobber (match_dup 5))])]
18058   "")
18059
18060 (define_insn "fist<mode>2_ceil"
18061   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18062         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18063          UNSPEC_FIST_CEIL))
18064    (use (match_operand:HI 2 "memory_operand" "m"))
18065    (use (match_operand:HI 3 "memory_operand" "m"))]
18066   "TARGET_USE_FANCY_MATH_387
18067    && flag_unsafe_math_optimizations"
18068   "* return output_fix_trunc (insn, operands, 0);"
18069   [(set_attr "type" "fistp")
18070    (set_attr "i387_cw" "ceil")
18071    (set_attr "mode" "<MODE>")])
18072
18073 (define_insn "fist<mode>2_ceil_with_temp"
18074   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18075         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18076          UNSPEC_FIST_CEIL))
18077    (use (match_operand:HI 2 "memory_operand" "m,m"))
18078    (use (match_operand:HI 3 "memory_operand" "m,m"))
18079    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18080   "TARGET_USE_FANCY_MATH_387
18081    && flag_unsafe_math_optimizations"
18082   "#"
18083   [(set_attr "type" "fistp")
18084    (set_attr "i387_cw" "ceil")
18085    (set_attr "mode" "<MODE>")])
18086
18087 (define_split
18088   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18089         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18090          UNSPEC_FIST_CEIL))
18091    (use (match_operand:HI 2 "memory_operand" ""))
18092    (use (match_operand:HI 3 "memory_operand" ""))
18093    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18094   "reload_completed"
18095   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18096                                   UNSPEC_FIST_CEIL))
18097               (use (match_dup 2))
18098               (use (match_dup 3))])
18099    (set (match_dup 0) (match_dup 4))]
18100   "")
18101
18102 (define_split
18103   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18104         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18105          UNSPEC_FIST_CEIL))
18106    (use (match_operand:HI 2 "memory_operand" ""))
18107    (use (match_operand:HI 3 "memory_operand" ""))
18108    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18109   "reload_completed"
18110   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18111                                   UNSPEC_FIST_CEIL))
18112               (use (match_dup 2))
18113               (use (match_dup 3))])]
18114   "")
18115
18116 (define_expand "lceilxf<mode>2"
18117   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18118                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18119                     UNSPEC_FIST_CEIL))
18120               (clobber (reg:CC FLAGS_REG))])]
18121   "TARGET_USE_FANCY_MATH_387
18122    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18123    && flag_unsafe_math_optimizations"
18124   "")
18125
18126 (define_expand "lceil<mode>di2"
18127   [(match_operand:DI 0 "nonimmediate_operand" "")
18128    (match_operand:MODEF 1 "register_operand" "")]
18129   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18130    && !flag_trapping_math"
18131 {
18132   ix86_expand_lfloorceil (operand0, operand1, false);
18133   DONE;
18134 })
18135
18136 (define_expand "lceil<mode>si2"
18137   [(match_operand:SI 0 "nonimmediate_operand" "")
18138    (match_operand:MODEF 1 "register_operand" "")]
18139   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18140    && !flag_trapping_math"
18141 {
18142   ix86_expand_lfloorceil (operand0, operand1, false);
18143   DONE;
18144 })
18145
18146 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18147 (define_insn_and_split "frndintxf2_trunc"
18148   [(set (match_operand:XF 0 "register_operand" "")
18149         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18150          UNSPEC_FRNDINT_TRUNC))
18151    (clobber (reg:CC FLAGS_REG))]
18152   "TARGET_USE_FANCY_MATH_387
18153    && flag_unsafe_math_optimizations
18154    && !(reload_completed || reload_in_progress)"
18155   "#"
18156   "&& 1"
18157   [(const_int 0)]
18158 {
18159   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18160
18161   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18162   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18163
18164   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18165                                         operands[2], operands[3]));
18166   DONE;
18167 }
18168   [(set_attr "type" "frndint")
18169    (set_attr "i387_cw" "trunc")
18170    (set_attr "mode" "XF")])
18171
18172 (define_insn "frndintxf2_trunc_i387"
18173   [(set (match_operand:XF 0 "register_operand" "=f")
18174         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18175          UNSPEC_FRNDINT_TRUNC))
18176    (use (match_operand:HI 2 "memory_operand" "m"))
18177    (use (match_operand:HI 3 "memory_operand" "m"))]
18178   "TARGET_USE_FANCY_MATH_387
18179    && flag_unsafe_math_optimizations"
18180   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18181   [(set_attr "type" "frndint")
18182    (set_attr "i387_cw" "trunc")
18183    (set_attr "mode" "XF")])
18184
18185 (define_expand "btruncxf2"
18186   [(use (match_operand:XF 0 "register_operand" ""))
18187    (use (match_operand:XF 1 "register_operand" ""))]
18188   "TARGET_USE_FANCY_MATH_387
18189    && flag_unsafe_math_optimizations && !optimize_size"
18190 {
18191   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18192   DONE;
18193 })
18194
18195 (define_expand "btrunc<mode>2"
18196   [(use (match_operand:MODEF 0 "register_operand" ""))
18197    (use (match_operand:MODEF 1 "register_operand" ""))]
18198   "(TARGET_USE_FANCY_MATH_387
18199     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18200         || TARGET_MIX_SSE_I387)
18201     && flag_unsafe_math_optimizations && !optimize_size)
18202    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18203        && !flag_trapping_math
18204        && (TARGET_ROUND || !optimize_size))"
18205 {
18206   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18207       && !flag_trapping_math
18208       && (TARGET_ROUND || !optimize_size))
18209     {
18210       if (TARGET_ROUND)
18211         emit_insn (gen_sse4_1_round<mode>2
18212                    (operands[0], operands[1], GEN_INT (0x03)));
18213       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18214         ix86_expand_trunc (operand0, operand1);
18215       else
18216         ix86_expand_truncdf_32 (operand0, operand1);
18217     }
18218   else
18219     {
18220       rtx op0 = gen_reg_rtx (XFmode);
18221       rtx op1 = gen_reg_rtx (XFmode);
18222
18223       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18224       emit_insn (gen_frndintxf2_trunc (op0, op1));
18225
18226       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18227     }
18228   DONE;
18229 })
18230
18231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18232 (define_insn_and_split "frndintxf2_mask_pm"
18233   [(set (match_operand:XF 0 "register_operand" "")
18234         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18235          UNSPEC_FRNDINT_MASK_PM))
18236    (clobber (reg:CC FLAGS_REG))]
18237   "TARGET_USE_FANCY_MATH_387
18238    && flag_unsafe_math_optimizations
18239    && !(reload_completed || reload_in_progress)"
18240   "#"
18241   "&& 1"
18242   [(const_int 0)]
18243 {
18244   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18245
18246   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18247   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18248
18249   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18250                                           operands[2], operands[3]));
18251   DONE;
18252 }
18253   [(set_attr "type" "frndint")
18254    (set_attr "i387_cw" "mask_pm")
18255    (set_attr "mode" "XF")])
18256
18257 (define_insn "frndintxf2_mask_pm_i387"
18258   [(set (match_operand:XF 0 "register_operand" "=f")
18259         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18260          UNSPEC_FRNDINT_MASK_PM))
18261    (use (match_operand:HI 2 "memory_operand" "m"))
18262    (use (match_operand:HI 3 "memory_operand" "m"))]
18263   "TARGET_USE_FANCY_MATH_387
18264    && flag_unsafe_math_optimizations"
18265   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18266   [(set_attr "type" "frndint")
18267    (set_attr "i387_cw" "mask_pm")
18268    (set_attr "mode" "XF")])
18269
18270 (define_expand "nearbyintxf2"
18271   [(use (match_operand:XF 0 "register_operand" ""))
18272    (use (match_operand:XF 1 "register_operand" ""))]
18273   "TARGET_USE_FANCY_MATH_387
18274    && flag_unsafe_math_optimizations"
18275 {
18276   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18277
18278   DONE;
18279 })
18280
18281 (define_expand "nearbyint<mode>2"
18282   [(use (match_operand:MODEF 0 "register_operand" ""))
18283    (use (match_operand:MODEF 1 "register_operand" ""))]
18284   "TARGET_USE_FANCY_MATH_387
18285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18286        || TARGET_MIX_SSE_I387)
18287    && flag_unsafe_math_optimizations"
18288 {
18289   rtx op0 = gen_reg_rtx (XFmode);
18290   rtx op1 = gen_reg_rtx (XFmode);
18291
18292   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18293   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18294
18295   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18296   DONE;
18297 })
18298
18299 (define_insn "fxam<mode>2_i387"
18300   [(set (match_operand:HI 0 "register_operand" "=a")
18301         (unspec:HI
18302           [(match_operand:X87MODEF 1 "register_operand" "f")]
18303           UNSPEC_FXAM))]
18304   "TARGET_USE_FANCY_MATH_387"
18305   "fxam\n\tfnstsw\t%0"
18306   [(set_attr "type" "multi")
18307    (set_attr "unit" "i387")
18308    (set_attr "mode" "<MODE>")])
18309
18310 (define_expand "isinf<mode>2"
18311   [(use (match_operand:SI 0 "register_operand" ""))
18312    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18313   "TARGET_USE_FANCY_MATH_387
18314    && TARGET_C99_FUNCTIONS
18315    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18316 {
18317   rtx mask = GEN_INT (0x45);
18318   rtx val = GEN_INT (0x05);
18319
18320   rtx cond;
18321
18322   rtx scratch = gen_reg_rtx (HImode);
18323   rtx res = gen_reg_rtx (QImode);
18324
18325   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18326   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18327   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18328   cond = gen_rtx_fmt_ee (EQ, QImode,
18329                          gen_rtx_REG (CCmode, FLAGS_REG),
18330                          const0_rtx);
18331   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18332   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18333   DONE;
18334 })
18335
18336 (define_expand "signbit<mode>2"
18337   [(use (match_operand:SI 0 "register_operand" ""))
18338    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18339   "TARGET_USE_FANCY_MATH_387
18340    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18341 {
18342   rtx mask = GEN_INT (0x0200);
18343
18344   rtx scratch = gen_reg_rtx (HImode);
18345
18346   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18347   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18348   DONE;
18349 })
18350 \f
18351 ;; Block operation instructions
18352
18353 (define_expand "movmemsi"
18354   [(use (match_operand:BLK 0 "memory_operand" ""))
18355    (use (match_operand:BLK 1 "memory_operand" ""))
18356    (use (match_operand:SI 2 "nonmemory_operand" ""))
18357    (use (match_operand:SI 3 "const_int_operand" ""))
18358    (use (match_operand:SI 4 "const_int_operand" ""))
18359    (use (match_operand:SI 5 "const_int_operand" ""))]
18360   ""
18361 {
18362  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18363                          operands[4], operands[5]))
18364    DONE;
18365  else
18366    FAIL;
18367 })
18368
18369 (define_expand "movmemdi"
18370   [(use (match_operand:BLK 0 "memory_operand" ""))
18371    (use (match_operand:BLK 1 "memory_operand" ""))
18372    (use (match_operand:DI 2 "nonmemory_operand" ""))
18373    (use (match_operand:DI 3 "const_int_operand" ""))
18374    (use (match_operand:SI 4 "const_int_operand" ""))
18375    (use (match_operand:SI 5 "const_int_operand" ""))]
18376   "TARGET_64BIT"
18377 {
18378  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18379                          operands[4], operands[5]))
18380    DONE;
18381  else
18382    FAIL;
18383 })
18384
18385 ;; Most CPUs don't like single string operations
18386 ;; Handle this case here to simplify previous expander.
18387
18388 (define_expand "strmov"
18389   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18390    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18391    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18392               (clobber (reg:CC FLAGS_REG))])
18393    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18394               (clobber (reg:CC FLAGS_REG))])]
18395   ""
18396 {
18397   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18398
18399   /* If .md ever supports :P for Pmode, these can be directly
18400      in the pattern above.  */
18401   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18402   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18403
18404   /* Can't use this if the user has appropriated esi or edi.  */
18405   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18406       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18407     {
18408       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18409                                       operands[2], operands[3],
18410                                       operands[5], operands[6]));
18411       DONE;
18412     }
18413
18414   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18415 })
18416
18417 (define_expand "strmov_singleop"
18418   [(parallel [(set (match_operand 1 "memory_operand" "")
18419                    (match_operand 3 "memory_operand" ""))
18420               (set (match_operand 0 "register_operand" "")
18421                    (match_operand 4 "" ""))
18422               (set (match_operand 2 "register_operand" "")
18423                    (match_operand 5 "" ""))])]
18424   "TARGET_SINGLE_STRINGOP || optimize_size"
18425   "")
18426
18427 (define_insn "*strmovdi_rex_1"
18428   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18429         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18430    (set (match_operand:DI 0 "register_operand" "=D")
18431         (plus:DI (match_dup 2)
18432                  (const_int 8)))
18433    (set (match_operand:DI 1 "register_operand" "=S")
18434         (plus:DI (match_dup 3)
18435                  (const_int 8)))]
18436   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18437   "movsq"
18438   [(set_attr "type" "str")
18439    (set_attr "mode" "DI")
18440    (set_attr "memory" "both")])
18441
18442 (define_insn "*strmovsi_1"
18443   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18444         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18445    (set (match_operand:SI 0 "register_operand" "=D")
18446         (plus:SI (match_dup 2)
18447                  (const_int 4)))
18448    (set (match_operand:SI 1 "register_operand" "=S")
18449         (plus:SI (match_dup 3)
18450                  (const_int 4)))]
18451   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18452   "{movsl|movsd}"
18453   [(set_attr "type" "str")
18454    (set_attr "mode" "SI")
18455    (set_attr "memory" "both")])
18456
18457 (define_insn "*strmovsi_rex_1"
18458   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18459         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18460    (set (match_operand:DI 0 "register_operand" "=D")
18461         (plus:DI (match_dup 2)
18462                  (const_int 4)))
18463    (set (match_operand:DI 1 "register_operand" "=S")
18464         (plus:DI (match_dup 3)
18465                  (const_int 4)))]
18466   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18467   "{movsl|movsd}"
18468   [(set_attr "type" "str")
18469    (set_attr "mode" "SI")
18470    (set_attr "memory" "both")])
18471
18472 (define_insn "*strmovhi_1"
18473   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18474         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18475    (set (match_operand:SI 0 "register_operand" "=D")
18476         (plus:SI (match_dup 2)
18477                  (const_int 2)))
18478    (set (match_operand:SI 1 "register_operand" "=S")
18479         (plus:SI (match_dup 3)
18480                  (const_int 2)))]
18481   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18482   "movsw"
18483   [(set_attr "type" "str")
18484    (set_attr "memory" "both")
18485    (set_attr "mode" "HI")])
18486
18487 (define_insn "*strmovhi_rex_1"
18488   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18489         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18490    (set (match_operand:DI 0 "register_operand" "=D")
18491         (plus:DI (match_dup 2)
18492                  (const_int 2)))
18493    (set (match_operand:DI 1 "register_operand" "=S")
18494         (plus:DI (match_dup 3)
18495                  (const_int 2)))]
18496   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18497   "movsw"
18498   [(set_attr "type" "str")
18499    (set_attr "memory" "both")
18500    (set_attr "mode" "HI")])
18501
18502 (define_insn "*strmovqi_1"
18503   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18504         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18505    (set (match_operand:SI 0 "register_operand" "=D")
18506         (plus:SI (match_dup 2)
18507                  (const_int 1)))
18508    (set (match_operand:SI 1 "register_operand" "=S")
18509         (plus:SI (match_dup 3)
18510                  (const_int 1)))]
18511   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18512   "movsb"
18513   [(set_attr "type" "str")
18514    (set_attr "memory" "both")
18515    (set_attr "mode" "QI")])
18516
18517 (define_insn "*strmovqi_rex_1"
18518   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18519         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18520    (set (match_operand:DI 0 "register_operand" "=D")
18521         (plus:DI (match_dup 2)
18522                  (const_int 1)))
18523    (set (match_operand:DI 1 "register_operand" "=S")
18524         (plus:DI (match_dup 3)
18525                  (const_int 1)))]
18526   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18527   "movsb"
18528   [(set_attr "type" "str")
18529    (set_attr "memory" "both")
18530    (set_attr "mode" "QI")])
18531
18532 (define_expand "rep_mov"
18533   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18534               (set (match_operand 0 "register_operand" "")
18535                    (match_operand 5 "" ""))
18536               (set (match_operand 2 "register_operand" "")
18537                    (match_operand 6 "" ""))
18538               (set (match_operand 1 "memory_operand" "")
18539                    (match_operand 3 "memory_operand" ""))
18540               (use (match_dup 4))])]
18541   ""
18542   "")
18543
18544 (define_insn "*rep_movdi_rex64"
18545   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18546    (set (match_operand:DI 0 "register_operand" "=D")
18547         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18548                             (const_int 3))
18549                  (match_operand:DI 3 "register_operand" "0")))
18550    (set (match_operand:DI 1 "register_operand" "=S")
18551         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18552                  (match_operand:DI 4 "register_operand" "1")))
18553    (set (mem:BLK (match_dup 3))
18554         (mem:BLK (match_dup 4)))
18555    (use (match_dup 5))]
18556   "TARGET_64BIT"
18557   "rep movsq"
18558   [(set_attr "type" "str")
18559    (set_attr "prefix_rep" "1")
18560    (set_attr "memory" "both")
18561    (set_attr "mode" "DI")])
18562
18563 (define_insn "*rep_movsi"
18564   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18565    (set (match_operand:SI 0 "register_operand" "=D")
18566         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18567                             (const_int 2))
18568                  (match_operand:SI 3 "register_operand" "0")))
18569    (set (match_operand:SI 1 "register_operand" "=S")
18570         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18571                  (match_operand:SI 4 "register_operand" "1")))
18572    (set (mem:BLK (match_dup 3))
18573         (mem:BLK (match_dup 4)))
18574    (use (match_dup 5))]
18575   "!TARGET_64BIT"
18576   "rep movs{l|d}"
18577   [(set_attr "type" "str")
18578    (set_attr "prefix_rep" "1")
18579    (set_attr "memory" "both")
18580    (set_attr "mode" "SI")])
18581
18582 (define_insn "*rep_movsi_rex64"
18583   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18584    (set (match_operand:DI 0 "register_operand" "=D")
18585         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18586                             (const_int 2))
18587                  (match_operand:DI 3 "register_operand" "0")))
18588    (set (match_operand:DI 1 "register_operand" "=S")
18589         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18590                  (match_operand:DI 4 "register_operand" "1")))
18591    (set (mem:BLK (match_dup 3))
18592         (mem:BLK (match_dup 4)))
18593    (use (match_dup 5))]
18594   "TARGET_64BIT"
18595   "rep movs{l|d}"
18596   [(set_attr "type" "str")
18597    (set_attr "prefix_rep" "1")
18598    (set_attr "memory" "both")
18599    (set_attr "mode" "SI")])
18600
18601 (define_insn "*rep_movqi"
18602   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18603    (set (match_operand:SI 0 "register_operand" "=D")
18604         (plus:SI (match_operand:SI 3 "register_operand" "0")
18605                  (match_operand:SI 5 "register_operand" "2")))
18606    (set (match_operand:SI 1 "register_operand" "=S")
18607         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18608    (set (mem:BLK (match_dup 3))
18609         (mem:BLK (match_dup 4)))
18610    (use (match_dup 5))]
18611   "!TARGET_64BIT"
18612   "rep movsb"
18613   [(set_attr "type" "str")
18614    (set_attr "prefix_rep" "1")
18615    (set_attr "memory" "both")
18616    (set_attr "mode" "SI")])
18617
18618 (define_insn "*rep_movqi_rex64"
18619   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18620    (set (match_operand:DI 0 "register_operand" "=D")
18621         (plus:DI (match_operand:DI 3 "register_operand" "0")
18622                  (match_operand:DI 5 "register_operand" "2")))
18623    (set (match_operand:DI 1 "register_operand" "=S")
18624         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18625    (set (mem:BLK (match_dup 3))
18626         (mem:BLK (match_dup 4)))
18627    (use (match_dup 5))]
18628   "TARGET_64BIT"
18629   "rep movsb"
18630   [(set_attr "type" "str")
18631    (set_attr "prefix_rep" "1")
18632    (set_attr "memory" "both")
18633    (set_attr "mode" "SI")])
18634
18635 (define_expand "setmemsi"
18636    [(use (match_operand:BLK 0 "memory_operand" ""))
18637     (use (match_operand:SI 1 "nonmemory_operand" ""))
18638     (use (match_operand 2 "const_int_operand" ""))
18639     (use (match_operand 3 "const_int_operand" ""))
18640     (use (match_operand:SI 4 "const_int_operand" ""))
18641     (use (match_operand:SI 5 "const_int_operand" ""))]
18642   ""
18643 {
18644  if (ix86_expand_setmem (operands[0], operands[1],
18645                          operands[2], operands[3],
18646                          operands[4], operands[5]))
18647    DONE;
18648  else
18649    FAIL;
18650 })
18651
18652 (define_expand "setmemdi"
18653    [(use (match_operand:BLK 0 "memory_operand" ""))
18654     (use (match_operand:DI 1 "nonmemory_operand" ""))
18655     (use (match_operand 2 "const_int_operand" ""))
18656     (use (match_operand 3 "const_int_operand" ""))
18657     (use (match_operand 4 "const_int_operand" ""))
18658     (use (match_operand 5 "const_int_operand" ""))]
18659   "TARGET_64BIT"
18660 {
18661  if (ix86_expand_setmem (operands[0], operands[1],
18662                          operands[2], operands[3],
18663                          operands[4], operands[5]))
18664    DONE;
18665  else
18666    FAIL;
18667 })
18668
18669 ;; Most CPUs don't like single string operations
18670 ;; Handle this case here to simplify previous expander.
18671
18672 (define_expand "strset"
18673   [(set (match_operand 1 "memory_operand" "")
18674         (match_operand 2 "register_operand" ""))
18675    (parallel [(set (match_operand 0 "register_operand" "")
18676                    (match_dup 3))
18677               (clobber (reg:CC FLAGS_REG))])]
18678   ""
18679 {
18680   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18681     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18682
18683   /* If .md ever supports :P for Pmode, this can be directly
18684      in the pattern above.  */
18685   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18686                               GEN_INT (GET_MODE_SIZE (GET_MODE
18687                                                       (operands[2]))));
18688   if (TARGET_SINGLE_STRINGOP || optimize_size)
18689     {
18690       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18691                                       operands[3]));
18692       DONE;
18693     }
18694 })
18695
18696 (define_expand "strset_singleop"
18697   [(parallel [(set (match_operand 1 "memory_operand" "")
18698                    (match_operand 2 "register_operand" ""))
18699               (set (match_operand 0 "register_operand" "")
18700                    (match_operand 3 "" ""))])]
18701   "TARGET_SINGLE_STRINGOP || optimize_size"
18702   "")
18703
18704 (define_insn "*strsetdi_rex_1"
18705   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18706         (match_operand:DI 2 "register_operand" "a"))
18707    (set (match_operand:DI 0 "register_operand" "=D")
18708         (plus:DI (match_dup 1)
18709                  (const_int 8)))]
18710   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18711   "stosq"
18712   [(set_attr "type" "str")
18713    (set_attr "memory" "store")
18714    (set_attr "mode" "DI")])
18715
18716 (define_insn "*strsetsi_1"
18717   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18718         (match_operand:SI 2 "register_operand" "a"))
18719    (set (match_operand:SI 0 "register_operand" "=D")
18720         (plus:SI (match_dup 1)
18721                  (const_int 4)))]
18722   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18723   "{stosl|stosd}"
18724   [(set_attr "type" "str")
18725    (set_attr "memory" "store")
18726    (set_attr "mode" "SI")])
18727
18728 (define_insn "*strsetsi_rex_1"
18729   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18730         (match_operand:SI 2 "register_operand" "a"))
18731    (set (match_operand:DI 0 "register_operand" "=D")
18732         (plus:DI (match_dup 1)
18733                  (const_int 4)))]
18734   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18735   "{stosl|stosd}"
18736   [(set_attr "type" "str")
18737    (set_attr "memory" "store")
18738    (set_attr "mode" "SI")])
18739
18740 (define_insn "*strsethi_1"
18741   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18742         (match_operand:HI 2 "register_operand" "a"))
18743    (set (match_operand:SI 0 "register_operand" "=D")
18744         (plus:SI (match_dup 1)
18745                  (const_int 2)))]
18746   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18747   "stosw"
18748   [(set_attr "type" "str")
18749    (set_attr "memory" "store")
18750    (set_attr "mode" "HI")])
18751
18752 (define_insn "*strsethi_rex_1"
18753   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18754         (match_operand:HI 2 "register_operand" "a"))
18755    (set (match_operand:DI 0 "register_operand" "=D")
18756         (plus:DI (match_dup 1)
18757                  (const_int 2)))]
18758   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18759   "stosw"
18760   [(set_attr "type" "str")
18761    (set_attr "memory" "store")
18762    (set_attr "mode" "HI")])
18763
18764 (define_insn "*strsetqi_1"
18765   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18766         (match_operand:QI 2 "register_operand" "a"))
18767    (set (match_operand:SI 0 "register_operand" "=D")
18768         (plus:SI (match_dup 1)
18769                  (const_int 1)))]
18770   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18771   "stosb"
18772   [(set_attr "type" "str")
18773    (set_attr "memory" "store")
18774    (set_attr "mode" "QI")])
18775
18776 (define_insn "*strsetqi_rex_1"
18777   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18778         (match_operand:QI 2 "register_operand" "a"))
18779    (set (match_operand:DI 0 "register_operand" "=D")
18780         (plus:DI (match_dup 1)
18781                  (const_int 1)))]
18782   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18783   "stosb"
18784   [(set_attr "type" "str")
18785    (set_attr "memory" "store")
18786    (set_attr "mode" "QI")])
18787
18788 (define_expand "rep_stos"
18789   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18790               (set (match_operand 0 "register_operand" "")
18791                    (match_operand 4 "" ""))
18792               (set (match_operand 2 "memory_operand" "") (const_int 0))
18793               (use (match_operand 3 "register_operand" ""))
18794               (use (match_dup 1))])]
18795   ""
18796   "")
18797
18798 (define_insn "*rep_stosdi_rex64"
18799   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18800    (set (match_operand:DI 0 "register_operand" "=D")
18801         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18802                             (const_int 3))
18803                  (match_operand:DI 3 "register_operand" "0")))
18804    (set (mem:BLK (match_dup 3))
18805         (const_int 0))
18806    (use (match_operand:DI 2 "register_operand" "a"))
18807    (use (match_dup 4))]
18808   "TARGET_64BIT"
18809   "rep stosq"
18810   [(set_attr "type" "str")
18811    (set_attr "prefix_rep" "1")
18812    (set_attr "memory" "store")
18813    (set_attr "mode" "DI")])
18814
18815 (define_insn "*rep_stossi"
18816   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18817    (set (match_operand:SI 0 "register_operand" "=D")
18818         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18819                             (const_int 2))
18820                  (match_operand:SI 3 "register_operand" "0")))
18821    (set (mem:BLK (match_dup 3))
18822         (const_int 0))
18823    (use (match_operand:SI 2 "register_operand" "a"))
18824    (use (match_dup 4))]
18825   "!TARGET_64BIT"
18826   "rep stos{l|d}"
18827   [(set_attr "type" "str")
18828    (set_attr "prefix_rep" "1")
18829    (set_attr "memory" "store")
18830    (set_attr "mode" "SI")])
18831
18832 (define_insn "*rep_stossi_rex64"
18833   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18834    (set (match_operand:DI 0 "register_operand" "=D")
18835         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18836                             (const_int 2))
18837                  (match_operand:DI 3 "register_operand" "0")))
18838    (set (mem:BLK (match_dup 3))
18839         (const_int 0))
18840    (use (match_operand:SI 2 "register_operand" "a"))
18841    (use (match_dup 4))]
18842   "TARGET_64BIT"
18843   "rep stos{l|d}"
18844   [(set_attr "type" "str")
18845    (set_attr "prefix_rep" "1")
18846    (set_attr "memory" "store")
18847    (set_attr "mode" "SI")])
18848
18849 (define_insn "*rep_stosqi"
18850   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18851    (set (match_operand:SI 0 "register_operand" "=D")
18852         (plus:SI (match_operand:SI 3 "register_operand" "0")
18853                  (match_operand:SI 4 "register_operand" "1")))
18854    (set (mem:BLK (match_dup 3))
18855         (const_int 0))
18856    (use (match_operand:QI 2 "register_operand" "a"))
18857    (use (match_dup 4))]
18858   "!TARGET_64BIT"
18859   "rep stosb"
18860   [(set_attr "type" "str")
18861    (set_attr "prefix_rep" "1")
18862    (set_attr "memory" "store")
18863    (set_attr "mode" "QI")])
18864
18865 (define_insn "*rep_stosqi_rex64"
18866   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18867    (set (match_operand:DI 0 "register_operand" "=D")
18868         (plus:DI (match_operand:DI 3 "register_operand" "0")
18869                  (match_operand:DI 4 "register_operand" "1")))
18870    (set (mem:BLK (match_dup 3))
18871         (const_int 0))
18872    (use (match_operand:QI 2 "register_operand" "a"))
18873    (use (match_dup 4))]
18874   "TARGET_64BIT"
18875   "rep stosb"
18876   [(set_attr "type" "str")
18877    (set_attr "prefix_rep" "1")
18878    (set_attr "memory" "store")
18879    (set_attr "mode" "QI")])
18880
18881 (define_expand "cmpstrnsi"
18882   [(set (match_operand:SI 0 "register_operand" "")
18883         (compare:SI (match_operand:BLK 1 "general_operand" "")
18884                     (match_operand:BLK 2 "general_operand" "")))
18885    (use (match_operand 3 "general_operand" ""))
18886    (use (match_operand 4 "immediate_operand" ""))]
18887   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18888 {
18889   rtx addr1, addr2, out, outlow, count, countreg, align;
18890
18891   /* Can't use this if the user has appropriated esi or edi.  */
18892   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18893     FAIL;
18894
18895   out = operands[0];
18896   if (!REG_P (out))
18897     out = gen_reg_rtx (SImode);
18898
18899   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18900   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18901   if (addr1 != XEXP (operands[1], 0))
18902     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18903   if (addr2 != XEXP (operands[2], 0))
18904     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18905
18906   count = operands[3];
18907   countreg = ix86_zero_extend_to_Pmode (count);
18908
18909   /* %%% Iff we are testing strict equality, we can use known alignment
18910      to good advantage.  This may be possible with combine, particularly
18911      once cc0 is dead.  */
18912   align = operands[4];
18913
18914   if (CONST_INT_P (count))
18915     {
18916       if (INTVAL (count) == 0)
18917         {
18918           emit_move_insn (operands[0], const0_rtx);
18919           DONE;
18920         }
18921       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18922                                      operands[1], operands[2]));
18923     }
18924   else
18925     {
18926       if (TARGET_64BIT)
18927         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18928       else
18929         emit_insn (gen_cmpsi_1 (countreg, countreg));
18930       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18931                                   operands[1], operands[2]));
18932     }
18933
18934   outlow = gen_lowpart (QImode, out);
18935   emit_insn (gen_cmpintqi (outlow));
18936   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18937
18938   if (operands[0] != out)
18939     emit_move_insn (operands[0], out);
18940
18941   DONE;
18942 })
18943
18944 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18945
18946 (define_expand "cmpintqi"
18947   [(set (match_dup 1)
18948         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18949    (set (match_dup 2)
18950         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18951    (parallel [(set (match_operand:QI 0 "register_operand" "")
18952                    (minus:QI (match_dup 1)
18953                              (match_dup 2)))
18954               (clobber (reg:CC FLAGS_REG))])]
18955   ""
18956   "operands[1] = gen_reg_rtx (QImode);
18957    operands[2] = gen_reg_rtx (QImode);")
18958
18959 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18960 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18961
18962 (define_expand "cmpstrnqi_nz_1"
18963   [(parallel [(set (reg:CC FLAGS_REG)
18964                    (compare:CC (match_operand 4 "memory_operand" "")
18965                                (match_operand 5 "memory_operand" "")))
18966               (use (match_operand 2 "register_operand" ""))
18967               (use (match_operand:SI 3 "immediate_operand" ""))
18968               (clobber (match_operand 0 "register_operand" ""))
18969               (clobber (match_operand 1 "register_operand" ""))
18970               (clobber (match_dup 2))])]
18971   ""
18972   "")
18973
18974 (define_insn "*cmpstrnqi_nz_1"
18975   [(set (reg:CC FLAGS_REG)
18976         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18977                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18978    (use (match_operand:SI 6 "register_operand" "2"))
18979    (use (match_operand:SI 3 "immediate_operand" "i"))
18980    (clobber (match_operand:SI 0 "register_operand" "=S"))
18981    (clobber (match_operand:SI 1 "register_operand" "=D"))
18982    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18983   "!TARGET_64BIT"
18984   "repz cmpsb"
18985   [(set_attr "type" "str")
18986    (set_attr "mode" "QI")
18987    (set_attr "prefix_rep" "1")])
18988
18989 (define_insn "*cmpstrnqi_nz_rex_1"
18990   [(set (reg:CC FLAGS_REG)
18991         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18992                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18993    (use (match_operand:DI 6 "register_operand" "2"))
18994    (use (match_operand:SI 3 "immediate_operand" "i"))
18995    (clobber (match_operand:DI 0 "register_operand" "=S"))
18996    (clobber (match_operand:DI 1 "register_operand" "=D"))
18997    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18998   "TARGET_64BIT"
18999   "repz cmpsb"
19000   [(set_attr "type" "str")
19001    (set_attr "mode" "QI")
19002    (set_attr "prefix_rep" "1")])
19003
19004 ;; The same, but the count is not known to not be zero.
19005
19006 (define_expand "cmpstrnqi_1"
19007   [(parallel [(set (reg:CC FLAGS_REG)
19008                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19009                                      (const_int 0))
19010                   (compare:CC (match_operand 4 "memory_operand" "")
19011                               (match_operand 5 "memory_operand" ""))
19012                   (const_int 0)))
19013               (use (match_operand:SI 3 "immediate_operand" ""))
19014               (use (reg:CC FLAGS_REG))
19015               (clobber (match_operand 0 "register_operand" ""))
19016               (clobber (match_operand 1 "register_operand" ""))
19017               (clobber (match_dup 2))])]
19018   ""
19019   "")
19020
19021 (define_insn "*cmpstrnqi_1"
19022   [(set (reg:CC FLAGS_REG)
19023         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19024                              (const_int 0))
19025           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19026                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19027           (const_int 0)))
19028    (use (match_operand:SI 3 "immediate_operand" "i"))
19029    (use (reg:CC FLAGS_REG))
19030    (clobber (match_operand:SI 0 "register_operand" "=S"))
19031    (clobber (match_operand:SI 1 "register_operand" "=D"))
19032    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19033   "!TARGET_64BIT"
19034   "repz cmpsb"
19035   [(set_attr "type" "str")
19036    (set_attr "mode" "QI")
19037    (set_attr "prefix_rep" "1")])
19038
19039 (define_insn "*cmpstrnqi_rex_1"
19040   [(set (reg:CC FLAGS_REG)
19041         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19042                              (const_int 0))
19043           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19044                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19045           (const_int 0)))
19046    (use (match_operand:SI 3 "immediate_operand" "i"))
19047    (use (reg:CC FLAGS_REG))
19048    (clobber (match_operand:DI 0 "register_operand" "=S"))
19049    (clobber (match_operand:DI 1 "register_operand" "=D"))
19050    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19051   "TARGET_64BIT"
19052   "repz cmpsb"
19053   [(set_attr "type" "str")
19054    (set_attr "mode" "QI")
19055    (set_attr "prefix_rep" "1")])
19056
19057 (define_expand "strlensi"
19058   [(set (match_operand:SI 0 "register_operand" "")
19059         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19060                     (match_operand:QI 2 "immediate_operand" "")
19061                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19062   ""
19063 {
19064  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19065    DONE;
19066  else
19067    FAIL;
19068 })
19069
19070 (define_expand "strlendi"
19071   [(set (match_operand:DI 0 "register_operand" "")
19072         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19073                     (match_operand:QI 2 "immediate_operand" "")
19074                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19075   ""
19076 {
19077  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19078    DONE;
19079  else
19080    FAIL;
19081 })
19082
19083 (define_expand "strlenqi_1"
19084   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19085               (clobber (match_operand 1 "register_operand" ""))
19086               (clobber (reg:CC FLAGS_REG))])]
19087   ""
19088   "")
19089
19090 (define_insn "*strlenqi_1"
19091   [(set (match_operand:SI 0 "register_operand" "=&c")
19092         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19093                     (match_operand:QI 2 "register_operand" "a")
19094                     (match_operand:SI 3 "immediate_operand" "i")
19095                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19096    (clobber (match_operand:SI 1 "register_operand" "=D"))
19097    (clobber (reg:CC FLAGS_REG))]
19098   "!TARGET_64BIT"
19099   "repnz scasb"
19100   [(set_attr "type" "str")
19101    (set_attr "mode" "QI")
19102    (set_attr "prefix_rep" "1")])
19103
19104 (define_insn "*strlenqi_rex_1"
19105   [(set (match_operand:DI 0 "register_operand" "=&c")
19106         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19107                     (match_operand:QI 2 "register_operand" "a")
19108                     (match_operand:DI 3 "immediate_operand" "i")
19109                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19110    (clobber (match_operand:DI 1 "register_operand" "=D"))
19111    (clobber (reg:CC FLAGS_REG))]
19112   "TARGET_64BIT"
19113   "repnz scasb"
19114   [(set_attr "type" "str")
19115    (set_attr "mode" "QI")
19116    (set_attr "prefix_rep" "1")])
19117
19118 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19119 ;; handled in combine, but it is not currently up to the task.
19120 ;; When used for their truth value, the cmpstrn* expanders generate
19121 ;; code like this:
19122 ;;
19123 ;;   repz cmpsb
19124 ;;   seta       %al
19125 ;;   setb       %dl
19126 ;;   cmpb       %al, %dl
19127 ;;   jcc        label
19128 ;;
19129 ;; The intermediate three instructions are unnecessary.
19130
19131 ;; This one handles cmpstrn*_nz_1...
19132 (define_peephole2
19133   [(parallel[
19134      (set (reg:CC FLAGS_REG)
19135           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19136                       (mem:BLK (match_operand 5 "register_operand" ""))))
19137      (use (match_operand 6 "register_operand" ""))
19138      (use (match_operand:SI 3 "immediate_operand" ""))
19139      (clobber (match_operand 0 "register_operand" ""))
19140      (clobber (match_operand 1 "register_operand" ""))
19141      (clobber (match_operand 2 "register_operand" ""))])
19142    (set (match_operand:QI 7 "register_operand" "")
19143         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19144    (set (match_operand:QI 8 "register_operand" "")
19145         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19146    (set (reg FLAGS_REG)
19147         (compare (match_dup 7) (match_dup 8)))
19148   ]
19149   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19150   [(parallel[
19151      (set (reg:CC FLAGS_REG)
19152           (compare:CC (mem:BLK (match_dup 4))
19153                       (mem:BLK (match_dup 5))))
19154      (use (match_dup 6))
19155      (use (match_dup 3))
19156      (clobber (match_dup 0))
19157      (clobber (match_dup 1))
19158      (clobber (match_dup 2))])]
19159   "")
19160
19161 ;; ...and this one handles cmpstrn*_1.
19162 (define_peephole2
19163   [(parallel[
19164      (set (reg:CC FLAGS_REG)
19165           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19166                                (const_int 0))
19167             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19168                         (mem:BLK (match_operand 5 "register_operand" "")))
19169             (const_int 0)))
19170      (use (match_operand:SI 3 "immediate_operand" ""))
19171      (use (reg:CC FLAGS_REG))
19172      (clobber (match_operand 0 "register_operand" ""))
19173      (clobber (match_operand 1 "register_operand" ""))
19174      (clobber (match_operand 2 "register_operand" ""))])
19175    (set (match_operand:QI 7 "register_operand" "")
19176         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19177    (set (match_operand:QI 8 "register_operand" "")
19178         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19179    (set (reg FLAGS_REG)
19180         (compare (match_dup 7) (match_dup 8)))
19181   ]
19182   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19183   [(parallel[
19184      (set (reg:CC FLAGS_REG)
19185           (if_then_else:CC (ne (match_dup 6)
19186                                (const_int 0))
19187             (compare:CC (mem:BLK (match_dup 4))
19188                         (mem:BLK (match_dup 5)))
19189             (const_int 0)))
19190      (use (match_dup 3))
19191      (use (reg:CC FLAGS_REG))
19192      (clobber (match_dup 0))
19193      (clobber (match_dup 1))
19194      (clobber (match_dup 2))])]
19195   "")
19196
19197
19198 \f
19199 ;; Conditional move instructions.
19200
19201 (define_expand "movdicc"
19202   [(set (match_operand:DI 0 "register_operand" "")
19203         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19204                          (match_operand:DI 2 "general_operand" "")
19205                          (match_operand:DI 3 "general_operand" "")))]
19206   "TARGET_64BIT"
19207   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19208
19209 (define_insn "x86_movdicc_0_m1_rex64"
19210   [(set (match_operand:DI 0 "register_operand" "=r")
19211         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19212           (const_int -1)
19213           (const_int 0)))
19214    (clobber (reg:CC FLAGS_REG))]
19215   "TARGET_64BIT"
19216   "sbb{q}\t%0, %0"
19217   ; Since we don't have the proper number of operands for an alu insn,
19218   ; fill in all the blanks.
19219   [(set_attr "type" "alu")
19220    (set_attr "pent_pair" "pu")
19221    (set_attr "memory" "none")
19222    (set_attr "imm_disp" "false")
19223    (set_attr "mode" "DI")
19224    (set_attr "length_immediate" "0")])
19225
19226 (define_insn "*x86_movdicc_0_m1_se"
19227   [(set (match_operand:DI 0 "register_operand" "=r")
19228         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19229                          (const_int 1)
19230                          (const_int 0)))
19231    (clobber (reg:CC FLAGS_REG))]
19232   ""
19233   "sbb{q}\t%0, %0"
19234   [(set_attr "type" "alu")
19235    (set_attr "pent_pair" "pu")
19236    (set_attr "memory" "none")
19237    (set_attr "imm_disp" "false")
19238    (set_attr "mode" "DI")
19239    (set_attr "length_immediate" "0")])
19240
19241 (define_insn "*movdicc_c_rex64"
19242   [(set (match_operand:DI 0 "register_operand" "=r,r")
19243         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19244                                 [(reg FLAGS_REG) (const_int 0)])
19245                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19246                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19247   "TARGET_64BIT && TARGET_CMOVE
19248    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19249   "@
19250    cmov%O2%C1\t{%2, %0|%0, %2}
19251    cmov%O2%c1\t{%3, %0|%0, %3}"
19252   [(set_attr "type" "icmov")
19253    (set_attr "mode" "DI")])
19254
19255 (define_expand "movsicc"
19256   [(set (match_operand:SI 0 "register_operand" "")
19257         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19258                          (match_operand:SI 2 "general_operand" "")
19259                          (match_operand:SI 3 "general_operand" "")))]
19260   ""
19261   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19262
19263 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19264 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19265 ;; So just document what we're doing explicitly.
19266
19267 (define_insn "x86_movsicc_0_m1"
19268   [(set (match_operand:SI 0 "register_operand" "=r")
19269         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19270           (const_int -1)
19271           (const_int 0)))
19272    (clobber (reg:CC FLAGS_REG))]
19273   ""
19274   "sbb{l}\t%0, %0"
19275   ; Since we don't have the proper number of operands for an alu insn,
19276   ; fill in all the blanks.
19277   [(set_attr "type" "alu")
19278    (set_attr "pent_pair" "pu")
19279    (set_attr "memory" "none")
19280    (set_attr "imm_disp" "false")
19281    (set_attr "mode" "SI")
19282    (set_attr "length_immediate" "0")])
19283
19284 (define_insn "*x86_movsicc_0_m1_se"
19285   [(set (match_operand:SI 0 "register_operand" "=r")
19286         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19287                          (const_int 1)
19288                          (const_int 0)))
19289    (clobber (reg:CC FLAGS_REG))]
19290   ""
19291   "sbb{l}\t%0, %0"
19292   [(set_attr "type" "alu")
19293    (set_attr "pent_pair" "pu")
19294    (set_attr "memory" "none")
19295    (set_attr "imm_disp" "false")
19296    (set_attr "mode" "SI")
19297    (set_attr "length_immediate" "0")])
19298
19299 (define_insn "*movsicc_noc"
19300   [(set (match_operand:SI 0 "register_operand" "=r,r")
19301         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19302                                 [(reg FLAGS_REG) (const_int 0)])
19303                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19304                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19305   "TARGET_CMOVE
19306    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19307   "@
19308    cmov%O2%C1\t{%2, %0|%0, %2}
19309    cmov%O2%c1\t{%3, %0|%0, %3}"
19310   [(set_attr "type" "icmov")
19311    (set_attr "mode" "SI")])
19312
19313 (define_expand "movhicc"
19314   [(set (match_operand:HI 0 "register_operand" "")
19315         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19316                          (match_operand:HI 2 "general_operand" "")
19317                          (match_operand:HI 3 "general_operand" "")))]
19318   "TARGET_HIMODE_MATH"
19319   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19320
19321 (define_insn "*movhicc_noc"
19322   [(set (match_operand:HI 0 "register_operand" "=r,r")
19323         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19324                                 [(reg FLAGS_REG) (const_int 0)])
19325                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19326                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19327   "TARGET_CMOVE
19328    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19329   "@
19330    cmov%O2%C1\t{%2, %0|%0, %2}
19331    cmov%O2%c1\t{%3, %0|%0, %3}"
19332   [(set_attr "type" "icmov")
19333    (set_attr "mode" "HI")])
19334
19335 (define_expand "movqicc"
19336   [(set (match_operand:QI 0 "register_operand" "")
19337         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19338                          (match_operand:QI 2 "general_operand" "")
19339                          (match_operand:QI 3 "general_operand" "")))]
19340   "TARGET_QIMODE_MATH"
19341   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19342
19343 (define_insn_and_split "*movqicc_noc"
19344   [(set (match_operand:QI 0 "register_operand" "=r,r")
19345         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19346                                 [(match_operand 4 "flags_reg_operand" "")
19347                                  (const_int 0)])
19348                       (match_operand:QI 2 "register_operand" "r,0")
19349                       (match_operand:QI 3 "register_operand" "0,r")))]
19350   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19351   "#"
19352   "&& reload_completed"
19353   [(set (match_dup 0)
19354         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19355                       (match_dup 2)
19356                       (match_dup 3)))]
19357   "operands[0] = gen_lowpart (SImode, operands[0]);
19358    operands[2] = gen_lowpart (SImode, operands[2]);
19359    operands[3] = gen_lowpart (SImode, operands[3]);"
19360   [(set_attr "type" "icmov")
19361    (set_attr "mode" "SI")])
19362
19363 (define_expand "mov<mode>cc"
19364   [(set (match_operand:X87MODEF 0 "register_operand" "")
19365         (if_then_else:X87MODEF
19366           (match_operand 1 "comparison_operator" "")
19367           (match_operand:X87MODEF 2 "register_operand" "")
19368           (match_operand:X87MODEF 3 "register_operand" "")))]
19369   "(TARGET_80387 && TARGET_CMOVE)
19370    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19371   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19372
19373 (define_insn "*movsfcc_1_387"
19374   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19375         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19376                                 [(reg FLAGS_REG) (const_int 0)])
19377                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19378                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19379   "TARGET_80387 && TARGET_CMOVE
19380    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19381   "@
19382    fcmov%F1\t{%2, %0|%0, %2}
19383    fcmov%f1\t{%3, %0|%0, %3}
19384    cmov%O2%C1\t{%2, %0|%0, %2}
19385    cmov%O2%c1\t{%3, %0|%0, %3}"
19386   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19387    (set_attr "mode" "SF,SF,SI,SI")])
19388
19389 (define_insn "*movdfcc_1"
19390   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19391         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19392                                 [(reg FLAGS_REG) (const_int 0)])
19393                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19394                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19395   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19396    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19397   "@
19398    fcmov%F1\t{%2, %0|%0, %2}
19399    fcmov%f1\t{%3, %0|%0, %3}
19400    #
19401    #"
19402   [(set_attr "type" "fcmov,fcmov,multi,multi")
19403    (set_attr "mode" "DF")])
19404
19405 (define_insn "*movdfcc_1_rex64"
19406   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19407         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19408                                 [(reg FLAGS_REG) (const_int 0)])
19409                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19410                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19411   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19412    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19413   "@
19414    fcmov%F1\t{%2, %0|%0, %2}
19415    fcmov%f1\t{%3, %0|%0, %3}
19416    cmov%O2%C1\t{%2, %0|%0, %2}
19417    cmov%O2%c1\t{%3, %0|%0, %3}"
19418   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19419    (set_attr "mode" "DF")])
19420
19421 (define_split
19422   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19423         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19424                                 [(match_operand 4 "flags_reg_operand" "")
19425                                  (const_int 0)])
19426                       (match_operand:DF 2 "nonimmediate_operand" "")
19427                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19428   "!TARGET_64BIT && reload_completed"
19429   [(set (match_dup 2)
19430         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19431                       (match_dup 5)
19432                       (match_dup 7)))
19433    (set (match_dup 3)
19434         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19435                       (match_dup 6)
19436                       (match_dup 8)))]
19437   "split_di (operands+2, 1, operands+5, operands+6);
19438    split_di (operands+3, 1, operands+7, operands+8);
19439    split_di (operands, 1, operands+2, operands+3);")
19440
19441 (define_insn "*movxfcc_1"
19442   [(set (match_operand:XF 0 "register_operand" "=f,f")
19443         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19444                                 [(reg FLAGS_REG) (const_int 0)])
19445                       (match_operand:XF 2 "register_operand" "f,0")
19446                       (match_operand:XF 3 "register_operand" "0,f")))]
19447   "TARGET_80387 && TARGET_CMOVE"
19448   "@
19449    fcmov%F1\t{%2, %0|%0, %2}
19450    fcmov%f1\t{%3, %0|%0, %3}"
19451   [(set_attr "type" "fcmov")
19452    (set_attr "mode" "XF")])
19453
19454 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19455 ;; the scalar versions to have only XMM registers as operands.
19456
19457 ;; SSE5 conditional move
19458 (define_insn "*sse5_pcmov_<mode>"
19459   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19460         (if_then_else:MODEF
19461           (match_operand:MODEF 1 "register_operand" "x,0")
19462           (match_operand:MODEF 2 "register_operand" "0,x")
19463           (match_operand:MODEF 3 "register_operand" "x,x")))]
19464   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19465   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19466   [(set_attr "type" "sse4arg")])
19467
19468 ;; These versions of the min/max patterns are intentionally ignorant of
19469 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19470 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19471 ;; are undefined in this condition, we're certain this is correct.
19472
19473 (define_insn "<code><mode>3"
19474   [(set (match_operand:MODEF 0 "register_operand" "=x")
19475         (smaxmin:MODEF
19476           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19477           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19478   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19479   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19480   [(set_attr "type" "sseadd")
19481    (set_attr "mode" "<MODE>")])
19482
19483 ;; These versions of the min/max patterns implement exactly the operations
19484 ;;   min = (op1 < op2 ? op1 : op2)
19485 ;;   max = (!(op1 < op2) ? op1 : op2)
19486 ;; Their operands are not commutative, and thus they may be used in the
19487 ;; presence of -0.0 and NaN.
19488
19489 (define_insn "*ieee_smin<mode>3"
19490   [(set (match_operand:MODEF 0 "register_operand" "=x")
19491         (unspec:MODEF
19492           [(match_operand:MODEF 1 "register_operand" "0")
19493            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19494          UNSPEC_IEEE_MIN))]
19495   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19496   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19497   [(set_attr "type" "sseadd")
19498    (set_attr "mode" "<MODE>")])
19499
19500 (define_insn "*ieee_smax<mode>3"
19501   [(set (match_operand:MODEF 0 "register_operand" "=x")
19502         (unspec:MODEF
19503           [(match_operand:MODEF 1 "register_operand" "0")
19504            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19505          UNSPEC_IEEE_MAX))]
19506   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19507   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19508   [(set_attr "type" "sseadd")
19509    (set_attr "mode" "<MODE>")])
19510
19511 ;; Make two stack loads independent:
19512 ;;   fld aa              fld aa
19513 ;;   fld %st(0)     ->   fld bb
19514 ;;   fmul bb             fmul %st(1), %st
19515 ;;
19516 ;; Actually we only match the last two instructions for simplicity.
19517 (define_peephole2
19518   [(set (match_operand 0 "fp_register_operand" "")
19519         (match_operand 1 "fp_register_operand" ""))
19520    (set (match_dup 0)
19521         (match_operator 2 "binary_fp_operator"
19522            [(match_dup 0)
19523             (match_operand 3 "memory_operand" "")]))]
19524   "REGNO (operands[0]) != REGNO (operands[1])"
19525   [(set (match_dup 0) (match_dup 3))
19526    (set (match_dup 0) (match_dup 4))]
19527
19528   ;; The % modifier is not operational anymore in peephole2's, so we have to
19529   ;; swap the operands manually in the case of addition and multiplication.
19530   "if (COMMUTATIVE_ARITH_P (operands[2]))
19531      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19532                                  operands[0], operands[1]);
19533    else
19534      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19535                                  operands[1], operands[0]);")
19536
19537 ;; Conditional addition patterns
19538 (define_expand "addqicc"
19539   [(match_operand:QI 0 "register_operand" "")
19540    (match_operand 1 "comparison_operator" "")
19541    (match_operand:QI 2 "register_operand" "")
19542    (match_operand:QI 3 "const_int_operand" "")]
19543   ""
19544   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19545
19546 (define_expand "addhicc"
19547   [(match_operand:HI 0 "register_operand" "")
19548    (match_operand 1 "comparison_operator" "")
19549    (match_operand:HI 2 "register_operand" "")
19550    (match_operand:HI 3 "const_int_operand" "")]
19551   ""
19552   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19553
19554 (define_expand "addsicc"
19555   [(match_operand:SI 0 "register_operand" "")
19556    (match_operand 1 "comparison_operator" "")
19557    (match_operand:SI 2 "register_operand" "")
19558    (match_operand:SI 3 "const_int_operand" "")]
19559   ""
19560   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19561
19562 (define_expand "adddicc"
19563   [(match_operand:DI 0 "register_operand" "")
19564    (match_operand 1 "comparison_operator" "")
19565    (match_operand:DI 2 "register_operand" "")
19566    (match_operand:DI 3 "const_int_operand" "")]
19567   "TARGET_64BIT"
19568   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19569
19570 \f
19571 ;; Misc patterns (?)
19572
19573 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19574 ;; Otherwise there will be nothing to keep
19575 ;;
19576 ;; [(set (reg ebp) (reg esp))]
19577 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19578 ;;  (clobber (eflags)]
19579 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19580 ;;
19581 ;; in proper program order.
19582 (define_insn "pro_epilogue_adjust_stack_1"
19583   [(set (match_operand:SI 0 "register_operand" "=r,r")
19584         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19585                  (match_operand:SI 2 "immediate_operand" "i,i")))
19586    (clobber (reg:CC FLAGS_REG))
19587    (clobber (mem:BLK (scratch)))]
19588   "!TARGET_64BIT"
19589 {
19590   switch (get_attr_type (insn))
19591     {
19592     case TYPE_IMOV:
19593       return "mov{l}\t{%1, %0|%0, %1}";
19594
19595     case TYPE_ALU:
19596       if (CONST_INT_P (operands[2])
19597           && (INTVAL (operands[2]) == 128
19598               || (INTVAL (operands[2]) < 0
19599                   && INTVAL (operands[2]) != -128)))
19600         {
19601           operands[2] = GEN_INT (-INTVAL (operands[2]));
19602           return "sub{l}\t{%2, %0|%0, %2}";
19603         }
19604       return "add{l}\t{%2, %0|%0, %2}";
19605
19606     case TYPE_LEA:
19607       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19608       return "lea{l}\t{%a2, %0|%0, %a2}";
19609
19610     default:
19611       gcc_unreachable ();
19612     }
19613 }
19614   [(set (attr "type")
19615         (cond [(eq_attr "alternative" "0")
19616                  (const_string "alu")
19617                (match_operand:SI 2 "const0_operand" "")
19618                  (const_string "imov")
19619               ]
19620               (const_string "lea")))
19621    (set_attr "mode" "SI")])
19622
19623 (define_insn "pro_epilogue_adjust_stack_rex64"
19624   [(set (match_operand:DI 0 "register_operand" "=r,r")
19625         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19626                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
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_IMOV:
19634       return "mov{q}\t{%1, %0|%0, %1}";
19635
19636     case TYPE_ALU:
19637       if (CONST_INT_P (operands[2])
19638           /* Avoid overflows.  */
19639           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19640           && (INTVAL (operands[2]) == 128
19641               || (INTVAL (operands[2]) < 0
19642                   && INTVAL (operands[2]) != -128)))
19643         {
19644           operands[2] = GEN_INT (-INTVAL (operands[2]));
19645           return "sub{q}\t{%2, %0|%0, %2}";
19646         }
19647       return "add{q}\t{%2, %0|%0, %2}";
19648
19649     case TYPE_LEA:
19650       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19651       return "lea{q}\t{%a2, %0|%0, %a2}";
19652
19653     default:
19654       gcc_unreachable ();
19655     }
19656 }
19657   [(set (attr "type")
19658         (cond [(eq_attr "alternative" "0")
19659                  (const_string "alu")
19660                (match_operand:DI 2 "const0_operand" "")
19661                  (const_string "imov")
19662               ]
19663               (const_string "lea")))
19664    (set_attr "mode" "DI")])
19665
19666 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19667   [(set (match_operand:DI 0 "register_operand" "=r,r")
19668         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19669                  (match_operand:DI 3 "immediate_operand" "i,i")))
19670    (use (match_operand:DI 2 "register_operand" "r,r"))
19671    (clobber (reg:CC FLAGS_REG))
19672    (clobber (mem:BLK (scratch)))]
19673   "TARGET_64BIT"
19674 {
19675   switch (get_attr_type (insn))
19676     {
19677     case TYPE_ALU:
19678       return "add{q}\t{%2, %0|%0, %2}";
19679
19680     case TYPE_LEA:
19681       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19682       return "lea{q}\t{%a2, %0|%0, %a2}";
19683
19684     default:
19685       gcc_unreachable ();
19686     }
19687 }
19688   [(set_attr "type" "alu,lea")
19689    (set_attr "mode" "DI")])
19690
19691 (define_insn "allocate_stack_worker_32"
19692   [(set (match_operand:SI 0 "register_operand" "+a")
19693         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19694    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19695    (clobber (reg:CC FLAGS_REG))]
19696   "!TARGET_64BIT && TARGET_STACK_PROBE"
19697   "call\t___chkstk"
19698   [(set_attr "type" "multi")
19699    (set_attr "length" "5")])
19700
19701 (define_insn "allocate_stack_worker_64"
19702   [(set (match_operand:DI 0 "register_operand" "=a")
19703         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19704    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19705    (clobber (reg:DI R10_REG))
19706    (clobber (reg:DI R11_REG))
19707    (clobber (reg:CC FLAGS_REG))]
19708   "TARGET_64BIT && TARGET_STACK_PROBE"
19709   "call\t___chkstk"
19710   [(set_attr "type" "multi")
19711    (set_attr "length" "5")])
19712
19713 (define_expand "allocate_stack"
19714   [(match_operand 0 "register_operand" "")
19715    (match_operand 1 "general_operand" "")]
19716   "TARGET_STACK_PROBE"
19717 {
19718   rtx x;
19719
19720 #ifndef CHECK_STACK_LIMIT
19721 #define CHECK_STACK_LIMIT 0
19722 #endif
19723
19724   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19725       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19726     {
19727       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19728                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19729       if (x != stack_pointer_rtx)
19730         emit_move_insn (stack_pointer_rtx, x);
19731     }
19732   else
19733     {
19734       x = copy_to_mode_reg (Pmode, operands[1]);
19735       if (TARGET_64BIT)
19736         x = gen_allocate_stack_worker_64 (x);
19737       else
19738         x = gen_allocate_stack_worker_32 (x);
19739       emit_insn (x);
19740     }
19741
19742   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19743   DONE;
19744 })
19745
19746 (define_expand "builtin_setjmp_receiver"
19747   [(label_ref (match_operand 0 "" ""))]
19748   "!TARGET_64BIT && flag_pic"
19749 {
19750   if (TARGET_MACHO)
19751     {
19752       rtx xops[3];
19753       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19754       rtx label_rtx = gen_label_rtx ();
19755       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19756       xops[0] = xops[1] = picreg;
19757       xops[2] = gen_rtx_CONST (SImode,
19758                   gen_rtx_MINUS (SImode,
19759                     gen_rtx_LABEL_REF (SImode, label_rtx),
19760                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19761       ix86_expand_binary_operator (MINUS, SImode, xops);
19762     }
19763   else
19764     emit_insn (gen_set_got (pic_offset_table_rtx));
19765   DONE;
19766 })
19767 \f
19768 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19769
19770 (define_split
19771   [(set (match_operand 0 "register_operand" "")
19772         (match_operator 3 "promotable_binary_operator"
19773            [(match_operand 1 "register_operand" "")
19774             (match_operand 2 "aligned_operand" "")]))
19775    (clobber (reg:CC FLAGS_REG))]
19776   "! TARGET_PARTIAL_REG_STALL && reload_completed
19777    && ((GET_MODE (operands[0]) == HImode
19778         && ((!optimize_size && !TARGET_FAST_PREFIX)
19779             /* ??? next two lines just !satisfies_constraint_K (...) */
19780             || !CONST_INT_P (operands[2])
19781             || satisfies_constraint_K (operands[2])))
19782        || (GET_MODE (operands[0]) == QImode
19783            && (TARGET_PROMOTE_QImode || optimize_size)))"
19784   [(parallel [(set (match_dup 0)
19785                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19786               (clobber (reg:CC FLAGS_REG))])]
19787   "operands[0] = gen_lowpart (SImode, operands[0]);
19788    operands[1] = gen_lowpart (SImode, operands[1]);
19789    if (GET_CODE (operands[3]) != ASHIFT)
19790      operands[2] = gen_lowpart (SImode, operands[2]);
19791    PUT_MODE (operands[3], SImode);")
19792
19793 ; Promote the QImode tests, as i386 has encoding of the AND
19794 ; instruction with 32-bit sign-extended immediate and thus the
19795 ; instruction size is unchanged, except in the %eax case for
19796 ; which it is increased by one byte, hence the ! optimize_size.
19797 (define_split
19798   [(set (match_operand 0 "flags_reg_operand" "")
19799         (match_operator 2 "compare_operator"
19800           [(and (match_operand 3 "aligned_operand" "")
19801                 (match_operand 4 "const_int_operand" ""))
19802            (const_int 0)]))
19803    (set (match_operand 1 "register_operand" "")
19804         (and (match_dup 3) (match_dup 4)))]
19805   "! TARGET_PARTIAL_REG_STALL && reload_completed
19806    && ! optimize_size
19807    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19808        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19809    /* Ensure that the operand will remain sign-extended immediate.  */
19810    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19811   [(parallel [(set (match_dup 0)
19812                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19813                                     (const_int 0)]))
19814               (set (match_dup 1)
19815                    (and:SI (match_dup 3) (match_dup 4)))])]
19816 {
19817   operands[4]
19818     = gen_int_mode (INTVAL (operands[4])
19819                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19820   operands[1] = gen_lowpart (SImode, operands[1]);
19821   operands[3] = gen_lowpart (SImode, operands[3]);
19822 })
19823
19824 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19825 ; the TEST instruction with 32-bit sign-extended immediate and thus
19826 ; the instruction size would at least double, which is not what we
19827 ; want even with ! optimize_size.
19828 (define_split
19829   [(set (match_operand 0 "flags_reg_operand" "")
19830         (match_operator 1 "compare_operator"
19831           [(and (match_operand:HI 2 "aligned_operand" "")
19832                 (match_operand:HI 3 "const_int_operand" ""))
19833            (const_int 0)]))]
19834   "! TARGET_PARTIAL_REG_STALL && reload_completed
19835    && ! TARGET_FAST_PREFIX
19836    && ! optimize_size
19837    /* Ensure that the operand will remain sign-extended immediate.  */
19838    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19839   [(set (match_dup 0)
19840         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19841                          (const_int 0)]))]
19842 {
19843   operands[3]
19844     = gen_int_mode (INTVAL (operands[3])
19845                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19846   operands[2] = gen_lowpart (SImode, operands[2]);
19847 })
19848
19849 (define_split
19850   [(set (match_operand 0 "register_operand" "")
19851         (neg (match_operand 1 "register_operand" "")))
19852    (clobber (reg:CC FLAGS_REG))]
19853   "! TARGET_PARTIAL_REG_STALL && reload_completed
19854    && (GET_MODE (operands[0]) == HImode
19855        || (GET_MODE (operands[0]) == QImode
19856            && (TARGET_PROMOTE_QImode || optimize_size)))"
19857   [(parallel [(set (match_dup 0)
19858                    (neg:SI (match_dup 1)))
19859               (clobber (reg:CC FLAGS_REG))])]
19860   "operands[0] = gen_lowpart (SImode, operands[0]);
19861    operands[1] = gen_lowpart (SImode, operands[1]);")
19862
19863 (define_split
19864   [(set (match_operand 0 "register_operand" "")
19865         (not (match_operand 1 "register_operand" "")))]
19866   "! TARGET_PARTIAL_REG_STALL && reload_completed
19867    && (GET_MODE (operands[0]) == HImode
19868        || (GET_MODE (operands[0]) == QImode
19869            && (TARGET_PROMOTE_QImode || optimize_size)))"
19870   [(set (match_dup 0)
19871         (not:SI (match_dup 1)))]
19872   "operands[0] = gen_lowpart (SImode, operands[0]);
19873    operands[1] = gen_lowpart (SImode, operands[1]);")
19874
19875 (define_split
19876   [(set (match_operand 0 "register_operand" "")
19877         (if_then_else (match_operator 1 "comparison_operator"
19878                                 [(reg FLAGS_REG) (const_int 0)])
19879                       (match_operand 2 "register_operand" "")
19880                       (match_operand 3 "register_operand" "")))]
19881   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19882    && (GET_MODE (operands[0]) == HImode
19883        || (GET_MODE (operands[0]) == QImode
19884            && (TARGET_PROMOTE_QImode || optimize_size)))"
19885   [(set (match_dup 0)
19886         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19887   "operands[0] = gen_lowpart (SImode, operands[0]);
19888    operands[2] = gen_lowpart (SImode, operands[2]);
19889    operands[3] = gen_lowpart (SImode, operands[3]);")
19890
19891 \f
19892 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19893 ;; transform a complex memory operation into two memory to register operations.
19894
19895 ;; Don't push memory operands
19896 (define_peephole2
19897   [(set (match_operand:SI 0 "push_operand" "")
19898         (match_operand:SI 1 "memory_operand" ""))
19899    (match_scratch:SI 2 "r")]
19900   "!optimize_size && !TARGET_PUSH_MEMORY
19901    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19902   [(set (match_dup 2) (match_dup 1))
19903    (set (match_dup 0) (match_dup 2))]
19904   "")
19905
19906 (define_peephole2
19907   [(set (match_operand:DI 0 "push_operand" "")
19908         (match_operand:DI 1 "memory_operand" ""))
19909    (match_scratch:DI 2 "r")]
19910   "!optimize_size && !TARGET_PUSH_MEMORY
19911    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19912   [(set (match_dup 2) (match_dup 1))
19913    (set (match_dup 0) (match_dup 2))]
19914   "")
19915
19916 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19917 ;; SImode pushes.
19918 (define_peephole2
19919   [(set (match_operand:SF 0 "push_operand" "")
19920         (match_operand:SF 1 "memory_operand" ""))
19921    (match_scratch:SF 2 "r")]
19922   "!optimize_size && !TARGET_PUSH_MEMORY
19923    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19924   [(set (match_dup 2) (match_dup 1))
19925    (set (match_dup 0) (match_dup 2))]
19926   "")
19927
19928 (define_peephole2
19929   [(set (match_operand:HI 0 "push_operand" "")
19930         (match_operand:HI 1 "memory_operand" ""))
19931    (match_scratch:HI 2 "r")]
19932   "!optimize_size && !TARGET_PUSH_MEMORY
19933    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19934   [(set (match_dup 2) (match_dup 1))
19935    (set (match_dup 0) (match_dup 2))]
19936   "")
19937
19938 (define_peephole2
19939   [(set (match_operand:QI 0 "push_operand" "")
19940         (match_operand:QI 1 "memory_operand" ""))
19941    (match_scratch:QI 2 "q")]
19942   "!optimize_size && !TARGET_PUSH_MEMORY
19943    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19944   [(set (match_dup 2) (match_dup 1))
19945    (set (match_dup 0) (match_dup 2))]
19946   "")
19947
19948 ;; Don't move an immediate directly to memory when the instruction
19949 ;; gets too big.
19950 (define_peephole2
19951   [(match_scratch:SI 1 "r")
19952    (set (match_operand:SI 0 "memory_operand" "")
19953         (const_int 0))]
19954   "! optimize_size
19955    && ! TARGET_USE_MOV0
19956    && TARGET_SPLIT_LONG_MOVES
19957    && get_attr_length (insn) >= ix86_cost->large_insn
19958    && peep2_regno_dead_p (0, FLAGS_REG)"
19959   [(parallel [(set (match_dup 1) (const_int 0))
19960               (clobber (reg:CC FLAGS_REG))])
19961    (set (match_dup 0) (match_dup 1))]
19962   "")
19963
19964 (define_peephole2
19965   [(match_scratch:HI 1 "r")
19966    (set (match_operand:HI 0 "memory_operand" "")
19967         (const_int 0))]
19968   "! optimize_size
19969    && ! TARGET_USE_MOV0
19970    && TARGET_SPLIT_LONG_MOVES
19971    && get_attr_length (insn) >= ix86_cost->large_insn
19972    && peep2_regno_dead_p (0, FLAGS_REG)"
19973   [(parallel [(set (match_dup 2) (const_int 0))
19974               (clobber (reg:CC FLAGS_REG))])
19975    (set (match_dup 0) (match_dup 1))]
19976   "operands[2] = gen_lowpart (SImode, operands[1]);")
19977
19978 (define_peephole2
19979   [(match_scratch:QI 1 "q")
19980    (set (match_operand:QI 0 "memory_operand" "")
19981         (const_int 0))]
19982   "! optimize_size
19983    && ! TARGET_USE_MOV0
19984    && TARGET_SPLIT_LONG_MOVES
19985    && get_attr_length (insn) >= ix86_cost->large_insn
19986    && peep2_regno_dead_p (0, FLAGS_REG)"
19987   [(parallel [(set (match_dup 2) (const_int 0))
19988               (clobber (reg:CC FLAGS_REG))])
19989    (set (match_dup 0) (match_dup 1))]
19990   "operands[2] = gen_lowpart (SImode, operands[1]);")
19991
19992 (define_peephole2
19993   [(match_scratch:SI 2 "r")
19994    (set (match_operand:SI 0 "memory_operand" "")
19995         (match_operand:SI 1 "immediate_operand" ""))]
19996   "! optimize_size
19997    && TARGET_SPLIT_LONG_MOVES
19998    && get_attr_length (insn) >= ix86_cost->large_insn"
19999   [(set (match_dup 2) (match_dup 1))
20000    (set (match_dup 0) (match_dup 2))]
20001   "")
20002
20003 (define_peephole2
20004   [(match_scratch:HI 2 "r")
20005    (set (match_operand:HI 0 "memory_operand" "")
20006         (match_operand:HI 1 "immediate_operand" ""))]
20007   "! optimize_size
20008    && TARGET_SPLIT_LONG_MOVES
20009    && get_attr_length (insn) >= ix86_cost->large_insn"
20010   [(set (match_dup 2) (match_dup 1))
20011    (set (match_dup 0) (match_dup 2))]
20012   "")
20013
20014 (define_peephole2
20015   [(match_scratch:QI 2 "q")
20016    (set (match_operand:QI 0 "memory_operand" "")
20017         (match_operand:QI 1 "immediate_operand" ""))]
20018   "! optimize_size
20019    && TARGET_SPLIT_LONG_MOVES
20020    && get_attr_length (insn) >= ix86_cost->large_insn"
20021   [(set (match_dup 2) (match_dup 1))
20022    (set (match_dup 0) (match_dup 2))]
20023   "")
20024
20025 ;; Don't compare memory with zero, load and use a test instead.
20026 (define_peephole2
20027   [(set (match_operand 0 "flags_reg_operand" "")
20028         (match_operator 1 "compare_operator"
20029           [(match_operand:SI 2 "memory_operand" "")
20030            (const_int 0)]))
20031    (match_scratch:SI 3 "r")]
20032   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20033   [(set (match_dup 3) (match_dup 2))
20034    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20035   "")
20036
20037 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20038 ;; Don't split NOTs with a displacement operand, because resulting XOR
20039 ;; will not be pairable anyway.
20040 ;;
20041 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20042 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20043 ;; so this split helps here as well.
20044 ;;
20045 ;; Note: Can't do this as a regular split because we can't get proper
20046 ;; lifetime information then.
20047
20048 (define_peephole2
20049   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20050         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20051   "!optimize_size
20052    && ((TARGET_NOT_UNPAIRABLE
20053         && (!MEM_P (operands[0])
20054             || !memory_displacement_operand (operands[0], SImode)))
20055        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20056    && peep2_regno_dead_p (0, FLAGS_REG)"
20057   [(parallel [(set (match_dup 0)
20058                    (xor:SI (match_dup 1) (const_int -1)))
20059               (clobber (reg:CC FLAGS_REG))])]
20060   "")
20061
20062 (define_peephole2
20063   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20064         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20065   "!optimize_size
20066    && ((TARGET_NOT_UNPAIRABLE
20067         && (!MEM_P (operands[0])
20068             || !memory_displacement_operand (operands[0], HImode)))
20069        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20070    && peep2_regno_dead_p (0, FLAGS_REG)"
20071   [(parallel [(set (match_dup 0)
20072                    (xor:HI (match_dup 1) (const_int -1)))
20073               (clobber (reg:CC FLAGS_REG))])]
20074   "")
20075
20076 (define_peephole2
20077   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20078         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20079   "!optimize_size
20080    && ((TARGET_NOT_UNPAIRABLE
20081         && (!MEM_P (operands[0])
20082             || !memory_displacement_operand (operands[0], QImode)))
20083        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20084    && peep2_regno_dead_p (0, FLAGS_REG)"
20085   [(parallel [(set (match_dup 0)
20086                    (xor:QI (match_dup 1) (const_int -1)))
20087               (clobber (reg:CC FLAGS_REG))])]
20088   "")
20089
20090 ;; Non pairable "test imm, reg" instructions can be translated to
20091 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20092 ;; byte opcode instead of two, have a short form for byte operands),
20093 ;; so do it for other CPUs as well.  Given that the value was dead,
20094 ;; this should not create any new dependencies.  Pass on the sub-word
20095 ;; versions if we're concerned about partial register stalls.
20096
20097 (define_peephole2
20098   [(set (match_operand 0 "flags_reg_operand" "")
20099         (match_operator 1 "compare_operator"
20100           [(and:SI (match_operand:SI 2 "register_operand" "")
20101                    (match_operand:SI 3 "immediate_operand" ""))
20102            (const_int 0)]))]
20103   "ix86_match_ccmode (insn, CCNOmode)
20104    && (true_regnum (operands[2]) != AX_REG
20105        || satisfies_constraint_K (operands[3]))
20106    && peep2_reg_dead_p (1, operands[2])"
20107   [(parallel
20108      [(set (match_dup 0)
20109            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20110                             (const_int 0)]))
20111       (set (match_dup 2)
20112            (and:SI (match_dup 2) (match_dup 3)))])]
20113   "")
20114
20115 ;; We don't need to handle HImode case, because it will be promoted to SImode
20116 ;; on ! TARGET_PARTIAL_REG_STALL
20117
20118 (define_peephole2
20119   [(set (match_operand 0 "flags_reg_operand" "")
20120         (match_operator 1 "compare_operator"
20121           [(and:QI (match_operand:QI 2 "register_operand" "")
20122                    (match_operand:QI 3 "immediate_operand" ""))
20123            (const_int 0)]))]
20124   "! TARGET_PARTIAL_REG_STALL
20125    && ix86_match_ccmode (insn, CCNOmode)
20126    && true_regnum (operands[2]) != AX_REG
20127    && peep2_reg_dead_p (1, operands[2])"
20128   [(parallel
20129      [(set (match_dup 0)
20130            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20131                             (const_int 0)]))
20132       (set (match_dup 2)
20133            (and:QI (match_dup 2) (match_dup 3)))])]
20134   "")
20135
20136 (define_peephole2
20137   [(set (match_operand 0 "flags_reg_operand" "")
20138         (match_operator 1 "compare_operator"
20139           [(and:SI
20140              (zero_extract:SI
20141                (match_operand 2 "ext_register_operand" "")
20142                (const_int 8)
20143                (const_int 8))
20144              (match_operand 3 "const_int_operand" ""))
20145            (const_int 0)]))]
20146   "! TARGET_PARTIAL_REG_STALL
20147    && ix86_match_ccmode (insn, CCNOmode)
20148    && true_regnum (operands[2]) != AX_REG
20149    && peep2_reg_dead_p (1, operands[2])"
20150   [(parallel [(set (match_dup 0)
20151                    (match_op_dup 1
20152                      [(and:SI
20153                         (zero_extract:SI
20154                           (match_dup 2)
20155                           (const_int 8)
20156                           (const_int 8))
20157                         (match_dup 3))
20158                       (const_int 0)]))
20159               (set (zero_extract:SI (match_dup 2)
20160                                     (const_int 8)
20161                                     (const_int 8))
20162                    (and:SI
20163                      (zero_extract:SI
20164                        (match_dup 2)
20165                        (const_int 8)
20166                        (const_int 8))
20167                      (match_dup 3)))])]
20168   "")
20169
20170 ;; Don't do logical operations with memory inputs.
20171 (define_peephole2
20172   [(match_scratch:SI 2 "r")
20173    (parallel [(set (match_operand:SI 0 "register_operand" "")
20174                    (match_operator:SI 3 "arith_or_logical_operator"
20175                      [(match_dup 0)
20176                       (match_operand:SI 1 "memory_operand" "")]))
20177               (clobber (reg:CC FLAGS_REG))])]
20178   "! optimize_size && ! TARGET_READ_MODIFY"
20179   [(set (match_dup 2) (match_dup 1))
20180    (parallel [(set (match_dup 0)
20181                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20182               (clobber (reg:CC FLAGS_REG))])]
20183   "")
20184
20185 (define_peephole2
20186   [(match_scratch:SI 2 "r")
20187    (parallel [(set (match_operand:SI 0 "register_operand" "")
20188                    (match_operator:SI 3 "arith_or_logical_operator"
20189                      [(match_operand:SI 1 "memory_operand" "")
20190                       (match_dup 0)]))
20191               (clobber (reg:CC FLAGS_REG))])]
20192   "! optimize_size && ! TARGET_READ_MODIFY"
20193   [(set (match_dup 2) (match_dup 1))
20194    (parallel [(set (match_dup 0)
20195                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20196               (clobber (reg:CC FLAGS_REG))])]
20197   "")
20198
20199 ; Don't do logical operations with memory outputs
20200 ;
20201 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20202 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20203 ; the same decoder scheduling characteristics as the original.
20204
20205 (define_peephole2
20206   [(match_scratch:SI 2 "r")
20207    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20208                    (match_operator:SI 3 "arith_or_logical_operator"
20209                      [(match_dup 0)
20210                       (match_operand:SI 1 "nonmemory_operand" "")]))
20211               (clobber (reg:CC FLAGS_REG))])]
20212   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20213   [(set (match_dup 2) (match_dup 0))
20214    (parallel [(set (match_dup 2)
20215                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20216               (clobber (reg:CC FLAGS_REG))])
20217    (set (match_dup 0) (match_dup 2))]
20218   "")
20219
20220 (define_peephole2
20221   [(match_scratch:SI 2 "r")
20222    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20223                    (match_operator:SI 3 "arith_or_logical_operator"
20224                      [(match_operand:SI 1 "nonmemory_operand" "")
20225                       (match_dup 0)]))
20226               (clobber (reg:CC FLAGS_REG))])]
20227   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20228   [(set (match_dup 2) (match_dup 0))
20229    (parallel [(set (match_dup 2)
20230                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20231               (clobber (reg:CC FLAGS_REG))])
20232    (set (match_dup 0) (match_dup 2))]
20233   "")
20234
20235 ;; Attempt to always use XOR for zeroing registers.
20236 (define_peephole2
20237   [(set (match_operand 0 "register_operand" "")
20238         (match_operand 1 "const0_operand" ""))]
20239   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20240    && (! TARGET_USE_MOV0 || optimize_size)
20241    && GENERAL_REG_P (operands[0])
20242    && peep2_regno_dead_p (0, FLAGS_REG)"
20243   [(parallel [(set (match_dup 0) (const_int 0))
20244               (clobber (reg:CC FLAGS_REG))])]
20245 {
20246   operands[0] = gen_lowpart (word_mode, operands[0]);
20247 })
20248
20249 (define_peephole2
20250   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20251         (const_int 0))]
20252   "(GET_MODE (operands[0]) == QImode
20253     || GET_MODE (operands[0]) == HImode)
20254    && (! TARGET_USE_MOV0 || optimize_size)
20255    && peep2_regno_dead_p (0, FLAGS_REG)"
20256   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20257               (clobber (reg:CC FLAGS_REG))])])
20258
20259 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20260 (define_peephole2
20261   [(set (match_operand 0 "register_operand" "")
20262         (const_int -1))]
20263   "(GET_MODE (operands[0]) == HImode
20264     || GET_MODE (operands[0]) == SImode
20265     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20266    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20267    && peep2_regno_dead_p (0, FLAGS_REG)"
20268   [(parallel [(set (match_dup 0) (const_int -1))
20269               (clobber (reg:CC FLAGS_REG))])]
20270   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20271                               operands[0]);")
20272
20273 ;; Attempt to convert simple leas to adds. These can be created by
20274 ;; move expanders.
20275 (define_peephole2
20276   [(set (match_operand:SI 0 "register_operand" "")
20277         (plus:SI (match_dup 0)
20278                  (match_operand:SI 1 "nonmemory_operand" "")))]
20279   "peep2_regno_dead_p (0, FLAGS_REG)"
20280   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20281               (clobber (reg:CC FLAGS_REG))])]
20282   "")
20283
20284 (define_peephole2
20285   [(set (match_operand:SI 0 "register_operand" "")
20286         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20287                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20288   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20289   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20290               (clobber (reg:CC FLAGS_REG))])]
20291   "operands[2] = gen_lowpart (SImode, operands[2]);")
20292
20293 (define_peephole2
20294   [(set (match_operand:DI 0 "register_operand" "")
20295         (plus:DI (match_dup 0)
20296                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20297   "peep2_regno_dead_p (0, FLAGS_REG)"
20298   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20299               (clobber (reg:CC FLAGS_REG))])]
20300   "")
20301
20302 (define_peephole2
20303   [(set (match_operand:SI 0 "register_operand" "")
20304         (mult:SI (match_dup 0)
20305                  (match_operand:SI 1 "const_int_operand" "")))]
20306   "exact_log2 (INTVAL (operands[1])) >= 0
20307    && peep2_regno_dead_p (0, FLAGS_REG)"
20308   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20309               (clobber (reg:CC FLAGS_REG))])]
20310   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20311
20312 (define_peephole2
20313   [(set (match_operand:DI 0 "register_operand" "")
20314         (mult:DI (match_dup 0)
20315                  (match_operand:DI 1 "const_int_operand" "")))]
20316   "exact_log2 (INTVAL (operands[1])) >= 0
20317    && peep2_regno_dead_p (0, FLAGS_REG)"
20318   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20319               (clobber (reg:CC FLAGS_REG))])]
20320   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20321
20322 (define_peephole2
20323   [(set (match_operand:SI 0 "register_operand" "")
20324         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20325                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20326   "exact_log2 (INTVAL (operands[2])) >= 0
20327    && REGNO (operands[0]) == REGNO (operands[1])
20328    && peep2_regno_dead_p (0, FLAGS_REG)"
20329   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20330               (clobber (reg:CC FLAGS_REG))])]
20331   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20332
20333 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20334 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20335 ;; many CPUs it is also faster, since special hardware to avoid esp
20336 ;; dependencies is present.
20337
20338 ;; While some of these conversions may be done using splitters, we use peepholes
20339 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20340
20341 ;; Convert prologue esp subtractions to push.
20342 ;; We need register to push.  In order to keep verify_flow_info happy we have
20343 ;; two choices
20344 ;; - use scratch and clobber it in order to avoid dependencies
20345 ;; - use already live register
20346 ;; We can't use the second way right now, since there is no reliable way how to
20347 ;; verify that given register is live.  First choice will also most likely in
20348 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20349 ;; call clobbered registers are dead.  We may want to use base pointer as an
20350 ;; alternative when no register is available later.
20351
20352 (define_peephole2
20353   [(match_scratch:SI 0 "r")
20354    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20355               (clobber (reg:CC FLAGS_REG))
20356               (clobber (mem:BLK (scratch)))])]
20357   "optimize_size || !TARGET_SUB_ESP_4"
20358   [(clobber (match_dup 0))
20359    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20360               (clobber (mem:BLK (scratch)))])])
20361
20362 (define_peephole2
20363   [(match_scratch:SI 0 "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_SUB_ESP_8"
20368   [(clobber (match_dup 0))
20369    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20370    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20371               (clobber (mem:BLK (scratch)))])])
20372
20373 ;; Convert esp subtractions to push.
20374 (define_peephole2
20375   [(match_scratch:SI 0 "r")
20376    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20377               (clobber (reg:CC FLAGS_REG))])]
20378   "optimize_size || !TARGET_SUB_ESP_4"
20379   [(clobber (match_dup 0))
20380    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20381
20382 (define_peephole2
20383   [(match_scratch:SI 0 "r")
20384    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20385               (clobber (reg:CC FLAGS_REG))])]
20386   "optimize_size || !TARGET_SUB_ESP_8"
20387   [(clobber (match_dup 0))
20388    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20389    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20390
20391 ;; Convert epilogue deallocator to pop.
20392 (define_peephole2
20393   [(match_scratch:SI 0 "r")
20394    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20395               (clobber (reg:CC FLAGS_REG))
20396               (clobber (mem:BLK (scratch)))])]
20397   "optimize_size || !TARGET_ADD_ESP_4"
20398   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20399               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20400               (clobber (mem:BLK (scratch)))])]
20401   "")
20402
20403 ;; Two pops case is tricky, since pop causes dependency on destination register.
20404 ;; We use two registers if available.
20405 (define_peephole2
20406   [(match_scratch:SI 0 "r")
20407    (match_scratch:SI 1 "r")
20408    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20409               (clobber (reg:CC FLAGS_REG))
20410               (clobber (mem:BLK (scratch)))])]
20411   "optimize_size || !TARGET_ADD_ESP_8"
20412   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20414               (clobber (mem:BLK (scratch)))])
20415    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20416               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20417   "")
20418
20419 (define_peephole2
20420   [(match_scratch:SI 0 "r")
20421    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20422               (clobber (reg:CC FLAGS_REG))
20423               (clobber (mem:BLK (scratch)))])]
20424   "optimize_size"
20425   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20426               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20427               (clobber (mem:BLK (scratch)))])
20428    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20429               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20430   "")
20431
20432 ;; Convert esp additions to pop.
20433 (define_peephole2
20434   [(match_scratch:SI 0 "r")
20435    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20436               (clobber (reg:CC FLAGS_REG))])]
20437   ""
20438   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20439               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20440   "")
20441
20442 ;; Two pops case is tricky, since pop causes dependency on destination register.
20443 ;; We use two registers if available.
20444 (define_peephole2
20445   [(match_scratch:SI 0 "r")
20446    (match_scratch:SI 1 "r")
20447    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20448               (clobber (reg:CC FLAGS_REG))])]
20449   ""
20450   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20451               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20452    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20453               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20454   "")
20455
20456 (define_peephole2
20457   [(match_scratch:SI 0 "r")
20458    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20459               (clobber (reg:CC FLAGS_REG))])]
20460   "optimize_size"
20461   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20462               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20463    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20464               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20465   "")
20466 \f
20467 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20468 ;; required and register dies.  Similarly for 128 to plus -128.
20469 (define_peephole2
20470   [(set (match_operand 0 "flags_reg_operand" "")
20471         (match_operator 1 "compare_operator"
20472           [(match_operand 2 "register_operand" "")
20473            (match_operand 3 "const_int_operand" "")]))]
20474   "(INTVAL (operands[3]) == -1
20475     || INTVAL (operands[3]) == 1
20476     || INTVAL (operands[3]) == 128)
20477    && ix86_match_ccmode (insn, CCGCmode)
20478    && peep2_reg_dead_p (1, operands[2])"
20479   [(parallel [(set (match_dup 0)
20480                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20481               (clobber (match_dup 2))])]
20482   "")
20483 \f
20484 (define_peephole2
20485   [(match_scratch:DI 0 "r")
20486    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20487               (clobber (reg:CC FLAGS_REG))
20488               (clobber (mem:BLK (scratch)))])]
20489   "optimize_size || !TARGET_SUB_ESP_4"
20490   [(clobber (match_dup 0))
20491    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20492               (clobber (mem:BLK (scratch)))])])
20493
20494 (define_peephole2
20495   [(match_scratch:DI 0 "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_SUB_ESP_8"
20500   [(clobber (match_dup 0))
20501    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20502    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20503               (clobber (mem:BLK (scratch)))])])
20504
20505 ;; Convert esp subtractions to push.
20506 (define_peephole2
20507   [(match_scratch:DI 0 "r")
20508    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20509               (clobber (reg:CC FLAGS_REG))])]
20510   "optimize_size || !TARGET_SUB_ESP_4"
20511   [(clobber (match_dup 0))
20512    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20513
20514 (define_peephole2
20515   [(match_scratch:DI 0 "r")
20516    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20517               (clobber (reg:CC FLAGS_REG))])]
20518   "optimize_size || !TARGET_SUB_ESP_8"
20519   [(clobber (match_dup 0))
20520    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20521    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20522
20523 ;; Convert epilogue deallocator to pop.
20524 (define_peephole2
20525   [(match_scratch:DI 0 "r")
20526    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20527               (clobber (reg:CC FLAGS_REG))
20528               (clobber (mem:BLK (scratch)))])]
20529   "optimize_size || !TARGET_ADD_ESP_4"
20530   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20531               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20532               (clobber (mem:BLK (scratch)))])]
20533   "")
20534
20535 ;; Two pops case is tricky, since pop causes dependency on destination register.
20536 ;; We use two registers if available.
20537 (define_peephole2
20538   [(match_scratch:DI 0 "r")
20539    (match_scratch:DI 1 "r")
20540    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20541               (clobber (reg:CC FLAGS_REG))
20542               (clobber (mem:BLK (scratch)))])]
20543   "optimize_size || !TARGET_ADD_ESP_8"
20544   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20546               (clobber (mem:BLK (scratch)))])
20547    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20548               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20549   "")
20550
20551 (define_peephole2
20552   [(match_scratch:DI 0 "r")
20553    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20554               (clobber (reg:CC FLAGS_REG))
20555               (clobber (mem:BLK (scratch)))])]
20556   "optimize_size"
20557   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20558               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20559               (clobber (mem:BLK (scratch)))])
20560    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20561               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20562   "")
20563
20564 ;; Convert esp additions to pop.
20565 (define_peephole2
20566   [(match_scratch:DI 0 "r")
20567    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20568               (clobber (reg:CC FLAGS_REG))])]
20569   ""
20570   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20571               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20572   "")
20573
20574 ;; Two pops case is tricky, since pop causes dependency on destination register.
20575 ;; We use two registers if available.
20576 (define_peephole2
20577   [(match_scratch:DI 0 "r")
20578    (match_scratch:DI 1 "r")
20579    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20580               (clobber (reg:CC FLAGS_REG))])]
20581   ""
20582   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20583               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20584    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20585               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20586   "")
20587
20588 (define_peephole2
20589   [(match_scratch:DI 0 "r")
20590    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20591               (clobber (reg:CC FLAGS_REG))])]
20592   "optimize_size"
20593   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20594               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20595    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20596               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20597   "")
20598 \f
20599 ;; Convert imul by three, five and nine into lea
20600 (define_peephole2
20601   [(parallel
20602     [(set (match_operand:SI 0 "register_operand" "")
20603           (mult:SI (match_operand:SI 1 "register_operand" "")
20604                    (match_operand:SI 2 "const_int_operand" "")))
20605      (clobber (reg:CC FLAGS_REG))])]
20606   "INTVAL (operands[2]) == 3
20607    || INTVAL (operands[2]) == 5
20608    || INTVAL (operands[2]) == 9"
20609   [(set (match_dup 0)
20610         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20611                  (match_dup 1)))]
20612   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20613
20614 (define_peephole2
20615   [(parallel
20616     [(set (match_operand:SI 0 "register_operand" "")
20617           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20618                    (match_operand:SI 2 "const_int_operand" "")))
20619      (clobber (reg:CC FLAGS_REG))])]
20620   "!optimize_size
20621    && (INTVAL (operands[2]) == 3
20622        || INTVAL (operands[2]) == 5
20623        || INTVAL (operands[2]) == 9)"
20624   [(set (match_dup 0) (match_dup 1))
20625    (set (match_dup 0)
20626         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20627                  (match_dup 0)))]
20628   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20629
20630 (define_peephole2
20631   [(parallel
20632     [(set (match_operand:DI 0 "register_operand" "")
20633           (mult:DI (match_operand:DI 1 "register_operand" "")
20634                    (match_operand:DI 2 "const_int_operand" "")))
20635      (clobber (reg:CC FLAGS_REG))])]
20636   "TARGET_64BIT
20637    && (INTVAL (operands[2]) == 3
20638        || INTVAL (operands[2]) == 5
20639        || INTVAL (operands[2]) == 9)"
20640   [(set (match_dup 0)
20641         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20642                  (match_dup 1)))]
20643   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20644
20645 (define_peephole2
20646   [(parallel
20647     [(set (match_operand:DI 0 "register_operand" "")
20648           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20649                    (match_operand:DI 2 "const_int_operand" "")))
20650      (clobber (reg:CC FLAGS_REG))])]
20651   "TARGET_64BIT
20652    && !optimize_size
20653    && (INTVAL (operands[2]) == 3
20654        || INTVAL (operands[2]) == 5
20655        || INTVAL (operands[2]) == 9)"
20656   [(set (match_dup 0) (match_dup 1))
20657    (set (match_dup 0)
20658         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20659                  (match_dup 0)))]
20660   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20661
20662 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20663 ;; imul $32bit_imm, reg, reg is direct decoded.
20664 (define_peephole2
20665   [(match_scratch:DI 3 "r")
20666    (parallel [(set (match_operand:DI 0 "register_operand" "")
20667                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20668                             (match_operand:DI 2 "immediate_operand" "")))
20669               (clobber (reg:CC FLAGS_REG))])]
20670   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20671    && !satisfies_constraint_K (operands[2])"
20672   [(set (match_dup 3) (match_dup 1))
20673    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20674               (clobber (reg:CC FLAGS_REG))])]
20675 "")
20676
20677 (define_peephole2
20678   [(match_scratch:SI 3 "r")
20679    (parallel [(set (match_operand:SI 0 "register_operand" "")
20680                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20681                             (match_operand:SI 2 "immediate_operand" "")))
20682               (clobber (reg:CC FLAGS_REG))])]
20683   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20684    && !satisfies_constraint_K (operands[2])"
20685   [(set (match_dup 3) (match_dup 1))
20686    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20687               (clobber (reg:CC FLAGS_REG))])]
20688 "")
20689
20690 (define_peephole2
20691   [(match_scratch:SI 3 "r")
20692    (parallel [(set (match_operand:DI 0 "register_operand" "")
20693                    (zero_extend:DI
20694                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20695                               (match_operand:SI 2 "immediate_operand" ""))))
20696               (clobber (reg:CC FLAGS_REG))])]
20697   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20698    && !satisfies_constraint_K (operands[2])"
20699   [(set (match_dup 3) (match_dup 1))
20700    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20701               (clobber (reg:CC FLAGS_REG))])]
20702 "")
20703
20704 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20705 ;; Convert it into imul reg, reg
20706 ;; It would be better to force assembler to encode instruction using long
20707 ;; immediate, but there is apparently no way to do so.
20708 (define_peephole2
20709   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20710                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20711                             (match_operand:DI 2 "const_int_operand" "")))
20712               (clobber (reg:CC FLAGS_REG))])
20713    (match_scratch:DI 3 "r")]
20714   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20715    && satisfies_constraint_K (operands[2])"
20716   [(set (match_dup 3) (match_dup 2))
20717    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20718               (clobber (reg:CC FLAGS_REG))])]
20719 {
20720   if (!rtx_equal_p (operands[0], operands[1]))
20721     emit_move_insn (operands[0], operands[1]);
20722 })
20723
20724 (define_peephole2
20725   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20726                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20727                             (match_operand:SI 2 "const_int_operand" "")))
20728               (clobber (reg:CC FLAGS_REG))])
20729    (match_scratch:SI 3 "r")]
20730   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20731    && satisfies_constraint_K (operands[2])"
20732   [(set (match_dup 3) (match_dup 2))
20733    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20734               (clobber (reg:CC FLAGS_REG))])]
20735 {
20736   if (!rtx_equal_p (operands[0], operands[1]))
20737     emit_move_insn (operands[0], operands[1]);
20738 })
20739
20740 (define_peephole2
20741   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20742                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20743                             (match_operand:HI 2 "immediate_operand" "")))
20744               (clobber (reg:CC FLAGS_REG))])
20745    (match_scratch:HI 3 "r")]
20746   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20747   [(set (match_dup 3) (match_dup 2))
20748    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20749               (clobber (reg:CC FLAGS_REG))])]
20750 {
20751   if (!rtx_equal_p (operands[0], operands[1]))
20752     emit_move_insn (operands[0], operands[1]);
20753 })
20754
20755 ;; After splitting up read-modify operations, array accesses with memory
20756 ;; operands might end up in form:
20757 ;;  sall    $2, %eax
20758 ;;  movl    4(%esp), %edx
20759 ;;  addl    %edx, %eax
20760 ;; instead of pre-splitting:
20761 ;;  sall    $2, %eax
20762 ;;  addl    4(%esp), %eax
20763 ;; Turn it into:
20764 ;;  movl    4(%esp), %edx
20765 ;;  leal    (%edx,%eax,4), %eax
20766
20767 (define_peephole2
20768   [(parallel [(set (match_operand 0 "register_operand" "")
20769                    (ashift (match_operand 1 "register_operand" "")
20770                            (match_operand 2 "const_int_operand" "")))
20771                (clobber (reg:CC FLAGS_REG))])
20772    (set (match_operand 3 "register_operand")
20773         (match_operand 4 "x86_64_general_operand" ""))
20774    (parallel [(set (match_operand 5 "register_operand" "")
20775                    (plus (match_operand 6 "register_operand" "")
20776                          (match_operand 7 "register_operand" "")))
20777                    (clobber (reg:CC FLAGS_REG))])]
20778   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20779    /* Validate MODE for lea.  */
20780    && ((!TARGET_PARTIAL_REG_STALL
20781         && (GET_MODE (operands[0]) == QImode
20782             || GET_MODE (operands[0]) == HImode))
20783        || GET_MODE (operands[0]) == SImode
20784        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20785    /* We reorder load and the shift.  */
20786    && !rtx_equal_p (operands[1], operands[3])
20787    && !reg_overlap_mentioned_p (operands[0], operands[4])
20788    /* Last PLUS must consist of operand 0 and 3.  */
20789    && !rtx_equal_p (operands[0], operands[3])
20790    && (rtx_equal_p (operands[3], operands[6])
20791        || rtx_equal_p (operands[3], operands[7]))
20792    && (rtx_equal_p (operands[0], operands[6])
20793        || rtx_equal_p (operands[0], operands[7]))
20794    /* The intermediate operand 0 must die or be same as output.  */
20795    && (rtx_equal_p (operands[0], operands[5])
20796        || peep2_reg_dead_p (3, operands[0]))"
20797   [(set (match_dup 3) (match_dup 4))
20798    (set (match_dup 0) (match_dup 1))]
20799 {
20800   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20801   int scale = 1 << INTVAL (operands[2]);
20802   rtx index = gen_lowpart (Pmode, operands[1]);
20803   rtx base = gen_lowpart (Pmode, operands[3]);
20804   rtx dest = gen_lowpart (mode, operands[5]);
20805
20806   operands[1] = gen_rtx_PLUS (Pmode, base,
20807                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20808   if (mode != Pmode)
20809     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20810   operands[0] = dest;
20811 })
20812 \f
20813 ;; Call-value patterns last so that the wildcard operand does not
20814 ;; disrupt insn-recog's switch tables.
20815
20816 (define_insn "*call_value_pop_0"
20817   [(set (match_operand 0 "" "")
20818         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20819               (match_operand:SI 2 "" "")))
20820    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20821                             (match_operand:SI 3 "immediate_operand" "")))]
20822   "!TARGET_64BIT"
20823 {
20824   if (SIBLING_CALL_P (insn))
20825     return "jmp\t%P1";
20826   else
20827     return "call\t%P1";
20828 }
20829   [(set_attr "type" "callv")])
20830
20831 (define_insn "*call_value_pop_1"
20832   [(set (match_operand 0 "" "")
20833         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20834               (match_operand:SI 2 "" "")))
20835    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20836                             (match_operand:SI 3 "immediate_operand" "i")))]
20837   "!TARGET_64BIT"
20838 {
20839   if (constant_call_address_operand (operands[1], Pmode))
20840     {
20841       if (SIBLING_CALL_P (insn))
20842         return "jmp\t%P1";
20843       else
20844         return "call\t%P1";
20845     }
20846   if (SIBLING_CALL_P (insn))
20847     return "jmp\t%A1";
20848   else
20849     return "call\t%A1";
20850 }
20851   [(set_attr "type" "callv")])
20852
20853 (define_insn "*call_value_0"
20854   [(set (match_operand 0 "" "")
20855         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20856               (match_operand:SI 2 "" "")))]
20857   "!TARGET_64BIT"
20858 {
20859   if (SIBLING_CALL_P (insn))
20860     return "jmp\t%P1";
20861   else
20862     return "call\t%P1";
20863 }
20864   [(set_attr "type" "callv")])
20865
20866 (define_insn "*call_value_0_rex64"
20867   [(set (match_operand 0 "" "")
20868         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20869               (match_operand:DI 2 "const_int_operand" "")))]
20870   "TARGET_64BIT"
20871 {
20872   if (SIBLING_CALL_P (insn))
20873     return "jmp\t%P1";
20874   else
20875     return "call\t%P1";
20876 }
20877   [(set_attr "type" "callv")])
20878
20879 (define_insn "*call_value_1"
20880   [(set (match_operand 0 "" "")
20881         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20882               (match_operand:SI 2 "" "")))]
20883   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20884 {
20885   if (constant_call_address_operand (operands[1], Pmode))
20886     return "call\t%P1";
20887   return "call\t%A1";
20888 }
20889   [(set_attr "type" "callv")])
20890
20891 (define_insn "*sibcall_value_1"
20892   [(set (match_operand 0 "" "")
20893         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20894               (match_operand:SI 2 "" "")))]
20895   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20896 {
20897   if (constant_call_address_operand (operands[1], Pmode))
20898     return "jmp\t%P1";
20899   return "jmp\t%A1";
20900 }
20901   [(set_attr "type" "callv")])
20902
20903 (define_insn "*call_value_1_rex64"
20904   [(set (match_operand 0 "" "")
20905         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20906               (match_operand:DI 2 "" "")))]
20907   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20908    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20909 {
20910   if (constant_call_address_operand (operands[1], Pmode))
20911     return "call\t%P1";
20912   return "call\t%A1";
20913 }
20914   [(set_attr "type" "callv")])
20915
20916 (define_insn "*call_value_1_rex64_large"
20917   [(set (match_operand 0 "" "")
20918         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20919               (match_operand:DI 2 "" "")))]
20920   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20921   "call\t%A1"
20922   [(set_attr "type" "callv")])
20923
20924 (define_insn "*sibcall_value_1_rex64"
20925   [(set (match_operand 0 "" "")
20926         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20927               (match_operand:DI 2 "" "")))]
20928   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20929   "jmp\t%P1"
20930   [(set_attr "type" "callv")])
20931
20932 (define_insn "*sibcall_value_1_rex64_v"
20933   [(set (match_operand 0 "" "")
20934         (call (mem:QI (reg:DI R11_REG))
20935               (match_operand:DI 1 "" "")))]
20936   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20937   "jmp\t{*%%}r11"
20938   [(set_attr "type" "callv")])
20939 \f
20940 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20941 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20942 ;; caught for use by garbage collectors and the like.  Using an insn that
20943 ;; maps to SIGILL makes it more likely the program will rightfully die.
20944 ;; Keeping with tradition, "6" is in honor of #UD.
20945 (define_insn "trap"
20946   [(trap_if (const_int 1) (const_int 6))]
20947   ""
20948   { return ASM_SHORT "0x0b0f"; }
20949   [(set_attr "length" "2")])
20950
20951 (define_expand "sse_prologue_save"
20952   [(parallel [(set (match_operand:BLK 0 "" "")
20953                    (unspec:BLK [(reg:DI 21)
20954                                 (reg:DI 22)
20955                                 (reg:DI 23)
20956                                 (reg:DI 24)
20957                                 (reg:DI 25)
20958                                 (reg:DI 26)
20959                                 (reg:DI 27)
20960                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20961               (use (match_operand:DI 1 "register_operand" ""))
20962               (use (match_operand:DI 2 "immediate_operand" ""))
20963               (use (label_ref:DI (match_operand 3 "" "")))])]
20964   "TARGET_64BIT"
20965   "")
20966
20967 (define_insn "*sse_prologue_save_insn"
20968   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20969                           (match_operand:DI 4 "const_int_operand" "n")))
20970         (unspec:BLK [(reg:DI 21)
20971                      (reg:DI 22)
20972                      (reg:DI 23)
20973                      (reg:DI 24)
20974                      (reg:DI 25)
20975                      (reg:DI 26)
20976                      (reg:DI 27)
20977                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20978    (use (match_operand:DI 1 "register_operand" "r"))
20979    (use (match_operand:DI 2 "const_int_operand" "i"))
20980    (use (label_ref:DI (match_operand 3 "" "X")))]
20981   "TARGET_64BIT
20982    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20983    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20984   "*
20985 {
20986   int i;
20987   operands[0] = gen_rtx_MEM (Pmode,
20988                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20989   output_asm_insn (\"jmp\\t%A1\", operands);
20990   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20991     {
20992       operands[4] = adjust_address (operands[0], DImode, i*16);
20993       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20994       PUT_MODE (operands[4], TImode);
20995       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20996         output_asm_insn (\"rex\", operands);
20997       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20998     }
20999   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21000                              CODE_LABEL_NUMBER (operands[3]));
21001   return \"\";
21002 }
21003   "
21004   [(set_attr "type" "other")
21005    (set_attr "length_immediate" "0")
21006    (set_attr "length_address" "0")
21007    (set_attr "length" "135")
21008    (set_attr "memory" "store")
21009    (set_attr "modrm" "0")
21010    (set_attr "mode" "DI")])
21011
21012 (define_expand "prefetch"
21013   [(prefetch (match_operand 0 "address_operand" "")
21014              (match_operand:SI 1 "const_int_operand" "")
21015              (match_operand:SI 2 "const_int_operand" ""))]
21016   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21017 {
21018   int rw = INTVAL (operands[1]);
21019   int locality = INTVAL (operands[2]);
21020
21021   gcc_assert (rw == 0 || rw == 1);
21022   gcc_assert (locality >= 0 && locality <= 3);
21023   gcc_assert (GET_MODE (operands[0]) == Pmode
21024               || GET_MODE (operands[0]) == VOIDmode);
21025
21026   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21027      supported by SSE counterpart or the SSE prefetch is not available
21028      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21029      of locality.  */
21030   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21031     operands[2] = GEN_INT (3);
21032   else
21033     operands[1] = const0_rtx;
21034 })
21035
21036 (define_insn "*prefetch_sse"
21037   [(prefetch (match_operand:SI 0 "address_operand" "p")
21038              (const_int 0)
21039              (match_operand:SI 1 "const_int_operand" ""))]
21040   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21041 {
21042   static const char * const patterns[4] = {
21043    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21044   };
21045
21046   int locality = INTVAL (operands[1]);
21047   gcc_assert (locality >= 0 && locality <= 3);
21048
21049   return patterns[locality];
21050 }
21051   [(set_attr "type" "sse")
21052    (set_attr "memory" "none")])
21053
21054 (define_insn "*prefetch_sse_rex"
21055   [(prefetch (match_operand:DI 0 "address_operand" "p")
21056              (const_int 0)
21057              (match_operand:SI 1 "const_int_operand" ""))]
21058   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21059 {
21060   static const char * const patterns[4] = {
21061    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21062   };
21063
21064   int locality = INTVAL (operands[1]);
21065   gcc_assert (locality >= 0 && locality <= 3);
21066
21067   return patterns[locality];
21068 }
21069   [(set_attr "type" "sse")
21070    (set_attr "memory" "none")])
21071
21072 (define_insn "*prefetch_3dnow"
21073   [(prefetch (match_operand:SI 0 "address_operand" "p")
21074              (match_operand:SI 1 "const_int_operand" "n")
21075              (const_int 3))]
21076   "TARGET_3DNOW && !TARGET_64BIT"
21077 {
21078   if (INTVAL (operands[1]) == 0)
21079     return "prefetch\t%a0";
21080   else
21081     return "prefetchw\t%a0";
21082 }
21083   [(set_attr "type" "mmx")
21084    (set_attr "memory" "none")])
21085
21086 (define_insn "*prefetch_3dnow_rex"
21087   [(prefetch (match_operand:DI 0 "address_operand" "p")
21088              (match_operand:SI 1 "const_int_operand" "n")
21089              (const_int 3))]
21090   "TARGET_3DNOW && TARGET_64BIT"
21091 {
21092   if (INTVAL (operands[1]) == 0)
21093     return "prefetch\t%a0";
21094   else
21095     return "prefetchw\t%a0";
21096 }
21097   [(set_attr "type" "mmx")
21098    (set_attr "memory" "none")])
21099
21100 (define_expand "stack_protect_set"
21101   [(match_operand 0 "memory_operand" "")
21102    (match_operand 1 "memory_operand" "")]
21103   ""
21104 {
21105 #ifdef TARGET_THREAD_SSP_OFFSET
21106   if (TARGET_64BIT)
21107     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21108                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21109   else
21110     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21111                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21112 #else
21113   if (TARGET_64BIT)
21114     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21115   else
21116     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21117 #endif
21118   DONE;
21119 })
21120
21121 (define_insn "stack_protect_set_si"
21122   [(set (match_operand:SI 0 "memory_operand" "=m")
21123         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21124    (set (match_scratch:SI 2 "=&r") (const_int 0))
21125    (clobber (reg:CC FLAGS_REG))]
21126   ""
21127   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21128   [(set_attr "type" "multi")])
21129
21130 (define_insn "stack_protect_set_di"
21131   [(set (match_operand:DI 0 "memory_operand" "=m")
21132         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21133    (set (match_scratch:DI 2 "=&r") (const_int 0))
21134    (clobber (reg:CC FLAGS_REG))]
21135   "TARGET_64BIT"
21136   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21137   [(set_attr "type" "multi")])
21138
21139 (define_insn "stack_tls_protect_set_si"
21140   [(set (match_operand:SI 0 "memory_operand" "=m")
21141         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21142    (set (match_scratch:SI 2 "=&r") (const_int 0))
21143    (clobber (reg:CC FLAGS_REG))]
21144   ""
21145   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21146   [(set_attr "type" "multi")])
21147
21148 (define_insn "stack_tls_protect_set_di"
21149   [(set (match_operand:DI 0 "memory_operand" "=m")
21150         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21151    (set (match_scratch:DI 2 "=&r") (const_int 0))
21152    (clobber (reg:CC FLAGS_REG))]
21153   "TARGET_64BIT"
21154   {
21155      /* The kernel uses a different segment register for performance reasons; a
21156         system call would not have to trash the userspace segment register,
21157         which would be expensive */
21158      if (ix86_cmodel != CM_KERNEL)
21159         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21160      else
21161         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21162   }
21163   [(set_attr "type" "multi")])
21164
21165 (define_expand "stack_protect_test"
21166   [(match_operand 0 "memory_operand" "")
21167    (match_operand 1 "memory_operand" "")
21168    (match_operand 2 "" "")]
21169   ""
21170 {
21171   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21172   ix86_compare_op0 = operands[0];
21173   ix86_compare_op1 = operands[1];
21174   ix86_compare_emitted = flags;
21175
21176 #ifdef TARGET_THREAD_SSP_OFFSET
21177   if (TARGET_64BIT)
21178     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21179                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21180   else
21181     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21182                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21183 #else
21184   if (TARGET_64BIT)
21185     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21186   else
21187     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21188 #endif
21189   emit_jump_insn (gen_beq (operands[2]));
21190   DONE;
21191 })
21192
21193 (define_insn "stack_protect_test_si"
21194   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21195         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21196                      (match_operand:SI 2 "memory_operand" "m")]
21197                     UNSPEC_SP_TEST))
21198    (clobber (match_scratch:SI 3 "=&r"))]
21199   ""
21200   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21201   [(set_attr "type" "multi")])
21202
21203 (define_insn "stack_protect_test_di"
21204   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21205         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21206                      (match_operand:DI 2 "memory_operand" "m")]
21207                     UNSPEC_SP_TEST))
21208    (clobber (match_scratch:DI 3 "=&r"))]
21209   "TARGET_64BIT"
21210   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21211   [(set_attr "type" "multi")])
21212
21213 (define_insn "stack_tls_protect_test_si"
21214   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21215         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21216                      (match_operand:SI 2 "const_int_operand" "i")]
21217                     UNSPEC_SP_TLS_TEST))
21218    (clobber (match_scratch:SI 3 "=r"))]
21219   ""
21220   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21221   [(set_attr "type" "multi")])
21222
21223 (define_insn "stack_tls_protect_test_di"
21224   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21225         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21226                      (match_operand:DI 2 "const_int_operand" "i")]
21227                     UNSPEC_SP_TLS_TEST))
21228    (clobber (match_scratch:DI 3 "=r"))]
21229   "TARGET_64BIT"
21230   {
21231      /* The kernel uses a different segment register for performance reasons; a
21232         system call would not have to trash the userspace segment register,
21233         which would be expensive */
21234      if (ix86_cmodel != CM_KERNEL)
21235         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21236      else
21237         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21238   }
21239   [(set_attr "type" "multi")])
21240
21241 (define_mode_iterator CRC32MODE [QI HI SI])
21242 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21243 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21244
21245 (define_insn "sse4_2_crc32<mode>"
21246   [(set (match_operand:SI 0 "register_operand" "=r")
21247         (unspec:SI
21248           [(match_operand:SI 1 "register_operand" "0")
21249            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21250           UNSPEC_CRC32))]
21251   "TARGET_SSE4_2"
21252   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21253   [(set_attr "type" "sselog1")
21254    (set_attr "prefix_rep" "1")
21255    (set_attr "prefix_extra" "1")
21256    (set_attr "mode" "SI")])
21257
21258 (define_insn "sse4_2_crc32di"
21259   [(set (match_operand:DI 0 "register_operand" "=r")
21260         (unspec:DI
21261           [(match_operand:DI 1 "register_operand" "0")
21262            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21263           UNSPEC_CRC32))]
21264   "TARGET_SSE4_2 && TARGET_64BIT"
21265   "crc32q\t{%2, %0|%0, %2}"
21266   [(set_attr "type" "sselog1")
21267    (set_attr "prefix_rep" "1")
21268    (set_attr "prefix_extra" "1")
21269    (set_attr "mode" "DI")])
21270
21271 (include "mmx.md")
21272 (include "sse.md")
21273 (include "sync.md")