Merge branch 'vendor/GCC44'
[dragonfly.git] / contrib / gcc-4.4 / 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, 2009
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    (UNSPEC_MACHOPIC_OFFSET      10)
62
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
71    (UNSPEC_MEMORY_BLOCKAGE      18)
72
73    ; TLS support
74    (UNSPEC_TP                   20)
75    (UNSPEC_TLS_GD               21)
76    (UNSPEC_TLS_LD_BASE          22)
77    (UNSPEC_TLSDESC              23)
78
79    ; Other random patterns
80    (UNSPEC_EH_RETURN            29)
81    (UNSPEC_SCAS                 30)
82    (UNSPEC_FNSTSW               31)
83    (UNSPEC_SAHF                 32)
84    (UNSPEC_PARITY               33)
85    (UNSPEC_FSTCW                34)
86    (UNSPEC_ADD_CARRY            35)
87    (UNSPEC_FLDCW                36)
88    (UNSPEC_REP                  37)
89    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
90    (UNSPEC_TRUNC_NOOP           39)
91
92    ; For SSE/MMX support:
93    (UNSPEC_FIX_NOTRUNC          40)
94    (UNSPEC_MASKMOV              41)
95    (UNSPEC_MOVMSK               42)
96    (UNSPEC_MOVNT                43)
97    (UNSPEC_MOVU                 44)
98    (UNSPEC_RCP                  45)
99    (UNSPEC_RSQRT                46)
100    (UNSPEC_SFENCE               47)
101    (UNSPEC_PFRCP                49)
102    (UNSPEC_PFRCPIT1             40)
103    (UNSPEC_PFRCPIT2             41)
104    (UNSPEC_PFRSQRT              42)
105    (UNSPEC_PFRSQIT1             43)
106    (UNSPEC_MFENCE               44)
107    (UNSPEC_LFENCE               45)
108    (UNSPEC_PSADBW               46)
109    (UNSPEC_LDDQU                47)
110    (UNSPEC_MS_TO_SYSV_CALL      48)
111
112    ; Generic math support
113    (UNSPEC_COPYSIGN             50)
114    (UNSPEC_IEEE_MIN             51)     ; not commutative
115    (UNSPEC_IEEE_MAX             52)     ; not commutative
116
117    ; x87 Floating point
118    (UNSPEC_SIN                  60)
119    (UNSPEC_COS                  61)
120    (UNSPEC_FPATAN               62)
121    (UNSPEC_FYL2X                63)
122    (UNSPEC_FYL2XP1              64)
123    (UNSPEC_FRNDINT              65)
124    (UNSPEC_FIST                 66)
125    (UNSPEC_F2XM1                67)
126    (UNSPEC_TAN                  68)
127    (UNSPEC_FXAM                 69)
128
129    ; x87 Rounding
130    (UNSPEC_FRNDINT_FLOOR        70)
131    (UNSPEC_FRNDINT_CEIL         71)
132    (UNSPEC_FRNDINT_TRUNC        72)
133    (UNSPEC_FRNDINT_MASK_PM      73)
134    (UNSPEC_FIST_FLOOR           74)
135    (UNSPEC_FIST_CEIL            75)
136
137    ; x87 Double output FP
138    (UNSPEC_SINCOS_COS           80)
139    (UNSPEC_SINCOS_SIN           81)
140    (UNSPEC_XTRACT_FRACT         84)
141    (UNSPEC_XTRACT_EXP           85)
142    (UNSPEC_FSCALE_FRACT         86)
143    (UNSPEC_FSCALE_EXP           87)
144    (UNSPEC_FPREM_F              88)
145    (UNSPEC_FPREM_U              89)
146    (UNSPEC_FPREM1_F             90)
147    (UNSPEC_FPREM1_U             91)
148
149    (UNSPEC_C2_FLAG              95)
150    (UNSPEC_FXAM_MEM             96)
151
152    ; SSP patterns
153    (UNSPEC_SP_SET               100)
154    (UNSPEC_SP_TEST              101)
155    (UNSPEC_SP_TLS_SET           102)
156    (UNSPEC_SP_TLS_TEST          103)
157
158    ; SSSE3
159    (UNSPEC_PSHUFB               120)
160    (UNSPEC_PSIGN                121)
161    (UNSPEC_PALIGNR              122)
162
163    ; For SSE4A support
164    (UNSPEC_EXTRQI               130)
165    (UNSPEC_EXTRQ                131)
166    (UNSPEC_INSERTQI             132)
167    (UNSPEC_INSERTQ              133)
168
169    ; For SSE4.1 support
170    (UNSPEC_BLENDV               134)
171    (UNSPEC_INSERTPS             135)
172    (UNSPEC_DP                   136)
173    (UNSPEC_MOVNTDQA             137)
174    (UNSPEC_MPSADBW              138)
175    (UNSPEC_PHMINPOSUW           139)
176    (UNSPEC_PTEST                140)
177    (UNSPEC_ROUND                141)
178
179    ; For SSE4.2 support
180    (UNSPEC_CRC32                143)
181    (UNSPEC_PCMPESTR             144)
182    (UNSPEC_PCMPISTR             145)
183
184    ;; For SSE5
185    (UNSPEC_SSE5_INTRINSIC       150)
186    (UNSPEC_SSE5_UNSIGNED_CMP    151)
187    (UNSPEC_SSE5_TRUEFALSE       152)
188    (UNSPEC_SSE5_PERMUTE         153)
189    (UNSPEC_FRCZ                 154)
190    (UNSPEC_CVTPH2PS             155)
191    (UNSPEC_CVTPS2PH             156)
192
193    ; For AES support
194    (UNSPEC_AESENC               159)
195    (UNSPEC_AESENCLAST           160)
196    (UNSPEC_AESDEC               161)
197    (UNSPEC_AESDECLAST           162)
198    (UNSPEC_AESIMC               163)
199    (UNSPEC_AESKEYGENASSIST      164)
200
201    ; For PCLMUL support
202    (UNSPEC_PCLMUL               165)
203
204    ; For AVX support
205    (UNSPEC_PCMP                 166)
206    (UNSPEC_VPERMIL              167)
207    (UNSPEC_VPERMIL2F128         168)
208    (UNSPEC_MASKLOAD             169)
209    (UNSPEC_MASKSTORE            170)
210    (UNSPEC_CAST                 171)
211    (UNSPEC_VTESTP               172)
212   ])
213
214 (define_constants
215   [(UNSPECV_BLOCKAGE            0)
216    (UNSPECV_STACK_PROBE         1)
217    (UNSPECV_EMMS                2)
218    (UNSPECV_LDMXCSR             3)
219    (UNSPECV_STMXCSR             4)
220    (UNSPECV_FEMMS               5)
221    (UNSPECV_CLFLUSH             6)
222    (UNSPECV_ALIGN               7)
223    (UNSPECV_MONITOR             8)
224    (UNSPECV_MWAIT               9)
225    (UNSPECV_CMPXCHG             10)
226    (UNSPECV_XCHG                12)
227    (UNSPECV_LOCK                13)
228    (UNSPECV_PROLOGUE_USE        14)
229    (UNSPECV_CLD                 15)
230    (UNSPECV_VZEROALL            16)
231    (UNSPECV_VZEROUPPER          17)
232   ])
233
234 ;; Constants to represent pcomtrue/pcomfalse variants
235 (define_constants
236   [(PCOM_FALSE                  0)
237    (PCOM_TRUE                   1)
238    (COM_FALSE_S                 2)
239    (COM_FALSE_P                 3)
240    (COM_TRUE_S                  4)
241    (COM_TRUE_P                  5)
242   ])
243
244 ;; Constants used in the SSE5 pperm instruction
245 (define_constants
246   [(PPERM_SRC                   0x00)   /* copy source */
247    (PPERM_INVERT                0x20)   /* invert source */
248    (PPERM_REVERSE               0x40)   /* bit reverse source */
249    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
250    (PPERM_ZERO                  0x80)   /* all 0's */
251    (PPERM_ONES                  0xa0)   /* all 1's */
252    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
253    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
254    (PPERM_SRC1                  0x00)   /* use first source byte */
255    (PPERM_SRC2                  0x10)   /* use second source byte */
256    ])
257
258 ;; Registers by name.
259 (define_constants
260   [(AX_REG                       0)
261    (DX_REG                       1)
262    (CX_REG                       2)
263    (BX_REG                       3)
264    (SI_REG                       4)
265    (DI_REG                       5)
266    (BP_REG                       6)
267    (SP_REG                       7)
268    (ST0_REG                      8)
269    (ST1_REG                      9)
270    (ST2_REG                     10)
271    (ST3_REG                     11)
272    (ST4_REG                     12)
273    (ST5_REG                     13)
274    (ST6_REG                     14)
275    (ST7_REG                     15)
276    (FLAGS_REG                   17)
277    (FPSR_REG                    18)
278    (FPCR_REG                    19)
279    (XMM0_REG                    21)
280    (XMM1_REG                    22)
281    (XMM2_REG                    23)
282    (XMM3_REG                    24)
283    (XMM4_REG                    25)
284    (XMM5_REG                    26)
285    (XMM6_REG                    27)
286    (XMM7_REG                    28)
287    (MM0_REG                     29)
288    (MM1_REG                     30)
289    (MM2_REG                     31)
290    (MM3_REG                     32)
291    (MM4_REG                     33)
292    (MM5_REG                     34)
293    (MM6_REG                     35)
294    (MM7_REG                     36)
295    (R8_REG                      37)
296    (R9_REG                      38)
297    (R10_REG                     39)
298    (R11_REG                     40)
299    (R13_REG                     42)
300    (XMM8_REG                    45)
301    (XMM9_REG                    46)
302    (XMM10_REG                   47)
303    (XMM11_REG                   48)
304    (XMM12_REG                   49)
305    (XMM13_REG                   50)
306    (XMM14_REG                   51)
307    (XMM15_REG                   52)
308   ])
309
310 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
311 ;; from i386.c.
312
313 ;; In C guard expressions, put expressions which may be compile-time
314 ;; constants first.  This allows for better optimization.  For
315 ;; example, write "TARGET_64BIT && reload_completed", not
316 ;; "reload_completed && TARGET_64BIT".
317
318 \f
319 ;; Processor type.
320 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
321                     generic64,amdfam10"
322   (const (symbol_ref "ix86_schedule")))
323
324 ;; A basic instruction type.  Refinements due to arguments to be
325 ;; provided in other attributes.
326 (define_attr "type"
327   "other,multi,
328    alu,alu1,negnot,imov,imovx,lea,
329    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
330    icmp,test,ibr,setcc,icmov,
331    push,pop,call,callv,leave,
332    str,bitmanip,
333    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
334    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
335    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
336    ssemuladd,sse4arg,
337    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
338   (const_string "other"))
339
340 ;; Main data type used by the insn
341 (define_attr "mode"
342   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
343   (const_string "unknown"))
344
345 ;; The CPU unit operations uses.
346 (define_attr "unit" "integer,i387,sse,mmx,unknown"
347   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
348            (const_string "i387")
349          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
350                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
351                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
352            (const_string "sse")
353          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
354            (const_string "mmx")
355          (eq_attr "type" "other")
356            (const_string "unknown")]
357          (const_string "integer")))
358
359 ;; The (bounding maximum) length of an instruction immediate.
360 (define_attr "length_immediate" ""
361   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
362                           bitmanip")
363            (const_int 0)
364          (eq_attr "unit" "i387,sse,mmx")
365            (const_int 0)
366          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
367                           imul,icmp,push,pop")
368            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
369          (eq_attr "type" "imov,test")
370            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
371          (eq_attr "type" "call")
372            (if_then_else (match_operand 0 "constant_call_address_operand" "")
373              (const_int 4)
374              (const_int 0))
375          (eq_attr "type" "callv")
376            (if_then_else (match_operand 1 "constant_call_address_operand" "")
377              (const_int 4)
378              (const_int 0))
379          ;; We don't know the size before shorten_branches.  Expect
380          ;; the instruction to fit for better scheduling.
381          (eq_attr "type" "ibr")
382            (const_int 1)
383          ]
384          (symbol_ref "/* Update immediate_length and other attributes! */
385                       gcc_unreachable (),1")))
386
387 ;; The (bounding maximum) length of an instruction address.
388 (define_attr "length_address" ""
389   (cond [(eq_attr "type" "str,other,multi,fxch")
390            (const_int 0)
391          (and (eq_attr "type" "call")
392               (match_operand 0 "constant_call_address_operand" ""))
393              (const_int 0)
394          (and (eq_attr "type" "callv")
395               (match_operand 1 "constant_call_address_operand" ""))
396              (const_int 0)
397          ]
398          (symbol_ref "ix86_attr_length_address_default (insn)")))
399
400 ;; Set when length prefix is used.
401 (define_attr "prefix_data16" ""
402   (if_then_else (ior (eq_attr "mode" "HI")
403                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
404     (const_int 1)
405     (const_int 0)))
406
407 ;; Set when string REP prefix is used.
408 (define_attr "prefix_rep" ""
409   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
410     (const_int 1)
411     (const_int 0)))
412
413 ;; Set when 0f opcode prefix is used.
414 (define_attr "prefix_0f" ""
415   (if_then_else
416     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
417          (eq_attr "unit" "sse,mmx"))
418     (const_int 1)
419     (const_int 0)))
420
421 ;; Set when REX opcode prefix is used.
422 (define_attr "prefix_rex" ""
423   (cond [(and (eq_attr "mode" "DI")
424               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
425            (const_int 1)
426          (and (eq_attr "mode" "QI")
427               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
428                   (const_int 0)))
429            (const_int 1)
430          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
431              (const_int 0))
432            (const_int 1)
433         ]
434         (const_int 0)))
435
436 ;; There are also additional prefixes in SSSE3.
437 (define_attr "prefix_extra" "" (const_int 0))
438
439 ;; Prefix used: original, VEX or maybe VEX.
440 (define_attr "prefix" "orig,vex,maybe_vex"
441   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
442     (const_string "vex")
443     (const_string "orig")))
444
445 ;; There is a 8bit immediate for VEX.
446 (define_attr "prefix_vex_imm8" "" (const_int 0))
447
448 ;; VEX W bit is used.
449 (define_attr "prefix_vex_w" "" (const_int 0))
450
451 ;; The length of VEX prefix
452 (define_attr "length_vex" ""
453   (if_then_else (eq_attr "prefix_0f" "1")
454     (if_then_else (eq_attr "prefix_vex_w" "1")
455       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
456       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
457     (if_then_else (eq_attr "prefix_vex_w" "1")
458       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
459       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
460
461 ;; Set when modrm byte is used.
462 (define_attr "modrm" ""
463   (cond [(eq_attr "type" "str,leave")
464            (const_int 0)
465          (eq_attr "unit" "i387")
466            (const_int 0)
467          (and (eq_attr "type" "incdec")
468               (ior (match_operand:SI 1 "register_operand" "")
469                    (match_operand:HI 1 "register_operand" "")))
470            (const_int 0)
471          (and (eq_attr "type" "push")
472               (not (match_operand 1 "memory_operand" "")))
473            (const_int 0)
474          (and (eq_attr "type" "pop")
475               (not (match_operand 0 "memory_operand" "")))
476            (const_int 0)
477          (and (eq_attr "type" "imov")
478               (ior (and (match_operand 0 "register_operand" "")
479                         (match_operand 1 "immediate_operand" ""))
480                    (ior (and (match_operand 0 "ax_reg_operand" "")
481                              (match_operand 1 "memory_displacement_only_operand" ""))
482                         (and (match_operand 0 "memory_displacement_only_operand" "")
483                              (match_operand 1 "ax_reg_operand" "")))))
484            (const_int 0)
485          (and (eq_attr "type" "call")
486               (match_operand 0 "constant_call_address_operand" ""))
487              (const_int 0)
488          (and (eq_attr "type" "callv")
489               (match_operand 1 "constant_call_address_operand" ""))
490              (const_int 0)
491          ]
492          (const_int 1)))
493
494 ;; The (bounding maximum) length of an instruction in bytes.
495 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
496 ;; Later we may want to split them and compute proper length as for
497 ;; other insns.
498 (define_attr "length" ""
499   (cond [(eq_attr "type" "other,multi,fistp,frndint")
500            (const_int 16)
501          (eq_attr "type" "fcmp")
502            (const_int 4)
503          (eq_attr "unit" "i387")
504            (plus (const_int 2)
505                  (plus (attr "prefix_data16")
506                        (attr "length_address")))
507          (ior (eq_attr "prefix" "vex")
508               (and (eq_attr "prefix" "maybe_vex")
509                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
510            (plus (attr "length_vex")
511                  (plus (attr "prefix_vex_imm8")
512                        (plus (attr "modrm")
513                              (attr "length_address"))))]
514          (plus (plus (attr "modrm")
515                      (plus (attr "prefix_0f")
516                            (plus (attr "prefix_rex")
517                                  (plus (attr "prefix_extra")
518                                        (const_int 1)))))
519                (plus (attr "prefix_rep")
520                      (plus (attr "prefix_data16")
521                            (plus (attr "length_immediate")
522                                  (attr "length_address")))))))
523
524 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
525 ;; `store' if there is a simple memory reference therein, or `unknown'
526 ;; if the instruction is complex.
527
528 (define_attr "memory" "none,load,store,both,unknown"
529   (cond [(eq_attr "type" "other,multi,str")
530            (const_string "unknown")
531          (eq_attr "type" "lea,fcmov,fpspc")
532            (const_string "none")
533          (eq_attr "type" "fistp,leave")
534            (const_string "both")
535          (eq_attr "type" "frndint")
536            (const_string "load")
537          (eq_attr "type" "push")
538            (if_then_else (match_operand 1 "memory_operand" "")
539              (const_string "both")
540              (const_string "store"))
541          (eq_attr "type" "pop")
542            (if_then_else (match_operand 0 "memory_operand" "")
543              (const_string "both")
544              (const_string "load"))
545          (eq_attr "type" "setcc")
546            (if_then_else (match_operand 0 "memory_operand" "")
547              (const_string "store")
548              (const_string "none"))
549          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
550            (if_then_else (ior (match_operand 0 "memory_operand" "")
551                               (match_operand 1 "memory_operand" ""))
552              (const_string "load")
553              (const_string "none"))
554          (eq_attr "type" "ibr")
555            (if_then_else (match_operand 0 "memory_operand" "")
556              (const_string "load")
557              (const_string "none"))
558          (eq_attr "type" "call")
559            (if_then_else (match_operand 0 "constant_call_address_operand" "")
560              (const_string "none")
561              (const_string "load"))
562          (eq_attr "type" "callv")
563            (if_then_else (match_operand 1 "constant_call_address_operand" "")
564              (const_string "none")
565              (const_string "load"))
566          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
567               (match_operand 1 "memory_operand" ""))
568            (const_string "both")
569          (and (match_operand 0 "memory_operand" "")
570               (match_operand 1 "memory_operand" ""))
571            (const_string "both")
572          (match_operand 0 "memory_operand" "")
573            (const_string "store")
574          (match_operand 1 "memory_operand" "")
575            (const_string "load")
576          (and (eq_attr "type"
577                  "!alu1,negnot,ishift1,
578                    imov,imovx,icmp,test,bitmanip,
579                    fmov,fcmp,fsgn,
580                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
581                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
582               (match_operand 2 "memory_operand" ""))
583            (const_string "load")
584          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
585               (match_operand 3 "memory_operand" ""))
586            (const_string "load")
587         ]
588         (const_string "none")))
589
590 ;; Indicates if an instruction has both an immediate and a displacement.
591
592 (define_attr "imm_disp" "false,true,unknown"
593   (cond [(eq_attr "type" "other,multi")
594            (const_string "unknown")
595          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
596               (and (match_operand 0 "memory_displacement_operand" "")
597                    (match_operand 1 "immediate_operand" "")))
598            (const_string "true")
599          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
600               (and (match_operand 0 "memory_displacement_operand" "")
601                    (match_operand 2 "immediate_operand" "")))
602            (const_string "true")
603         ]
604         (const_string "false")))
605
606 ;; Indicates if an FP operation has an integer source.
607
608 (define_attr "fp_int_src" "false,true"
609   (const_string "false"))
610
611 ;; Defines rounding mode of an FP operation.
612
613 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
614   (const_string "any"))
615
616 ;; Describe a user's asm statement.
617 (define_asm_attributes
618   [(set_attr "length" "128")
619    (set_attr "type" "multi")])
620
621 ;; All integer comparison codes.
622 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
623
624 ;; All floating-point comparison codes.
625 (define_code_iterator fp_cond [unordered ordered
626                                uneq unge ungt unle unlt ltgt ])
627
628 (define_code_iterator plusminus [plus minus])
629
630 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
631
632 ;; Base name for define_insn
633 (define_code_attr plusminus_insn
634   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
635    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
636
637 ;; Base name for insn mnemonic.
638 (define_code_attr plusminus_mnemonic
639   [(plus "add") (ss_plus "adds") (us_plus "addus")
640    (minus "sub") (ss_minus "subs") (us_minus "subus")])
641
642 ;; Mark commutative operators as such in constraints.
643 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
644                         (minus "") (ss_minus "") (us_minus "")])
645
646 ;; Mapping of signed max and min
647 (define_code_iterator smaxmin [smax smin])
648
649 ;; Mapping of unsigned max and min
650 (define_code_iterator umaxmin [umax umin])
651
652 ;; Mapping of signed/unsigned max and min
653 (define_code_iterator maxmin [smax smin umax umin])
654
655 ;; Base name for integer and FP insn mnemonic
656 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
657                                  (umax "maxu") (umin "minu")])
658 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
659
660 ;; Mapping of parallel logic operators
661 (define_code_iterator plogic [and ior xor])
662
663 ;; Base name for insn mnemonic.
664 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
665
666 ;; Mapping of abs neg operators
667 (define_code_iterator absneg [abs neg])
668
669 ;; Base name for x87 insn mnemonic.
670 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
671
672 ;; All single word integer modes.
673 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
674
675 ;; Single word integer modes without QImode.
676 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
677
678 ;; Instruction suffix for integer modes.
679 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
680
681 ;; Register class for integer modes.
682 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
683
684 ;; Immediate operand constraint for integer modes.
685 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
686
687 ;; General operand predicate for integer modes.
688 (define_mode_attr general_operand
689         [(QI "general_operand")
690          (HI "general_operand")
691          (SI "general_operand")
692          (DI "x86_64_general_operand")])
693
694 ;; SSE and x87 SFmode and DFmode floating point modes
695 (define_mode_iterator MODEF [SF DF])
696
697 ;; All x87 floating point modes
698 (define_mode_iterator X87MODEF [SF DF XF])
699
700 ;; All integer modes handled by x87 fisttp operator.
701 (define_mode_iterator X87MODEI [HI SI DI])
702
703 ;; All integer modes handled by integer x87 operators.
704 (define_mode_iterator X87MODEI12 [HI SI])
705
706 ;; All integer modes handled by SSE cvtts?2si* operators.
707 (define_mode_iterator SSEMODEI24 [SI DI])
708
709 ;; SSE asm suffix for floating point modes
710 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
711
712 ;; SSE vector mode corresponding to a scalar mode
713 (define_mode_attr ssevecmode
714   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
715
716 ;; Instruction suffix for REX 64bit operators.
717 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
718
719 ;; This mode iterator allows :P to be used for patterns that operate on
720 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
721 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
722
723 \f
724 ;; Scheduling descriptions
725
726 (include "pentium.md")
727 (include "ppro.md")
728 (include "k6.md")
729 (include "athlon.md")
730 (include "geode.md")
731
732 \f
733 ;; Operand and operator predicates and constraints
734
735 (include "predicates.md")
736 (include "constraints.md")
737
738 \f
739 ;; Compare instructions.
740
741 ;; All compare insns have expanders that save the operands away without
742 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
743 ;; after the cmp) will actually emit the cmpM.
744
745 (define_expand "cmpti"
746   [(set (reg:CC FLAGS_REG)
747         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
748                     (match_operand:TI 1 "x86_64_general_operand" "")))]
749   "TARGET_64BIT"
750 {
751   if (MEM_P (operands[0]) && MEM_P (operands[1]))
752     operands[0] = force_reg (TImode, operands[0]);
753   ix86_compare_op0 = operands[0];
754   ix86_compare_op1 = operands[1];
755   DONE;
756 })
757
758 (define_expand "cmpdi"
759   [(set (reg:CC FLAGS_REG)
760         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
761                     (match_operand:DI 1 "x86_64_general_operand" "")))]
762   ""
763 {
764   if (MEM_P (operands[0]) && MEM_P (operands[1]))
765     operands[0] = force_reg (DImode, operands[0]);
766   ix86_compare_op0 = operands[0];
767   ix86_compare_op1 = operands[1];
768   DONE;
769 })
770
771 (define_expand "cmpsi"
772   [(set (reg:CC FLAGS_REG)
773         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
774                     (match_operand:SI 1 "general_operand" "")))]
775   ""
776 {
777   if (MEM_P (operands[0]) && MEM_P (operands[1]))
778     operands[0] = force_reg (SImode, operands[0]);
779   ix86_compare_op0 = operands[0];
780   ix86_compare_op1 = operands[1];
781   DONE;
782 })
783
784 (define_expand "cmphi"
785   [(set (reg:CC FLAGS_REG)
786         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
787                     (match_operand:HI 1 "general_operand" "")))]
788   ""
789 {
790   if (MEM_P (operands[0]) && MEM_P (operands[1]))
791     operands[0] = force_reg (HImode, operands[0]);
792   ix86_compare_op0 = operands[0];
793   ix86_compare_op1 = operands[1];
794   DONE;
795 })
796
797 (define_expand "cmpqi"
798   [(set (reg:CC FLAGS_REG)
799         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
800                     (match_operand:QI 1 "general_operand" "")))]
801   "TARGET_QIMODE_MATH"
802 {
803   if (MEM_P (operands[0]) && MEM_P (operands[1]))
804     operands[0] = force_reg (QImode, operands[0]);
805   ix86_compare_op0 = operands[0];
806   ix86_compare_op1 = operands[1];
807   DONE;
808 })
809
810 (define_insn "cmpdi_ccno_1_rex64"
811   [(set (reg FLAGS_REG)
812         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
813                  (match_operand:DI 1 "const0_operand" "")))]
814   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
815   "@
816    test{q}\t%0, %0
817    cmp{q}\t{%1, %0|%0, %1}"
818   [(set_attr "type" "test,icmp")
819    (set_attr "length_immediate" "0,1")
820    (set_attr "mode" "DI")])
821
822 (define_insn "*cmpdi_minus_1_rex64"
823   [(set (reg FLAGS_REG)
824         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
825                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
826                  (const_int 0)))]
827   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
828   "cmp{q}\t{%1, %0|%0, %1}"
829   [(set_attr "type" "icmp")
830    (set_attr "mode" "DI")])
831
832 (define_expand "cmpdi_1_rex64"
833   [(set (reg:CC FLAGS_REG)
834         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
835                     (match_operand:DI 1 "general_operand" "")))]
836   "TARGET_64BIT"
837   "")
838
839 (define_insn "cmpdi_1_insn_rex64"
840   [(set (reg FLAGS_REG)
841         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
842                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
843   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
844   "cmp{q}\t{%1, %0|%0, %1}"
845   [(set_attr "type" "icmp")
846    (set_attr "mode" "DI")])
847
848
849 (define_insn "*cmpsi_ccno_1"
850   [(set (reg FLAGS_REG)
851         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
852                  (match_operand:SI 1 "const0_operand" "")))]
853   "ix86_match_ccmode (insn, CCNOmode)"
854   "@
855    test{l}\t%0, %0
856    cmp{l}\t{%1, %0|%0, %1}"
857   [(set_attr "type" "test,icmp")
858    (set_attr "length_immediate" "0,1")
859    (set_attr "mode" "SI")])
860
861 (define_insn "*cmpsi_minus_1"
862   [(set (reg FLAGS_REG)
863         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
864                            (match_operand:SI 1 "general_operand" "ri,mr"))
865                  (const_int 0)))]
866   "ix86_match_ccmode (insn, CCGOCmode)"
867   "cmp{l}\t{%1, %0|%0, %1}"
868   [(set_attr "type" "icmp")
869    (set_attr "mode" "SI")])
870
871 (define_expand "cmpsi_1"
872   [(set (reg:CC FLAGS_REG)
873         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
874                     (match_operand:SI 1 "general_operand" "")))]
875   ""
876   "")
877
878 (define_insn "*cmpsi_1_insn"
879   [(set (reg FLAGS_REG)
880         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
881                  (match_operand:SI 1 "general_operand" "ri,mr")))]
882   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
883     && ix86_match_ccmode (insn, CCmode)"
884   "cmp{l}\t{%1, %0|%0, %1}"
885   [(set_attr "type" "icmp")
886    (set_attr "mode" "SI")])
887
888 (define_insn "*cmphi_ccno_1"
889   [(set (reg FLAGS_REG)
890         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
891                  (match_operand:HI 1 "const0_operand" "")))]
892   "ix86_match_ccmode (insn, CCNOmode)"
893   "@
894    test{w}\t%0, %0
895    cmp{w}\t{%1, %0|%0, %1}"
896   [(set_attr "type" "test,icmp")
897    (set_attr "length_immediate" "0,1")
898    (set_attr "mode" "HI")])
899
900 (define_insn "*cmphi_minus_1"
901   [(set (reg FLAGS_REG)
902         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
903                            (match_operand:HI 1 "general_operand" "rn,mr"))
904                  (const_int 0)))]
905   "ix86_match_ccmode (insn, CCGOCmode)"
906   "cmp{w}\t{%1, %0|%0, %1}"
907   [(set_attr "type" "icmp")
908    (set_attr "mode" "HI")])
909
910 (define_insn "*cmphi_1"
911   [(set (reg FLAGS_REG)
912         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
913                  (match_operand:HI 1 "general_operand" "rn,mr")))]
914   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
915    && ix86_match_ccmode (insn, CCmode)"
916   "cmp{w}\t{%1, %0|%0, %1}"
917   [(set_attr "type" "icmp")
918    (set_attr "mode" "HI")])
919
920 (define_insn "*cmpqi_ccno_1"
921   [(set (reg FLAGS_REG)
922         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
923                  (match_operand:QI 1 "const0_operand" "")))]
924   "ix86_match_ccmode (insn, CCNOmode)"
925   "@
926    test{b}\t%0, %0
927    cmp{b}\t{$0, %0|%0, 0}"
928   [(set_attr "type" "test,icmp")
929    (set_attr "length_immediate" "0,1")
930    (set_attr "mode" "QI")])
931
932 (define_insn "*cmpqi_1"
933   [(set (reg FLAGS_REG)
934         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
935                  (match_operand:QI 1 "general_operand" "qn,mq")))]
936   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
937     && ix86_match_ccmode (insn, CCmode)"
938   "cmp{b}\t{%1, %0|%0, %1}"
939   [(set_attr "type" "icmp")
940    (set_attr "mode" "QI")])
941
942 (define_insn "*cmpqi_minus_1"
943   [(set (reg FLAGS_REG)
944         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
945                            (match_operand:QI 1 "general_operand" "qn,mq"))
946                  (const_int 0)))]
947   "ix86_match_ccmode (insn, CCGOCmode)"
948   "cmp{b}\t{%1, %0|%0, %1}"
949   [(set_attr "type" "icmp")
950    (set_attr "mode" "QI")])
951
952 (define_insn "*cmpqi_ext_1"
953   [(set (reg FLAGS_REG)
954         (compare
955           (match_operand:QI 0 "general_operand" "Qm")
956           (subreg:QI
957             (zero_extract:SI
958               (match_operand 1 "ext_register_operand" "Q")
959               (const_int 8)
960               (const_int 8)) 0)))]
961   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
962   "cmp{b}\t{%h1, %0|%0, %h1}"
963   [(set_attr "type" "icmp")
964    (set_attr "mode" "QI")])
965
966 (define_insn "*cmpqi_ext_1_rex64"
967   [(set (reg FLAGS_REG)
968         (compare
969           (match_operand:QI 0 "register_operand" "Q")
970           (subreg:QI
971             (zero_extract:SI
972               (match_operand 1 "ext_register_operand" "Q")
973               (const_int 8)
974               (const_int 8)) 0)))]
975   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
976   "cmp{b}\t{%h1, %0|%0, %h1}"
977   [(set_attr "type" "icmp")
978    (set_attr "mode" "QI")])
979
980 (define_insn "*cmpqi_ext_2"
981   [(set (reg FLAGS_REG)
982         (compare
983           (subreg:QI
984             (zero_extract:SI
985               (match_operand 0 "ext_register_operand" "Q")
986               (const_int 8)
987               (const_int 8)) 0)
988           (match_operand:QI 1 "const0_operand" "")))]
989   "ix86_match_ccmode (insn, CCNOmode)"
990   "test{b}\t%h0, %h0"
991   [(set_attr "type" "test")
992    (set_attr "length_immediate" "0")
993    (set_attr "mode" "QI")])
994
995 (define_expand "cmpqi_ext_3"
996   [(set (reg:CC FLAGS_REG)
997         (compare:CC
998           (subreg:QI
999             (zero_extract:SI
1000               (match_operand 0 "ext_register_operand" "")
1001               (const_int 8)
1002               (const_int 8)) 0)
1003           (match_operand:QI 1 "general_operand" "")))]
1004   ""
1005   "")
1006
1007 (define_insn "cmpqi_ext_3_insn"
1008   [(set (reg FLAGS_REG)
1009         (compare
1010           (subreg:QI
1011             (zero_extract:SI
1012               (match_operand 0 "ext_register_operand" "Q")
1013               (const_int 8)
1014               (const_int 8)) 0)
1015           (match_operand:QI 1 "general_operand" "Qmn")))]
1016   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1017   "cmp{b}\t{%1, %h0|%h0, %1}"
1018   [(set_attr "type" "icmp")
1019    (set_attr "mode" "QI")])
1020
1021 (define_insn "cmpqi_ext_3_insn_rex64"
1022   [(set (reg FLAGS_REG)
1023         (compare
1024           (subreg:QI
1025             (zero_extract:SI
1026               (match_operand 0 "ext_register_operand" "Q")
1027               (const_int 8)
1028               (const_int 8)) 0)
1029           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1030   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1031   "cmp{b}\t{%1, %h0|%h0, %1}"
1032   [(set_attr "type" "icmp")
1033    (set_attr "mode" "QI")])
1034
1035 (define_insn "*cmpqi_ext_4"
1036   [(set (reg FLAGS_REG)
1037         (compare
1038           (subreg:QI
1039             (zero_extract:SI
1040               (match_operand 0 "ext_register_operand" "Q")
1041               (const_int 8)
1042               (const_int 8)) 0)
1043           (subreg:QI
1044             (zero_extract:SI
1045               (match_operand 1 "ext_register_operand" "Q")
1046               (const_int 8)
1047               (const_int 8)) 0)))]
1048   "ix86_match_ccmode (insn, CCmode)"
1049   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1050   [(set_attr "type" "icmp")
1051    (set_attr "mode" "QI")])
1052
1053 ;; These implement float point compares.
1054 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1055 ;; which would allow mix and match FP modes on the compares.  Which is what
1056 ;; the old patterns did, but with many more of them.
1057
1058 (define_expand "cmpxf"
1059   [(set (reg:CC FLAGS_REG)
1060         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1061                     (match_operand:XF 1 "nonmemory_operand" "")))]
1062   "TARGET_80387"
1063 {
1064   ix86_compare_op0 = operands[0];
1065   ix86_compare_op1 = operands[1];
1066   DONE;
1067 })
1068
1069 (define_expand "cmp<mode>"
1070   [(set (reg:CC FLAGS_REG)
1071         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1072                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1073   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1074 {
1075   ix86_compare_op0 = operands[0];
1076   ix86_compare_op1 = operands[1];
1077   DONE;
1078 })
1079
1080 ;; FP compares, step 1:
1081 ;; Set the FP condition codes.
1082 ;;
1083 ;; CCFPmode     compare with exceptions
1084 ;; CCFPUmode    compare with no exceptions
1085
1086 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1087 ;; used to manage the reg stack popping would not be preserved.
1088
1089 (define_insn "*cmpfp_0"
1090   [(set (match_operand:HI 0 "register_operand" "=a")
1091         (unspec:HI
1092           [(compare:CCFP
1093              (match_operand 1 "register_operand" "f")
1094              (match_operand 2 "const0_operand" ""))]
1095         UNSPEC_FNSTSW))]
1096   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1097    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098   "* return output_fp_compare (insn, operands, 0, 0);"
1099   [(set_attr "type" "multi")
1100    (set_attr "unit" "i387")
1101    (set (attr "mode")
1102      (cond [(match_operand:SF 1 "" "")
1103               (const_string "SF")
1104             (match_operand:DF 1 "" "")
1105               (const_string "DF")
1106            ]
1107            (const_string "XF")))])
1108
1109 (define_insn_and_split "*cmpfp_0_cc"
1110   [(set (reg:CCFP FLAGS_REG)
1111         (compare:CCFP
1112           (match_operand 1 "register_operand" "f")
1113           (match_operand 2 "const0_operand" "")))
1114    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1115   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1116    && TARGET_SAHF && !TARGET_CMOVE
1117    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1118   "#"
1119   "&& reload_completed"
1120   [(set (match_dup 0)
1121         (unspec:HI
1122           [(compare:CCFP (match_dup 1)(match_dup 2))]
1123         UNSPEC_FNSTSW))
1124    (set (reg:CC FLAGS_REG)
1125         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1126   ""
1127   [(set_attr "type" "multi")
1128    (set_attr "unit" "i387")
1129    (set (attr "mode")
1130      (cond [(match_operand:SF 1 "" "")
1131               (const_string "SF")
1132             (match_operand:DF 1 "" "")
1133               (const_string "DF")
1134            ]
1135            (const_string "XF")))])
1136
1137 (define_insn "*cmpfp_xf"
1138   [(set (match_operand:HI 0 "register_operand" "=a")
1139         (unspec:HI
1140           [(compare:CCFP
1141              (match_operand:XF 1 "register_operand" "f")
1142              (match_operand:XF 2 "register_operand" "f"))]
1143           UNSPEC_FNSTSW))]
1144   "TARGET_80387"
1145   "* return output_fp_compare (insn, operands, 0, 0);"
1146   [(set_attr "type" "multi")
1147    (set_attr "unit" "i387")
1148    (set_attr "mode" "XF")])
1149
1150 (define_insn_and_split "*cmpfp_xf_cc"
1151   [(set (reg:CCFP FLAGS_REG)
1152         (compare:CCFP
1153           (match_operand:XF 1 "register_operand" "f")
1154           (match_operand:XF 2 "register_operand" "f")))
1155    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1156   "TARGET_80387
1157    && TARGET_SAHF && !TARGET_CMOVE"
1158   "#"
1159   "&& reload_completed"
1160   [(set (match_dup 0)
1161         (unspec:HI
1162           [(compare:CCFP (match_dup 1)(match_dup 2))]
1163         UNSPEC_FNSTSW))
1164    (set (reg:CC FLAGS_REG)
1165         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1166   ""
1167   [(set_attr "type" "multi")
1168    (set_attr "unit" "i387")
1169    (set_attr "mode" "XF")])
1170
1171 (define_insn "*cmpfp_<mode>"
1172   [(set (match_operand:HI 0 "register_operand" "=a")
1173         (unspec:HI
1174           [(compare:CCFP
1175              (match_operand:MODEF 1 "register_operand" "f")
1176              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1177           UNSPEC_FNSTSW))]
1178   "TARGET_80387"
1179   "* return output_fp_compare (insn, operands, 0, 0);"
1180   [(set_attr "type" "multi")
1181    (set_attr "unit" "i387")
1182    (set_attr "mode" "<MODE>")])
1183
1184 (define_insn_and_split "*cmpfp_<mode>_cc"
1185   [(set (reg:CCFP FLAGS_REG)
1186         (compare:CCFP
1187           (match_operand:MODEF 1 "register_operand" "f")
1188           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1189    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1190   "TARGET_80387
1191    && TARGET_SAHF && !TARGET_CMOVE"
1192   "#"
1193   "&& reload_completed"
1194   [(set (match_dup 0)
1195         (unspec:HI
1196           [(compare:CCFP (match_dup 1)(match_dup 2))]
1197         UNSPEC_FNSTSW))
1198    (set (reg:CC FLAGS_REG)
1199         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1200   ""
1201   [(set_attr "type" "multi")
1202    (set_attr "unit" "i387")
1203    (set_attr "mode" "<MODE>")])
1204
1205 (define_insn "*cmpfp_u"
1206   [(set (match_operand:HI 0 "register_operand" "=a")
1207         (unspec:HI
1208           [(compare:CCFPU
1209              (match_operand 1 "register_operand" "f")
1210              (match_operand 2 "register_operand" "f"))]
1211           UNSPEC_FNSTSW))]
1212   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1213    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1214   "* return output_fp_compare (insn, operands, 0, 1);"
1215   [(set_attr "type" "multi")
1216    (set_attr "unit" "i387")
1217    (set (attr "mode")
1218      (cond [(match_operand:SF 1 "" "")
1219               (const_string "SF")
1220             (match_operand:DF 1 "" "")
1221               (const_string "DF")
1222            ]
1223            (const_string "XF")))])
1224
1225 (define_insn_and_split "*cmpfp_u_cc"
1226   [(set (reg:CCFPU FLAGS_REG)
1227         (compare:CCFPU
1228           (match_operand 1 "register_operand" "f")
1229           (match_operand 2 "register_operand" "f")))
1230    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1231   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1232    && TARGET_SAHF && !TARGET_CMOVE
1233    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234   "#"
1235   "&& reload_completed"
1236   [(set (match_dup 0)
1237         (unspec:HI
1238           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1239         UNSPEC_FNSTSW))
1240    (set (reg:CC FLAGS_REG)
1241         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1242   ""
1243   [(set_attr "type" "multi")
1244    (set_attr "unit" "i387")
1245    (set (attr "mode")
1246      (cond [(match_operand:SF 1 "" "")
1247               (const_string "SF")
1248             (match_operand:DF 1 "" "")
1249               (const_string "DF")
1250            ]
1251            (const_string "XF")))])
1252
1253 (define_insn "*cmpfp_<mode>"
1254   [(set (match_operand:HI 0 "register_operand" "=a")
1255         (unspec:HI
1256           [(compare:CCFP
1257              (match_operand 1 "register_operand" "f")
1258              (match_operator 3 "float_operator"
1259                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1260           UNSPEC_FNSTSW))]
1261   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1262    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1263    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1264   "* return output_fp_compare (insn, operands, 0, 0);"
1265   [(set_attr "type" "multi")
1266    (set_attr "unit" "i387")
1267    (set_attr "fp_int_src" "true")
1268    (set_attr "mode" "<MODE>")])
1269
1270 (define_insn_and_split "*cmpfp_<mode>_cc"
1271   [(set (reg:CCFP FLAGS_REG)
1272         (compare:CCFP
1273           (match_operand 1 "register_operand" "f")
1274           (match_operator 3 "float_operator"
1275             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1276    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1277   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1278    && TARGET_SAHF && !TARGET_CMOVE
1279    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1280    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1281   "#"
1282   "&& reload_completed"
1283   [(set (match_dup 0)
1284         (unspec:HI
1285           [(compare:CCFP
1286              (match_dup 1)
1287              (match_op_dup 3 [(match_dup 2)]))]
1288         UNSPEC_FNSTSW))
1289    (set (reg:CC FLAGS_REG)
1290         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1291   ""
1292   [(set_attr "type" "multi")
1293    (set_attr "unit" "i387")
1294    (set_attr "fp_int_src" "true")
1295    (set_attr "mode" "<MODE>")])
1296
1297 ;; FP compares, step 2
1298 ;; Move the fpsw to ax.
1299
1300 (define_insn "x86_fnstsw_1"
1301   [(set (match_operand:HI 0 "register_operand" "=a")
1302         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1303   "TARGET_80387"
1304   "fnstsw\t%0"
1305   [(set_attr "length" "2")
1306    (set_attr "mode" "SI")
1307    (set_attr "unit" "i387")])
1308
1309 ;; FP compares, step 3
1310 ;; Get ax into flags, general case.
1311
1312 (define_insn "x86_sahf_1"
1313   [(set (reg:CC FLAGS_REG)
1314         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1315                    UNSPEC_SAHF))]
1316   "TARGET_SAHF"
1317 {
1318 #ifndef HAVE_AS_IX86_SAHF
1319   if (TARGET_64BIT)
1320     return ".byte\t0x9e";
1321   else
1322 #endif
1323   return "sahf";
1324 }
1325   [(set_attr "length" "1")
1326    (set_attr "athlon_decode" "vector")
1327    (set_attr "amdfam10_decode" "direct")
1328    (set_attr "mode" "SI")])
1329
1330 ;; Pentium Pro can do steps 1 through 3 in one go.
1331 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1332 (define_insn "*cmpfp_i_mixed"
1333   [(set (reg:CCFP FLAGS_REG)
1334         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1335                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1336   "TARGET_MIX_SSE_I387
1337    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1338    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1339   "* return output_fp_compare (insn, operands, 1, 0);"
1340   [(set_attr "type" "fcmp,ssecomi")
1341    (set_attr "prefix" "orig,maybe_vex")
1342    (set (attr "mode")
1343      (if_then_else (match_operand:SF 1 "" "")
1344         (const_string "SF")
1345         (const_string "DF")))
1346    (set_attr "athlon_decode" "vector")
1347    (set_attr "amdfam10_decode" "direct")])
1348
1349 (define_insn "*cmpfp_i_sse"
1350   [(set (reg:CCFP FLAGS_REG)
1351         (compare:CCFP (match_operand 0 "register_operand" "x")
1352                       (match_operand 1 "nonimmediate_operand" "xm")))]
1353   "TARGET_SSE_MATH
1354    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1355    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1356   "* return output_fp_compare (insn, operands, 1, 0);"
1357   [(set_attr "type" "ssecomi")
1358    (set_attr "prefix" "maybe_vex")
1359    (set (attr "mode")
1360      (if_then_else (match_operand:SF 1 "" "")
1361         (const_string "SF")
1362         (const_string "DF")))
1363    (set_attr "athlon_decode" "vector")
1364    (set_attr "amdfam10_decode" "direct")])
1365
1366 (define_insn "*cmpfp_i_i387"
1367   [(set (reg:CCFP FLAGS_REG)
1368         (compare:CCFP (match_operand 0 "register_operand" "f")
1369                       (match_operand 1 "register_operand" "f")))]
1370   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1371    && TARGET_CMOVE
1372    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1373    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1374   "* return output_fp_compare (insn, operands, 1, 0);"
1375   [(set_attr "type" "fcmp")
1376    (set (attr "mode")
1377      (cond [(match_operand:SF 1 "" "")
1378               (const_string "SF")
1379             (match_operand:DF 1 "" "")
1380               (const_string "DF")
1381            ]
1382            (const_string "XF")))
1383    (set_attr "athlon_decode" "vector")
1384    (set_attr "amdfam10_decode" "direct")])
1385
1386 (define_insn "*cmpfp_iu_mixed"
1387   [(set (reg:CCFPU FLAGS_REG)
1388         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1389                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1390   "TARGET_MIX_SSE_I387
1391    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1392    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1393   "* return output_fp_compare (insn, operands, 1, 1);"
1394   [(set_attr "type" "fcmp,ssecomi")
1395    (set_attr "prefix" "orig,maybe_vex")
1396    (set (attr "mode")
1397      (if_then_else (match_operand:SF 1 "" "")
1398         (const_string "SF")
1399         (const_string "DF")))
1400    (set_attr "athlon_decode" "vector")
1401    (set_attr "amdfam10_decode" "direct")])
1402
1403 (define_insn "*cmpfp_iu_sse"
1404   [(set (reg:CCFPU FLAGS_REG)
1405         (compare:CCFPU (match_operand 0 "register_operand" "x")
1406                        (match_operand 1 "nonimmediate_operand" "xm")))]
1407   "TARGET_SSE_MATH
1408    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1409    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1410   "* return output_fp_compare (insn, operands, 1, 1);"
1411   [(set_attr "type" "ssecomi")
1412    (set_attr "prefix" "maybe_vex")
1413    (set (attr "mode")
1414      (if_then_else (match_operand:SF 1 "" "")
1415         (const_string "SF")
1416         (const_string "DF")))
1417    (set_attr "athlon_decode" "vector")
1418    (set_attr "amdfam10_decode" "direct")])
1419
1420 (define_insn "*cmpfp_iu_387"
1421   [(set (reg:CCFPU FLAGS_REG)
1422         (compare:CCFPU (match_operand 0 "register_operand" "f")
1423                        (match_operand 1 "register_operand" "f")))]
1424   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1425    && TARGET_CMOVE
1426    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1427    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1428   "* return output_fp_compare (insn, operands, 1, 1);"
1429   [(set_attr "type" "fcmp")
1430    (set (attr "mode")
1431      (cond [(match_operand:SF 1 "" "")
1432               (const_string "SF")
1433             (match_operand:DF 1 "" "")
1434               (const_string "DF")
1435            ]
1436            (const_string "XF")))
1437    (set_attr "athlon_decode" "vector")
1438    (set_attr "amdfam10_decode" "direct")])
1439 \f
1440 ;; Move instructions.
1441
1442 ;; General case of fullword move.
1443
1444 (define_expand "movsi"
1445   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1446         (match_operand:SI 1 "general_operand" ""))]
1447   ""
1448   "ix86_expand_move (SImode, operands); DONE;")
1449
1450 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1451 ;; general_operand.
1452 ;;
1453 ;; %%% We don't use a post-inc memory reference because x86 is not a
1454 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1455 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1456 ;; targets without our curiosities, and it is just as easy to represent
1457 ;; this differently.
1458
1459 (define_insn "*pushsi2"
1460   [(set (match_operand:SI 0 "push_operand" "=<")
1461         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1462   "!TARGET_64BIT"
1463   "push{l}\t%1"
1464   [(set_attr "type" "push")
1465    (set_attr "mode" "SI")])
1466
1467 ;; For 64BIT abi we always round up to 8 bytes.
1468 (define_insn "*pushsi2_rex64"
1469   [(set (match_operand:SI 0 "push_operand" "=X")
1470         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1471   "TARGET_64BIT"
1472   "push{q}\t%q1"
1473   [(set_attr "type" "push")
1474    (set_attr "mode" "SI")])
1475
1476 (define_insn "*pushsi2_prologue"
1477   [(set (match_operand:SI 0 "push_operand" "=<")
1478         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1479    (clobber (mem:BLK (scratch)))]
1480   "!TARGET_64BIT"
1481   "push{l}\t%1"
1482   [(set_attr "type" "push")
1483    (set_attr "mode" "SI")])
1484
1485 (define_insn "*popsi1_epilogue"
1486   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1487         (mem:SI (reg:SI SP_REG)))
1488    (set (reg:SI SP_REG)
1489         (plus:SI (reg:SI SP_REG) (const_int 4)))
1490    (clobber (mem:BLK (scratch)))]
1491   "!TARGET_64BIT"
1492   "pop{l}\t%0"
1493   [(set_attr "type" "pop")
1494    (set_attr "mode" "SI")])
1495
1496 (define_insn "popsi1"
1497   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1498         (mem:SI (reg:SI SP_REG)))
1499    (set (reg:SI SP_REG)
1500         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1501   "!TARGET_64BIT"
1502   "pop{l}\t%0"
1503   [(set_attr "type" "pop")
1504    (set_attr "mode" "SI")])
1505
1506 (define_insn "*movsi_xor"
1507   [(set (match_operand:SI 0 "register_operand" "=r")
1508         (match_operand:SI 1 "const0_operand" ""))
1509    (clobber (reg:CC FLAGS_REG))]
1510   "reload_completed"
1511   "xor{l}\t%0, %0"
1512   [(set_attr "type" "alu1")
1513    (set_attr "mode" "SI")
1514    (set_attr "length_immediate" "0")])
1515
1516 (define_insn "*movsi_or"
1517   [(set (match_operand:SI 0 "register_operand" "=r")
1518         (match_operand:SI 1 "immediate_operand" "i"))
1519    (clobber (reg:CC FLAGS_REG))]
1520   "reload_completed
1521    && operands[1] == constm1_rtx"
1522 {
1523   operands[1] = constm1_rtx;
1524   return "or{l}\t{%1, %0|%0, %1}";
1525 }
1526   [(set_attr "type" "alu1")
1527    (set_attr "mode" "SI")
1528    (set_attr "length_immediate" "1")])
1529
1530 (define_insn "*movsi_1"
1531   [(set (match_operand:SI 0 "nonimmediate_operand"
1532                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1533         (match_operand:SI 1 "general_operand"
1534                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1535   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1536 {
1537   switch (get_attr_type (insn))
1538     {
1539     case TYPE_SSELOG1:
1540       if (get_attr_mode (insn) == MODE_TI)
1541         return "%vpxor\t%0, %d0";
1542       return "%vxorps\t%0, %d0";
1543
1544     case TYPE_SSEMOV:
1545       switch (get_attr_mode (insn))
1546         {
1547         case MODE_TI:
1548           return "%vmovdqa\t{%1, %0|%0, %1}";
1549         case MODE_V4SF:
1550           return "%vmovaps\t{%1, %0|%0, %1}";
1551         case MODE_SI:
1552           return "%vmovd\t{%1, %0|%0, %1}";
1553         case MODE_SF:
1554           return "%vmovss\t{%1, %0|%0, %1}";
1555         default:
1556           gcc_unreachable ();
1557         }
1558
1559     case TYPE_MMX:
1560       return "pxor\t%0, %0";
1561
1562     case TYPE_MMXMOV:
1563       if (get_attr_mode (insn) == MODE_DI)
1564         return "movq\t{%1, %0|%0, %1}";
1565       return "movd\t{%1, %0|%0, %1}";
1566
1567     case TYPE_LEA:
1568       return "lea{l}\t{%a1, %0|%0, %a1}";
1569
1570     default:
1571       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1572       return "mov{l}\t{%1, %0|%0, %1}";
1573     }
1574 }
1575   [(set (attr "type")
1576      (cond [(eq_attr "alternative" "2")
1577               (const_string "mmx")
1578             (eq_attr "alternative" "3,4,5")
1579               (const_string "mmxmov")
1580             (eq_attr "alternative" "6")
1581               (const_string "sselog1")
1582             (eq_attr "alternative" "7,8,9,10,11")
1583               (const_string "ssemov")
1584             (match_operand:DI 1 "pic_32bit_operand" "")
1585               (const_string "lea")
1586            ]
1587            (const_string "imov")))
1588    (set (attr "prefix")
1589      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1590        (const_string "orig")
1591        (const_string "maybe_vex")))
1592    (set (attr "mode")
1593      (cond [(eq_attr "alternative" "2,3")
1594               (const_string "DI")
1595             (eq_attr "alternative" "6,7")
1596               (if_then_else
1597                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1598                 (const_string "V4SF")
1599                 (const_string "TI"))
1600             (and (eq_attr "alternative" "8,9,10,11")
1601                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1602               (const_string "SF")
1603            ]
1604            (const_string "SI")))])
1605
1606 ;; Stores and loads of ax to arbitrary constant address.
1607 ;; We fake an second form of instruction to force reload to load address
1608 ;; into register when rax is not available
1609 (define_insn "*movabssi_1_rex64"
1610   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1611         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1612   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1613   "@
1614    movabs{l}\t{%1, %P0|%P0, %1}
1615    mov{l}\t{%1, %a0|%a0, %1}"
1616   [(set_attr "type" "imov")
1617    (set_attr "modrm" "0,*")
1618    (set_attr "length_address" "8,0")
1619    (set_attr "length_immediate" "0,*")
1620    (set_attr "memory" "store")
1621    (set_attr "mode" "SI")])
1622
1623 (define_insn "*movabssi_2_rex64"
1624   [(set (match_operand:SI 0 "register_operand" "=a,r")
1625         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1626   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1627   "@
1628    movabs{l}\t{%P1, %0|%0, %P1}
1629    mov{l}\t{%a1, %0|%0, %a1}"
1630   [(set_attr "type" "imov")
1631    (set_attr "modrm" "0,*")
1632    (set_attr "length_address" "8,0")
1633    (set_attr "length_immediate" "0")
1634    (set_attr "memory" "load")
1635    (set_attr "mode" "SI")])
1636
1637 (define_insn "*swapsi"
1638   [(set (match_operand:SI 0 "register_operand" "+r")
1639         (match_operand:SI 1 "register_operand" "+r"))
1640    (set (match_dup 1)
1641         (match_dup 0))]
1642   ""
1643   "xchg{l}\t%1, %0"
1644   [(set_attr "type" "imov")
1645    (set_attr "mode" "SI")
1646    (set_attr "pent_pair" "np")
1647    (set_attr "athlon_decode" "vector")
1648    (set_attr "amdfam10_decode" "double")])
1649
1650 (define_expand "movhi"
1651   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1652         (match_operand:HI 1 "general_operand" ""))]
1653   ""
1654   "ix86_expand_move (HImode, operands); DONE;")
1655
1656 (define_insn "*pushhi2"
1657   [(set (match_operand:HI 0 "push_operand" "=X")
1658         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1659   "!TARGET_64BIT"
1660   "push{l}\t%k1"
1661   [(set_attr "type" "push")
1662    (set_attr "mode" "SI")])
1663
1664 ;; For 64BIT abi we always round up to 8 bytes.
1665 (define_insn "*pushhi2_rex64"
1666   [(set (match_operand:HI 0 "push_operand" "=X")
1667         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1668   "TARGET_64BIT"
1669   "push{q}\t%q1"
1670   [(set_attr "type" "push")
1671    (set_attr "mode" "DI")])
1672
1673 (define_insn "*movhi_1"
1674   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1675         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1676   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1677 {
1678   switch (get_attr_type (insn))
1679     {
1680     case TYPE_IMOVX:
1681       /* movzwl is faster than movw on p2 due to partial word stalls,
1682          though not as fast as an aligned movl.  */
1683       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1684     default:
1685       if (get_attr_mode (insn) == MODE_SI)
1686         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1687       else
1688         return "mov{w}\t{%1, %0|%0, %1}";
1689     }
1690 }
1691   [(set (attr "type")
1692      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1693               (const_string "imov")
1694             (and (eq_attr "alternative" "0")
1695                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1696                           (const_int 0))
1697                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1698                           (const_int 0))))
1699               (const_string "imov")
1700             (and (eq_attr "alternative" "1,2")
1701                  (match_operand:HI 1 "aligned_operand" ""))
1702               (const_string "imov")
1703             (and (ne (symbol_ref "TARGET_MOVX")
1704                      (const_int 0))
1705                  (eq_attr "alternative" "0,2"))
1706               (const_string "imovx")
1707            ]
1708            (const_string "imov")))
1709     (set (attr "mode")
1710       (cond [(eq_attr "type" "imovx")
1711                (const_string "SI")
1712              (and (eq_attr "alternative" "1,2")
1713                   (match_operand:HI 1 "aligned_operand" ""))
1714                (const_string "SI")
1715              (and (eq_attr "alternative" "0")
1716                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1717                            (const_int 0))
1718                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1719                            (const_int 0))))
1720                (const_string "SI")
1721             ]
1722             (const_string "HI")))])
1723
1724 ;; Stores and loads of ax to arbitrary constant address.
1725 ;; We fake an second form of instruction to force reload to load address
1726 ;; into register when rax is not available
1727 (define_insn "*movabshi_1_rex64"
1728   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1729         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1730   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1731   "@
1732    movabs{w}\t{%1, %P0|%P0, %1}
1733    mov{w}\t{%1, %a0|%a0, %1}"
1734   [(set_attr "type" "imov")
1735    (set_attr "modrm" "0,*")
1736    (set_attr "length_address" "8,0")
1737    (set_attr "length_immediate" "0,*")
1738    (set_attr "memory" "store")
1739    (set_attr "mode" "HI")])
1740
1741 (define_insn "*movabshi_2_rex64"
1742   [(set (match_operand:HI 0 "register_operand" "=a,r")
1743         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1744   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1745   "@
1746    movabs{w}\t{%P1, %0|%0, %P1}
1747    mov{w}\t{%a1, %0|%0, %a1}"
1748   [(set_attr "type" "imov")
1749    (set_attr "modrm" "0,*")
1750    (set_attr "length_address" "8,0")
1751    (set_attr "length_immediate" "0")
1752    (set_attr "memory" "load")
1753    (set_attr "mode" "HI")])
1754
1755 (define_insn "*swaphi_1"
1756   [(set (match_operand:HI 0 "register_operand" "+r")
1757         (match_operand:HI 1 "register_operand" "+r"))
1758    (set (match_dup 1)
1759         (match_dup 0))]
1760   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1761   "xchg{l}\t%k1, %k0"
1762   [(set_attr "type" "imov")
1763    (set_attr "mode" "SI")
1764    (set_attr "pent_pair" "np")
1765    (set_attr "athlon_decode" "vector")
1766    (set_attr "amdfam10_decode" "double")])
1767
1768 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1769 (define_insn "*swaphi_2"
1770   [(set (match_operand:HI 0 "register_operand" "+r")
1771         (match_operand:HI 1 "register_operand" "+r"))
1772    (set (match_dup 1)
1773         (match_dup 0))]
1774   "TARGET_PARTIAL_REG_STALL"
1775   "xchg{w}\t%1, %0"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "HI")
1778    (set_attr "pent_pair" "np")
1779    (set_attr "athlon_decode" "vector")])
1780
1781 (define_expand "movstricthi"
1782   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1783         (match_operand:HI 1 "general_operand" ""))]
1784   ""
1785 {
1786   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1787     FAIL;
1788   /* Don't generate memory->memory moves, go through a register */
1789   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1790     operands[1] = force_reg (HImode, operands[1]);
1791 })
1792
1793 (define_insn "*movstricthi_1"
1794   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1795         (match_operand:HI 1 "general_operand" "rn,m"))]
1796   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1798   "mov{w}\t{%1, %0|%0, %1}"
1799   [(set_attr "type" "imov")
1800    (set_attr "mode" "HI")])
1801
1802 (define_insn "*movstricthi_xor"
1803   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1804         (match_operand:HI 1 "const0_operand" ""))
1805    (clobber (reg:CC FLAGS_REG))]
1806   "reload_completed"
1807   "xor{w}\t%0, %0"
1808   [(set_attr "type" "alu1")
1809    (set_attr "mode" "HI")
1810    (set_attr "length_immediate" "0")])
1811
1812 (define_expand "movqi"
1813   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1814         (match_operand:QI 1 "general_operand" ""))]
1815   ""
1816   "ix86_expand_move (QImode, operands); DONE;")
1817
1818 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1819 ;; "push a byte".  But actually we use pushl, which has the effect
1820 ;; of rounding the amount pushed up to a word.
1821
1822 (define_insn "*pushqi2"
1823   [(set (match_operand:QI 0 "push_operand" "=X")
1824         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1825   "!TARGET_64BIT"
1826   "push{l}\t%k1"
1827   [(set_attr "type" "push")
1828    (set_attr "mode" "SI")])
1829
1830 ;; For 64BIT abi we always round up to 8 bytes.
1831 (define_insn "*pushqi2_rex64"
1832   [(set (match_operand:QI 0 "push_operand" "=X")
1833         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1834   "TARGET_64BIT"
1835   "push{q}\t%q1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "DI")])
1838
1839 ;; Situation is quite tricky about when to choose full sized (SImode) move
1840 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1841 ;; partial register dependency machines (such as AMD Athlon), where QImode
1842 ;; moves issue extra dependency and for partial register stalls machines
1843 ;; that don't use QImode patterns (and QImode move cause stall on the next
1844 ;; instruction).
1845 ;;
1846 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1847 ;; register stall machines with, where we use QImode instructions, since
1848 ;; partial register stall can be caused there.  Then we use movzx.
1849 (define_insn "*movqi_1"
1850   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1851         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1852   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1853 {
1854   switch (get_attr_type (insn))
1855     {
1856     case TYPE_IMOVX:
1857       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1858       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1859     default:
1860       if (get_attr_mode (insn) == MODE_SI)
1861         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1862       else
1863         return "mov{b}\t{%1, %0|%0, %1}";
1864     }
1865 }
1866   [(set (attr "type")
1867      (cond [(and (eq_attr "alternative" "5")
1868                  (not (match_operand:QI 1 "aligned_operand" "")))
1869               (const_string "imovx")
1870             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1871               (const_string "imov")
1872             (and (eq_attr "alternative" "3")
1873                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1874                           (const_int 0))
1875                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1876                           (const_int 0))))
1877               (const_string "imov")
1878             (eq_attr "alternative" "3,5")
1879               (const_string "imovx")
1880             (and (ne (symbol_ref "TARGET_MOVX")
1881                      (const_int 0))
1882                  (eq_attr "alternative" "2"))
1883               (const_string "imovx")
1884            ]
1885            (const_string "imov")))
1886    (set (attr "mode")
1887       (cond [(eq_attr "alternative" "3,4,5")
1888                (const_string "SI")
1889              (eq_attr "alternative" "6")
1890                (const_string "QI")
1891              (eq_attr "type" "imovx")
1892                (const_string "SI")
1893              (and (eq_attr "type" "imov")
1894                   (and (eq_attr "alternative" "0,1")
1895                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1896                                 (const_int 0))
1897                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1898                                      (const_int 0))
1899                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1900                                      (const_int 0))))))
1901                (const_string "SI")
1902              ;; Avoid partial register stalls when not using QImode arithmetic
1903              (and (eq_attr "type" "imov")
1904                   (and (eq_attr "alternative" "0,1")
1905                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1906                                 (const_int 0))
1907                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1908                                 (const_int 0)))))
1909                (const_string "SI")
1910            ]
1911            (const_string "QI")))])
1912
1913 (define_insn "*swapqi_1"
1914   [(set (match_operand:QI 0 "register_operand" "+r")
1915         (match_operand:QI 1 "register_operand" "+r"))
1916    (set (match_dup 1)
1917         (match_dup 0))]
1918   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1919   "xchg{l}\t%k1, %k0"
1920   [(set_attr "type" "imov")
1921    (set_attr "mode" "SI")
1922    (set_attr "pent_pair" "np")
1923    (set_attr "athlon_decode" "vector")
1924    (set_attr "amdfam10_decode" "vector")])
1925
1926 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1927 (define_insn "*swapqi_2"
1928   [(set (match_operand:QI 0 "register_operand" "+q")
1929         (match_operand:QI 1 "register_operand" "+q"))
1930    (set (match_dup 1)
1931         (match_dup 0))]
1932   "TARGET_PARTIAL_REG_STALL"
1933   "xchg{b}\t%1, %0"
1934   [(set_attr "type" "imov")
1935    (set_attr "mode" "QI")
1936    (set_attr "pent_pair" "np")
1937    (set_attr "athlon_decode" "vector")])
1938
1939 (define_expand "movstrictqi"
1940   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1941         (match_operand:QI 1 "general_operand" ""))]
1942   ""
1943 {
1944   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1945     FAIL;
1946   /* Don't generate memory->memory moves, go through a register.  */
1947   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1948     operands[1] = force_reg (QImode, operands[1]);
1949 })
1950
1951 (define_insn "*movstrictqi_1"
1952   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1953         (match_operand:QI 1 "general_operand" "*qn,m"))]
1954   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1955    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1956   "mov{b}\t{%1, %0|%0, %1}"
1957   [(set_attr "type" "imov")
1958    (set_attr "mode" "QI")])
1959
1960 (define_insn "*movstrictqi_xor"
1961   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1962         (match_operand:QI 1 "const0_operand" ""))
1963    (clobber (reg:CC FLAGS_REG))]
1964   "reload_completed"
1965   "xor{b}\t%0, %0"
1966   [(set_attr "type" "alu1")
1967    (set_attr "mode" "QI")
1968    (set_attr "length_immediate" "0")])
1969
1970 (define_insn "*movsi_extv_1"
1971   [(set (match_operand:SI 0 "register_operand" "=R")
1972         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1973                          (const_int 8)
1974                          (const_int 8)))]
1975   ""
1976   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1977   [(set_attr "type" "imovx")
1978    (set_attr "mode" "SI")])
1979
1980 (define_insn "*movhi_extv_1"
1981   [(set (match_operand:HI 0 "register_operand" "=R")
1982         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1983                          (const_int 8)
1984                          (const_int 8)))]
1985   ""
1986   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1987   [(set_attr "type" "imovx")
1988    (set_attr "mode" "SI")])
1989
1990 (define_insn "*movqi_extv_1"
1991   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1992         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1993                          (const_int 8)
1994                          (const_int 8)))]
1995   "!TARGET_64BIT"
1996 {
1997   switch (get_attr_type (insn))
1998     {
1999     case TYPE_IMOVX:
2000       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2001     default:
2002       return "mov{b}\t{%h1, %0|%0, %h1}";
2003     }
2004 }
2005   [(set (attr "type")
2006      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2007                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2008                              (ne (symbol_ref "TARGET_MOVX")
2009                                  (const_int 0))))
2010         (const_string "imovx")
2011         (const_string "imov")))
2012    (set (attr "mode")
2013      (if_then_else (eq_attr "type" "imovx")
2014         (const_string "SI")
2015         (const_string "QI")))])
2016
2017 (define_insn "*movqi_extv_1_rex64"
2018   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2019         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2020                          (const_int 8)
2021                          (const_int 8)))]
2022   "TARGET_64BIT"
2023 {
2024   switch (get_attr_type (insn))
2025     {
2026     case TYPE_IMOVX:
2027       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2028     default:
2029       return "mov{b}\t{%h1, %0|%0, %h1}";
2030     }
2031 }
2032   [(set (attr "type")
2033      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2034                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2035                              (ne (symbol_ref "TARGET_MOVX")
2036                                  (const_int 0))))
2037         (const_string "imovx")
2038         (const_string "imov")))
2039    (set (attr "mode")
2040      (if_then_else (eq_attr "type" "imovx")
2041         (const_string "SI")
2042         (const_string "QI")))])
2043
2044 ;; Stores and loads of ax to arbitrary constant address.
2045 ;; We fake an second form of instruction to force reload to load address
2046 ;; into register when rax is not available
2047 (define_insn "*movabsqi_1_rex64"
2048   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2049         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2050   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2051   "@
2052    movabs{b}\t{%1, %P0|%P0, %1}
2053    mov{b}\t{%1, %a0|%a0, %1}"
2054   [(set_attr "type" "imov")
2055    (set_attr "modrm" "0,*")
2056    (set_attr "length_address" "8,0")
2057    (set_attr "length_immediate" "0,*")
2058    (set_attr "memory" "store")
2059    (set_attr "mode" "QI")])
2060
2061 (define_insn "*movabsqi_2_rex64"
2062   [(set (match_operand:QI 0 "register_operand" "=a,r")
2063         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2064   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2065   "@
2066    movabs{b}\t{%P1, %0|%0, %P1}
2067    mov{b}\t{%a1, %0|%0, %a1}"
2068   [(set_attr "type" "imov")
2069    (set_attr "modrm" "0,*")
2070    (set_attr "length_address" "8,0")
2071    (set_attr "length_immediate" "0")
2072    (set_attr "memory" "load")
2073    (set_attr "mode" "QI")])
2074
2075 (define_insn "*movdi_extzv_1"
2076   [(set (match_operand:DI 0 "register_operand" "=R")
2077         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2078                          (const_int 8)
2079                          (const_int 8)))]
2080   "TARGET_64BIT"
2081   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2082   [(set_attr "type" "imovx")
2083    (set_attr "mode" "DI")])
2084
2085 (define_insn "*movsi_extzv_1"
2086   [(set (match_operand:SI 0 "register_operand" "=R")
2087         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2088                          (const_int 8)
2089                          (const_int 8)))]
2090   ""
2091   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2092   [(set_attr "type" "imovx")
2093    (set_attr "mode" "SI")])
2094
2095 (define_insn "*movqi_extzv_2"
2096   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2097         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2098                                     (const_int 8)
2099                                     (const_int 8)) 0))]
2100   "!TARGET_64BIT"
2101 {
2102   switch (get_attr_type (insn))
2103     {
2104     case TYPE_IMOVX:
2105       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2106     default:
2107       return "mov{b}\t{%h1, %0|%0, %h1}";
2108     }
2109 }
2110   [(set (attr "type")
2111      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2112                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2113                              (ne (symbol_ref "TARGET_MOVX")
2114                                  (const_int 0))))
2115         (const_string "imovx")
2116         (const_string "imov")))
2117    (set (attr "mode")
2118      (if_then_else (eq_attr "type" "imovx")
2119         (const_string "SI")
2120         (const_string "QI")))])
2121
2122 (define_insn "*movqi_extzv_2_rex64"
2123   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2124         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2125                                     (const_int 8)
2126                                     (const_int 8)) 0))]
2127   "TARGET_64BIT"
2128 {
2129   switch (get_attr_type (insn))
2130     {
2131     case TYPE_IMOVX:
2132       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2133     default:
2134       return "mov{b}\t{%h1, %0|%0, %h1}";
2135     }
2136 }
2137   [(set (attr "type")
2138      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2139                         (ne (symbol_ref "TARGET_MOVX")
2140                             (const_int 0)))
2141         (const_string "imovx")
2142         (const_string "imov")))
2143    (set (attr "mode")
2144      (if_then_else (eq_attr "type" "imovx")
2145         (const_string "SI")
2146         (const_string "QI")))])
2147
2148 (define_insn "movsi_insv_1"
2149   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2150                          (const_int 8)
2151                          (const_int 8))
2152         (match_operand:SI 1 "general_operand" "Qmn"))]
2153   "!TARGET_64BIT"
2154   "mov{b}\t{%b1, %h0|%h0, %b1}"
2155   [(set_attr "type" "imov")
2156    (set_attr "mode" "QI")])
2157
2158 (define_insn "*movsi_insv_1_rex64"
2159   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2160                          (const_int 8)
2161                          (const_int 8))
2162         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2163   "TARGET_64BIT"
2164   "mov{b}\t{%b1, %h0|%h0, %b1}"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "QI")])
2167
2168 (define_insn "movdi_insv_1_rex64"
2169   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2170                          (const_int 8)
2171                          (const_int 8))
2172         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2173   "TARGET_64BIT"
2174   "mov{b}\t{%b1, %h0|%h0, %b1}"
2175   [(set_attr "type" "imov")
2176    (set_attr "mode" "QI")])
2177
2178 (define_insn "*movqi_insv_2"
2179   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2180                          (const_int 8)
2181                          (const_int 8))
2182         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2183                      (const_int 8)))]
2184   ""
2185   "mov{b}\t{%h1, %h0|%h0, %h1}"
2186   [(set_attr "type" "imov")
2187    (set_attr "mode" "QI")])
2188
2189 (define_expand "movdi"
2190   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2191         (match_operand:DI 1 "general_operand" ""))]
2192   ""
2193   "ix86_expand_move (DImode, operands); DONE;")
2194
2195 (define_insn "*pushdi"
2196   [(set (match_operand:DI 0 "push_operand" "=<")
2197         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2198   "!TARGET_64BIT"
2199   "#")
2200
2201 (define_insn "*pushdi2_rex64"
2202   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2203         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2204   "TARGET_64BIT"
2205   "@
2206    push{q}\t%1
2207    #"
2208   [(set_attr "type" "push,multi")
2209    (set_attr "mode" "DI")])
2210
2211 ;; Convert impossible pushes of immediate to existing instructions.
2212 ;; First try to get scratch register and go through it.  In case this
2213 ;; fails, push sign extended lower part first and then overwrite
2214 ;; upper part by 32bit move.
2215 (define_peephole2
2216   [(match_scratch:DI 2 "r")
2217    (set (match_operand:DI 0 "push_operand" "")
2218         (match_operand:DI 1 "immediate_operand" ""))]
2219   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2220    && !x86_64_immediate_operand (operands[1], DImode)"
2221   [(set (match_dup 2) (match_dup 1))
2222    (set (match_dup 0) (match_dup 2))]
2223   "")
2224
2225 ;; We need to define this as both peepholer and splitter for case
2226 ;; peephole2 pass is not run.
2227 ;; "&& 1" is needed to keep it from matching the previous pattern.
2228 (define_peephole2
2229   [(set (match_operand:DI 0 "push_operand" "")
2230         (match_operand:DI 1 "immediate_operand" ""))]
2231   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2232    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2233   [(set (match_dup 0) (match_dup 1))
2234    (set (match_dup 2) (match_dup 3))]
2235   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2236    operands[1] = gen_lowpart (DImode, operands[2]);
2237    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2238                                                     GEN_INT (4)));
2239   ")
2240
2241 (define_split
2242   [(set (match_operand:DI 0 "push_operand" "")
2243         (match_operand:DI 1 "immediate_operand" ""))]
2244   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2245                     ? epilogue_completed : reload_completed)
2246    && !symbolic_operand (operands[1], DImode)
2247    && !x86_64_immediate_operand (operands[1], DImode)"
2248   [(set (match_dup 0) (match_dup 1))
2249    (set (match_dup 2) (match_dup 3))]
2250   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2251    operands[1] = gen_lowpart (DImode, operands[2]);
2252    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2253                                                     GEN_INT (4)));
2254   ")
2255
2256 (define_insn "*pushdi2_prologue_rex64"
2257   [(set (match_operand:DI 0 "push_operand" "=<")
2258         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2259    (clobber (mem:BLK (scratch)))]
2260   "TARGET_64BIT"
2261   "push{q}\t%1"
2262   [(set_attr "type" "push")
2263    (set_attr "mode" "DI")])
2264
2265 (define_insn "*popdi1_epilogue_rex64"
2266   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2267         (mem:DI (reg:DI SP_REG)))
2268    (set (reg:DI SP_REG)
2269         (plus:DI (reg:DI SP_REG) (const_int 8)))
2270    (clobber (mem:BLK (scratch)))]
2271   "TARGET_64BIT"
2272   "pop{q}\t%0"
2273   [(set_attr "type" "pop")
2274    (set_attr "mode" "DI")])
2275
2276 (define_insn "popdi1"
2277   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2278         (mem:DI (reg:DI SP_REG)))
2279    (set (reg:DI SP_REG)
2280         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2281   "TARGET_64BIT"
2282   "pop{q}\t%0"
2283   [(set_attr "type" "pop")
2284    (set_attr "mode" "DI")])
2285
2286 (define_insn "*movdi_xor_rex64"
2287   [(set (match_operand:DI 0 "register_operand" "=r")
2288         (match_operand:DI 1 "const0_operand" ""))
2289    (clobber (reg:CC FLAGS_REG))]
2290   "TARGET_64BIT
2291    && reload_completed"
2292   "xor{l}\t%k0, %k0";
2293   [(set_attr "type" "alu1")
2294    (set_attr "mode" "SI")
2295    (set_attr "length_immediate" "0")])
2296
2297 (define_insn "*movdi_or_rex64"
2298   [(set (match_operand:DI 0 "register_operand" "=r")
2299         (match_operand:DI 1 "const_int_operand" "i"))
2300    (clobber (reg:CC FLAGS_REG))]
2301   "TARGET_64BIT
2302    && reload_completed
2303    && operands[1] == constm1_rtx"
2304 {
2305   operands[1] = constm1_rtx;
2306   return "or{q}\t{%1, %0|%0, %1}";
2307 }
2308   [(set_attr "type" "alu1")
2309    (set_attr "mode" "DI")
2310    (set_attr "length_immediate" "1")])
2311
2312 (define_insn "*movdi_2"
2313   [(set (match_operand:DI 0 "nonimmediate_operand"
2314                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2315         (match_operand:DI 1 "general_operand"
2316                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2317   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2318   "@
2319    #
2320    #
2321    pxor\t%0, %0
2322    movq\t{%1, %0|%0, %1}
2323    movq\t{%1, %0|%0, %1}
2324    %vpxor\t%0, %d0
2325    %vmovq\t{%1, %0|%0, %1}
2326    %vmovdqa\t{%1, %0|%0, %1}
2327    %vmovq\t{%1, %0|%0, %1}
2328    xorps\t%0, %0
2329    movlps\t{%1, %0|%0, %1}
2330    movaps\t{%1, %0|%0, %1}
2331    movlps\t{%1, %0|%0, %1}"
2332   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2333    (set (attr "prefix")
2334      (if_then_else (eq_attr "alternative" "5,6,7,8")
2335        (const_string "vex")
2336        (const_string "orig")))
2337    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2338
2339 (define_split
2340   [(set (match_operand:DI 0 "push_operand" "")
2341         (match_operand:DI 1 "general_operand" ""))]
2342   "!TARGET_64BIT && reload_completed
2343    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2344   [(const_int 0)]
2345   "ix86_split_long_move (operands); DONE;")
2346
2347 ;; %%% This multiword shite has got to go.
2348 (define_split
2349   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2350         (match_operand:DI 1 "general_operand" ""))]
2351   "!TARGET_64BIT && reload_completed
2352    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2353    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2354   [(const_int 0)]
2355   "ix86_split_long_move (operands); DONE;")
2356
2357 (define_insn "*movdi_1_rex64"
2358   [(set (match_operand:DI 0 "nonimmediate_operand"
2359           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2360         (match_operand:DI 1 "general_operand"
2361           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2362   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2363 {
2364   switch (get_attr_type (insn))
2365     {
2366     case TYPE_SSECVT:
2367       if (SSE_REG_P (operands[0]))
2368         return "movq2dq\t{%1, %0|%0, %1}";
2369       else
2370         return "movdq2q\t{%1, %0|%0, %1}";
2371
2372     case TYPE_SSEMOV:
2373       if (TARGET_AVX)
2374         {
2375           if (get_attr_mode (insn) == MODE_TI)
2376             return "vmovdqa\t{%1, %0|%0, %1}";
2377           else
2378             return "vmovq\t{%1, %0|%0, %1}";
2379         }
2380
2381       if (get_attr_mode (insn) == MODE_TI)
2382         return "movdqa\t{%1, %0|%0, %1}";
2383       /* FALLTHRU */
2384
2385     case TYPE_MMXMOV:
2386       /* Moves from and into integer register is done using movd
2387          opcode with REX prefix.  */
2388       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2389         return "movd\t{%1, %0|%0, %1}";
2390       return "movq\t{%1, %0|%0, %1}";
2391
2392     case TYPE_SSELOG1:
2393       return "%vpxor\t%0, %d0";
2394
2395     case TYPE_MMX:
2396       return "pxor\t%0, %0";
2397
2398     case TYPE_MULTI:
2399       return "#";
2400
2401     case TYPE_LEA:
2402       return "lea{q}\t{%a1, %0|%0, %a1}";
2403
2404     default:
2405       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2406       if (get_attr_mode (insn) == MODE_SI)
2407         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2408       else if (which_alternative == 2)
2409         return "movabs{q}\t{%1, %0|%0, %1}";
2410       else
2411         return "mov{q}\t{%1, %0|%0, %1}";
2412     }
2413 }
2414   [(set (attr "type")
2415      (cond [(eq_attr "alternative" "5")
2416               (const_string "mmx")
2417             (eq_attr "alternative" "6,7,8,9,10")
2418               (const_string "mmxmov")
2419             (eq_attr "alternative" "11")
2420               (const_string "sselog1")
2421             (eq_attr "alternative" "12,13,14,15,16")
2422               (const_string "ssemov")
2423             (eq_attr "alternative" "17,18")
2424               (const_string "ssecvt")
2425             (eq_attr "alternative" "4")
2426               (const_string "multi")
2427             (match_operand:DI 1 "pic_32bit_operand" "")
2428               (const_string "lea")
2429            ]
2430            (const_string "imov")))
2431    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2432    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2433    (set (attr "prefix")
2434      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2435        (const_string "maybe_vex")
2436        (const_string "orig")))
2437    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2438
2439 ;; Stores and loads of ax to arbitrary constant address.
2440 ;; We fake an second form of instruction to force reload to load address
2441 ;; into register when rax is not available
2442 (define_insn "*movabsdi_1_rex64"
2443   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2444         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2445   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2446   "@
2447    movabs{q}\t{%1, %P0|%P0, %1}
2448    mov{q}\t{%1, %a0|%a0, %1}"
2449   [(set_attr "type" "imov")
2450    (set_attr "modrm" "0,*")
2451    (set_attr "length_address" "8,0")
2452    (set_attr "length_immediate" "0,*")
2453    (set_attr "memory" "store")
2454    (set_attr "mode" "DI")])
2455
2456 (define_insn "*movabsdi_2_rex64"
2457   [(set (match_operand:DI 0 "register_operand" "=a,r")
2458         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2459   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2460   "@
2461    movabs{q}\t{%P1, %0|%0, %P1}
2462    mov{q}\t{%a1, %0|%0, %a1}"
2463   [(set_attr "type" "imov")
2464    (set_attr "modrm" "0,*")
2465    (set_attr "length_address" "8,0")
2466    (set_attr "length_immediate" "0")
2467    (set_attr "memory" "load")
2468    (set_attr "mode" "DI")])
2469
2470 ;; Convert impossible stores of immediate to existing instructions.
2471 ;; First try to get scratch register and go through it.  In case this
2472 ;; fails, move by 32bit parts.
2473 (define_peephole2
2474   [(match_scratch:DI 2 "r")
2475    (set (match_operand:DI 0 "memory_operand" "")
2476         (match_operand:DI 1 "immediate_operand" ""))]
2477   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2478    && !x86_64_immediate_operand (operands[1], DImode)"
2479   [(set (match_dup 2) (match_dup 1))
2480    (set (match_dup 0) (match_dup 2))]
2481   "")
2482
2483 ;; We need to define this as both peepholer and splitter for case
2484 ;; peephole2 pass is not run.
2485 ;; "&& 1" is needed to keep it from matching the previous pattern.
2486 (define_peephole2
2487   [(set (match_operand:DI 0 "memory_operand" "")
2488         (match_operand:DI 1 "immediate_operand" ""))]
2489   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2490    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2491   [(set (match_dup 2) (match_dup 3))
2492    (set (match_dup 4) (match_dup 5))]
2493   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2494
2495 (define_split
2496   [(set (match_operand:DI 0 "memory_operand" "")
2497         (match_operand:DI 1 "immediate_operand" ""))]
2498   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2499                     ? epilogue_completed : reload_completed)
2500    && !symbolic_operand (operands[1], DImode)
2501    && !x86_64_immediate_operand (operands[1], DImode)"
2502   [(set (match_dup 2) (match_dup 3))
2503    (set (match_dup 4) (match_dup 5))]
2504   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2505
2506 (define_insn "*swapdi_rex64"
2507   [(set (match_operand:DI 0 "register_operand" "+r")
2508         (match_operand:DI 1 "register_operand" "+r"))
2509    (set (match_dup 1)
2510         (match_dup 0))]
2511   "TARGET_64BIT"
2512   "xchg{q}\t%1, %0"
2513   [(set_attr "type" "imov")
2514    (set_attr "mode" "DI")
2515    (set_attr "pent_pair" "np")
2516    (set_attr "athlon_decode" "vector")
2517    (set_attr "amdfam10_decode" "double")])
2518
2519 (define_expand "movoi"
2520   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2521         (match_operand:OI 1 "general_operand" ""))]
2522   "TARGET_AVX"
2523   "ix86_expand_move (OImode, operands); DONE;")
2524
2525 (define_insn "*movoi_internal"
2526   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2527         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2528   "TARGET_AVX
2529    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2530 {
2531   switch (which_alternative)
2532     {
2533     case 0:
2534       return "vxorps\t%0, %0, %0";
2535     case 1:
2536     case 2:
2537       if (misaligned_operand (operands[0], OImode)
2538           || misaligned_operand (operands[1], OImode))
2539         return "vmovdqu\t{%1, %0|%0, %1}";
2540       else
2541         return "vmovdqa\t{%1, %0|%0, %1}";
2542     default:
2543       gcc_unreachable ();
2544     }
2545 }
2546   [(set_attr "type" "sselog1,ssemov,ssemov")
2547    (set_attr "prefix" "vex")
2548    (set_attr "mode" "OI")])
2549
2550 (define_expand "movti"
2551   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2552         (match_operand:TI 1 "nonimmediate_operand" ""))]
2553   "TARGET_SSE || TARGET_64BIT"
2554 {
2555   if (TARGET_64BIT)
2556     ix86_expand_move (TImode, operands);
2557   else if (push_operand (operands[0], TImode))
2558     ix86_expand_push (TImode, operands[1]);
2559   else
2560     ix86_expand_vector_move (TImode, operands);
2561   DONE;
2562 })
2563
2564 (define_insn "*movti_internal"
2565   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2566         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2567   "TARGET_SSE && !TARGET_64BIT
2568    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2569 {
2570   switch (which_alternative)
2571     {
2572     case 0:
2573       if (get_attr_mode (insn) == MODE_V4SF)
2574         return "%vxorps\t%0, %d0";
2575       else
2576         return "%vpxor\t%0, %d0";
2577     case 1:
2578     case 2:
2579       /* TDmode values are passed as TImode on the stack.  Moving them
2580          to stack may result in unaligned memory access.  */
2581       if (misaligned_operand (operands[0], TImode)
2582           || misaligned_operand (operands[1], TImode))
2583         {
2584           if (get_attr_mode (insn) == MODE_V4SF)
2585             return "%vmovups\t{%1, %0|%0, %1}";
2586          else
2587            return "%vmovdqu\t{%1, %0|%0, %1}";
2588         }
2589       else
2590         {
2591           if (get_attr_mode (insn) == MODE_V4SF)
2592             return "%vmovaps\t{%1, %0|%0, %1}";
2593          else
2594            return "%vmovdqa\t{%1, %0|%0, %1}";
2595         }
2596     default:
2597       gcc_unreachable ();
2598     }
2599 }
2600   [(set_attr "type" "sselog1,ssemov,ssemov")
2601    (set_attr "prefix" "maybe_vex")
2602    (set (attr "mode")
2603         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2604                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2605                  (const_string "V4SF")
2606                (and (eq_attr "alternative" "2")
2607                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2608                         (const_int 0)))
2609                  (const_string "V4SF")]
2610               (const_string "TI")))])
2611
2612 (define_insn "*movti_rex64"
2613   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2614         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2615   "TARGET_64BIT
2616    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2617 {
2618   switch (which_alternative)
2619     {
2620     case 0:
2621     case 1:
2622       return "#";
2623     case 2:
2624       if (get_attr_mode (insn) == MODE_V4SF)
2625         return "%vxorps\t%0, %d0";
2626       else
2627         return "%vpxor\t%0, %d0";
2628     case 3:
2629     case 4:
2630       /* TDmode values are passed as TImode on the stack.  Moving them
2631          to stack may result in unaligned memory access.  */
2632       if (misaligned_operand (operands[0], TImode)
2633           || misaligned_operand (operands[1], TImode))
2634         {
2635           if (get_attr_mode (insn) == MODE_V4SF)
2636             return "%vmovups\t{%1, %0|%0, %1}";
2637          else
2638            return "%vmovdqu\t{%1, %0|%0, %1}";
2639         }
2640       else
2641         {
2642           if (get_attr_mode (insn) == MODE_V4SF)
2643             return "%vmovaps\t{%1, %0|%0, %1}";
2644          else
2645            return "%vmovdqa\t{%1, %0|%0, %1}";
2646         }
2647     default:
2648       gcc_unreachable ();
2649     }
2650 }
2651   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2652    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2653    (set (attr "mode")
2654         (cond [(eq_attr "alternative" "2,3")
2655                  (if_then_else
2656                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2657                        (const_int 0))
2658                    (const_string "V4SF")
2659                    (const_string "TI"))
2660                (eq_attr "alternative" "4")
2661                  (if_then_else
2662                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2663                             (const_int 0))
2664                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2665                             (const_int 0)))
2666                    (const_string "V4SF")
2667                    (const_string "TI"))]
2668                (const_string "DI")))])
2669
2670 (define_split
2671   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2672         (match_operand:TI 1 "general_operand" ""))]
2673   "reload_completed && !SSE_REG_P (operands[0])
2674    && !SSE_REG_P (operands[1])"
2675   [(const_int 0)]
2676   "ix86_split_long_move (operands); DONE;")
2677
2678 ;; This expands to what emit_move_complex would generate if we didn't
2679 ;; have a movti pattern.  Having this avoids problems with reload on
2680 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2681 ;; to have around all the time.
2682 (define_expand "movcdi"
2683   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2684         (match_operand:CDI 1 "general_operand" ""))]
2685   ""
2686 {
2687   if (push_operand (operands[0], CDImode))
2688     emit_move_complex_push (CDImode, operands[0], operands[1]);
2689   else
2690     emit_move_complex_parts (operands[0], operands[1]);
2691   DONE;
2692 })
2693
2694 (define_expand "movsf"
2695   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2696         (match_operand:SF 1 "general_operand" ""))]
2697   ""
2698   "ix86_expand_move (SFmode, operands); DONE;")
2699
2700 (define_insn "*pushsf"
2701   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2702         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2703   "!TARGET_64BIT"
2704 {
2705   /* Anything else should be already split before reg-stack.  */
2706   gcc_assert (which_alternative == 1);
2707   return "push{l}\t%1";
2708 }
2709   [(set_attr "type" "multi,push,multi")
2710    (set_attr "unit" "i387,*,*")
2711    (set_attr "mode" "SF,SI,SF")])
2712
2713 (define_insn "*pushsf_rex64"
2714   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2715         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2716   "TARGET_64BIT"
2717 {
2718   /* Anything else should be already split before reg-stack.  */
2719   gcc_assert (which_alternative == 1);
2720   return "push{q}\t%q1";
2721 }
2722   [(set_attr "type" "multi,push,multi")
2723    (set_attr "unit" "i387,*,*")
2724    (set_attr "mode" "SF,DI,SF")])
2725
2726 (define_split
2727   [(set (match_operand:SF 0 "push_operand" "")
2728         (match_operand:SF 1 "memory_operand" ""))]
2729   "reload_completed
2730    && MEM_P (operands[1])
2731    && (operands[2] = find_constant_src (insn))"
2732   [(set (match_dup 0)
2733         (match_dup 2))])
2734
2735
2736 ;; %%% Kill this when call knows how to work this out.
2737 (define_split
2738   [(set (match_operand:SF 0 "push_operand" "")
2739         (match_operand:SF 1 "any_fp_register_operand" ""))]
2740   "!TARGET_64BIT"
2741   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2742    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2743
2744 (define_split
2745   [(set (match_operand:SF 0 "push_operand" "")
2746         (match_operand:SF 1 "any_fp_register_operand" ""))]
2747   "TARGET_64BIT"
2748   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2749    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2750
2751 (define_insn "*movsf_1"
2752   [(set (match_operand:SF 0 "nonimmediate_operand"
2753           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2754         (match_operand:SF 1 "general_operand"
2755           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2756   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2757    && (reload_in_progress || reload_completed
2758        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2759        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2760            && standard_80387_constant_p (operands[1]))
2761        || GET_CODE (operands[1]) != CONST_DOUBLE
2762        || memory_operand (operands[0], SFmode))"
2763 {
2764   switch (which_alternative)
2765     {
2766     case 0:
2767     case 1:
2768       return output_387_reg_move (insn, operands);
2769
2770     case 2:
2771       return standard_80387_constant_opcode (operands[1]);
2772
2773     case 3:
2774     case 4:
2775       return "mov{l}\t{%1, %0|%0, %1}";
2776     case 5:
2777       if (get_attr_mode (insn) == MODE_TI)
2778         return "%vpxor\t%0, %d0";
2779       else
2780         return "%vxorps\t%0, %d0";
2781     case 6:
2782       if (get_attr_mode (insn) == MODE_V4SF)
2783         return "%vmovaps\t{%1, %0|%0, %1}";
2784       else
2785         return "%vmovss\t{%1, %d0|%d0, %1}";
2786     case 7:
2787       if (TARGET_AVX)
2788         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2789                                    : "vmovss\t{%1, %0|%0, %1}";
2790       else
2791         return "movss\t{%1, %0|%0, %1}";
2792     case 8:
2793       return "%vmovss\t{%1, %0|%0, %1}";
2794
2795     case 9: case 10: case 14: case 15:
2796       return "movd\t{%1, %0|%0, %1}";
2797     case 12: case 13:
2798       return "%vmovd\t{%1, %0|%0, %1}";
2799
2800     case 11:
2801       return "movq\t{%1, %0|%0, %1}";
2802
2803     default:
2804       gcc_unreachable ();
2805     }
2806 }
2807   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2808    (set (attr "prefix")
2809      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2810        (const_string "maybe_vex")
2811        (const_string "orig")))
2812    (set (attr "mode")
2813         (cond [(eq_attr "alternative" "3,4,9,10")
2814                  (const_string "SI")
2815                (eq_attr "alternative" "5")
2816                  (if_then_else
2817                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2818                                  (const_int 0))
2819                              (ne (symbol_ref "TARGET_SSE2")
2820                                  (const_int 0)))
2821                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2822                             (const_int 0)))
2823                    (const_string "TI")
2824                    (const_string "V4SF"))
2825                /* For architectures resolving dependencies on
2826                   whole SSE registers use APS move to break dependency
2827                   chains, otherwise use short move to avoid extra work.
2828
2829                   Do the same for architectures resolving dependencies on
2830                   the parts.  While in DF mode it is better to always handle
2831                   just register parts, the SF mode is different due to lack
2832                   of instructions to load just part of the register.  It is
2833                   better to maintain the whole registers in single format
2834                   to avoid problems on using packed logical operations.  */
2835                (eq_attr "alternative" "6")
2836                  (if_then_else
2837                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2838                             (const_int 0))
2839                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2840                             (const_int 0)))
2841                    (const_string "V4SF")
2842                    (const_string "SF"))
2843                (eq_attr "alternative" "11")
2844                  (const_string "DI")]
2845                (const_string "SF")))])
2846
2847 (define_insn "*swapsf"
2848   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2849         (match_operand:SF 1 "fp_register_operand" "+f"))
2850    (set (match_dup 1)
2851         (match_dup 0))]
2852   "reload_completed || TARGET_80387"
2853 {
2854   if (STACK_TOP_P (operands[0]))
2855     return "fxch\t%1";
2856   else
2857     return "fxch\t%0";
2858 }
2859   [(set_attr "type" "fxch")
2860    (set_attr "mode" "SF")])
2861
2862 (define_expand "movdf"
2863   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2864         (match_operand:DF 1 "general_operand" ""))]
2865   ""
2866   "ix86_expand_move (DFmode, operands); DONE;")
2867
2868 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2869 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2870 ;; On the average, pushdf using integers can be still shorter.  Allow this
2871 ;; pattern for optimize_size too.
2872
2873 (define_insn "*pushdf_nointeger"
2874   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2875         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2876   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2877 {
2878   /* This insn should be already split before reg-stack.  */
2879   gcc_unreachable ();
2880 }
2881   [(set_attr "type" "multi")
2882    (set_attr "unit" "i387,*,*,*")
2883    (set_attr "mode" "DF,SI,SI,DF")])
2884
2885 (define_insn "*pushdf_integer"
2886   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2887         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2888   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2889 {
2890   /* This insn should be already split before reg-stack.  */
2891   gcc_unreachable ();
2892 }
2893   [(set_attr "type" "multi")
2894    (set_attr "unit" "i387,*,*")
2895    (set_attr "mode" "DF,SI,DF")])
2896
2897 ;; %%% Kill this when call knows how to work this out.
2898 (define_split
2899   [(set (match_operand:DF 0 "push_operand" "")
2900         (match_operand:DF 1 "any_fp_register_operand" ""))]
2901   "reload_completed"
2902   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2903    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2904   "")
2905
2906 (define_split
2907   [(set (match_operand:DF 0 "push_operand" "")
2908         (match_operand:DF 1 "general_operand" ""))]
2909   "reload_completed"
2910   [(const_int 0)]
2911   "ix86_split_long_move (operands); DONE;")
2912
2913 ;; Moving is usually shorter when only FP registers are used. This separate
2914 ;; movdf pattern avoids the use of integer registers for FP operations
2915 ;; when optimizing for size.
2916
2917 (define_insn "*movdf_nointeger"
2918   [(set (match_operand:DF 0 "nonimmediate_operand"
2919                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2920         (match_operand:DF 1 "general_operand"
2921                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2922   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2923    && ((optimize_function_for_size_p (cfun)
2924        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2925    && (reload_in_progress || reload_completed
2926        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2927        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2928            && optimize_function_for_size_p (cfun)
2929            && !memory_operand (operands[0], DFmode)
2930            && standard_80387_constant_p (operands[1]))
2931        || GET_CODE (operands[1]) != CONST_DOUBLE
2932        || ((optimize_function_for_size_p (cfun)
2933             || !TARGET_MEMORY_MISMATCH_STALL
2934             || reload_in_progress || reload_completed)
2935            && memory_operand (operands[0], DFmode)))"
2936 {
2937   switch (which_alternative)
2938     {
2939     case 0:
2940     case 1:
2941       return output_387_reg_move (insn, operands);
2942
2943     case 2:
2944       return standard_80387_constant_opcode (operands[1]);
2945
2946     case 3:
2947     case 4:
2948       return "#";
2949     case 5:
2950       switch (get_attr_mode (insn))
2951         {
2952         case MODE_V4SF:
2953           return "%vxorps\t%0, %d0";
2954         case MODE_V2DF:
2955           return "%vxorpd\t%0, %d0";
2956         case MODE_TI:
2957           return "%vpxor\t%0, %d0";
2958         default:
2959           gcc_unreachable ();
2960         }
2961     case 6:
2962     case 7:
2963     case 8:
2964       switch (get_attr_mode (insn))
2965         {
2966         case MODE_V4SF:
2967           return "%vmovaps\t{%1, %0|%0, %1}";
2968         case MODE_V2DF:
2969           return "%vmovapd\t{%1, %0|%0, %1}";
2970         case MODE_TI:
2971           return "%vmovdqa\t{%1, %0|%0, %1}";
2972         case MODE_DI:
2973           return "%vmovq\t{%1, %0|%0, %1}";
2974         case MODE_DF:
2975           if (TARGET_AVX)
2976             {
2977               if (REG_P (operands[0]) && REG_P (operands[1]))
2978                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2979               else
2980                 return "vmovsd\t{%1, %0|%0, %1}";
2981             }
2982           else
2983             return "movsd\t{%1, %0|%0, %1}";
2984         case MODE_V1DF:
2985           if (TARGET_AVX)
2986             {
2987               if (REG_P (operands[0]))
2988                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2989               else
2990                 return "vmovlpd\t{%1, %0|%0, %1}";
2991             }
2992           else
2993             return "movlpd\t{%1, %0|%0, %1}";
2994         case MODE_V2SF:
2995           if (TARGET_AVX)
2996             {
2997               if (REG_P (operands[0]))
2998                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2999               else
3000                 return "vmovlps\t{%1, %0|%0, %1}";
3001             }
3002           else
3003             return "movlps\t{%1, %0|%0, %1}";
3004         default:
3005           gcc_unreachable ();
3006         }
3007
3008     default:
3009       gcc_unreachable ();
3010     }
3011 }
3012   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3013    (set (attr "prefix")
3014      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3015        (const_string "orig")
3016        (const_string "maybe_vex")))
3017    (set (attr "mode")
3018         (cond [(eq_attr "alternative" "0,1,2")
3019                  (const_string "DF")
3020                (eq_attr "alternative" "3,4")
3021                  (const_string "SI")
3022
3023                /* For SSE1, we have many fewer alternatives.  */
3024                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3025                  (cond [(eq_attr "alternative" "5,6")
3026                           (const_string "V4SF")
3027                        ]
3028                    (const_string "V2SF"))
3029
3030                /* xorps is one byte shorter.  */
3031                (eq_attr "alternative" "5")
3032                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3033                             (const_int 0))
3034                           (const_string "V4SF")
3035                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3036                             (const_int 0))
3037                           (const_string "TI")
3038                        ]
3039                        (const_string "V2DF"))
3040
3041                /* For architectures resolving dependencies on
3042                   whole SSE registers use APD move to break dependency
3043                   chains, otherwise use short move to avoid extra work.
3044
3045                   movaps encodes one byte shorter.  */
3046                (eq_attr "alternative" "6")
3047                  (cond
3048                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3049                         (const_int 0))
3050                       (const_string "V4SF")
3051                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3052                         (const_int 0))
3053                       (const_string "V2DF")
3054                    ]
3055                    (const_string "DF"))
3056                /* For architectures resolving dependencies on register
3057                   parts we may avoid extra work to zero out upper part
3058                   of register.  */
3059                (eq_attr "alternative" "7")
3060                  (if_then_else
3061                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3062                        (const_int 0))
3063                    (const_string "V1DF")
3064                    (const_string "DF"))
3065               ]
3066               (const_string "DF")))])
3067
3068 (define_insn "*movdf_integer_rex64"
3069   [(set (match_operand:DF 0 "nonimmediate_operand"
3070                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3071         (match_operand:DF 1 "general_operand"
3072                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3073   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3074    && (reload_in_progress || reload_completed
3075        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3076        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3077            && optimize_function_for_size_p (cfun)
3078            && standard_80387_constant_p (operands[1]))
3079        || GET_CODE (operands[1]) != CONST_DOUBLE
3080        || memory_operand (operands[0], DFmode))"
3081 {
3082   switch (which_alternative)
3083     {
3084     case 0:
3085     case 1:
3086       return output_387_reg_move (insn, operands);
3087
3088     case 2:
3089       return standard_80387_constant_opcode (operands[1]);
3090
3091     case 3:
3092     case 4:
3093       return "#";
3094
3095     case 5:
3096       switch (get_attr_mode (insn))
3097         {
3098         case MODE_V4SF:
3099           return "%vxorps\t%0, %d0";
3100         case MODE_V2DF:
3101           return "%vxorpd\t%0, %d0";
3102         case MODE_TI:
3103           return "%vpxor\t%0, %d0";
3104         default:
3105           gcc_unreachable ();
3106         }
3107     case 6:
3108     case 7:
3109     case 8:
3110       switch (get_attr_mode (insn))
3111         {
3112         case MODE_V4SF:
3113           return "%vmovaps\t{%1, %0|%0, %1}";
3114         case MODE_V2DF:
3115           return "%vmovapd\t{%1, %0|%0, %1}";
3116         case MODE_TI:
3117           return "%vmovdqa\t{%1, %0|%0, %1}";
3118         case MODE_DI:
3119           return "%vmovq\t{%1, %0|%0, %1}";
3120         case MODE_DF:
3121           if (TARGET_AVX)
3122             {
3123               if (REG_P (operands[0]) && REG_P (operands[1]))
3124                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3125               else
3126                 return "vmovsd\t{%1, %0|%0, %1}";
3127             }
3128           else
3129             return "movsd\t{%1, %0|%0, %1}";
3130         case MODE_V1DF:
3131           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3132         case MODE_V2SF:
3133           return "%vmovlps\t{%1, %d0|%d0, %1}";
3134         default:
3135           gcc_unreachable ();
3136         }
3137
3138     case 9:
3139     case 10:
3140     return "%vmovd\t{%1, %0|%0, %1}";
3141
3142     default:
3143       gcc_unreachable();
3144     }
3145 }
3146   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3147    (set (attr "prefix")
3148      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3149        (const_string "orig")
3150        (const_string "maybe_vex")))
3151    (set (attr "mode")
3152         (cond [(eq_attr "alternative" "0,1,2")
3153                  (const_string "DF")
3154                (eq_attr "alternative" "3,4,9,10")
3155                  (const_string "DI")
3156
3157                /* For SSE1, we have many fewer alternatives.  */
3158                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3159                  (cond [(eq_attr "alternative" "5,6")
3160                           (const_string "V4SF")
3161                        ]
3162                    (const_string "V2SF"))
3163
3164                /* xorps is one byte shorter.  */
3165                (eq_attr "alternative" "5")
3166                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3167                             (const_int 0))
3168                           (const_string "V4SF")
3169                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3170                             (const_int 0))
3171                           (const_string "TI")
3172                        ]
3173                        (const_string "V2DF"))
3174
3175                /* For architectures resolving dependencies on
3176                   whole SSE registers use APD move to break dependency
3177                   chains, otherwise use short move to avoid extra work.
3178
3179                   movaps encodes one byte shorter.  */
3180                (eq_attr "alternative" "6")
3181                  (cond
3182                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3183                         (const_int 0))
3184                       (const_string "V4SF")
3185                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3186                         (const_int 0))
3187                       (const_string "V2DF")
3188                    ]
3189                    (const_string "DF"))
3190                /* For architectures resolving dependencies on register
3191                   parts we may avoid extra work to zero out upper part
3192                   of register.  */
3193                (eq_attr "alternative" "7")
3194                  (if_then_else
3195                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3196                        (const_int 0))
3197                    (const_string "V1DF")
3198                    (const_string "DF"))
3199               ]
3200               (const_string "DF")))])
3201
3202 (define_insn "*movdf_integer"
3203   [(set (match_operand:DF 0 "nonimmediate_operand"
3204                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3205         (match_operand:DF 1 "general_operand"
3206                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3207   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208    && optimize_function_for_speed_p (cfun)
3209    && TARGET_INTEGER_DFMODE_MOVES
3210    && (reload_in_progress || reload_completed
3211        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3212        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3213            && optimize_function_for_size_p (cfun)
3214            && standard_80387_constant_p (operands[1]))
3215        || GET_CODE (operands[1]) != CONST_DOUBLE
3216        || memory_operand (operands[0], DFmode))"
3217 {
3218   switch (which_alternative)
3219     {
3220     case 0:
3221     case 1:
3222       return output_387_reg_move (insn, operands);
3223
3224     case 2:
3225       return standard_80387_constant_opcode (operands[1]);
3226
3227     case 3:
3228     case 4:
3229       return "#";
3230
3231     case 5:
3232       switch (get_attr_mode (insn))
3233         {
3234         case MODE_V4SF:
3235           return "xorps\t%0, %0";
3236         case MODE_V2DF:
3237           return "xorpd\t%0, %0";
3238         case MODE_TI:
3239           return "pxor\t%0, %0";
3240         default:
3241           gcc_unreachable ();
3242         }
3243     case 6:
3244     case 7:
3245     case 8:
3246       switch (get_attr_mode (insn))
3247         {
3248         case MODE_V4SF:
3249           return "movaps\t{%1, %0|%0, %1}";
3250         case MODE_V2DF:
3251           return "movapd\t{%1, %0|%0, %1}";
3252         case MODE_TI:
3253           return "movdqa\t{%1, %0|%0, %1}";
3254         case MODE_DI:
3255           return "movq\t{%1, %0|%0, %1}";
3256         case MODE_DF:
3257           return "movsd\t{%1, %0|%0, %1}";
3258         case MODE_V1DF:
3259           return "movlpd\t{%1, %0|%0, %1}";
3260         case MODE_V2SF:
3261           return "movlps\t{%1, %0|%0, %1}";
3262         default:
3263           gcc_unreachable ();
3264         }
3265
3266     default:
3267       gcc_unreachable();
3268     }
3269 }
3270   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3271    (set (attr "mode")
3272         (cond [(eq_attr "alternative" "0,1,2")
3273                  (const_string "DF")
3274                (eq_attr "alternative" "3,4")
3275                  (const_string "SI")
3276
3277                /* For SSE1, we have many fewer alternatives.  */
3278                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3279                  (cond [(eq_attr "alternative" "5,6")
3280                           (const_string "V4SF")
3281                        ]
3282                    (const_string "V2SF"))
3283
3284                /* xorps is one byte shorter.  */
3285                (eq_attr "alternative" "5")
3286                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3287                             (const_int 0))
3288                           (const_string "V4SF")
3289                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3290                             (const_int 0))
3291                           (const_string "TI")
3292                        ]
3293                        (const_string "V2DF"))
3294
3295                /* For architectures resolving dependencies on
3296                   whole SSE registers use APD move to break dependency
3297                   chains, otherwise use short move to avoid extra work.
3298
3299                   movaps encodes one byte shorter.  */
3300                (eq_attr "alternative" "6")
3301                  (cond
3302                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3303                         (const_int 0))
3304                       (const_string "V4SF")
3305                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3306                         (const_int 0))
3307                       (const_string "V2DF")
3308                    ]
3309                    (const_string "DF"))
3310                /* For architectures resolving dependencies on register
3311                   parts we may avoid extra work to zero out upper part
3312                   of register.  */
3313                (eq_attr "alternative" "7")
3314                  (if_then_else
3315                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3316                        (const_int 0))
3317                    (const_string "V1DF")
3318                    (const_string "DF"))
3319               ]
3320               (const_string "DF")))])
3321
3322 (define_split
3323   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3324         (match_operand:DF 1 "general_operand" ""))]
3325   "reload_completed
3326    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3327    && ! (ANY_FP_REG_P (operands[0]) ||
3328          (GET_CODE (operands[0]) == SUBREG
3329           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3330    && ! (ANY_FP_REG_P (operands[1]) ||
3331          (GET_CODE (operands[1]) == SUBREG
3332           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3333   [(const_int 0)]
3334   "ix86_split_long_move (operands); DONE;")
3335
3336 (define_insn "*swapdf"
3337   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3338         (match_operand:DF 1 "fp_register_operand" "+f"))
3339    (set (match_dup 1)
3340         (match_dup 0))]
3341   "reload_completed || TARGET_80387"
3342 {
3343   if (STACK_TOP_P (operands[0]))
3344     return "fxch\t%1";
3345   else
3346     return "fxch\t%0";
3347 }
3348   [(set_attr "type" "fxch")
3349    (set_attr "mode" "DF")])
3350
3351 (define_expand "movxf"
3352   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3353         (match_operand:XF 1 "general_operand" ""))]
3354   ""
3355   "ix86_expand_move (XFmode, operands); DONE;")
3356
3357 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3358 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3359 ;; Pushing using integer instructions is longer except for constants
3360 ;; and direct memory references.
3361 ;; (assuming that any given constant is pushed only once, but this ought to be
3362 ;;  handled elsewhere).
3363
3364 (define_insn "*pushxf_nointeger"
3365   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3366         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3367   "optimize_function_for_size_p (cfun)"
3368 {
3369   /* This insn should be already split before reg-stack.  */
3370   gcc_unreachable ();
3371 }
3372   [(set_attr "type" "multi")
3373    (set_attr "unit" "i387,*,*")
3374    (set_attr "mode" "XF,SI,SI")])
3375
3376 (define_insn "*pushxf_integer"
3377   [(set (match_operand:XF 0 "push_operand" "=<,<")
3378         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3379   "optimize_function_for_speed_p (cfun)"
3380 {
3381   /* This insn should be already split before reg-stack.  */
3382   gcc_unreachable ();
3383 }
3384   [(set_attr "type" "multi")
3385    (set_attr "unit" "i387,*")
3386    (set_attr "mode" "XF,SI")])
3387
3388 (define_split
3389   [(set (match_operand 0 "push_operand" "")
3390         (match_operand 1 "general_operand" ""))]
3391   "reload_completed
3392    && (GET_MODE (operands[0]) == XFmode
3393        || GET_MODE (operands[0]) == DFmode)
3394    && !ANY_FP_REG_P (operands[1])"
3395   [(const_int 0)]
3396   "ix86_split_long_move (operands); DONE;")
3397
3398 (define_split
3399   [(set (match_operand:XF 0 "push_operand" "")
3400         (match_operand:XF 1 "any_fp_register_operand" ""))]
3401   ""
3402   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3403    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3404   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3405
3406 ;; Do not use integer registers when optimizing for size
3407 (define_insn "*movxf_nointeger"
3408   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3409         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3410   "optimize_function_for_size_p (cfun)
3411    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3412    && (reload_in_progress || reload_completed
3413        || standard_80387_constant_p (operands[1])
3414        || GET_CODE (operands[1]) != CONST_DOUBLE
3415        || memory_operand (operands[0], XFmode))"
3416 {
3417   switch (which_alternative)
3418     {
3419     case 0:
3420     case 1:
3421       return output_387_reg_move (insn, operands);
3422
3423     case 2:
3424       return standard_80387_constant_opcode (operands[1]);
3425
3426     case 3: case 4:
3427       return "#";
3428     default:
3429       gcc_unreachable ();
3430     }
3431 }
3432   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3433    (set_attr "mode" "XF,XF,XF,SI,SI")])
3434
3435 (define_insn "*movxf_integer"
3436   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3437         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3438   "optimize_function_for_speed_p (cfun)
3439    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3440    && (reload_in_progress || reload_completed
3441        || GET_CODE (operands[1]) != CONST_DOUBLE
3442        || memory_operand (operands[0], XFmode))"
3443 {
3444   switch (which_alternative)
3445     {
3446     case 0:
3447     case 1:
3448       return output_387_reg_move (insn, operands);
3449
3450     case 2:
3451       return standard_80387_constant_opcode (operands[1]);
3452
3453     case 3: case 4:
3454       return "#";
3455
3456     default:
3457       gcc_unreachable ();
3458     }
3459 }
3460   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3461    (set_attr "mode" "XF,XF,XF,SI,SI")])
3462
3463 (define_expand "movtf"
3464   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3465         (match_operand:TF 1 "nonimmediate_operand" ""))]
3466   "TARGET_SSE2"
3467 {
3468   ix86_expand_move (TFmode, operands);
3469   DONE;
3470 })
3471
3472 (define_insn "*movtf_internal"
3473   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3474         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3475   "TARGET_SSE2
3476    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3477 {
3478   switch (which_alternative)
3479     {
3480     case 0:
3481     case 1:
3482       if (get_attr_mode (insn) == MODE_V4SF)
3483         return "%vmovaps\t{%1, %0|%0, %1}";
3484       else
3485         return "%vmovdqa\t{%1, %0|%0, %1}";
3486     case 2:
3487       if (get_attr_mode (insn) == MODE_V4SF)
3488         return "%vxorps\t%0, %d0";
3489       else
3490         return "%vpxor\t%0, %d0";
3491     case 3:
3492     case 4:
3493         return "#";
3494     default:
3495       gcc_unreachable ();
3496     }
3497 }
3498   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3499    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3500    (set (attr "mode")
3501         (cond [(eq_attr "alternative" "0,2")
3502                  (if_then_else
3503                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3504                        (const_int 0))
3505                    (const_string "V4SF")
3506                    (const_string "TI"))
3507                (eq_attr "alternative" "1")
3508                  (if_then_else
3509                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3510                             (const_int 0))
3511                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3512                             (const_int 0)))
3513                    (const_string "V4SF")
3514                    (const_string "TI"))]
3515                (const_string "DI")))])
3516
3517 (define_insn "*pushtf_sse"
3518   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3519         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3520   "TARGET_SSE2"
3521 {
3522   /* This insn should be already split before reg-stack.  */
3523   gcc_unreachable ();
3524 }
3525   [(set_attr "type" "multi")
3526    (set_attr "unit" "sse,*,*")
3527    (set_attr "mode" "TF,SI,SI")])
3528
3529 (define_split
3530   [(set (match_operand:TF 0 "push_operand" "")
3531         (match_operand:TF 1 "general_operand" ""))]
3532   "TARGET_SSE2 && reload_completed
3533    && !SSE_REG_P (operands[1])"
3534   [(const_int 0)]
3535   "ix86_split_long_move (operands); DONE;")
3536
3537 (define_split
3538   [(set (match_operand:TF 0 "push_operand" "")
3539         (match_operand:TF 1 "any_fp_register_operand" ""))]
3540   "TARGET_SSE2"
3541   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3542    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3543   "")
3544
3545 (define_split
3546   [(set (match_operand 0 "nonimmediate_operand" "")
3547         (match_operand 1 "general_operand" ""))]
3548   "reload_completed
3549    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3550    && GET_MODE (operands[0]) == XFmode
3551    && ! (ANY_FP_REG_P (operands[0]) ||
3552          (GET_CODE (operands[0]) == SUBREG
3553           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3554    && ! (ANY_FP_REG_P (operands[1]) ||
3555          (GET_CODE (operands[1]) == SUBREG
3556           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3557   [(const_int 0)]
3558   "ix86_split_long_move (operands); DONE;")
3559
3560 (define_split
3561   [(set (match_operand 0 "register_operand" "")
3562         (match_operand 1 "memory_operand" ""))]
3563   "reload_completed
3564    && MEM_P (operands[1])
3565    && (GET_MODE (operands[0]) == TFmode
3566        || GET_MODE (operands[0]) == XFmode
3567        || GET_MODE (operands[0]) == SFmode
3568        || GET_MODE (operands[0]) == DFmode)
3569    && (operands[2] = find_constant_src (insn))"
3570   [(set (match_dup 0) (match_dup 2))]
3571 {
3572   rtx c = operands[2];
3573   rtx r = operands[0];
3574
3575   if (GET_CODE (r) == SUBREG)
3576     r = SUBREG_REG (r);
3577
3578   if (SSE_REG_P (r))
3579     {
3580       if (!standard_sse_constant_p (c))
3581         FAIL;
3582     }
3583   else if (FP_REG_P (r))
3584     {
3585       if (!standard_80387_constant_p (c))
3586         FAIL;
3587     }
3588   else if (MMX_REG_P (r))
3589     FAIL;
3590 })
3591
3592 (define_split
3593   [(set (match_operand 0 "register_operand" "")
3594         (float_extend (match_operand 1 "memory_operand" "")))]
3595   "reload_completed
3596    && MEM_P (operands[1])
3597    && (GET_MODE (operands[0]) == TFmode
3598        || GET_MODE (operands[0]) == XFmode
3599        || GET_MODE (operands[0]) == SFmode
3600        || GET_MODE (operands[0]) == DFmode)
3601    && (operands[2] = find_constant_src (insn))"
3602   [(set (match_dup 0) (match_dup 2))]
3603 {
3604   rtx c = operands[2];
3605   rtx r = operands[0];
3606
3607   if (GET_CODE (r) == SUBREG)
3608     r = SUBREG_REG (r);
3609
3610   if (SSE_REG_P (r))
3611     {
3612       if (!standard_sse_constant_p (c))
3613         FAIL;
3614     }
3615   else if (FP_REG_P (r))
3616     {
3617       if (!standard_80387_constant_p (c))
3618         FAIL;
3619     }
3620   else if (MMX_REG_P (r))
3621     FAIL;
3622 })
3623
3624 (define_insn "swapxf"
3625   [(set (match_operand:XF 0 "register_operand" "+f")
3626         (match_operand:XF 1 "register_operand" "+f"))
3627    (set (match_dup 1)
3628         (match_dup 0))]
3629   "TARGET_80387"
3630 {
3631   if (STACK_TOP_P (operands[0]))
3632     return "fxch\t%1";
3633   else
3634     return "fxch\t%0";
3635 }
3636   [(set_attr "type" "fxch")
3637    (set_attr "mode" "XF")])
3638
3639 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3640 (define_split
3641   [(set (match_operand:X87MODEF 0 "register_operand" "")
3642         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3643   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3644    && (standard_80387_constant_p (operands[1]) == 8
3645        || standard_80387_constant_p (operands[1]) == 9)"
3646   [(set (match_dup 0)(match_dup 1))
3647    (set (match_dup 0)
3648         (neg:X87MODEF (match_dup 0)))]
3649 {
3650   REAL_VALUE_TYPE r;
3651
3652   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3653   if (real_isnegzero (&r))
3654     operands[1] = CONST0_RTX (<MODE>mode);
3655   else
3656     operands[1] = CONST1_RTX (<MODE>mode);
3657 })
3658
3659 (define_split
3660   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3661         (match_operand:TF 1 "general_operand" ""))]
3662   "reload_completed
3663    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3664   [(const_int 0)]
3665   "ix86_split_long_move (operands); DONE;")
3666 \f
3667 ;; Zero extension instructions
3668
3669 (define_expand "zero_extendhisi2"
3670   [(set (match_operand:SI 0 "register_operand" "")
3671      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3672   ""
3673 {
3674   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3675     {
3676       operands[1] = force_reg (HImode, operands[1]);
3677       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3678       DONE;
3679     }
3680 })
3681
3682 (define_insn "zero_extendhisi2_and"
3683   [(set (match_operand:SI 0 "register_operand" "=r")
3684      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3685    (clobber (reg:CC FLAGS_REG))]
3686   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3687   "#"
3688   [(set_attr "type" "alu1")
3689    (set_attr "mode" "SI")])
3690
3691 (define_split
3692   [(set (match_operand:SI 0 "register_operand" "")
3693         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3694    (clobber (reg:CC FLAGS_REG))]
3695   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3696    && optimize_function_for_speed_p (cfun)"
3697   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3698               (clobber (reg:CC FLAGS_REG))])]
3699   "")
3700
3701 (define_insn "*zero_extendhisi2_movzwl"
3702   [(set (match_operand:SI 0 "register_operand" "=r")
3703      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3704   "!TARGET_ZERO_EXTEND_WITH_AND
3705    || optimize_function_for_size_p (cfun)"
3706   "movz{wl|x}\t{%1, %0|%0, %1}"
3707   [(set_attr "type" "imovx")
3708    (set_attr "mode" "SI")])
3709
3710 (define_expand "zero_extendqihi2"
3711   [(parallel
3712     [(set (match_operand:HI 0 "register_operand" "")
3713        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3714      (clobber (reg:CC FLAGS_REG))])]
3715   ""
3716   "")
3717
3718 (define_insn "*zero_extendqihi2_and"
3719   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3720      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3721    (clobber (reg:CC FLAGS_REG))]
3722   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3723   "#"
3724   [(set_attr "type" "alu1")
3725    (set_attr "mode" "HI")])
3726
3727 (define_insn "*zero_extendqihi2_movzbw_and"
3728   [(set (match_operand:HI 0 "register_operand" "=r,r")
3729      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3730    (clobber (reg:CC FLAGS_REG))]
3731   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3732   "#"
3733   [(set_attr "type" "imovx,alu1")
3734    (set_attr "mode" "HI")])
3735
3736 ; zero extend to SImode here to avoid partial register stalls
3737 (define_insn "*zero_extendqihi2_movzbl"
3738   [(set (match_operand:HI 0 "register_operand" "=r")
3739      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3740   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3741    && reload_completed"
3742   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3743   [(set_attr "type" "imovx")
3744    (set_attr "mode" "SI")])
3745
3746 ;; For the movzbw case strip only the clobber
3747 (define_split
3748   [(set (match_operand:HI 0 "register_operand" "")
3749         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3750    (clobber (reg:CC FLAGS_REG))]
3751   "reload_completed
3752    && (!TARGET_ZERO_EXTEND_WITH_AND
3753        || optimize_function_for_size_p (cfun))
3754    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3755   [(set (match_operand:HI 0 "register_operand" "")
3756         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3757
3758 ;; When source and destination does not overlap, clear destination
3759 ;; first and then do the movb
3760 (define_split
3761   [(set (match_operand:HI 0 "register_operand" "")
3762         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3763    (clobber (reg:CC FLAGS_REG))]
3764   "reload_completed
3765    && ANY_QI_REG_P (operands[0])
3766    && (TARGET_ZERO_EXTEND_WITH_AND
3767        && optimize_function_for_speed_p (cfun))
3768    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3769   [(set (match_dup 0) (const_int 0))
3770    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3771   "operands[2] = gen_lowpart (QImode, operands[0]);")
3772
3773 ;; Rest is handled by single and.
3774 (define_split
3775   [(set (match_operand:HI 0 "register_operand" "")
3776         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3777    (clobber (reg:CC FLAGS_REG))]
3778   "reload_completed
3779    && true_regnum (operands[0]) == true_regnum (operands[1])"
3780   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3781               (clobber (reg:CC FLAGS_REG))])]
3782   "")
3783
3784 (define_expand "zero_extendqisi2"
3785   [(parallel
3786     [(set (match_operand:SI 0 "register_operand" "")
3787        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3788      (clobber (reg:CC FLAGS_REG))])]
3789   ""
3790   "")
3791
3792 (define_insn "*zero_extendqisi2_and"
3793   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3794      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3795    (clobber (reg:CC FLAGS_REG))]
3796   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3797   "#"
3798   [(set_attr "type" "alu1")
3799    (set_attr "mode" "SI")])
3800
3801 (define_insn "*zero_extendqisi2_movzbw_and"
3802   [(set (match_operand:SI 0 "register_operand" "=r,r")
3803      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3804    (clobber (reg:CC FLAGS_REG))]
3805   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3806   "#"
3807   [(set_attr "type" "imovx,alu1")
3808    (set_attr "mode" "SI")])
3809
3810 (define_insn "*zero_extendqisi2_movzbw"
3811   [(set (match_operand:SI 0 "register_operand" "=r")
3812      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3813   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3814    && reload_completed"
3815   "movz{bl|x}\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "imovx")
3817    (set_attr "mode" "SI")])
3818
3819 ;; For the movzbl case strip only the clobber
3820 (define_split
3821   [(set (match_operand:SI 0 "register_operand" "")
3822         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3823    (clobber (reg:CC FLAGS_REG))]
3824   "reload_completed
3825    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3826    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3827   [(set (match_dup 0)
3828         (zero_extend:SI (match_dup 1)))])
3829
3830 ;; When source and destination does not overlap, clear destination
3831 ;; first and then do the movb
3832 (define_split
3833   [(set (match_operand:SI 0 "register_operand" "")
3834         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3835    (clobber (reg:CC FLAGS_REG))]
3836   "reload_completed
3837    && ANY_QI_REG_P (operands[0])
3838    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3839    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3840    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3841   [(set (match_dup 0) (const_int 0))
3842    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3843   "operands[2] = gen_lowpart (QImode, operands[0]);")
3844
3845 ;; Rest is handled by single and.
3846 (define_split
3847   [(set (match_operand:SI 0 "register_operand" "")
3848         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3849    (clobber (reg:CC FLAGS_REG))]
3850   "reload_completed
3851    && true_regnum (operands[0]) == true_regnum (operands[1])"
3852   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3853               (clobber (reg:CC FLAGS_REG))])]
3854   "")
3855
3856 ;; %%% Kill me once multi-word ops are sane.
3857 (define_expand "zero_extendsidi2"
3858   [(set (match_operand:DI 0 "register_operand" "")
3859      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3860   ""
3861 {
3862   if (!TARGET_64BIT)
3863     {
3864       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3865       DONE;
3866     }
3867 })
3868
3869 (define_insn "zero_extendsidi2_32"
3870   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3871         (zero_extend:DI
3872          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3873    (clobber (reg:CC FLAGS_REG))]
3874   "!TARGET_64BIT"
3875   "@
3876    #
3877    #
3878    #
3879    movd\t{%1, %0|%0, %1}
3880    movd\t{%1, %0|%0, %1}
3881    %vmovd\t{%1, %0|%0, %1}
3882    %vmovd\t{%1, %0|%0, %1}"
3883   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3884    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3885    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3886
3887 (define_insn "zero_extendsidi2_rex64"
3888   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3889      (zero_extend:DI
3890        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3891   "TARGET_64BIT"
3892   "@
3893    mov\t{%k1, %k0|%k0, %k1}
3894    #
3895    movd\t{%1, %0|%0, %1}
3896    movd\t{%1, %0|%0, %1}
3897    %vmovd\t{%1, %0|%0, %1}
3898    %vmovd\t{%1, %0|%0, %1}"
3899   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3900    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3901    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3902
3903 (define_split
3904   [(set (match_operand:DI 0 "memory_operand" "")
3905      (zero_extend:DI (match_dup 0)))]
3906   "TARGET_64BIT"
3907   [(set (match_dup 4) (const_int 0))]
3908   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3909
3910 (define_split
3911   [(set (match_operand:DI 0 "register_operand" "")
3912         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3913    (clobber (reg:CC FLAGS_REG))]
3914   "!TARGET_64BIT && reload_completed
3915    && true_regnum (operands[0]) == true_regnum (operands[1])"
3916   [(set (match_dup 4) (const_int 0))]
3917   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3918
3919 (define_split
3920   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3921         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3922    (clobber (reg:CC FLAGS_REG))]
3923   "!TARGET_64BIT && reload_completed
3924    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3925   [(set (match_dup 3) (match_dup 1))
3926    (set (match_dup 4) (const_int 0))]
3927   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3928
3929 (define_insn "zero_extendhidi2"
3930   [(set (match_operand:DI 0 "register_operand" "=r")
3931      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3932   "TARGET_64BIT"
3933   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3934   [(set_attr "type" "imovx")
3935    (set_attr "mode" "DI")])
3936
3937 (define_insn "zero_extendqidi2"
3938   [(set (match_operand:DI 0 "register_op