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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
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 2, or (at your option)
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.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
77 ; Other random patterns
87 ; For SSE/MMX support:
88 (UNSPEC_FIX_NOTRUNC 30)
96 (UNSPEC_NOP 38) ; prevents combiner cleverness
107 ; Generic math support
109 (UNSPEC_IEEE_MIN 51) ; not commutative
110 (UNSPEC_IEEE_MAX 52) ; not commutative
123 (UNSPEC_FRNDINT_FLOOR 70)
124 (UNSPEC_FRNDINT_CEIL 71)
125 (UNSPEC_FRNDINT_TRUNC 72)
126 (UNSPEC_FRNDINT_MASK_PM 73)
127 (UNSPEC_FIST_FLOOR 74)
128 (UNSPEC_FIST_CEIL 75)
130 ; x87 Double output FP
131 (UNSPEC_SINCOS_COS 80)
132 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_XTRACT_FRACT 84)
136 (UNSPEC_XTRACT_EXP 85)
137 (UNSPEC_FSCALE_FRACT 86)
138 (UNSPEC_FSCALE_EXP 87)
147 (UNSPEC_SP_TLS_SET 102)
148 (UNSPEC_SP_TLS_TEST 103)
152 [(UNSPECV_BLOCKAGE 0)
153 (UNSPECV_STACK_PROBE 1)
162 (UNSPECV_CMPXCHG_1 10)
163 (UNSPECV_CMPXCHG_2 11)
168 ;; Registers by name.
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first. This allows for better optimization. For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
186 ;; Processor type. This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189 (const (symbol_ref "ix86_tune")))
191 ;; A basic instruction type. Refinements due to arguments to be
192 ;; provided in other attributes.
195 alu,alu1,negnot,imov,imovx,lea,
196 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197 icmp,test,ibr,setcc,icmov,
198 push,pop,call,callv,leave,
200 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201 sselog,sselog1,sseiadd,sseishft,sseimul,
202 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204 (const_string "other"))
206 ;; Main data type used by the insn
208 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209 (const_string "unknown"))
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214 (const_string "i387")
215 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
218 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
220 (eq_attr "type" "other")
221 (const_string "unknown")]
222 (const_string "integer")))
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
228 (eq_attr "unit" "i387,sse,mmx")
230 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
232 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233 (eq_attr "type" "imov,test")
234 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235 (eq_attr "type" "call")
236 (if_then_else (match_operand 0 "constant_call_address_operand" "")
239 (eq_attr "type" "callv")
240 (if_then_else (match_operand 1 "constant_call_address_operand" "")
243 ;; We don't know the size before shorten_branches. Expect
244 ;; the instruction to fit for better scheduling.
245 (eq_attr "type" "ibr")
248 (symbol_ref "/* Update immediate_length and other attributes! */
249 gcc_unreachable (),1")))
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
255 (and (eq_attr "type" "call")
256 (match_operand 0 "constant_call_address_operand" ""))
258 (and (eq_attr "type" "callv")
259 (match_operand 1 "constant_call_address_operand" ""))
262 (symbol_ref "ix86_attr_length_address_default (insn)")))
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266 (if_then_else (ior (eq_attr "mode" "HI")
267 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" ""
273 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
280 (ior (eq_attr "type" "imovx,setcc,icmov")
281 (eq_attr "unit" "sse,mmx"))
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287 (cond [(and (eq_attr "mode" "DI")
288 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
290 (and (eq_attr "mode" "QI")
291 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302 (cond [(eq_attr "type" "str,cld,leave")
304 (eq_attr "unit" "i387")
306 (and (eq_attr "type" "incdec")
307 (ior (match_operand:SI 1 "register_operand" "")
308 (match_operand:HI 1 "register_operand" "")))
310 (and (eq_attr "type" "push")
311 (not (match_operand 1 "memory_operand" "")))
313 (and (eq_attr "type" "pop")
314 (not (match_operand 0 "memory_operand" "")))
316 (and (eq_attr "type" "imov")
317 (ior (and (match_operand 0 "register_operand" "")
318 (match_operand 1 "immediate_operand" ""))
319 (ior (and (match_operand 0 "ax_reg_operand" "")
320 (match_operand 1 "memory_displacement_only_operand" ""))
321 (and (match_operand 0 "memory_displacement_only_operand" "")
322 (match_operand 1 "ax_reg_operand" "")))))
324 (and (eq_attr "type" "call")
325 (match_operand 0 "constant_call_address_operand" ""))
327 (and (eq_attr "type" "callv")
328 (match_operand 1 "constant_call_address_operand" ""))
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
337 (define_attr "length" ""
338 (cond [(eq_attr "type" "other,multi,fistp,frndint")
340 (eq_attr "type" "fcmp")
342 (eq_attr "unit" "i387")
344 (plus (attr "prefix_data16")
345 (attr "length_address")))]
346 (plus (plus (attr "modrm")
347 (plus (attr "prefix_0f")
348 (plus (attr "prefix_rex")
350 (plus (attr "prefix_rep")
351 (plus (attr "prefix_data16")
352 (plus (attr "length_immediate")
353 (attr "length_address")))))))
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
359 (define_attr "memory" "none,load,store,both,unknown"
360 (cond [(eq_attr "type" "other,multi,str")
361 (const_string "unknown")
362 (eq_attr "type" "lea,fcmov,fpspc,cld")
363 (const_string "none")
364 (eq_attr "type" "fistp,leave")
365 (const_string "both")
366 (eq_attr "type" "frndint")
367 (const_string "load")
368 (eq_attr "type" "push")
369 (if_then_else (match_operand 1 "memory_operand" "")
370 (const_string "both")
371 (const_string "store"))
372 (eq_attr "type" "pop")
373 (if_then_else (match_operand 0 "memory_operand" "")
374 (const_string "both")
375 (const_string "load"))
376 (eq_attr "type" "setcc")
377 (if_then_else (match_operand 0 "memory_operand" "")
378 (const_string "store")
379 (const_string "none"))
380 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381 (if_then_else (ior (match_operand 0 "memory_operand" "")
382 (match_operand 1 "memory_operand" ""))
383 (const_string "load")
384 (const_string "none"))
385 (eq_attr "type" "ibr")
386 (if_then_else (match_operand 0 "memory_operand" "")
387 (const_string "load")
388 (const_string "none"))
389 (eq_attr "type" "call")
390 (if_then_else (match_operand 0 "constant_call_address_operand" "")
391 (const_string "none")
392 (const_string "load"))
393 (eq_attr "type" "callv")
394 (if_then_else (match_operand 1 "constant_call_address_operand" "")
395 (const_string "none")
396 (const_string "load"))
397 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398 (match_operand 1 "memory_operand" ""))
399 (const_string "both")
400 (and (match_operand 0 "memory_operand" "")
401 (match_operand 1 "memory_operand" ""))
402 (const_string "both")
403 (match_operand 0 "memory_operand" "")
404 (const_string "store")
405 (match_operand 1 "memory_operand" "")
406 (const_string "load")
408 "!alu1,negnot,ishift1,
409 imov,imovx,icmp,test,
411 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412 mmx,mmxmov,mmxcmp,mmxcvt")
413 (match_operand 2 "memory_operand" ""))
414 (const_string "load")
415 (and (eq_attr "type" "icmov")
416 (match_operand 3 "memory_operand" ""))
417 (const_string "load")
419 (const_string "none")))
421 ;; Indicates if an instruction has both an immediate and a displacement.
423 (define_attr "imm_disp" "false,true,unknown"
424 (cond [(eq_attr "type" "other,multi")
425 (const_string "unknown")
426 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427 (and (match_operand 0 "memory_displacement_operand" "")
428 (match_operand 1 "immediate_operand" "")))
429 (const_string "true")
430 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431 (and (match_operand 0 "memory_displacement_operand" "")
432 (match_operand 2 "immediate_operand" "")))
433 (const_string "true")
435 (const_string "false")))
437 ;; Indicates if an FP operation has an integer source.
439 (define_attr "fp_int_src" "false,true"
440 (const_string "false"))
442 ;; Defines rounding mode of an FP operation.
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445 (const_string "any"))
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449 [(set_attr "length" "128")
450 (set_attr "type" "multi")])
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
468 ;; Scheduling descriptions
470 (include "pentium.md")
473 (include "athlon.md")
476 ;; Operand and operator predicates
478 (include "predicates.md")
481 ;; Compare instructions.
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
487 (define_expand "cmpti"
488 [(set (reg:CC FLAGS_REG)
489 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490 (match_operand:TI 1 "x86_64_general_operand" "")))]
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (TImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
500 (define_expand "cmpdi"
501 [(set (reg:CC FLAGS_REG)
502 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503 (match_operand:DI 1 "x86_64_general_operand" "")))]
506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507 operands[0] = force_reg (DImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
513 (define_expand "cmpsi"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516 (match_operand:SI 1 "general_operand" "")))]
519 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520 operands[0] = force_reg (SImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
526 (define_expand "cmphi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529 (match_operand:HI 1 "general_operand" "")))]
532 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533 operands[0] = force_reg (HImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
539 (define_expand "cmpqi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542 (match_operand:QI 1 "general_operand" "")))]
545 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546 operands[0] = force_reg (QImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
552 (define_insn "cmpdi_ccno_1_rex64"
553 [(set (reg FLAGS_REG)
554 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:DI 1 "const0_operand" "n,n")))]
556 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
558 test{q}\t{%0, %0|%0, %0}
559 cmp{q}\t{%1, %0|%0, %1}"
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "DI")])
564 (define_insn "*cmpdi_minus_1_rex64"
565 [(set (reg FLAGS_REG)
566 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
569 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570 "cmp{q}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "icmp")
572 (set_attr "mode" "DI")])
574 (define_expand "cmpdi_1_rex64"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577 (match_operand:DI 1 "general_operand" "")))]
581 (define_insn "cmpdi_1_insn_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586 "cmp{q}\t{%1, %0|%0, %1}"
587 [(set_attr "type" "icmp")
588 (set_attr "mode" "DI")])
591 (define_insn "*cmpsi_ccno_1"
592 [(set (reg FLAGS_REG)
593 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:SI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
597 test{l}\t{%0, %0|%0, %0}
598 cmp{l}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "SI")])
603 (define_insn "*cmpsi_minus_1"
604 [(set (reg FLAGS_REG)
605 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:SI 1 "general_operand" "ri,mr"))
608 "ix86_match_ccmode (insn, CCGOCmode)"
609 "cmp{l}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "SI")])
613 (define_expand "cmpsi_1"
614 [(set (reg:CC FLAGS_REG)
615 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:SI 1 "general_operand" "ri,mr")))]
620 (define_insn "*cmpsi_1_insn"
621 [(set (reg FLAGS_REG)
622 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr")))]
624 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625 && ix86_match_ccmode (insn, CCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
630 (define_insn "*cmphi_ccno_1"
631 [(set (reg FLAGS_REG)
632 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633 (match_operand:HI 1 "const0_operand" "n,n")))]
634 "ix86_match_ccmode (insn, CCNOmode)"
636 test{w}\t{%0, %0|%0, %0}
637 cmp{w}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "test,icmp")
639 (set_attr "length_immediate" "0,1")
640 (set_attr "mode" "HI")])
642 (define_insn "*cmphi_minus_1"
643 [(set (reg FLAGS_REG)
644 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645 (match_operand:HI 1 "general_operand" "ri,mr"))
647 "ix86_match_ccmode (insn, CCGOCmode)"
648 "cmp{w}\t{%1, %0|%0, %1}"
649 [(set_attr "type" "icmp")
650 (set_attr "mode" "HI")])
652 (define_insn "*cmphi_1"
653 [(set (reg FLAGS_REG)
654 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655 (match_operand:HI 1 "general_operand" "ri,mr")))]
656 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657 && ix86_match_ccmode (insn, CCmode)"
658 "cmp{w}\t{%1, %0|%0, %1}"
659 [(set_attr "type" "icmp")
660 (set_attr "mode" "HI")])
662 (define_insn "*cmpqi_ccno_1"
663 [(set (reg FLAGS_REG)
664 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665 (match_operand:QI 1 "const0_operand" "n,n")))]
666 "ix86_match_ccmode (insn, CCNOmode)"
668 test{b}\t{%0, %0|%0, %0}
669 cmp{b}\t{$0, %0|%0, 0}"
670 [(set_attr "type" "test,icmp")
671 (set_attr "length_immediate" "0,1")
672 (set_attr "mode" "QI")])
674 (define_insn "*cmpqi_1"
675 [(set (reg FLAGS_REG)
676 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677 (match_operand:QI 1 "general_operand" "qi,mq")))]
678 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679 && ix86_match_ccmode (insn, CCmode)"
680 "cmp{b}\t{%1, %0|%0, %1}"
681 [(set_attr "type" "icmp")
682 (set_attr "mode" "QI")])
684 (define_insn "*cmpqi_minus_1"
685 [(set (reg FLAGS_REG)
686 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687 (match_operand:QI 1 "general_operand" "qi,mq"))
689 "ix86_match_ccmode (insn, CCGOCmode)"
690 "cmp{b}\t{%1, %0|%0, %1}"
691 [(set_attr "type" "icmp")
692 (set_attr "mode" "QI")])
694 (define_insn "*cmpqi_ext_1"
695 [(set (reg FLAGS_REG)
697 (match_operand:QI 0 "general_operand" "Qm")
700 (match_operand 1 "ext_register_operand" "Q")
703 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704 "cmp{b}\t{%h1, %0|%0, %h1}"
705 [(set_attr "type" "icmp")
706 (set_attr "mode" "QI")])
708 (define_insn "*cmpqi_ext_1_rex64"
709 [(set (reg FLAGS_REG)
711 (match_operand:QI 0 "register_operand" "Q")
714 (match_operand 1 "ext_register_operand" "Q")
717 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718 "cmp{b}\t{%h1, %0|%0, %h1}"
719 [(set_attr "type" "icmp")
720 (set_attr "mode" "QI")])
722 (define_insn "*cmpqi_ext_2"
723 [(set (reg FLAGS_REG)
727 (match_operand 0 "ext_register_operand" "Q")
730 (match_operand:QI 1 "const0_operand" "n")))]
731 "ix86_match_ccmode (insn, CCNOmode)"
733 [(set_attr "type" "test")
734 (set_attr "length_immediate" "0")
735 (set_attr "mode" "QI")])
737 (define_expand "cmpqi_ext_3"
738 [(set (reg:CC FLAGS_REG)
742 (match_operand 0 "ext_register_operand" "")
745 (match_operand:QI 1 "general_operand" "")))]
749 (define_insn "cmpqi_ext_3_insn"
750 [(set (reg FLAGS_REG)
754 (match_operand 0 "ext_register_operand" "Q")
757 (match_operand:QI 1 "general_operand" "Qmn")))]
758 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759 "cmp{b}\t{%1, %h0|%h0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "QI")])
763 (define_insn "cmpqi_ext_3_insn_rex64"
764 [(set (reg FLAGS_REG)
768 (match_operand 0 "ext_register_operand" "Q")
771 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773 "cmp{b}\t{%1, %h0|%h0, %1}"
774 [(set_attr "type" "icmp")
775 (set_attr "mode" "QI")])
777 (define_insn "*cmpqi_ext_4"
778 [(set (reg FLAGS_REG)
782 (match_operand 0 "ext_register_operand" "Q")
787 (match_operand 1 "ext_register_operand" "Q")
790 "ix86_match_ccmode (insn, CCmode)"
791 "cmp{b}\t{%h1, %h0|%h0, %h1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares. Which is what
798 ;; the old patterns did, but with many more of them.
800 (define_expand "cmpxf"
801 [(set (reg:CC FLAGS_REG)
802 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803 (match_operand:XF 1 "nonmemory_operand" "")))]
806 ix86_compare_op0 = operands[0];
807 ix86_compare_op1 = operands[1];
811 (define_expand "cmpdf"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
817 ix86_compare_op0 = operands[0];
818 ix86_compare_op1 = operands[1];
822 (define_expand "cmpsf"
823 [(set (reg:CC FLAGS_REG)
824 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826 "TARGET_80387 || TARGET_SSE_MATH"
828 ix86_compare_op0 = operands[0];
829 ix86_compare_op1 = operands[1];
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
836 ;; CCFPmode compare with exceptions
837 ;; CCFPUmode compare with no exceptions
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
842 (define_insn "*cmpfp_0"
843 [(set (match_operand:HI 0 "register_operand" "=a")
846 (match_operand 1 "register_operand" "f")
847 (match_operand 2 "const0_operand" "X"))]
850 && FLOAT_MODE_P (GET_MODE (operands[1]))
851 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852 "* return output_fp_compare (insn, operands, 0, 0);"
853 [(set_attr "type" "multi")
854 (set_attr "unit" "i387")
856 (cond [(match_operand:SF 1 "" "")
858 (match_operand:DF 1 "" "")
861 (const_string "XF")))])
863 (define_insn "*cmpfp_sf"
864 [(set (match_operand:HI 0 "register_operand" "=a")
867 (match_operand:SF 1 "register_operand" "f")
868 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871 "* return output_fp_compare (insn, operands, 0, 0);"
872 [(set_attr "type" "multi")
873 (set_attr "unit" "i387")
874 (set_attr "mode" "SF")])
876 (define_insn "*cmpfp_df"
877 [(set (match_operand:HI 0 "register_operand" "=a")
880 (match_operand:DF 1 "register_operand" "f")
881 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884 "* return output_fp_compare (insn, operands, 0, 0);"
885 [(set_attr "type" "multi")
886 (set_attr "unit" "i387")
887 (set_attr "mode" "DF")])
889 (define_insn "*cmpfp_xf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
893 (match_operand:XF 1 "register_operand" "f")
894 (match_operand:XF 2 "register_operand" "f"))]
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "XF")])
902 (define_insn "*cmpfp_u"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand 1 "register_operand" "f")
907 (match_operand 2 "register_operand" "f"))]
910 && FLOAT_MODE_P (GET_MODE (operands[1]))
911 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912 "* return output_fp_compare (insn, operands, 0, 1);"
913 [(set_attr "type" "multi")
914 (set_attr "unit" "i387")
916 (cond [(match_operand:SF 1 "" "")
918 (match_operand:DF 1 "" "")
921 (const_string "XF")))])
923 (define_insn "*cmpfp_<mode>"
924 [(set (match_operand:HI 0 "register_operand" "=a")
927 (match_operand 1 "register_operand" "f")
928 (match_operator 3 "float_operator"
929 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
931 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932 && FLOAT_MODE_P (GET_MODE (operands[1]))
933 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934 "* return output_fp_compare (insn, operands, 0, 0);"
935 [(set_attr "type" "multi")
936 (set_attr "unit" "i387")
937 (set_attr "fp_int_src" "true")
938 (set_attr "mode" "<MODE>")])
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
943 (define_insn "x86_fnstsw_1"
944 [(set (match_operand:HI 0 "register_operand" "=a")
945 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948 [(set_attr "length" "2")
949 (set_attr "mode" "SI")
950 (set_attr "unit" "i387")])
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
955 (define_insn "x86_sahf_1"
956 [(set (reg:CC FLAGS_REG)
957 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960 [(set_attr "length" "1")
961 (set_attr "athlon_decode" "vector")
962 (set_attr "mode" "SI")])
964 ;; Pentium Pro can do steps 1 through 3 in one go.
966 (define_insn "*cmpfp_i_mixed"
967 [(set (reg:CCFP FLAGS_REG)
968 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
971 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973 "* return output_fp_compare (insn, operands, 1, 0);"
974 [(set_attr "type" "fcmp,ssecomi")
976 (if_then_else (match_operand:SF 1 "" "")
978 (const_string "DF")))
979 (set_attr "athlon_decode" "vector")])
981 (define_insn "*cmpfp_i_sse"
982 [(set (reg:CCFP FLAGS_REG)
983 (compare:CCFP (match_operand 0 "register_operand" "x")
984 (match_operand 1 "nonimmediate_operand" "xm")))]
986 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988 "* return output_fp_compare (insn, operands, 1, 0);"
989 [(set_attr "type" "ssecomi")
991 (if_then_else (match_operand:SF 1 "" "")
993 (const_string "DF")))
994 (set_attr "athlon_decode" "vector")])
996 (define_insn "*cmpfp_i_i387"
997 [(set (reg:CCFP FLAGS_REG)
998 (compare:CCFP (match_operand 0 "register_operand" "f")
999 (match_operand 1 "register_operand" "f")))]
1000 "TARGET_80387 && TARGET_CMOVE
1001 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002 && FLOAT_MODE_P (GET_MODE (operands[0]))
1003 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004 "* return output_fp_compare (insn, operands, 1, 0);"
1005 [(set_attr "type" "fcmp")
1007 (cond [(match_operand:SF 1 "" "")
1009 (match_operand:DF 1 "" "")
1012 (const_string "XF")))
1013 (set_attr "athlon_decode" "vector")])
1015 (define_insn "*cmpfp_iu_mixed"
1016 [(set (reg:CCFPU FLAGS_REG)
1017 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019 "TARGET_MIX_SSE_I387
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 1);"
1023 [(set_attr "type" "fcmp,ssecomi")
1025 (if_then_else (match_operand:SF 1 "" "")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")])
1030 (define_insn "*cmpfp_iu_sse"
1031 [(set (reg:CCFPU FLAGS_REG)
1032 (compare:CCFPU (match_operand 0 "register_operand" "x")
1033 (match_operand 1 "nonimmediate_operand" "xm")))]
1035 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037 "* return output_fp_compare (insn, operands, 1, 1);"
1038 [(set_attr "type" "ssecomi")
1040 (if_then_else (match_operand:SF 1 "" "")
1042 (const_string "DF")))
1043 (set_attr "athlon_decode" "vector")])
1045 (define_insn "*cmpfp_iu_387"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f")
1048 (match_operand 1 "register_operand" "f")))]
1049 "TARGET_80387 && TARGET_CMOVE
1050 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051 && FLOAT_MODE_P (GET_MODE (operands[0]))
1052 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053 "* return output_fp_compare (insn, operands, 1, 1);"
1054 [(set_attr "type" "fcmp")
1056 (cond [(match_operand:SF 1 "" "")
1058 (match_operand:DF 1 "" "")
1061 (const_string "XF")))
1062 (set_attr "athlon_decode" "vector")])
1064 ;; Move instructions.
1066 ;; General case of fullword move.
1068 (define_expand "movsi"
1069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070 (match_operand:SI 1 "general_operand" ""))]
1072 "ix86_expand_move (SImode, operands); DONE;")
1074 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1083 (define_insn "*pushsi2"
1084 [(set (match_operand:SI 0 "push_operand" "=<")
1085 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088 [(set_attr "type" "push")
1089 (set_attr "mode" "SI")])
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093 [(set (match_operand:SI 0 "push_operand" "=X")
1094 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1100 (define_insn "*pushsi2_prologue"
1101 [(set (match_operand:SI 0 "push_operand" "=<")
1102 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103 (clobber (mem:BLK (scratch)))]
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1109 (define_insn "*popsi1_epilogue"
1110 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111 (mem:SI (reg:SI SP_REG)))
1112 (set (reg:SI SP_REG)
1113 (plus:SI (reg:SI SP_REG) (const_int 4)))
1114 (clobber (mem:BLK (scratch)))]
1117 [(set_attr "type" "pop")
1118 (set_attr "mode" "SI")])
1120 (define_insn "popsi1"
1121 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122 (mem:SI (reg:SI SP_REG)))
1123 (set (reg:SI SP_REG)
1124 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127 [(set_attr "type" "pop")
1128 (set_attr "mode" "SI")])
1130 (define_insn "*movsi_xor"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (match_operand:SI 1 "const0_operand" "i"))
1133 (clobber (reg:CC FLAGS_REG))]
1134 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135 "xor{l}\t{%0, %0|%0, %0}"
1136 [(set_attr "type" "alu1")
1137 (set_attr "mode" "SI")
1138 (set_attr "length_immediate" "0")])
1140 (define_insn "*movsi_or"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (match_operand:SI 1 "immediate_operand" "i"))
1143 (clobber (reg:CC FLAGS_REG))]
1145 && operands[1] == constm1_rtx
1146 && (TARGET_PENTIUM || optimize_size)"
1148 operands[1] = constm1_rtx;
1149 return "or{l}\t{%1, %0|%0, %1}";
1151 [(set_attr "type" "alu1")
1152 (set_attr "mode" "SI")
1153 (set_attr "length_immediate" "1")])
1155 (define_insn "*movsi_1"
1156 [(set (match_operand:SI 0 "nonimmediate_operand"
1157 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158 (match_operand:SI 1 "general_operand"
1159 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1160 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1162 switch (get_attr_type (insn))
1165 if (get_attr_mode (insn) == MODE_TI)
1166 return "pxor\t%0, %0";
1167 return "xorps\t%0, %0";
1170 switch (get_attr_mode (insn))
1173 return "movdqa\t{%1, %0|%0, %1}";
1175 return "movaps\t{%1, %0|%0, %1}";
1177 return "movd\t{%1, %0|%0, %1}";
1179 return "movss\t{%1, %0|%0, %1}";
1185 return "pxor\t%0, %0";
1188 if (get_attr_mode (insn) == MODE_DI)
1189 return "movq\t{%1, %0|%0, %1}";
1190 return "movd\t{%1, %0|%0, %1}";
1193 return "lea{l}\t{%1, %0|%0, %1}";
1196 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197 return "mov{l}\t{%1, %0|%0, %1}";
1201 (cond [(eq_attr "alternative" "2")
1202 (const_string "mmxadd")
1203 (eq_attr "alternative" "3,4,5")
1204 (const_string "mmxmov")
1205 (eq_attr "alternative" "6")
1206 (const_string "sselog1")
1207 (eq_attr "alternative" "7,8,9,10,11")
1208 (const_string "ssemov")
1209 (match_operand:DI 1 "pic_32bit_operand" "")
1210 (const_string "lea")
1212 (const_string "imov")))
1214 (cond [(eq_attr "alternative" "2,3")
1216 (eq_attr "alternative" "6,7")
1218 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219 (const_string "V4SF")
1220 (const_string "TI"))
1221 (and (eq_attr "alternative" "8,9,10,11")
1222 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225 (const_string "SI")))])
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1235 movabs{l}\t{%1, %P0|%P0, %1}
1236 mov{l}\t{%1, %a0|%a0, %1}"
1237 [(set_attr "type" "imov")
1238 (set_attr "modrm" "0,*")
1239 (set_attr "length_address" "8,0")
1240 (set_attr "length_immediate" "0,*")
1241 (set_attr "memory" "store")
1242 (set_attr "mode" "SI")])
1244 (define_insn "*movabssi_2_rex64"
1245 [(set (match_operand:SI 0 "register_operand" "=a,r")
1246 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1249 movabs{l}\t{%P1, %0|%0, %P1}
1250 mov{l}\t{%a1, %0|%0, %a1}"
1251 [(set_attr "type" "imov")
1252 (set_attr "modrm" "0,*")
1253 (set_attr "length_address" "8,0")
1254 (set_attr "length_immediate" "0")
1255 (set_attr "memory" "load")
1256 (set_attr "mode" "SI")])
1258 (define_insn "*swapsi"
1259 [(set (match_operand:SI 0 "register_operand" "+r")
1260 (match_operand:SI 1 "register_operand" "+r"))
1265 [(set_attr "type" "imov")
1266 (set_attr "mode" "SI")
1267 (set_attr "pent_pair" "np")
1268 (set_attr "athlon_decode" "vector")])
1270 (define_expand "movhi"
1271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272 (match_operand:HI 1 "general_operand" ""))]
1274 "ix86_expand_move (HImode, operands); DONE;")
1276 (define_insn "*pushhi2"
1277 [(set (match_operand:HI 0 "push_operand" "=<,<")
1278 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1281 push{w}\t{|WORD PTR }%1
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "HI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "QI")])
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 switch (get_attr_type (insn))
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310 return "mov{w}\t{%1, %0|%0, %1}";
1314 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1330 (const_string "imov")))
1332 (cond [(eq_attr "type" "imovx")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1382 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384 [(set_attr "type" "imov")
1385 (set_attr "mode" "SI")
1386 (set_attr "pent_pair" "np")
1387 (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390 [(set (match_operand:HI 0 "register_operand" "+r")
1391 (match_operand:HI 1 "register_operand" "+r"))
1394 "TARGET_PARTIAL_REG_STALL"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1435 "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X,X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1446 push{w}\t{|word ptr }%1
1448 [(set_attr "type" "push")
1449 (set_attr "mode" "HI")])
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453 [(set (match_operand:QI 0 "push_operand" "=X")
1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1457 [(set_attr "type" "push")
1458 (set_attr "mode" "QI")])
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there. Then we use movzx.
1470 (define_insn "*movqi_1"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1473 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1475 switch (get_attr_type (insn))
1478 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481 if (get_attr_mode (insn) == MODE_SI)
1482 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484 return "mov{b}\t{%1, %0|%0, %1}";
1488 (cond [(and (eq_attr "alternative" "5")
1489 (not (match_operand:QI 1 "aligned_operand" "")))
1490 (const_string "imovx")
1491 (ne (symbol_ref "optimize_size") (const_int 0))
1492 (const_string "imov")
1493 (and (eq_attr "alternative" "3")
1494 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1496 (eq (symbol_ref "TARGET_QIMODE_MATH")
1498 (const_string "imov")
1499 (eq_attr "alternative" "3,5")
1500 (const_string "imovx")
1501 (and (ne (symbol_ref "TARGET_MOVX")
1503 (eq_attr "alternative" "2"))
1504 (const_string "imovx")
1506 (const_string "imov")))
1508 (cond [(eq_attr "alternative" "3,4,5")
1510 (eq_attr "alternative" "6")
1512 (eq_attr "type" "imovx")
1514 (and (eq_attr "type" "imov")
1515 (and (eq_attr "alternative" "0,1")
1516 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1519 ;; Avoid partial register stalls when not using QImode arithmetic
1520 (and (eq_attr "type" "imov")
1521 (and (eq_attr "alternative" "0,1")
1522 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1524 (eq (symbol_ref "TARGET_QIMODE_MATH")
1528 (const_string "QI")))])
1530 (define_expand "reload_outqi"
1531 [(parallel [(match_operand:QI 0 "" "=m")
1532 (match_operand:QI 1 "register_operand" "r")
1533 (match_operand:QI 2 "register_operand" "=&q")])]
1537 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1539 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1540 if (! q_regs_operand (op1, QImode))
1542 emit_insn (gen_movqi (op2, op1));
1545 emit_insn (gen_movqi (op0, op1));
1549 (define_insn "*swapqi_1"
1550 [(set (match_operand:QI 0 "register_operand" "+r")
1551 (match_operand:QI 1 "register_operand" "+r"))
1554 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1556 [(set_attr "type" "imov")
1557 (set_attr "mode" "SI")
1558 (set_attr "pent_pair" "np")
1559 (set_attr "athlon_decode" "vector")])
1561 (define_insn "*swapqi_2"
1562 [(set (match_operand:QI 0 "register_operand" "+q")
1563 (match_operand:QI 1 "register_operand" "+q"))
1566 "TARGET_PARTIAL_REG_STALL"
1568 [(set_attr "type" "imov")
1569 (set_attr "mode" "QI")
1570 (set_attr "pent_pair" "np")
1571 (set_attr "athlon_decode" "vector")])
1573 (define_expand "movstrictqi"
1574 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1575 (match_operand:QI 1 "general_operand" ""))]
1576 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1578 /* Don't generate memory->memory moves, go through a register. */
1579 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1580 operands[1] = force_reg (QImode, operands[1]);
1583 (define_insn "*movstrictqi_1"
1584 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1585 (match_operand:QI 1 "general_operand" "*qn,m"))]
1586 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1588 "mov{b}\t{%1, %0|%0, %1}"
1589 [(set_attr "type" "imov")
1590 (set_attr "mode" "QI")])
1592 (define_insn "*movstrictqi_xor"
1593 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1594 (match_operand:QI 1 "const0_operand" "i"))
1595 (clobber (reg:CC FLAGS_REG))]
1596 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1597 "xor{b}\t{%0, %0|%0, %0}"
1598 [(set_attr "type" "alu1")
1599 (set_attr "mode" "QI")
1600 (set_attr "length_immediate" "0")])
1602 (define_insn "*movsi_extv_1"
1603 [(set (match_operand:SI 0 "register_operand" "=R")
1604 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1609 [(set_attr "type" "imovx")
1610 (set_attr "mode" "SI")])
1612 (define_insn "*movhi_extv_1"
1613 [(set (match_operand:HI 0 "register_operand" "=R")
1614 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1619 [(set_attr "type" "imovx")
1620 (set_attr "mode" "SI")])
1622 (define_insn "*movqi_extv_1"
1623 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1624 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1629 switch (get_attr_type (insn))
1632 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1634 return "mov{b}\t{%h1, %0|%0, %h1}";
1638 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1639 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1640 (ne (symbol_ref "TARGET_MOVX")
1642 (const_string "imovx")
1643 (const_string "imov")))
1645 (if_then_else (eq_attr "type" "imovx")
1647 (const_string "QI")))])
1649 (define_insn "*movqi_extv_1_rex64"
1650 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1651 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1656 switch (get_attr_type (insn))
1659 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1661 return "mov{b}\t{%h1, %0|%0, %h1}";
1665 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1666 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1667 (ne (symbol_ref "TARGET_MOVX")
1669 (const_string "imovx")
1670 (const_string "imov")))
1672 (if_then_else (eq_attr "type" "imovx")
1674 (const_string "QI")))])
1676 ;; Stores and loads of ax to arbitrary constant address.
1677 ;; We fake an second form of instruction to force reload to load address
1678 ;; into register when rax is not available
1679 (define_insn "*movabsqi_1_rex64"
1680 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1681 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1682 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1684 movabs{b}\t{%1, %P0|%P0, %1}
1685 mov{b}\t{%1, %a0|%a0, %1}"
1686 [(set_attr "type" "imov")
1687 (set_attr "modrm" "0,*")
1688 (set_attr "length_address" "8,0")
1689 (set_attr "length_immediate" "0,*")
1690 (set_attr "memory" "store")
1691 (set_attr "mode" "QI")])
1693 (define_insn "*movabsqi_2_rex64"
1694 [(set (match_operand:QI 0 "register_operand" "=a,r")
1695 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1696 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1698 movabs{b}\t{%P1, %0|%0, %P1}
1699 mov{b}\t{%a1, %0|%0, %a1}"
1700 [(set_attr "type" "imov")
1701 (set_attr "modrm" "0,*")
1702 (set_attr "length_address" "8,0")
1703 (set_attr "length_immediate" "0")
1704 (set_attr "memory" "load")
1705 (set_attr "mode" "QI")])
1707 (define_insn "*movdi_extzv_1"
1708 [(set (match_operand:DI 0 "register_operand" "=R")
1709 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1714 [(set_attr "type" "imovx")
1715 (set_attr "mode" "DI")])
1717 (define_insn "*movsi_extzv_1"
1718 [(set (match_operand:SI 0 "register_operand" "=R")
1719 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1724 [(set_attr "type" "imovx")
1725 (set_attr "mode" "SI")])
1727 (define_insn "*movqi_extzv_2"
1728 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1729 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1734 switch (get_attr_type (insn))
1737 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1739 return "mov{b}\t{%h1, %0|%0, %h1}";
1743 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1744 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1745 (ne (symbol_ref "TARGET_MOVX")
1747 (const_string "imovx")
1748 (const_string "imov")))
1750 (if_then_else (eq_attr "type" "imovx")
1752 (const_string "QI")))])
1754 (define_insn "*movqi_extzv_2_rex64"
1755 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1756 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1761 switch (get_attr_type (insn))
1764 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1766 return "mov{b}\t{%h1, %0|%0, %h1}";
1770 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1771 (ne (symbol_ref "TARGET_MOVX")
1773 (const_string "imovx")
1774 (const_string "imov")))
1776 (if_then_else (eq_attr "type" "imovx")
1778 (const_string "QI")))])
1780 (define_insn "movsi_insv_1"
1781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784 (match_operand:SI 1 "general_operand" "Qmn"))]
1786 "mov{b}\t{%b1, %h0|%h0, %b1}"
1787 [(set_attr "type" "imov")
1788 (set_attr "mode" "QI")])
1790 (define_insn "movdi_insv_1_rex64"
1791 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1796 "mov{b}\t{%b1, %h0|%h0, %b1}"
1797 [(set_attr "type" "imov")
1798 (set_attr "mode" "QI")])
1800 (define_insn "*movqi_insv_2"
1801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807 "mov{b}\t{%h1, %h0|%h0, %h1}"
1808 [(set_attr "type" "imov")
1809 (set_attr "mode" "QI")])
1811 (define_expand "movdi"
1812 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1813 (match_operand:DI 1 "general_operand" ""))]
1815 "ix86_expand_move (DImode, operands); DONE;")
1817 (define_insn "*pushdi"
1818 [(set (match_operand:DI 0 "push_operand" "=<")
1819 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823 (define_insn "*pushdi2_rex64"
1824 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1825 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1830 [(set_attr "type" "push,multi")
1831 (set_attr "mode" "DI")])
1833 ;; Convert impossible pushes of immediate to existing instructions.
1834 ;; First try to get scratch register and go through it. In case this
1835 ;; fails, push sign extended lower part first and then overwrite
1836 ;; upper part by 32bit move.
1838 [(match_scratch:DI 2 "r")
1839 (set (match_operand:DI 0 "push_operand" "")
1840 (match_operand:DI 1 "immediate_operand" ""))]
1841 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1842 && !x86_64_immediate_operand (operands[1], DImode)"
1843 [(set (match_dup 2) (match_dup 1))
1844 (set (match_dup 0) (match_dup 2))]
1847 ;; We need to define this as both peepholer and splitter for case
1848 ;; peephole2 pass is not run.
1849 ;; "&& 1" is needed to keep it from matching the previous pattern.
1851 [(set (match_operand:DI 0 "push_operand" "")
1852 (match_operand:DI 1 "immediate_operand" ""))]
1853 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1854 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1855 [(set (match_dup 0) (match_dup 1))
1856 (set (match_dup 2) (match_dup 3))]
1857 "split_di (operands + 1, 1, operands + 2, operands + 3);
1858 operands[1] = gen_lowpart (DImode, operands[2]);
1859 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1864 [(set (match_operand:DI 0 "push_operand" "")
1865 (match_operand:DI 1 "immediate_operand" ""))]
1866 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1867 ? flow2_completed : reload_completed)
1868 && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode)"
1870 [(set (match_dup 0) (match_dup 1))
1871 (set (match_dup 2) (match_dup 3))]
1872 "split_di (operands + 1, 1, operands + 2, operands + 3);
1873 operands[1] = gen_lowpart (DImode, operands[2]);
1874 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878 (define_insn "*pushdi2_prologue_rex64"
1879 [(set (match_operand:DI 0 "push_operand" "=<")
1880 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1881 (clobber (mem:BLK (scratch)))]
1884 [(set_attr "type" "push")
1885 (set_attr "mode" "DI")])
1887 (define_insn "*popdi1_epilogue_rex64"
1888 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1889 (mem:DI (reg:DI SP_REG)))
1890 (set (reg:DI SP_REG)
1891 (plus:DI (reg:DI SP_REG) (const_int 8)))
1892 (clobber (mem:BLK (scratch)))]
1895 [(set_attr "type" "pop")
1896 (set_attr "mode" "DI")])
1898 (define_insn "popdi1"
1899 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900 (mem:DI (reg:DI SP_REG)))
1901 (set (reg:DI SP_REG)
1902 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905 [(set_attr "type" "pop")
1906 (set_attr "mode" "DI")])
1908 (define_insn "*movdi_xor_rex64"
1909 [(set (match_operand:DI 0 "register_operand" "=r")
1910 (match_operand:DI 1 "const0_operand" "i"))
1911 (clobber (reg:CC FLAGS_REG))]
1912 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1913 && reload_completed"
1914 "xor{l}\t{%k0, %k0|%k0, %k0}"
1915 [(set_attr "type" "alu1")
1916 (set_attr "mode" "SI")
1917 (set_attr "length_immediate" "0")])
1919 (define_insn "*movdi_or_rex64"
1920 [(set (match_operand:DI 0 "register_operand" "=r")
1921 (match_operand:DI 1 "const_int_operand" "i"))
1922 (clobber (reg:CC FLAGS_REG))]
1923 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1925 && operands[1] == constm1_rtx"
1927 operands[1] = constm1_rtx;
1928 return "or{q}\t{%1, %0|%0, %1}";
1930 [(set_attr "type" "alu1")
1931 (set_attr "mode" "DI")
1932 (set_attr "length_immediate" "1")])
1934 (define_insn "*movdi_2"
1935 [(set (match_operand:DI 0 "nonimmediate_operand"
1936 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1937 (match_operand:DI 1 "general_operand"
1938 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1939 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944 movq\t{%1, %0|%0, %1}
1945 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1948 movdqa\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}
1951 movlps\t{%1, %0|%0, %1}
1952 movaps\t{%1, %0|%0, %1}
1953 movlps\t{%1, %0|%0, %1}"
1954 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1955 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958 [(set (match_operand:DI 0 "push_operand" "")
1959 (match_operand:DI 1 "general_operand" ""))]
1960 "!TARGET_64BIT && reload_completed
1961 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1963 "ix86_split_long_move (operands); DONE;")
1965 ;; %%% This multiword shite has got to go.
1967 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1968 (match_operand:DI 1 "general_operand" ""))]
1969 "!TARGET_64BIT && reload_completed
1970 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1971 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973 "ix86_split_long_move (operands); DONE;")
1975 (define_insn "*movdi_1_rex64"
1976 [(set (match_operand:DI 0 "nonimmediate_operand"
1977 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1978 (match_operand:DI 1 "general_operand"
1979 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1980 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 switch (get_attr_type (insn))
1985 if (which_alternative == 13)
1986 return "movq2dq\t{%1, %0|%0, %1}";
1988 return "movdq2q\t{%1, %0|%0, %1}";
1990 if (get_attr_mode (insn) == MODE_TI)
1991 return "movdqa\t{%1, %0|%0, %1}";
1994 /* Moves from and into integer register is done using movd opcode with
1996 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997 return "movd\t{%1, %0|%0, %1}";
1998 return "movq\t{%1, %0|%0, %1}";
2001 return "pxor\t%0, %0";
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2007 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2008 if (get_attr_mode (insn) == MODE_SI)
2009 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2010 else if (which_alternative == 2)
2011 return "movabs{q}\t{%1, %0|%0, %1}";
2013 return "mov{q}\t{%1, %0|%0, %1}";
2017 (cond [(eq_attr "alternative" "5")
2018 (const_string "mmxadd")
2019 (eq_attr "alternative" "6,7,8")
2020 (const_string "mmxmov")
2021 (eq_attr "alternative" "9")
2022 (const_string "sselog1")
2023 (eq_attr "alternative" "10,11,12")
2024 (const_string "ssemov")
2025 (eq_attr "alternative" "13,14")
2026 (const_string "ssecvt")
2027 (eq_attr "alternative" "4")
2028 (const_string "multi")
2029 (match_operand:DI 1 "pic_32bit_operand" "")
2030 (const_string "lea")
2032 (const_string "imov")))
2033 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2034 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2035 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2037 ;; Stores and loads of ax to arbitrary constant address.
2038 ;; We fake an second form of instruction to force reload to load address
2039 ;; into register when rax is not available
2040 (define_insn "*movabsdi_1_rex64"
2041 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2042 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2043 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2045 movabs{q}\t{%1, %P0|%P0, %1}
2046 mov{q}\t{%1, %a0|%a0, %1}"
2047 [(set_attr "type" "imov")
2048 (set_attr "modrm" "0,*")
2049 (set_attr "length_address" "8,0")
2050 (set_attr "length_immediate" "0,*")
2051 (set_attr "memory" "store")
2052 (set_attr "mode" "DI")])
2054 (define_insn "*movabsdi_2_rex64"
2055 [(set (match_operand:DI 0 "register_operand" "=a,r")
2056 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2057 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2059 movabs{q}\t{%P1, %0|%0, %P1}
2060 mov{q}\t{%a1, %0|%0, %a1}"
2061 [(set_attr "type" "imov")
2062 (set_attr "modrm" "0,*")
2063 (set_attr "length_address" "8,0")
2064 (set_attr "length_immediate" "0")
2065 (set_attr "memory" "load")
2066 (set_attr "mode" "DI")])
2068 ;; Convert impossible stores of immediate to existing instructions.
2069 ;; First try to get scratch register and go through it. In case this
2070 ;; fails, move by 32bit parts.
2072 [(match_scratch:DI 2 "r")
2073 (set (match_operand:DI 0 "memory_operand" "")
2074 (match_operand:DI 1 "immediate_operand" ""))]
2075 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode)"
2077 [(set (match_dup 2) (match_dup 1))
2078 (set (match_dup 0) (match_dup 2))]
2081 ;; We need to define this as both peepholer and splitter for case
2082 ;; peephole2 pass is not run.
2083 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 [(set (match_operand:DI 0 "memory_operand" "")
2086 (match_operand:DI 1 "immediate_operand" ""))]
2087 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2088 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2089 [(set (match_dup 2) (match_dup 3))
2090 (set (match_dup 4) (match_dup 5))]
2091 "split_di (operands, 2, operands + 2, operands + 4);")
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? flow2_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 2) (match_dup 3))
2101 (set (match_dup 4) (match_dup 5))]
2102 "split_di (operands, 2, operands + 2, operands + 4);")
2104 (define_insn "*swapdi_rex64"
2105 [(set (match_operand:DI 0 "register_operand" "+r")
2106 (match_operand:DI 1 "register_operand" "+r"))
2111 [(set_attr "type" "imov")
2112 (set_attr "mode" "DI")
2113 (set_attr "pent_pair" "np")
2114 (set_attr "athlon_decode" "vector")])
2116 (define_expand "movti"
2117 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2118 (match_operand:TI 1 "nonimmediate_operand" ""))]
2119 "TARGET_SSE || TARGET_64BIT"
2122 ix86_expand_move (TImode, operands);
2124 ix86_expand_vector_move (TImode, operands);
2128 (define_insn "*movti_internal"
2129 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2130 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2131 "TARGET_SSE && !TARGET_64BIT
2132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2134 switch (which_alternative)
2137 if (get_attr_mode (insn) == MODE_V4SF)
2138 return "xorps\t%0, %0";
2140 return "pxor\t%0, %0";
2143 if (get_attr_mode (insn) == MODE_V4SF)
2144 return "movaps\t{%1, %0|%0, %1}";
2146 return "movdqa\t{%1, %0|%0, %1}";
2151 [(set_attr "type" "ssemov,ssemov,ssemov")
2153 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2154 (const_string "V4SF")
2156 (eq_attr "alternative" "0,1")
2158 (ne (symbol_ref "optimize_size")
2160 (const_string "V4SF")
2161 (const_string "TI"))
2162 (eq_attr "alternative" "2")
2164 (ne (symbol_ref "optimize_size")
2166 (const_string "V4SF")
2167 (const_string "TI"))]
2168 (const_string "TI")))])
2170 (define_insn "*movti_rex64"
2171 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2172 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2174 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2176 switch (which_alternative)
2182 if (get_attr_mode (insn) == MODE_V4SF)
2183 return "xorps\t%0, %0";
2185 return "pxor\t%0, %0";
2188 if (get_attr_mode (insn) == MODE_V4SF)
2189 return "movaps\t{%1, %0|%0, %1}";
2191 return "movdqa\t{%1, %0|%0, %1}";
2196 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2198 (cond [(eq_attr "alternative" "2,3")
2200 (ne (symbol_ref "optimize_size")
2202 (const_string "V4SF")
2203 (const_string "TI"))
2204 (eq_attr "alternative" "4")
2206 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2208 (ne (symbol_ref "optimize_size")
2210 (const_string "V4SF")
2211 (const_string "TI"))]
2212 (const_string "DI")))])
2215 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2216 (match_operand:TI 1 "general_operand" ""))]
2217 "reload_completed && !SSE_REG_P (operands[0])
2218 && !SSE_REG_P (operands[1])"
2220 "ix86_split_long_move (operands); DONE;")
2222 (define_expand "movsf"
2223 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2224 (match_operand:SF 1 "general_operand" ""))]
2226 "ix86_expand_move (SFmode, operands); DONE;")
2228 (define_insn "*pushsf"
2229 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2230 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2233 /* Anything else should be already split before reg-stack. */
2234 gcc_assert (which_alternative == 1);
2235 return "push{l}\t%1";
2237 [(set_attr "type" "multi,push,multi")
2238 (set_attr "unit" "i387,*,*")
2239 (set_attr "mode" "SF,SI,SF")])
2241 (define_insn "*pushsf_rex64"
2242 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2243 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2246 /* Anything else should be already split before reg-stack. */
2247 gcc_assert (which_alternative == 1);
2248 return "push{q}\t%q1";
2250 [(set_attr "type" "multi,push,multi")
2251 (set_attr "unit" "i387,*,*")
2252 (set_attr "mode" "SF,DI,SF")])
2255 [(set (match_operand:SF 0 "push_operand" "")
2256 (match_operand:SF 1 "memory_operand" ""))]
2258 && GET_CODE (operands[1]) == MEM
2259 && constant_pool_reference_p (operands[1])"
2262 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2265 ;; %%% Kill this when call knows how to work this out.
2267 [(set (match_operand:SF 0 "push_operand" "")
2268 (match_operand:SF 1 "any_fp_register_operand" ""))]
2270 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2271 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2274 [(set (match_operand:SF 0 "push_operand" "")
2275 (match_operand:SF 1 "any_fp_register_operand" ""))]
2277 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2278 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2280 (define_insn "*movsf_1"
2281 [(set (match_operand:SF 0 "nonimmediate_operand"
2282 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2283 (match_operand:SF 1 "general_operand"
2284 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2285 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2286 && (reload_in_progress || reload_completed
2287 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288 || GET_CODE (operands[1]) != CONST_DOUBLE
2289 || memory_operand (operands[0], SFmode))"
2291 switch (which_alternative)
2294 return output_387_reg_move (insn, operands);
2297 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298 return "fstp%z0\t%y0";
2300 return "fst%z0\t%y0";
2303 return standard_80387_constant_opcode (operands[1]);
2307 return "mov{l}\t{%1, %0|%0, %1}";
2309 if (get_attr_mode (insn) == MODE_TI)
2310 return "pxor\t%0, %0";
2312 return "xorps\t%0, %0";
2314 if (get_attr_mode (insn) == MODE_V4SF)
2315 return "movaps\t{%1, %0|%0, %1}";
2317 return "movss\t{%1, %0|%0, %1}";
2320 return "movss\t{%1, %0|%0, %1}";
2324 return "movd\t{%1, %0|%0, %1}";
2327 return "movq\t{%1, %0|%0, %1}";
2333 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2335 (cond [(eq_attr "alternative" "3,4,9,10")
2337 (eq_attr "alternative" "5")
2339 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2341 (ne (symbol_ref "TARGET_SSE2")
2343 (eq (symbol_ref "optimize_size")
2346 (const_string "V4SF"))
2347 /* For architectures resolving dependencies on
2348 whole SSE registers use APS move to break dependency
2349 chains, otherwise use short move to avoid extra work.
2351 Do the same for architectures resolving dependencies on
2352 the parts. While in DF mode it is better to always handle
2353 just register parts, the SF mode is different due to lack
2354 of instructions to load just part of the register. It is
2355 better to maintain the whole registers in single format
2356 to avoid problems on using packed logical operations. */
2357 (eq_attr "alternative" "6")
2359 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2361 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2363 (const_string "V4SF")
2364 (const_string "SF"))
2365 (eq_attr "alternative" "11")
2366 (const_string "DI")]
2367 (const_string "SF")))])
2369 (define_insn "*swapsf"
2370 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2371 (match_operand:SF 1 "fp_register_operand" "+f"))
2374 "reload_completed || TARGET_80387"
2376 if (STACK_TOP_P (operands[0]))
2381 [(set_attr "type" "fxch")
2382 (set_attr "mode" "SF")])
2384 (define_expand "movdf"
2385 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386 (match_operand:DF 1 "general_operand" ""))]
2388 "ix86_expand_move (DFmode, operands); DONE;")
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter. Allow this
2393 ;; pattern for optimize_size too.
2395 (define_insn "*pushdf_nointeger"
2396 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2400 /* This insn should be already split before reg-stack. */
2403 [(set_attr "type" "multi")
2404 (set_attr "unit" "i387,*,*,*")
2405 (set_attr "mode" "DF,SI,SI,DF")])
2407 (define_insn "*pushdf_integer"
2408 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2409 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2410 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2412 /* This insn should be already split before reg-stack. */
2415 [(set_attr "type" "multi")
2416 (set_attr "unit" "i387,*,*")
2417 (set_attr "mode" "DF,SI,DF")])
2419 ;; %%% Kill this when call knows how to work this out.
2421 [(set (match_operand:DF 0 "push_operand" "")
2422 (match_operand:DF 1 "any_fp_register_operand" ""))]
2423 "!TARGET_64BIT && reload_completed"
2424 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2425 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2429 [(set (match_operand:DF 0 "push_operand" "")
2430 (match_operand:DF 1 "any_fp_register_operand" ""))]
2431 "TARGET_64BIT && reload_completed"
2432 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2433 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2437 [(set (match_operand:DF 0 "push_operand" "")
2438 (match_operand:DF 1 "general_operand" ""))]
2441 "ix86_split_long_move (operands); DONE;")
2443 ;; Moving is usually shorter when only FP registers are used. This separate
2444 ;; movdf pattern avoids the use of integer registers for FP operations
2445 ;; when optimizing for size.
2447 (define_insn "*movdf_nointeger"
2448 [(set (match_operand:DF 0 "nonimmediate_operand"
2449 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2450 (match_operand:DF 1 "general_operand"
2451 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2452 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2453 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2454 && (reload_in_progress || reload_completed
2455 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2456 || GET_CODE (operands[1]) != CONST_DOUBLE
2457 || memory_operand (operands[0], DFmode))"
2459 switch (which_alternative)
2462 return output_387_reg_move (insn, operands);
2465 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2466 return "fstp%z0\t%y0";
2468 return "fst%z0\t%y0";
2471 return standard_80387_constant_opcode (operands[1]);
2477 switch (get_attr_mode (insn))
2480 return "xorps\t%0, %0";
2482 return "xorpd\t%0, %0";
2484 return "pxor\t%0, %0";
2491 switch (get_attr_mode (insn))
2494 return "movaps\t{%1, %0|%0, %1}";
2496 return "movapd\t{%1, %0|%0, %1}";
2498 return "movdqa\t{%1, %0|%0, %1}";
2500 return "movq\t{%1, %0|%0, %1}";
2502 return "movsd\t{%1, %0|%0, %1}";
2504 return "movlpd\t{%1, %0|%0, %1}";
2506 return "movlps\t{%1, %0|%0, %1}";
2515 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2517 (cond [(eq_attr "alternative" "0,1,2")
2519 (eq_attr "alternative" "3,4")
2522 /* For SSE1, we have many fewer alternatives. */
2523 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2524 (cond [(eq_attr "alternative" "5,6")
2525 (const_string "V4SF")
2527 (const_string "V2SF"))
2529 /* xorps is one byte shorter. */
2530 (eq_attr "alternative" "5")
2531 (cond [(ne (symbol_ref "optimize_size")
2533 (const_string "V4SF")
2534 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2538 (const_string "V2DF"))
2540 /* For architectures resolving dependencies on
2541 whole SSE registers use APD move to break dependency
2542 chains, otherwise use short move to avoid extra work.
2544 movaps encodes one byte shorter. */
2545 (eq_attr "alternative" "6")
2547 [(ne (symbol_ref "optimize_size")
2549 (const_string "V4SF")
2550 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2552 (const_string "V2DF")
2554 (const_string "DF"))
2555 /* For architectures resolving dependencies on register
2556 parts we may avoid extra work to zero out upper part
2558 (eq_attr "alternative" "7")
2560 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2562 (const_string "V1DF")
2563 (const_string "DF"))
2565 (const_string "DF")))])
2567 (define_insn "*movdf_integer"
2568 [(set (match_operand:DF 0 "nonimmediate_operand"
2569 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2570 (match_operand:DF 1 "general_operand"
2571 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2572 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574 && (reload_in_progress || reload_completed
2575 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576 || GET_CODE (operands[1]) != CONST_DOUBLE
2577 || memory_operand (operands[0], DFmode))"
2579 switch (which_alternative)
2582 return output_387_reg_move (insn, operands);
2585 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2586 return "fstp%z0\t%y0";
2588 return "fst%z0\t%y0";
2591 return standard_80387_constant_opcode (operands[1]);
2598 switch (get_attr_mode (insn))
2601 return "xorps\t%0, %0";
2603 return "xorpd\t%0, %0";
2605 return "pxor\t%0, %0";
2612 switch (get_attr_mode (insn))
2615 return "movaps\t{%1, %0|%0, %1}";
2617 return "movapd\t{%1, %0|%0, %1}";
2619 return "movdqa\t{%1, %0|%0, %1}";
2621 return "movq\t{%1, %0|%0, %1}";
2623 return "movsd\t{%1, %0|%0, %1}";
2625 return "movlpd\t{%1, %0|%0, %1}";
2627 return "movlps\t{%1, %0|%0, %1}";
2636 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2638 (cond [(eq_attr "alternative" "0,1,2")
2640 (eq_attr "alternative" "3,4")
2643 /* For SSE1, we have many fewer alternatives. */
2644 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2645 (cond [(eq_attr "alternative" "5,6")
2646 (const_string "V4SF")
2648 (const_string "V2SF"))
2650 /* xorps is one byte shorter. */
2651 (eq_attr "alternative" "5")
2652 (cond [(ne (symbol_ref "optimize_size")
2654 (const_string "V4SF")
2655 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2659 (const_string "V2DF"))
2661 /* For architectures resolving dependencies on
2662 whole SSE registers use APD move to break dependency
2663 chains, otherwise use short move to avoid extra work.
2665 movaps encodes one byte shorter. */
2666 (eq_attr "alternative" "6")
2668 [(ne (symbol_ref "optimize_size")
2670 (const_string "V4SF")
2671 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2673 (const_string "V2DF")
2675 (const_string "DF"))
2676 /* For architectures resolving dependencies on register
2677 parts we may avoid extra work to zero out upper part
2679 (eq_attr "alternative" "7")
2681 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2683 (const_string "V1DF")
2684 (const_string "DF"))
2686 (const_string "DF")))])
2689 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690 (match_operand:DF 1 "general_operand" ""))]
2692 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2693 && ! (ANY_FP_REG_P (operands[0]) ||
2694 (GET_CODE (operands[0]) == SUBREG
2695 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2696 && ! (ANY_FP_REG_P (operands[1]) ||
2697 (GET_CODE (operands[1]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2700 "ix86_split_long_move (operands); DONE;")
2702 (define_insn "*swapdf"
2703 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2704 (match_operand:DF 1 "fp_register_operand" "+f"))
2707 "reload_completed || TARGET_80387"
2709 if (STACK_TOP_P (operands[0]))
2714 [(set_attr "type" "fxch")
2715 (set_attr "mode" "DF")])
2717 (define_expand "movxf"
2718 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2719 (match_operand:XF 1 "general_operand" ""))]
2721 "ix86_expand_move (XFmode, operands); DONE;")
2723 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2724 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2725 ;; Pushing using integer instructions is longer except for constants
2726 ;; and direct memory references.
2727 ;; (assuming that any given constant is pushed only once, but this ought to be
2728 ;; handled elsewhere).
2730 (define_insn "*pushxf_nointeger"
2731 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2735 /* This insn should be already split before reg-stack. */
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*,*")
2740 (set_attr "mode" "XF,SI,SI")])
2742 (define_insn "*pushxf_integer"
2743 [(set (match_operand:XF 0 "push_operand" "=<,<")
2744 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2747 /* This insn should be already split before reg-stack. */
2750 [(set_attr "type" "multi")
2751 (set_attr "unit" "i387,*")
2752 (set_attr "mode" "XF,SI")])
2755 [(set (match_operand 0 "push_operand" "")
2756 (match_operand 1 "general_operand" ""))]
2758 && (GET_MODE (operands[0]) == XFmode
2759 || GET_MODE (operands[0]) == DFmode)
2760 && !ANY_FP_REG_P (operands[1])"
2762 "ix86_split_long_move (operands); DONE;")
2765 [(set (match_operand:XF 0 "push_operand" "")
2766 (match_operand:XF 1 "any_fp_register_operand" ""))]
2768 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2769 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2770 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773 [(set (match_operand:XF 0 "push_operand" "")
2774 (match_operand:XF 1 "any_fp_register_operand" ""))]
2776 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2777 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2778 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780 ;; Do not use integer registers when optimizing for size
2781 (define_insn "*movxf_nointeger"
2782 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2783 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2786 && (reload_in_progress || reload_completed
2787 || GET_CODE (operands[1]) != CONST_DOUBLE
2788 || memory_operand (operands[0], XFmode))"
2790 switch (which_alternative)
2793 return output_387_reg_move (insn, operands);
2796 /* There is no non-popping store to memory for XFmode. So if
2797 we need one, follow the store with a load. */
2798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799 return "fstp%z0\t%y0\;fld%z0\t%y0";
2801 return "fstp%z0\t%y0";
2804 return standard_80387_constant_opcode (operands[1]);
2812 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813 (set_attr "mode" "XF,XF,XF,SI,SI")])
2815 (define_insn "*movxf_integer"
2816 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2817 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820 && (reload_in_progress || reload_completed
2821 || GET_CODE (operands[1]) != CONST_DOUBLE
2822 || memory_operand (operands[0], XFmode))"
2824 switch (which_alternative)
2827 return output_387_reg_move (insn, operands);
2830 /* There is no non-popping store to memory for XFmode. So if
2831 we need one, follow the store with a load. */
2832 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2833 return "fstp%z0\t%y0\;fld%z0\t%y0";
2835 return "fstp%z0\t%y0";
2838 return standard_80387_constant_opcode (operands[1]);
2847 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2848 (set_attr "mode" "XF,XF,XF,SI,SI")])
2851 [(set (match_operand 0 "nonimmediate_operand" "")
2852 (match_operand 1 "general_operand" ""))]
2854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2855 && GET_MODE (operands[0]) == XFmode
2856 && ! (ANY_FP_REG_P (operands[0]) ||
2857 (GET_CODE (operands[0]) == SUBREG
2858 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2859 && ! (ANY_FP_REG_P (operands[1]) ||
2860 (GET_CODE (operands[1]) == SUBREG
2861 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2863 "ix86_split_long_move (operands); DONE;")
2866 [(set (match_operand 0 "register_operand" "")
2867 (match_operand 1 "memory_operand" ""))]
2869 && GET_CODE (operands[1]) == MEM
2870 && (GET_MODE (operands[0]) == XFmode
2871 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2872 && constant_pool_reference_p (operands[1])"
2873 [(set (match_dup 0) (match_dup 1))]
2875 rtx c = avoid_constant_pool_reference (operands[1]);
2876 rtx r = operands[0];
2878 if (GET_CODE (r) == SUBREG)
2883 if (!standard_sse_constant_p (c))
2886 else if (FP_REG_P (r))
2888 if (!standard_80387_constant_p (c))
2891 else if (MMX_REG_P (r))
2897 (define_insn "swapxf"
2898 [(set (match_operand:XF 0 "register_operand" "+f")
2899 (match_operand:XF 1 "register_operand" "+f"))
2904 if (STACK_TOP_P (operands[0]))
2909 [(set_attr "type" "fxch")
2910 (set_attr "mode" "XF")])
2912 (define_expand "movtf"
2913 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2914 (match_operand:TF 1 "nonimmediate_operand" ""))]
2917 ix86_expand_move (TFmode, operands);
2921 (define_insn "*movtf_internal"
2922 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2923 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2925 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2927 switch (which_alternative)
2933 if (get_attr_mode (insn) == MODE_V4SF)
2934 return "xorps\t%0, %0";
2936 return "pxor\t%0, %0";
2939 if (get_attr_mode (insn) == MODE_V4SF)
2940 return "movaps\t{%1, %0|%0, %1}";
2942 return "movdqa\t{%1, %0|%0, %1}";
2947 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2949 (cond [(eq_attr "alternative" "2,3")
2951 (ne (symbol_ref "optimize_size")
2953 (const_string "V4SF")
2954 (const_string "TI"))
2955 (eq_attr "alternative" "4")
2957 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2959 (ne (symbol_ref "optimize_size")
2961 (const_string "V4SF")
2962 (const_string "TI"))]
2963 (const_string "DI")))])
2966 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2967 (match_operand:TF 1 "general_operand" ""))]
2968 "reload_completed && !SSE_REG_P (operands[0])
2969 && !SSE_REG_P (operands[1])"
2971 "ix86_split_long_move (operands); DONE;")
2973 ;; Zero extension instructions
2975 (define_expand "zero_extendhisi2"
2976 [(set (match_operand:SI 0 "register_operand" "")
2977 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2980 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2982 operands[1] = force_reg (HImode, operands[1]);
2983 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2988 (define_insn "zero_extendhisi2_and"
2989 [(set (match_operand:SI 0 "register_operand" "=r")
2990 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2991 (clobber (reg:CC FLAGS_REG))]
2992 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994 [(set_attr "type" "alu1")
2995 (set_attr "mode" "SI")])
2998 [(set (match_operand:SI 0 "register_operand" "")
2999 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3000 (clobber (reg:CC FLAGS_REG))]
3001 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3002 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3003 (clobber (reg:CC FLAGS_REG))])]
3006 (define_insn "*zero_extendhisi2_movzwl"
3007 [(set (match_operand:SI 0 "register_operand" "=r")
3008 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3009 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3010 "movz{wl|x}\t{%1, %0|%0, %1}"
3011 [(set_attr "type" "imovx")
3012 (set_attr "mode" "SI")])
3014 (define_expand "zero_extendqihi2"
3016 [(set (match_operand:HI 0 "register_operand" "")
3017 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018 (clobber (reg:CC FLAGS_REG))])]
3022 (define_insn "*zero_extendqihi2_and"
3023 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3024 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3025 (clobber (reg:CC FLAGS_REG))]
3026 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028 [(set_attr "type" "alu1")
3029 (set_attr "mode" "HI")])
3031 (define_insn "*zero_extendqihi2_movzbw_and"
3032 [(set (match_operand:HI 0 "register_operand" "=r,r")
3033 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3034 (clobber (reg:CC FLAGS_REG))]
3035 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037 [(set_attr "type" "imovx,alu1")
3038 (set_attr "mode" "HI")])
3040 ; zero extend to SImode here to avoid partial register stalls
3041 (define_insn "*zero_extendqihi2_movzbl"
3042 [(set (match_operand:HI 0 "register_operand" "=r")
3043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3044 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3045 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3046 [(set_attr "type" "imovx")
3047 (set_attr "mode" "SI")])
3049 ;; For the movzbw case strip only the clobber
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053 (clobber (reg:CC FLAGS_REG))]
3055 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3056 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3060 ;; When source and destination does not overlap, clear destination
3061 ;; first and then do the movb
3063 [(set (match_operand:HI 0 "register_operand" "")
3064 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3065 (clobber (reg:CC FLAGS_REG))]
3067 && ANY_QI_REG_P (operands[0])
3068 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3069 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3070 [(set (match_dup 0) (const_int 0))
3071 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072 "operands[2] = gen_lowpart (QImode, operands[0]);")
3074 ;; Rest is handled by single and.
3076 [(set (match_operand:HI 0 "register_operand" "")
3077 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3078 (clobber (reg:CC FLAGS_REG))]
3080 && true_regnum (operands[0]) == true_regnum (operands[1])"
3081 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3082 (clobber (reg:CC FLAGS_REG))])]
3085 (define_expand "zero_extendqisi2"
3087 [(set (match_operand:SI 0 "register_operand" "")
3088 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3089 (clobber (reg:CC FLAGS_REG))])]
3093 (define_insn "*zero_extendqisi2_and"
3094 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3095 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3096 (clobber (reg:CC FLAGS_REG))]
3097 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3099 [(set_attr "type" "alu1")
3100 (set_attr "mode" "SI")])
3102 (define_insn "*zero_extendqisi2_movzbw_and"
3103 [(set (match_operand:SI 0 "register_operand" "=r,r")
3104 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3105 (clobber (reg:CC FLAGS_REG))]
3106 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3108 [(set_attr "type" "imovx,alu1")
3109 (set_attr "mode" "SI")])
3111 (define_insn "*zero_extendqisi2_movzbw"
3112 [(set (match_operand:SI 0 "register_operand" "=r")
3113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3114 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3115 "movz{bl|x}\t{%1, %0|%0, %1}"
3116 [(set_attr "type" "imovx")
3117 (set_attr "mode" "SI")])
3119 ;; For the movzbl case strip only the clobber
3121 [(set (match_operand:SI 0 "register_operand" "")
3122 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123 (clobber (reg:CC FLAGS_REG))]
3125 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3126 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3128 (zero_extend:SI (match_dup 1)))])
3130 ;; When source and destination does not overlap, clear destination
3131 ;; first and then do the movb
3133 [(set (match_operand:SI 0 "register_operand" "")
3134 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3135 (clobber (reg:CC FLAGS_REG))]
3137 && ANY_QI_REG_P (operands[0])
3138 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3139 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3140 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3141 [(set (match_dup 0) (const_int 0))
3142 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3143 "operands[2] = gen_lowpart (QImode, operands[0]);")
3145 ;; Rest is handled by single and.
3147 [(set (match_operand:SI 0 "register_operand" "")
3148 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3149 (clobber (reg:CC FLAGS_REG))]
3151 && true_regnum (operands[0]) == true_regnum (operands[1])"
3152 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3153 (clobber (reg:CC FLAGS_REG))])]
3156 ;; %%% Kill me once multi-word ops are sane.
3157 (define_expand "zero_extendsidi2"
3158 [(set (match_operand:DI 0 "register_operand" "=r")
3159 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3163 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3168 (define_insn "zero_extendsidi2_32"
3169 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3170 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3171 (clobber (reg:CC FLAGS_REG))]
3177 movd\t{%1, %0|%0, %1}
3178 movd\t{%1, %0|%0, %1}"
3179 [(set_attr "mode" "SI,SI,SI,DI,TI")
3180 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3182 (define_insn "zero_extendsidi2_rex64"
3183 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3184 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3187 mov\t{%k1, %k0|%k0, %k1}
3189 movd\t{%1, %0|%0, %1}
3190 movd\t{%1, %0|%0, %1}"
3191 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3192 (set_attr "mode" "SI,DI,SI,SI")])
3195 [(set (match_operand:DI 0 "memory_operand" "")
3196 (zero_extend:DI (match_dup 0)))]
3198 [(set (match_dup 4) (const_int 0))]
3199 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3202 [(set (match_operand:DI 0 "register_operand" "")
3203 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3204 (clobber (reg:CC FLAGS_REG))]
3205 "!TARGET_64BIT && reload_completed
3206 && true_regnum (operands[0]) == true_regnum (operands[1])"
3207 [(set (match_dup 4) (const_int 0))]
3208 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3211 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3212 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3213 (clobber (reg:CC FLAGS_REG))]
3214 "!TARGET_64BIT && reload_completed
3215 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3216 [(set (match_dup 3) (match_dup 1))
3217 (set (match_dup 4) (const_int 0))]
3218 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3220 (define_insn "zero_extendhidi2"
3221 [(set (match_operand:DI 0 "register_operand" "=r")
3222 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3224 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3225 [(set_attr "type" "imovx")
3226 (set_attr "mode" "DI")])
3228 (define_insn "zero_extendqidi2"
3229 [(set (match_operand:DI 0 "register_operand" "=r")
3230 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3232 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3233 [(set_attr "type" "imovx")
3234 (set_attr "mode" "DI")])
3236 ;; Sign extension instructions
3238 (define_expand "extendsidi2"
3239 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3240 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3241 (clobber (reg:CC FLAGS_REG))
3242 (clobber (match_scratch:SI 2 ""))])]
3247 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3252 (define_insn "*extendsidi2_1"
3253 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3254 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3255 (clobber (reg:CC FLAGS_REG))
3256 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3260 (define_insn "extendsidi2_rex64"
3261 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3262 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3266 movs{lq|x}\t{%1,%0|%0, %1}"
3267 [(set_attr "type" "imovx")
3268 (set_attr "mode" "DI")
3269 (set_attr "prefix_0f" "0")
3270 (set_attr "modrm" "0,1")])
3272 (define_insn "extendhidi2"
3273 [(set (match_operand:DI 0 "register_operand" "=r")
3274 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3276 "movs{wq|x}\t{%1,%0|%0, %1}"
3277 [(set_attr "type" "imovx")
3278 (set_attr "mode" "DI")])
3280 (define_insn "extendqidi2"
3281 [(set (match_operand:DI 0 "register_operand" "=r")
3282 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3284 "movs{bq|x}\t{%1,%0|%0, %1}"
3285 [(set_attr "type" "imovx")
3286 (set_attr "mode" "DI")])
3288 ;; Extend to memory case when source register does die.
3290 [(set (match_operand:DI 0 "memory_operand" "")
3291 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3292 (clobber (reg:CC FLAGS_REG))
3293 (clobber (match_operand:SI 2 "register_operand" ""))]
3295 && dead_or_set_p (insn, operands[1])
3296 && !reg_mentioned_p (operands[1], operands[0]))"
3297 [(set (match_dup 3) (match_dup 1))
3298 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3299 (clobber (reg:CC FLAGS_REG))])
3300 (set (match_dup 4) (match_dup 1))]
3301 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3303 ;; Extend to memory case when source register does not die.
3305 [(set (match_operand:DI 0 "memory_operand" "")
3306 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3307 (clobber (reg:CC FLAGS_REG))
3308 (clobber (match_operand:SI 2 "register_operand" ""))]
3312 split_di (&operands[0], 1, &operands[3], &operands[4]);
3314 emit_move_insn (operands[3], operands[1]);
3316 /* Generate a cltd if possible and doing so it profitable. */
3317 if (true_regnum (operands[1]) == 0
3318 && true_regnum (operands[2]) == 1
3319 && (optimize_size || TARGET_USE_CLTD))
3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3325 emit_move_insn (operands[2], operands[1]);
3326 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3328 emit_move_insn (operands[4], operands[2]);
3332 ;; Extend to register case. Optimize case where source and destination
3333 ;; registers match and cases where we can use cltd.
3335 [(set (match_operand:DI 0 "register_operand" "")
3336 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3337 (clobber (reg:CC FLAGS_REG))
3338 (clobber (match_scratch:SI 2 ""))]
3342 split_di (&operands[0], 1, &operands[3], &operands[4]);
3344 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3345 emit_move_insn (operands[3], operands[1]);
3347 /* Generate a cltd if possible and doing so it profitable. */
3348 if (true_regnum (operands[3]) == 0
3349 && (optimize_size || TARGET_USE_CLTD))
3351 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3355 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3356 emit_move_insn (operands[4], operands[1]);
3358 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3362 (define_insn "extendhisi2"
3363 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3364 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3367 switch (get_attr_prefix_0f (insn))
3370 return "{cwtl|cwde}";
3372 return "movs{wl|x}\t{%1,%0|%0, %1}";
3375 [(set_attr "type" "imovx")
3376 (set_attr "mode" "SI")
3377 (set (attr "prefix_0f")
3378 ;; movsx is short decodable while cwtl is vector decoded.
3379 (if_then_else (and (eq_attr "cpu" "!k6")
3380 (eq_attr "alternative" "0"))
3382 (const_string "1")))
3384 (if_then_else (eq_attr "prefix_0f" "0")
3386 (const_string "1")))])
3388 (define_insn "*extendhisi2_zext"
3389 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3391 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3394 switch (get_attr_prefix_0f (insn))
3397 return "{cwtl|cwde}";
3399 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3402 [(set_attr "type" "imovx")
3403 (set_attr "mode" "SI")
3404 (set (attr "prefix_0f")
3405 ;; movsx is short decodable while cwtl is vector decoded.
3406 (if_then_else (and (eq_attr "cpu" "!k6")
3407 (eq_attr "alternative" "0"))
3409 (const_string "1")))
3411 (if_then_else (eq_attr "prefix_0f" "0")
3413 (const_string "1")))])
3415 (define_insn "extendqihi2"
3416 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3417 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3420 switch (get_attr_prefix_0f (insn))
3423 return "{cbtw|cbw}";
3425 return "movs{bw|x}\t{%1,%0|%0, %1}";
3428 [(set_attr "type" "imovx")
3429 (set_attr "mode" "HI")
3430 (set (attr "prefix_0f")
3431 ;; movsx is short decodable while cwtl is vector decoded.
3432 (if_then_else (and (eq_attr "cpu" "!k6")
3433 (eq_attr "alternative" "0"))
3435 (const_string "1")))
3437 (if_then_else (eq_attr "prefix_0f" "0")
3439 (const_string "1")))])
3441 (define_insn "extendqisi2"
3442 [(set (match_operand:SI 0 "register_operand" "=r")
3443 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445 "movs{bl|x}\t{%1,%0|%0, %1}"
3446 [(set_attr "type" "imovx")
3447 (set_attr "mode" "SI")])
3449 (define_insn "*extendqisi2_zext"
3450 [(set (match_operand:DI 0 "register_operand" "=r")
3452 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3454 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3455 [(set_attr "type" "imovx")
3456 (set_attr "mode" "SI")])
3458 ;; Conversions between float and double.
3460 ;; These are all no-ops in the model used for the 80387. So just
3463 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3464 (define_insn "*dummy_extendsfdf2"
3465 [(set (match_operand:DF 0 "push_operand" "=<")
3466 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3471 [(set (match_operand:DF 0 "push_operand" "")
3472 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3475 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3478 [(set (match_operand:DF 0 "push_operand" "")
3479 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3481 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3482 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3484 (define_insn "*dummy_extendsfxf2"
3485 [(set (match_operand:XF 0 "push_operand" "=<")
3486 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3491 [(set (match_operand:XF 0 "push_operand" "")
3492 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3494 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3495 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3496 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499 [(set (match_operand:XF 0 "push_operand" "")
3500 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3502 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3503 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3504 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507 [(set (match_operand:XF 0 "push_operand" "")
3508 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3510 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3511 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3512 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515 [(set (match_operand:XF 0 "push_operand" "")
3516 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3518 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3519 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3520 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522 (define_expand "extendsfdf2"
3523 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3524 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3525 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3527 /* ??? Needed for compress_float_constant since all fp constants
3528 are LEGITIMATE_CONSTANT_P. */
3529 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3530 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3531 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3532 operands[1] = force_reg (SFmode, operands[1]);
3535 (define_insn "*extendsfdf2_mixed"
3536 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3537 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3538 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3539 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3541 switch (which_alternative)
3544 return output_387_reg_move (insn, operands);
3547 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3548 return "fstp%z0\t%y0";
3550 return "fst%z0\t%y0";
3553 return "cvtss2sd\t{%1, %0|%0, %1}";
3559 [(set_attr "type" "fmov,fmov,ssecvt")
3560 (set_attr "mode" "SF,XF,DF")])
3562 (define_insn "*extendsfdf2_sse"
3563 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3564 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3565 "TARGET_SSE2 && TARGET_SSE_MATH
3566 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567 "cvtss2sd\t{%1, %0|%0, %1}"
3568 [(set_attr "type" "ssecvt")
3569 (set_attr "mode" "DF")])
3571 (define_insn "*extendsfdf2_i387"
3572 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3573 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3575 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3577 switch (which_alternative)
3580 return output_387_reg_move (insn, operands);
3583 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584 return "fstp%z0\t%y0";
3586 return "fst%z0\t%y0";
3592 [(set_attr "type" "fmov")
3593 (set_attr "mode" "SF,XF")])
3595 (define_expand "extendsfxf2"
3596 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3597 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3600 /* ??? Needed for compress_float_constant since all fp constants
3601 are LEGITIMATE_CONSTANT_P. */
3602 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3603 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3604 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3605 operands[1] = force_reg (SFmode, operands[1]);
3608 (define_insn "*extendsfxf2_i387"
3609 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3610 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3612 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3614 switch (which_alternative)
3617 return output_387_reg_move (insn, operands);
3620 /* There is no non-popping store to memory for XFmode. So if
3621 we need one, follow the store with a load. */
3622 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3623 return "fstp%z0\t%y0";
3625 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3631 [(set_attr "type" "fmov")
3632 (set_attr "mode" "SF,XF")])
3634 (define_expand "extenddfxf2"
3635 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3636 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3639 /* ??? Needed for compress_float_constant since all fp constants
3640 are LEGITIMATE_CONSTANT_P. */
3641 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3642 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3643 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3644 operands[1] = force_reg (DFmode, operands[1]);
3647 (define_insn "*extenddfxf2_i387"
3648 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3649 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3651 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3653 switch (which_alternative)
3656 return output_387_reg_move (insn, operands);
3659 /* There is no non-popping store to memory for XFmode. So if
3660 we need one, follow the store with a load. */
3661 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3662 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3664 return "fstp%z0\t%y0";
3670 [(set_attr "type" "fmov")
3671 (set_attr "mode" "DF,XF")])
3673 ;; %%% This seems bad bad news.
3674 ;; This cannot output into an f-reg because there is no way to be sure
3675 ;; of truncating in that case. Otherwise this is just like a simple move
3676 ;; insn. So we pretend we can output to a reg in order to get better
3677 ;; register preferencing, but we really use a stack slot.
3679 ;; Conversion from DFmode to SFmode.
3681 (define_expand "truncdfsf2"
3682 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3684 (match_operand:DF 1 "nonimmediate_operand" "")))]
3685 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3687 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3688 operands[1] = force_reg (DFmode, operands[1]);
3690 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3692 else if (flag_unsafe_math_optimizations)
3696 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3697 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3702 (define_expand "truncdfsf2_with_temp"
3703 [(parallel [(set (match_operand:SF 0 "" "")
3704 (float_truncate:SF (match_operand:DF 1 "" "")))
3705 (clobber (match_operand:SF 2 "" ""))])]
3708 (define_insn "*truncdfsf_fast_mixed"
3709 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3711 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3712 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3714 switch (which_alternative)
3717 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3718 return "fstp%z0\t%y0";
3720 return "fst%z0\t%y0";
3722 return output_387_reg_move (insn, operands);
3724 return "cvtsd2ss\t{%1, %0|%0, %1}";
3729 [(set_attr "type" "fmov,fmov,ssecvt")
3730 (set_attr "mode" "SF")])
3732 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3733 ;; because nothing we do here is unsafe.
3734 (define_insn "*truncdfsf_fast_sse"
3735 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3737 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3738 "TARGET_SSE2 && TARGET_SSE_MATH"
3739 "cvtsd2ss\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "ssecvt")
3741 (set_attr "mode" "SF")])
3743 (define_insn "*truncdfsf_fast_i387"
3744 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3746 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3747 "TARGET_80387 && flag_unsafe_math_optimizations"
3748 "* return output_387_reg_move (insn, operands);"
3749 [(set_attr "type" "fmov")
3750 (set_attr "mode" "SF")])
3752 (define_insn "*truncdfsf_mixed"
3753 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3755 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3756 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3757 "TARGET_MIX_SSE_I387"
3759 switch (which_alternative)
3762 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3763 return "fstp%z0\t%y0";
3765 return "fst%z0\t%y0";
3769 return "cvtsd2ss\t{%1, %0|%0, %1}";
3774 [(set_attr "type" "fmov,multi,ssecvt")
3775 (set_attr "unit" "*,i387,*")
3776 (set_attr "mode" "SF")])
3778 (define_insn "*truncdfsf_i387"
3779 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3781 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3782 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3785 switch (which_alternative)
3788 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789 return "fstp%z0\t%y0";
3791 return "fst%z0\t%y0";
3798 [(set_attr "type" "fmov,multi")
3799 (set_attr "unit" "*,i387")
3800 (set_attr "mode" "SF")])
3802 (define_insn "*truncdfsf2_i387_1"
3803 [(set (match_operand:SF 0 "memory_operand" "=m")
3805 (match_operand:DF 1 "register_operand" "f")))]
3807 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3808 && !TARGET_MIX_SSE_I387"
3810 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811 return "fstp%z0\t%y0";
3813 return "fst%z0\t%y0";
3815 [(set_attr "type" "fmov")
3816 (set_attr "mode" "SF")])
3819 [(set (match_operand:SF 0 "register_operand" "")
3821 (match_operand:DF 1 "fp_register_operand" "")))
3822 (clobber (match_operand 2 "" ""))]
3824 [(set (match_dup 2) (match_dup 1))
3825 (set (match_dup 0) (match_dup 2))]
3827 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3830 ;; Conversion from XFmode to SFmode.
3832 (define_expand "truncxfsf2"
3833 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3835 (match_operand:XF 1 "register_operand" "")))
3836 (clobber (match_dup 2))])]
3839 if (flag_unsafe_math_optimizations)
3841 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3842 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3843 if (reg != operands[0])
3844 emit_move_insn (operands[0], reg);
3848 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3851 (define_insn "*truncxfsf2_mixed"
3852 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3854 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3855 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3856 "TARGET_MIX_SSE_I387"
3858 gcc_assert (!which_alternative);
3859 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3860 return "fstp%z0\t%y0";
3862 return "fst%z0\t%y0";
3864 [(set_attr "type" "fmov,multi,multi,multi")
3865 (set_attr "unit" "*,i387,i387,i387")
3866 (set_attr "mode" "SF")])
3868 (define_insn "truncxfsf2_i387_noop"
3869 [(set (match_operand:SF 0 "register_operand" "=f")
3870 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3871 "TARGET_80387 && flag_unsafe_math_optimizations"
3873 return output_387_reg_move (insn, operands);
3875 [(set_attr "type" "fmov")
3876 (set_attr "mode" "SF")])
3878 (define_insn "*truncxfsf2_i387"
3879 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3881 (match_operand:XF 1 "register_operand" "f,f,f")))
3882 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3885 gcc_assert (!which_alternative);
3886 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3887 return "fstp%z0\t%y0";
3889 return "fst%z0\t%y0";
3891 [(set_attr "type" "fmov,multi,multi")
3892 (set_attr "unit" "*,i387,i387")
3893 (set_attr "mode" "SF")])
3895 (define_insn "*truncxfsf2_i387_1"
3896 [(set (match_operand:SF 0 "memory_operand" "=m")
3898 (match_operand:XF 1 "register_operand" "f")))]
3901 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3902 return "fstp%z0\t%y0";
3904 return "fst%z0\t%y0";
3906 [(set_attr "type" "fmov")
3907 (set_attr "mode" "SF")])
3910 [(set (match_operand:SF 0 "register_operand" "")
3912 (match_operand:XF 1 "register_operand" "")))
3913 (clobber (match_operand:SF 2 "memory_operand" ""))]
3914 "TARGET_80387 && reload_completed"
3915 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3916 (set (match_dup 0) (match_dup 2))]
3920 [(set (match_operand:SF 0 "memory_operand" "")
3922 (match_operand:XF 1 "register_operand" "")))
3923 (clobber (match_operand:SF 2 "memory_operand" ""))]
3925 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3928 ;; Conversion from XFmode to DFmode.
3930 (define_expand "truncxfdf2"
3931 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3933 (match_operand:XF 1 "register_operand" "")))
3934 (clobber (match_dup 2))])]
3937 if (flag_unsafe_math_optimizations)
3939 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3940 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3941 if (reg != operands[0])
3942 emit_move_insn (operands[0], reg);
3946 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3949 (define_insn "*truncxfdf2_mixed"
3950 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3952 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3953 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3954 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3956 gcc_assert (!which_alternative);
3957 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3958 return "fstp%z0\t%y0";
3960 return "fst%z0\t%y0";
3962 [(set_attr "type" "fmov,multi,multi,multi")
3963 (set_attr "unit" "*,i387,i387,i387")
3964 (set_attr "mode" "DF")])
3966 (define_insn "truncxfdf2_i387_noop"
3967 [(set (match_operand:DF 0 "register_operand" "=f")
3968 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3969 "TARGET_80387 && flag_unsafe_math_optimizations"
3971 return output_387_reg_move (insn, operands);
3973 [(set_attr "type" "fmov")
3974 (set_attr "mode" "DF")])