Merge branch 'vendor/GCC44'
[dragonfly.git] / contrib / gcc-4.4 / gcc / config / i386 / i386.md
CommitLineData
c251ad9e
SS
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
4b1e227d 80 (UNSPEC_EH_RETURN 29)
c251ad9e
SS
81 (UNSPEC_SCAS 30)
82 (UNSPEC_FNSTSW 31)
83 (UNSPEC_SAHF 32)
4b1e227d
SW
84 (UNSPEC_PARITY 33)
85 (UNSPEC_FSTCW 34)
86 (UNSPEC_ADD_CARRY 35)
87 (UNSPEC_FLDCW 36)
88 (UNSPEC_REP 37)
c251ad9e
SS
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{
4b1e227d
SW
1318#ifndef HAVE_AS_IX86_SAHF
1319 if (TARGET_64BIT)
1320 return ".byte\t0x9e";
1321 else
c251ad9e 1322#endif
4b1e227d 1323 return "sahf";
c251ad9e
SS
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:
4b1e227d 1568 return "lea{l}\t{%a1, %0|%0, %a1}";
c251ad9e
SS
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