1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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 3, 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 COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
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 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
109 ;; For SSE/MMX support:
127 UNSPEC_MS_TO_SYSV_CALL
129 ;; Generic math support
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
134 ;; x87 Floating point
150 UNSPEC_FRNDINT_MASK_PM
154 ;; x87 Double output FP
186 ;; For SSE4.1 support
196 ;; For SSE4.2 support
202 UNSPEC_FMA4_INTRINSIC
205 UNSPEC_XOP_UNSIGNED_CMP
216 UNSPEC_AESKEYGENASSIST
218 ;; For PCLMUL support
234 (define_c_enum "unspecv" [
237 UNSPECV_PROBE_STACK_RANGE
257 UNSPECV_LLWP_INTRINSIC
258 UNSPECV_SLWP_INTRINSIC
259 UNSPECV_LWPVAL_INTRINSIC
260 UNSPECV_LWPINS_INTRINSIC
268 ;; Constants to represent pcomtrue/pcomfalse variants
278 ;; Constants used in the XOP pperm instruction
280 [(PPERM_SRC 0x00) /* copy source */
281 (PPERM_INVERT 0x20) /* invert source */
282 (PPERM_REVERSE 0x40) /* bit reverse source */
283 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
284 (PPERM_ZERO 0x80) /* all 0's */
285 (PPERM_ONES 0xa0) /* all 1's */
286 (PPERM_SIGN 0xc0) /* propagate sign bit */
287 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
288 (PPERM_SRC1 0x00) /* use first source byte */
289 (PPERM_SRC2 0x10) /* use second source byte */
292 ;; Registers by name.
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first. This allows for better optimization. For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356 generic64,amdfam10,bdver1"
357 (const (symbol_ref "ix86_schedule")))
359 ;; A basic instruction type. Refinements due to arguments to be
360 ;; provided in other attributes.
363 alu,alu1,negnot,imov,imovx,lea,
364 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365 icmp,test,ibr,setcc,icmov,
366 push,pop,call,callv,leave,
368 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371 ssemuladd,sse4arg,lwp,
372 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373 (const_string "other"))
375 ;; Main data type used by the insn
377 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378 (const_string "unknown"))
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383 (const_string "i387")
384 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
388 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
390 (eq_attr "type" "other")
391 (const_string "unknown")]
392 (const_string "integer")))
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
399 (eq_attr "unit" "i387,sse,mmx")
401 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
403 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404 (eq_attr "type" "imov,test")
405 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406 (eq_attr "type" "call")
407 (if_then_else (match_operand 0 "constant_call_address_operand" "")
410 (eq_attr "type" "callv")
411 (if_then_else (match_operand 1 "constant_call_address_operand" "")
414 ;; We don't know the size before shorten_branches. Expect
415 ;; the instruction to fit for better scheduling.
416 (eq_attr "type" "ibr")
419 (symbol_ref "/* Update immediate_length and other attributes! */
420 gcc_unreachable (),1")))
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424 (cond [(eq_attr "type" "str,other,multi,fxch")
426 (and (eq_attr "type" "call")
427 (match_operand 0 "constant_call_address_operand" ""))
429 (and (eq_attr "type" "callv")
430 (match_operand 1 "constant_call_address_operand" ""))
433 (symbol_ref "ix86_attr_length_address_default (insn)")))
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (eq_attr "mode" "HI")
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
450 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
458 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459 (eq_attr "unit" "sse,mmx"))
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
467 (and (eq_attr "mode" "DI")
468 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469 (eq_attr "unit" "!mmx")))
471 (and (eq_attr "mode" "QI")
472 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
475 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
478 (and (eq_attr "type" "imovx")
479 (match_operand:QI 1 "ext_QIreg_operand" ""))
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg")
491 (eq_attr "type" "sseiadd1,ssecvt1")
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
500 (const_string "orig")))
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510 (if_then_else (and (eq_attr "prefix_0f" "1")
511 (eq_attr "prefix_extra" "0"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515 (if_then_else (eq_attr "prefix_vex_w" "1")
516 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521 (cond [(eq_attr "type" "str,leave")
523 (eq_attr "unit" "i387")
525 (and (eq_attr "type" "incdec")
526 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527 (ior (match_operand:SI 1 "register_operand" "")
528 (match_operand:HI 1 "register_operand" ""))))
530 (and (eq_attr "type" "push")
531 (not (match_operand 1 "memory_operand" "")))
533 (and (eq_attr "type" "pop")
534 (not (match_operand 0 "memory_operand" "")))
536 (and (eq_attr "type" "imov")
537 (and (not (eq_attr "mode" "DI"))
538 (ior (and (match_operand 0 "register_operand" "")
539 (match_operand 1 "immediate_operand" ""))
540 (ior (and (match_operand 0 "ax_reg_operand" "")
541 (match_operand 1 "memory_displacement_only_operand" ""))
542 (and (match_operand 0 "memory_displacement_only_operand" "")
543 (match_operand 1 "ax_reg_operand" ""))))))
545 (and (eq_attr "type" "call")
546 (match_operand 0 "constant_call_address_operand" ""))
548 (and (eq_attr "type" "callv")
549 (match_operand 1 "constant_call_address_operand" ""))
551 (and (eq_attr "type" "alu,alu1,icmp,test")
552 (match_operand 0 "ax_reg_operand" ""))
553 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
561 (define_attr "length" ""
562 (cond [(eq_attr "type" "other,multi,fistp,frndint")
564 (eq_attr "type" "fcmp")
566 (eq_attr "unit" "i387")
568 (plus (attr "prefix_data16")
569 (attr "length_address")))
570 (ior (eq_attr "prefix" "vex")
571 (and (eq_attr "prefix" "maybe_vex")
572 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573 (plus (attr "length_vex")
574 (plus (attr "length_immediate")
576 (attr "length_address"))))]
577 (plus (plus (attr "modrm")
578 (plus (attr "prefix_0f")
579 (plus (attr "prefix_rex")
580 (plus (attr "prefix_extra")
582 (plus (attr "prefix_rep")
583 (plus (attr "prefix_data16")
584 (plus (attr "length_immediate")
585 (attr "length_address")))))))
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
591 (define_attr "memory" "none,load,store,both,unknown"
592 (cond [(eq_attr "type" "other,multi,str,lwp")
593 (const_string "unknown")
594 (eq_attr "type" "lea,fcmov,fpspc")
595 (const_string "none")
596 (eq_attr "type" "fistp,leave")
597 (const_string "both")
598 (eq_attr "type" "frndint")
599 (const_string "load")
600 (eq_attr "type" "push")
601 (if_then_else (match_operand 1 "memory_operand" "")
602 (const_string "both")
603 (const_string "store"))
604 (eq_attr "type" "pop")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "both")
607 (const_string "load"))
608 (eq_attr "type" "setcc")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "store")
611 (const_string "none"))
612 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613 (if_then_else (ior (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "ibr")
618 (if_then_else (match_operand 0 "memory_operand" "")
619 (const_string "load")
620 (const_string "none"))
621 (eq_attr "type" "call")
622 (if_then_else (match_operand 0 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (eq_attr "type" "callv")
626 (if_then_else (match_operand 1 "constant_call_address_operand" "")
627 (const_string "none")
628 (const_string "load"))
629 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (and (match_operand 0 "memory_operand" "")
633 (match_operand 1 "memory_operand" ""))
634 (const_string "both")
635 (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (match_operand 1 "memory_operand" "")
638 (const_string "load")
640 "!alu1,negnot,ishift1,
641 imov,imovx,icmp,test,bitmanip,
643 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645 (match_operand 2 "memory_operand" ""))
646 (const_string "load")
647 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648 (match_operand 3 "memory_operand" ""))
649 (const_string "load")
651 (const_string "none")))
653 ;; Indicates if an instruction has both an immediate and a displacement.
655 (define_attr "imm_disp" "false,true,unknown"
656 (cond [(eq_attr "type" "other,multi")
657 (const_string "unknown")
658 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 1 "immediate_operand" "")))
661 (const_string "true")
662 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663 (and (match_operand 0 "memory_displacement_operand" "")
664 (match_operand 2 "immediate_operand" "")))
665 (const_string "true")
667 (const_string "false")))
669 ;; Indicates if an FP operation has an integer source.
671 (define_attr "fp_int_src" "false,true"
672 (const_string "false"))
674 ;; Defines rounding mode of an FP operation.
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677 (const_string "any"))
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
690 (define_code_iterator plusminus [plus minus])
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701 [(plus "add") (ss_plus "adds") (us_plus "addus")
702 (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
716 ;; Mapping of signed/unsigned max and min
717 (define_code_iterator maxmin [smax smin umax umin])
719 ;; Base name for integer and FP insn mnemonic
720 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
721 (umax "maxu") (umin "minu")])
722 (define_code_attr maxmin_float [(smax "max") (smin "min")])
724 ;; Mapping of logic operators
725 (define_code_iterator any_logic [and ior xor])
726 (define_code_iterator any_or [ior xor])
728 ;; Base name for insn mnemonic.
729 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
731 ;; Mapping of shift-right operators
732 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
734 ;; Base name for define_insn
735 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
737 ;; Base name for insn mnemonic.
738 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
740 ;; Mapping of rotate operators
741 (define_code_iterator any_rotate [rotate rotatert])
743 ;; Base name for define_insn
744 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
746 ;; Base name for insn mnemonic.
747 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
749 ;; Mapping of abs neg operators
750 (define_code_iterator absneg [abs neg])
752 ;; Base name for x87 insn mnemonic.
753 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
755 ;; Used in signed and unsigned widening multiplications.
756 (define_code_iterator any_extend [sign_extend zero_extend])
758 ;; Various insn prefixes for signed and unsigned operations.
759 (define_code_attr u [(sign_extend "") (zero_extend "u")
760 (div "") (udiv "u")])
761 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
763 ;; Used in signed and unsigned divisions.
764 (define_code_iterator any_div [div udiv])
766 ;; Instruction prefix for signed and unsigned operations.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
768 (div "i") (udiv "")])
770 ;; 64bit single word integer modes.
771 (define_mode_iterator SWI1248x [QI HI SI DI])
773 ;; 64bit single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
776 ;; Single word integer modes.
777 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
779 ;; Single word integer modes without SImode and DImode.
780 (define_mode_iterator SWI12 [QI HI])
782 ;; Single word integer modes without DImode.
783 (define_mode_iterator SWI124 [QI HI SI])
785 ;; Single word integer modes without QImode and DImode.
786 (define_mode_iterator SWI24 [HI SI])
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI DI (TI "TARGET_64BIT")])
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
802 SI (DI "TARGET_64BIT")])
804 ;; Math-dependant single word integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806 (HI "TARGET_HIMODE_MATH")
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811 SI (DI "TARGET_64BIT")])
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815 (TI "TARGET_64BIT")])
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823 (DI "TARGET_64BIT")])
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
828 ;; Pointer size prefix for integer modes (Intel asm dialect)
829 (define_mode_attr iptrsize [(QI "BYTE")
834 ;; Register class for integer modes.
835 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
837 ;; Immediate operand constraint for integer modes.
838 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
840 ;; General operand constraint for word modes.
841 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
843 ;; Immediate operand constraint for double integer modes.
844 (define_mode_attr di [(SI "iF") (DI "e")])
846 ;; Immediate operand constraint for shifts.
847 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
849 ;; General operand predicate for integer modes.
850 (define_mode_attr general_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "general_operand")
854 (DI "x86_64_general_operand")
855 (TI "x86_64_general_operand")])
857 ;; General sign/zero extend operand predicate for integer modes.
858 (define_mode_attr general_szext_operand
859 [(QI "general_operand")
860 (HI "general_operand")
861 (SI "general_operand")
862 (DI "x86_64_szext_general_operand")])
864 ;; Immediate operand predicate for integer modes.
865 (define_mode_attr immediate_operand
866 [(QI "immediate_operand")
867 (HI "immediate_operand")
868 (SI "immediate_operand")
869 (DI "x86_64_immediate_operand")])
871 ;; Nonmemory operand predicate for integer modes.
872 (define_mode_attr nonmemory_operand
873 [(QI "nonmemory_operand")
874 (HI "nonmemory_operand")
875 (SI "nonmemory_operand")
876 (DI "x86_64_nonmemory_operand")])
878 ;; Operand predicate for shifts.
879 (define_mode_attr shift_operand
880 [(QI "nonimmediate_operand")
881 (HI "nonimmediate_operand")
882 (SI "nonimmediate_operand")
883 (DI "shiftdi_operand")
884 (TI "register_operand")])
886 ;; Operand predicate for shift argument.
887 (define_mode_attr shift_immediate_operand
888 [(QI "const_1_to_31_operand")
889 (HI "const_1_to_31_operand")
890 (SI "const_1_to_31_operand")
891 (DI "const_1_to_63_operand")])
893 ;; Input operand predicate for arithmetic left shifts.
894 (define_mode_attr ashl_input_operand
895 [(QI "nonimmediate_operand")
896 (HI "nonimmediate_operand")
897 (SI "nonimmediate_operand")
898 (DI "ashldi_input_operand")
899 (TI "reg_or_pm1_operand")])
901 ;; SSE and x87 SFmode and DFmode floating point modes
902 (define_mode_iterator MODEF [SF DF])
904 ;; All x87 floating point modes
905 (define_mode_iterator X87MODEF [SF DF XF])
907 ;; All integer modes handled by x87 fisttp operator.
908 (define_mode_iterator X87MODEI [HI SI DI])
910 ;; All integer modes handled by integer x87 operators.
911 (define_mode_iterator X87MODEI12 [HI SI])
913 ;; All integer modes handled by SSE cvtts?2si* operators.
914 (define_mode_iterator SSEMODEI24 [SI DI])
916 ;; SSE asm suffix for floating point modes
917 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
919 ;; SSE vector mode corresponding to a scalar mode
920 (define_mode_attr ssevecmode
921 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
923 ;; Instruction suffix for REX 64bit operators.
924 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
926 ;; This mode iterator allows :P to be used for patterns that operate on
927 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
928 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
930 ;; Scheduling descriptions
932 (include "pentium.md")
935 (include "athlon.md")
940 ;; Operand and operator predicates and constraints
942 (include "predicates.md")
943 (include "constraints.md")
946 ;; Compare and branch/compare and store instructions.
948 (define_expand "cbranch<mode>4"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
951 (match_operand:SDWIM 2 "<general_operand>" "")))
952 (set (pc) (if_then_else
953 (match_operator 0 "ordered_comparison_operator"
954 [(reg:CC FLAGS_REG) (const_int 0)])
955 (label_ref (match_operand 3 "" ""))
959 if (MEM_P (operands[1]) && MEM_P (operands[2]))
960 operands[1] = force_reg (<MODE>mode, operands[1]);
961 ix86_expand_branch (GET_CODE (operands[0]),
962 operands[1], operands[2], operands[3]);
966 (define_expand "cstore<mode>4"
967 [(set (reg:CC FLAGS_REG)
968 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
969 (match_operand:SWIM 3 "<general_operand>" "")))
970 (set (match_operand:QI 0 "register_operand" "")
971 (match_operator 1 "ordered_comparison_operator"
972 [(reg:CC FLAGS_REG) (const_int 0)]))]
975 if (MEM_P (operands[2]) && MEM_P (operands[3]))
976 operands[2] = force_reg (<MODE>mode, operands[2]);
977 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
978 operands[2], operands[3]);
982 (define_expand "cmp<mode>_1"
983 [(set (reg:CC FLAGS_REG)
984 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
985 (match_operand:SWI48 1 "<general_operand>" "")))])
987 (define_insn "*cmp<mode>_ccno_1"
988 [(set (reg FLAGS_REG)
989 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
990 (match_operand:SWI 1 "const0_operand" "")))]
991 "ix86_match_ccmode (insn, CCNOmode)"
993 test{<imodesuffix>}\t%0, %0
994 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995 [(set_attr "type" "test,icmp")
996 (set_attr "length_immediate" "0,1")
997 (set_attr "mode" "<MODE>")])
999 (define_insn "*cmp<mode>_1"
1000 [(set (reg FLAGS_REG)
1001 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1002 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1003 "ix86_match_ccmode (insn, CCmode)"
1004 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1005 [(set_attr "type" "icmp")
1006 (set_attr "mode" "<MODE>")])
1008 (define_insn "*cmp<mode>_minus_1"
1009 [(set (reg FLAGS_REG)
1011 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1012 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1014 "ix86_match_ccmode (insn, CCGOCmode)"
1015 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "<MODE>")])
1019 (define_insn "*cmpqi_ext_1"
1020 [(set (reg FLAGS_REG)
1022 (match_operand:QI 0 "general_operand" "Qm")
1025 (match_operand 1 "ext_register_operand" "Q")
1027 (const_int 8)) 0)))]
1028 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1029 "cmp{b}\t{%h1, %0|%0, %h1}"
1030 [(set_attr "type" "icmp")
1031 (set_attr "mode" "QI")])
1033 (define_insn "*cmpqi_ext_1_rex64"
1034 [(set (reg FLAGS_REG)
1036 (match_operand:QI 0 "register_operand" "Q")
1039 (match_operand 1 "ext_register_operand" "Q")
1041 (const_int 8)) 0)))]
1042 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1043 "cmp{b}\t{%h1, %0|%0, %h1}"
1044 [(set_attr "type" "icmp")
1045 (set_attr "mode" "QI")])
1047 (define_insn "*cmpqi_ext_2"
1048 [(set (reg FLAGS_REG)
1052 (match_operand 0 "ext_register_operand" "Q")
1055 (match_operand:QI 1 "const0_operand" "")))]
1056 "ix86_match_ccmode (insn, CCNOmode)"
1058 [(set_attr "type" "test")
1059 (set_attr "length_immediate" "0")
1060 (set_attr "mode" "QI")])
1062 (define_expand "cmpqi_ext_3"
1063 [(set (reg:CC FLAGS_REG)
1067 (match_operand 0 "ext_register_operand" "")
1070 (match_operand:QI 1 "immediate_operand" "")))])
1072 (define_insn "*cmpqi_ext_3_insn"
1073 [(set (reg FLAGS_REG)
1077 (match_operand 0 "ext_register_operand" "Q")
1080 (match_operand:QI 1 "general_operand" "Qmn")))]
1081 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1082 "cmp{b}\t{%1, %h0|%h0, %1}"
1083 [(set_attr "type" "icmp")
1084 (set_attr "modrm" "1")
1085 (set_attr "mode" "QI")])
1087 (define_insn "*cmpqi_ext_3_insn_rex64"
1088 [(set (reg FLAGS_REG)
1092 (match_operand 0 "ext_register_operand" "Q")
1095 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1096 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{b}\t{%1, %h0|%h0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "modrm" "1")
1100 (set_attr "mode" "QI")])
1102 (define_insn "*cmpqi_ext_4"
1103 [(set (reg FLAGS_REG)
1107 (match_operand 0 "ext_register_operand" "Q")
1112 (match_operand 1 "ext_register_operand" "Q")
1114 (const_int 8)) 0)))]
1115 "ix86_match_ccmode (insn, CCmode)"
1116 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1117 [(set_attr "type" "icmp")
1118 (set_attr "mode" "QI")])
1120 ;; These implement float point compares.
1121 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1122 ;; which would allow mix and match FP modes on the compares. Which is what
1123 ;; the old patterns did, but with many more of them.
1125 (define_expand "cbranchxf4"
1126 [(set (reg:CC FLAGS_REG)
1127 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1128 (match_operand:XF 2 "nonmemory_operand" "")))
1129 (set (pc) (if_then_else
1130 (match_operator 0 "ix86_fp_comparison_operator"
1133 (label_ref (match_operand 3 "" ""))
1137 ix86_expand_branch (GET_CODE (operands[0]),
1138 operands[1], operands[2], operands[3]);
1142 (define_expand "cstorexf4"
1143 [(set (reg:CC FLAGS_REG)
1144 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1145 (match_operand:XF 3 "nonmemory_operand" "")))
1146 (set (match_operand:QI 0 "register_operand" "")
1147 (match_operator 1 "ix86_fp_comparison_operator"
1152 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1153 operands[2], operands[3]);
1157 (define_expand "cbranch<mode>4"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1160 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1161 (set (pc) (if_then_else
1162 (match_operator 0 "ix86_fp_comparison_operator"
1165 (label_ref (match_operand 3 "" ""))
1167 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1169 ix86_expand_branch (GET_CODE (operands[0]),
1170 operands[1], operands[2], operands[3]);
1174 (define_expand "cstore<mode>4"
1175 [(set (reg:CC FLAGS_REG)
1176 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1177 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1178 (set (match_operand:QI 0 "register_operand" "")
1179 (match_operator 1 "ix86_fp_comparison_operator"
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1184 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185 operands[2], operands[3]);
1189 (define_expand "cbranchcc4"
1190 [(set (pc) (if_then_else
1191 (match_operator 0 "comparison_operator"
1192 [(match_operand 1 "flags_reg_operand" "")
1193 (match_operand 2 "const0_operand" "")])
1194 (label_ref (match_operand 3 "" ""))
1198 ix86_expand_branch (GET_CODE (operands[0]),
1199 operands[1], operands[2], operands[3]);
1203 (define_expand "cstorecc4"
1204 [(set (match_operand:QI 0 "register_operand" "")
1205 (match_operator 1 "comparison_operator"
1206 [(match_operand 2 "flags_reg_operand" "")
1207 (match_operand 3 "const0_operand" "")]))]
1210 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1211 operands[2], operands[3]);
1216 ;; FP compares, step 1:
1217 ;; Set the FP condition codes.
1219 ;; CCFPmode compare with exceptions
1220 ;; CCFPUmode compare with no exceptions
1222 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1223 ;; used to manage the reg stack popping would not be preserved.
1225 (define_insn "*cmpfp_0"
1226 [(set (match_operand:HI 0 "register_operand" "=a")
1229 (match_operand 1 "register_operand" "f")
1230 (match_operand 2 "const0_operand" ""))]
1232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234 "* return output_fp_compare (insn, operands, 0, 0);"
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1238 (cond [(match_operand:SF 1 "" "")
1240 (match_operand:DF 1 "" "")
1243 (const_string "XF")))])
1245 (define_insn_and_split "*cmpfp_0_cc"
1246 [(set (reg:CCFP FLAGS_REG)
1248 (match_operand 1 "register_operand" "f")
1249 (match_operand 2 "const0_operand" "")))
1250 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1251 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1252 && TARGET_SAHF && !TARGET_CMOVE
1253 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1255 "&& reload_completed"
1258 [(compare:CCFP (match_dup 1)(match_dup 2))]
1260 (set (reg:CC FLAGS_REG)
1261 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1263 [(set_attr "type" "multi")
1264 (set_attr "unit" "i387")
1266 (cond [(match_operand:SF 1 "" "")
1268 (match_operand:DF 1 "" "")
1271 (const_string "XF")))])
1273 (define_insn "*cmpfp_xf"
1274 [(set (match_operand:HI 0 "register_operand" "=a")
1277 (match_operand:XF 1 "register_operand" "f")
1278 (match_operand:XF 2 "register_operand" "f"))]
1281 "* return output_fp_compare (insn, operands, 0, 0);"
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1284 (set_attr "mode" "XF")])
1286 (define_insn_and_split "*cmpfp_xf_cc"
1287 [(set (reg:CCFP FLAGS_REG)
1289 (match_operand:XF 1 "register_operand" "f")
1290 (match_operand:XF 2 "register_operand" "f")))
1291 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1293 && TARGET_SAHF && !TARGET_CMOVE"
1295 "&& reload_completed"
1298 [(compare:CCFP (match_dup 1)(match_dup 2))]
1300 (set (reg:CC FLAGS_REG)
1301 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1303 [(set_attr "type" "multi")
1304 (set_attr "unit" "i387")
1305 (set_attr "mode" "XF")])
1307 (define_insn "*cmpfp_<mode>"
1308 [(set (match_operand:HI 0 "register_operand" "=a")
1311 (match_operand:MODEF 1 "register_operand" "f")
1312 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1315 "* return output_fp_compare (insn, operands, 0, 0);"
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set_attr "mode" "<MODE>")])
1320 (define_insn_and_split "*cmpfp_<mode>_cc"
1321 [(set (reg:CCFP FLAGS_REG)
1323 (match_operand:MODEF 1 "register_operand" "f")
1324 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1325 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1327 && TARGET_SAHF && !TARGET_CMOVE"
1329 "&& reload_completed"
1332 [(compare:CCFP (match_dup 1)(match_dup 2))]
1334 (set (reg:CC FLAGS_REG)
1335 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1337 [(set_attr "type" "multi")
1338 (set_attr "unit" "i387")
1339 (set_attr "mode" "<MODE>")])
1341 (define_insn "*cmpfp_u"
1342 [(set (match_operand:HI 0 "register_operand" "=a")
1345 (match_operand 1 "register_operand" "f")
1346 (match_operand 2 "register_operand" "f"))]
1348 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1349 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1350 "* return output_fp_compare (insn, operands, 0, 1);"
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1354 (cond [(match_operand:SF 1 "" "")
1356 (match_operand:DF 1 "" "")
1359 (const_string "XF")))])
1361 (define_insn_and_split "*cmpfp_u_cc"
1362 [(set (reg:CCFPU FLAGS_REG)
1364 (match_operand 1 "register_operand" "f")
1365 (match_operand 2 "register_operand" "f")))
1366 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1367 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1368 && TARGET_SAHF && !TARGET_CMOVE
1369 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1371 "&& reload_completed"
1374 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1376 (set (reg:CC FLAGS_REG)
1377 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1382 (cond [(match_operand:SF 1 "" "")
1384 (match_operand:DF 1 "" "")
1387 (const_string "XF")))])
1389 (define_insn "*cmpfp_<mode>"
1390 [(set (match_operand:HI 0 "register_operand" "=a")
1393 (match_operand 1 "register_operand" "f")
1394 (match_operator 3 "float_operator"
1395 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1397 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1398 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1399 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1400 "* return output_fp_compare (insn, operands, 0, 0);"
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "fp_int_src" "true")
1404 (set_attr "mode" "<MODE>")])
1406 (define_insn_and_split "*cmpfp_<mode>_cc"
1407 [(set (reg:CCFP FLAGS_REG)
1409 (match_operand 1 "register_operand" "f")
1410 (match_operator 3 "float_operator"
1411 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1412 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1414 && TARGET_SAHF && !TARGET_CMOVE
1415 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1416 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1418 "&& reload_completed"
1423 (match_op_dup 3 [(match_dup 2)]))]
1425 (set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1433 ;; FP compares, step 2
1434 ;; Move the fpsw to ax.
1436 (define_insn "x86_fnstsw_1"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1438 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1441 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1442 (set_attr "mode" "SI")
1443 (set_attr "unit" "i387")])
1445 ;; FP compares, step 3
1446 ;; Get ax into flags, general case.
1448 (define_insn "x86_sahf_1"
1449 [(set (reg:CC FLAGS_REG)
1450 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1454 #ifndef HAVE_AS_IX86_SAHF
1456 return ASM_BYTE "0x9e";
1461 [(set_attr "length" "1")
1462 (set_attr "athlon_decode" "vector")
1463 (set_attr "amdfam10_decode" "direct")
1464 (set_attr "mode" "SI")])
1466 ;; Pentium Pro can do steps 1 through 3 in one go.
1467 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1468 (define_insn "*cmpfp_i_mixed"
1469 [(set (reg:CCFP FLAGS_REG)
1470 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1471 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1472 "TARGET_MIX_SSE_I387
1473 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1474 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1475 "* return output_fp_compare (insn, operands, 1, 0);"
1476 [(set_attr "type" "fcmp,ssecomi")
1477 (set_attr "prefix" "orig,maybe_vex")
1479 (if_then_else (match_operand:SF 1 "" "")
1481 (const_string "DF")))
1482 (set (attr "prefix_rep")
1483 (if_then_else (eq_attr "type" "ssecomi")
1485 (const_string "*")))
1486 (set (attr "prefix_data16")
1487 (cond [(eq_attr "type" "fcmp")
1489 (eq_attr "mode" "DF")
1492 (const_string "0")))
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")])
1496 (define_insn "*cmpfp_i_sse"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "x")
1499 (match_operand 1 "nonimmediate_operand" "xm")))]
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, 1, 0);"
1504 [(set_attr "type" "ssecomi")
1505 (set_attr "prefix" "maybe_vex")
1507 (if_then_else (match_operand:SF 1 "" "")
1509 (const_string "DF")))
1510 (set_attr "prefix_rep" "0")
1511 (set (attr "prefix_data16")
1512 (if_then_else (eq_attr "mode" "DF")
1514 (const_string "0")))
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")])
1518 (define_insn "*cmpfp_i_i387"
1519 [(set (reg:CCFP FLAGS_REG)
1520 (compare:CCFP (match_operand 0 "register_operand" "f")
1521 (match_operand 1 "register_operand" "f")))]
1522 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526 "* return output_fp_compare (insn, operands, 1, 0);"
1527 [(set_attr "type" "fcmp")
1529 (cond [(match_operand:SF 1 "" "")
1531 (match_operand:DF 1 "" "")
1534 (const_string "XF")))
1535 (set_attr "athlon_decode" "vector")
1536 (set_attr "amdfam10_decode" "direct")])
1538 (define_insn "*cmpfp_iu_mixed"
1539 [(set (reg:CCFPU FLAGS_REG)
1540 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542 "TARGET_MIX_SSE_I387
1543 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545 "* return output_fp_compare (insn, operands, 1, 1);"
1546 [(set_attr "type" "fcmp,ssecomi")
1547 (set_attr "prefix" "orig,maybe_vex")
1549 (if_then_else (match_operand:SF 1 "" "")
1551 (const_string "DF")))
1552 (set (attr "prefix_rep")
1553 (if_then_else (eq_attr "type" "ssecomi")
1555 (const_string "*")))
1556 (set (attr "prefix_data16")
1557 (cond [(eq_attr "type" "fcmp")
1559 (eq_attr "mode" "DF")
1562 (const_string "0")))
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")])
1566 (define_insn "*cmpfp_iu_sse"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, 1, 1);"
1574 [(set_attr "type" "ssecomi")
1575 (set_attr "prefix" "maybe_vex")
1577 (if_then_else (match_operand:SF 1 "" "")
1579 (const_string "DF")))
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1584 (const_string "0")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")])
1588 (define_insn "*cmpfp_iu_387"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "f")
1591 (match_operand 1 "register_operand" "f")))]
1592 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1595 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596 "* return output_fp_compare (insn, operands, 1, 1);"
1597 [(set_attr "type" "fcmp")
1599 (cond [(match_operand:SF 1 "" "")
1601 (match_operand:DF 1 "" "")
1604 (const_string "XF")))
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")])
1608 ;; Push/pop instructions.
1610 (define_insn "*pushdi2_rex64"
1611 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617 [(set_attr "type" "push,multi")
1618 (set_attr "mode" "DI")])
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it. In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1625 [(match_scratch:DI 2 "r")
1626 (set (match_operand:DI 0 "push_operand" "")
1627 (match_operand:DI 1 "immediate_operand" ""))]
1628 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629 && !x86_64_immediate_operand (operands[1], DImode)"
1630 [(set (match_dup 2) (match_dup 1))
1631 (set (match_dup 0) (match_dup 2))])
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1637 [(set (match_operand:DI 0 "push_operand" "")
1638 (match_operand:DI 1 "immediate_operand" ""))]
1639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641 [(set (match_dup 0) (match_dup 1))
1642 (set (match_dup 2) (match_dup 3))]
1644 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1646 operands[1] = gen_lowpart (DImode, operands[2]);
1647 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1652 [(set (match_operand:DI 0 "push_operand" "")
1653 (match_operand:DI 1 "immediate_operand" ""))]
1654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655 ? epilogue_completed : reload_completed)
1656 && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1668 (define_insn "*pushdi2"
1669 [(set (match_operand:DI 0 "push_operand" "=<")
1670 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1675 [(set (match_operand:DI 0 "push_operand" "")
1676 (match_operand:DI 1 "general_operand" ""))]
1677 "!TARGET_64BIT && reload_completed
1678 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1680 "ix86_split_long_move (operands); DONE;")
1682 (define_insn "*pushsi2"
1683 [(set (match_operand:SI 0 "push_operand" "=<")
1684 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1687 [(set_attr "type" "push")
1688 (set_attr "mode" "SI")])
1690 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1691 ;; "push a byte/word". But actually we use pushl, which has the effect
1692 ;; of rounding the amount pushed up to a word.
1694 ;; For TARGET_64BIT we always round up to 8 bytes.
1695 (define_insn "*push<mode>2_rex64"
1696 [(set (match_operand:SWI124 0 "push_operand" "=X")
1697 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1700 [(set_attr "type" "push")
1701 (set_attr "mode" "DI")])
1703 (define_insn "*push<mode>2"
1704 [(set (match_operand:SWI12 0 "push_operand" "=X")
1705 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "SI")])
1711 (define_insn "*push<mode>2_prologue"
1712 [(set (match_operand:P 0 "push_operand" "=<")
1713 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1714 (clobber (mem:BLK (scratch)))]
1716 "push{<imodesuffix>}\t%1"
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "<MODE>")])
1720 (define_insn "*pop<mode>1"
1721 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1722 (match_operand:P 1 "pop_operand" ">"))]
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1728 (define_insn "*pop<mode>1_epilogue"
1729 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1730 (match_operand:P 1 "pop_operand" ">"))
1731 (clobber (mem:BLK (scratch)))]
1733 "pop{<imodesuffix>}\t%0"
1734 [(set_attr "type" "pop")
1735 (set_attr "mode" "<MODE>")])
1737 ;; Move instructions.
1739 (define_expand "movoi"
1740 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1741 (match_operand:OI 1 "general_operand" ""))]
1743 "ix86_expand_move (OImode, operands); DONE;")
1745 (define_expand "movti"
1746 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1747 (match_operand:TI 1 "nonimmediate_operand" ""))]
1748 "TARGET_64BIT || TARGET_SSE"
1751 ix86_expand_move (TImode, operands);
1752 else if (push_operand (operands[0], TImode))
1753 ix86_expand_push (TImode, operands[1]);
1755 ix86_expand_vector_move (TImode, operands);
1759 ;; This expands to what emit_move_complex would generate if we didn't
1760 ;; have a movti pattern. Having this avoids problems with reload on
1761 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1762 ;; to have around all the time.
1763 (define_expand "movcdi"
1764 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1765 (match_operand:CDI 1 "general_operand" ""))]
1768 if (push_operand (operands[0], CDImode))
1769 emit_move_complex_push (CDImode, operands[0], operands[1]);
1771 emit_move_complex_parts (operands[0], operands[1]);
1775 (define_expand "mov<mode>"
1776 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1777 (match_operand:SWI1248x 1 "general_operand" ""))]
1779 "ix86_expand_move (<MODE>mode, operands); DONE;")
1781 (define_insn "*mov<mode>_xor"
1782 [(set (match_operand:SWI48 0 "register_operand" "=r")
1783 (match_operand:SWI48 1 "const0_operand" ""))
1784 (clobber (reg:CC FLAGS_REG))]
1787 [(set_attr "type" "alu1")
1788 (set_attr "mode" "SI")
1789 (set_attr "length_immediate" "0")])
1791 (define_insn "*mov<mode>_or"
1792 [(set (match_operand:SWI48 0 "register_operand" "=r")
1793 (match_operand:SWI48 1 "const_int_operand" ""))
1794 (clobber (reg:CC FLAGS_REG))]
1796 && operands[1] == constm1_rtx"
1797 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1798 [(set_attr "type" "alu1")
1799 (set_attr "mode" "<MODE>")
1800 (set_attr "length_immediate" "1")])
1802 (define_insn "*movoi_internal_avx"
1803 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1804 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1805 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807 switch (which_alternative)
1810 return "vxorps\t%0, %0, %0";
1813 if (misaligned_operand (operands[0], OImode)
1814 || misaligned_operand (operands[1], OImode))
1815 return "vmovdqu\t{%1, %0|%0, %1}";
1817 return "vmovdqa\t{%1, %0|%0, %1}";
1822 [(set_attr "type" "sselog1,ssemov,ssemov")
1823 (set_attr "prefix" "vex")
1824 (set_attr "mode" "OI")])
1826 (define_insn "*movti_internal_rex64"
1827 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1828 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1829 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 switch (which_alternative)
1837 if (get_attr_mode (insn) == MODE_V4SF)
1838 return "%vxorps\t%0, %d0";
1840 return "%vpxor\t%0, %d0";
1843 /* TDmode values are passed as TImode on the stack. Moving them
1844 to stack may result in unaligned memory access. */
1845 if (misaligned_operand (operands[0], TImode)
1846 || misaligned_operand (operands[1], TImode))
1848 if (get_attr_mode (insn) == MODE_V4SF)
1849 return "%vmovups\t{%1, %0|%0, %1}";
1851 return "%vmovdqu\t{%1, %0|%0, %1}";
1855 if (get_attr_mode (insn) == MODE_V4SF)
1856 return "%vmovaps\t{%1, %0|%0, %1}";
1858 return "%vmovdqa\t{%1, %0|%0, %1}";
1864 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1867 (cond [(eq_attr "alternative" "2,3")
1869 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1871 (const_string "V4SF")
1872 (const_string "TI"))
1873 (eq_attr "alternative" "4")
1875 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1877 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1879 (const_string "V4SF")
1880 (const_string "TI"))]
1881 (const_string "DI")))])
1884 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1885 (match_operand:TI 1 "general_operand" ""))]
1887 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1889 "ix86_split_long_move (operands); DONE;")
1891 (define_insn "*movti_internal_sse"
1892 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1893 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1894 "TARGET_SSE && !TARGET_64BIT
1895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1897 switch (which_alternative)
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vxorps\t%0, %d0";
1903 return "%vpxor\t%0, %d0";
1906 /* TDmode values are passed as TImode on the stack. Moving them
1907 to stack may result in unaligned memory access. */
1908 if (misaligned_operand (operands[0], TImode)
1909 || misaligned_operand (operands[1], TImode))
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vmovups\t{%1, %0|%0, %1}";
1914 return "%vmovdqu\t{%1, %0|%0, %1}";
1918 if (get_attr_mode (insn) == MODE_V4SF)
1919 return "%vmovaps\t{%1, %0|%0, %1}";
1921 return "%vmovdqa\t{%1, %0|%0, %1}";
1927 [(set_attr "type" "sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "maybe_vex")
1930 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1931 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1933 (const_string "V4SF")
1934 (and (eq_attr "alternative" "2")
1935 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1937 (const_string "V4SF")]
1938 (const_string "TI")))])
1940 (define_insn "*movdi_internal_rex64"
1941 [(set (match_operand:DI 0 "nonimmediate_operand"
1942 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1943 (match_operand:DI 1 "general_operand"
1944 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1945 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 switch (get_attr_type (insn))
1950 if (SSE_REG_P (operands[0]))
1951 return "movq2dq\t{%1, %0|%0, %1}";
1953 return "movdq2q\t{%1, %0|%0, %1}";
1958 if (get_attr_mode (insn) == MODE_TI)
1959 return "vmovdqa\t{%1, %0|%0, %1}";
1961 return "vmovq\t{%1, %0|%0, %1}";
1964 if (get_attr_mode (insn) == MODE_TI)
1965 return "movdqa\t{%1, %0|%0, %1}";
1969 /* Moves from and into integer register is done using movd
1970 opcode with REX prefix. */
1971 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1972 return "movd\t{%1, %0|%0, %1}";
1973 return "movq\t{%1, %0|%0, %1}";
1976 return "%vpxor\t%0, %d0";
1979 return "pxor\t%0, %0";
1985 return "lea{q}\t{%a1, %0|%0, %a1}";
1988 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1989 if (get_attr_mode (insn) == MODE_SI)
1990 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1991 else if (which_alternative == 2)
1992 return "movabs{q}\t{%1, %0|%0, %1}";
1994 return "mov{q}\t{%1, %0|%0, %1}";
1998 (cond [(eq_attr "alternative" "5")
1999 (const_string "mmx")
2000 (eq_attr "alternative" "6,7,8,9,10")
2001 (const_string "mmxmov")
2002 (eq_attr "alternative" "11")
2003 (const_string "sselog1")
2004 (eq_attr "alternative" "12,13,14,15,16")
2005 (const_string "ssemov")
2006 (eq_attr "alternative" "17,18")
2007 (const_string "ssecvt")
2008 (eq_attr "alternative" "4")
2009 (const_string "multi")
2010 (match_operand:DI 1 "pic_32bit_operand" "")
2011 (const_string "lea")
2013 (const_string "imov")))
2016 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2018 (const_string "*")))
2019 (set (attr "length_immediate")
2021 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2023 (const_string "*")))
2024 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2025 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2026 (set (attr "prefix")
2027 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2028 (const_string "maybe_vex")
2029 (const_string "orig")))
2030 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2032 ;; Convert impossible stores of immediate to existing instructions.
2033 ;; First try to get scratch register and go through it. In case this
2034 ;; fails, move by 32bit parts.
2036 [(match_scratch:DI 2 "r")
2037 (set (match_operand:DI 0 "memory_operand" "")
2038 (match_operand:DI 1 "immediate_operand" ""))]
2039 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2040 && !x86_64_immediate_operand (operands[1], DImode)"
2041 [(set (match_dup 2) (match_dup 1))
2042 (set (match_dup 0) (match_dup 2))])
2044 ;; We need to define this as both peepholer and splitter for case
2045 ;; peephole2 pass is not run.
2046 ;; "&& 1" is needed to keep it from matching the previous pattern.
2048 [(set (match_operand:DI 0 "memory_operand" "")
2049 (match_operand:DI 1 "immediate_operand" ""))]
2050 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2051 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2052 [(set (match_dup 2) (match_dup 3))
2053 (set (match_dup 4) (match_dup 5))]
2054 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2057 [(set (match_operand:DI 0 "memory_operand" "")
2058 (match_operand:DI 1 "immediate_operand" ""))]
2059 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2060 ? epilogue_completed : reload_completed)
2061 && !symbolic_operand (operands[1], DImode)
2062 && !x86_64_immediate_operand (operands[1], DImode)"
2063 [(set (match_dup 2) (match_dup 3))
2064 (set (match_dup 4) (match_dup 5))]
2065 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2067 (define_insn "*movdi_internal"
2068 [(set (match_operand:DI 0 "nonimmediate_operand"
2069 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2070 (match_operand:DI 1 "general_operand"
2071 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2072 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2077 movq\t{%1, %0|%0, %1}
2078 movq\t{%1, %0|%0, %1}
2080 %vmovq\t{%1, %0|%0, %1}
2081 %vmovdqa\t{%1, %0|%0, %1}
2082 %vmovq\t{%1, %0|%0, %1}
2084 movlps\t{%1, %0|%0, %1}
2085 movaps\t{%1, %0|%0, %1}
2086 movlps\t{%1, %0|%0, %1}"
2087 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2088 (set (attr "prefix")
2089 (if_then_else (eq_attr "alternative" "5,6,7,8")
2090 (const_string "vex")
2091 (const_string "orig")))
2092 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2095 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2096 (match_operand:DI 1 "general_operand" ""))]
2097 "!TARGET_64BIT && reload_completed
2098 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2099 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2101 "ix86_split_long_move (operands); DONE;")
2103 (define_insn "*movsi_internal"
2104 [(set (match_operand:SI 0 "nonimmediate_operand"
2105 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2106 (match_operand:SI 1 "general_operand"
2107 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2108 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2110 switch (get_attr_type (insn))
2113 if (get_attr_mode (insn) == MODE_TI)
2114 return "%vpxor\t%0, %d0";
2115 return "%vxorps\t%0, %d0";
2118 switch (get_attr_mode (insn))
2121 return "%vmovdqa\t{%1, %0|%0, %1}";
2123 return "%vmovaps\t{%1, %0|%0, %1}";
2125 return "%vmovd\t{%1, %0|%0, %1}";
2127 return "%vmovss\t{%1, %0|%0, %1}";
2133 return "pxor\t%0, %0";
2136 if (get_attr_mode (insn) == MODE_DI)
2137 return "movq\t{%1, %0|%0, %1}";
2138 return "movd\t{%1, %0|%0, %1}";
2141 return "lea{l}\t{%a1, %0|%0, %a1}";
2144 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2145 return "mov{l}\t{%1, %0|%0, %1}";
2149 (cond [(eq_attr "alternative" "2")
2150 (const_string "mmx")
2151 (eq_attr "alternative" "3,4,5")
2152 (const_string "mmxmov")
2153 (eq_attr "alternative" "6")
2154 (const_string "sselog1")
2155 (eq_attr "alternative" "7,8,9,10,11")
2156 (const_string "ssemov")
2157 (match_operand:DI 1 "pic_32bit_operand" "")
2158 (const_string "lea")
2160 (const_string "imov")))
2161 (set (attr "prefix")
2162 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2163 (const_string "orig")
2164 (const_string "maybe_vex")))
2165 (set (attr "prefix_data16")
2166 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2168 (const_string "*")))
2170 (cond [(eq_attr "alternative" "2,3")
2172 (eq_attr "alternative" "6,7")
2174 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2175 (const_string "V4SF")
2176 (const_string "TI"))
2177 (and (eq_attr "alternative" "8,9,10,11")
2178 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2181 (const_string "SI")))])
2183 (define_insn "*movhi_internal"
2184 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2185 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2186 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 switch (get_attr_type (insn))
2191 /* movzwl is faster than movw on p2 due to partial word stalls,
2192 though not as fast as an aligned movl. */
2193 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2195 if (get_attr_mode (insn) == MODE_SI)
2196 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2198 return "mov{w}\t{%1, %0|%0, %1}";
2202 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2204 (const_string "imov")
2205 (and (eq_attr "alternative" "0")
2206 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2208 (eq (symbol_ref "TARGET_HIMODE_MATH")
2210 (const_string "imov")
2211 (and (eq_attr "alternative" "1,2")
2212 (match_operand:HI 1 "aligned_operand" ""))
2213 (const_string "imov")
2214 (and (ne (symbol_ref "TARGET_MOVX")
2216 (eq_attr "alternative" "0,2"))
2217 (const_string "imovx")
2219 (const_string "imov")))
2221 (cond [(eq_attr "type" "imovx")
2223 (and (eq_attr "alternative" "1,2")
2224 (match_operand:HI 1 "aligned_operand" ""))
2226 (and (eq_attr "alternative" "0")
2227 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2229 (eq (symbol_ref "TARGET_HIMODE_MATH")
2233 (const_string "HI")))])
2235 ;; Situation is quite tricky about when to choose full sized (SImode) move
2236 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2237 ;; partial register dependency machines (such as AMD Athlon), where QImode
2238 ;; moves issue extra dependency and for partial register stalls machines
2239 ;; that don't use QImode patterns (and QImode move cause stall on the next
2242 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2243 ;; register stall machines with, where we use QImode instructions, since
2244 ;; partial register stall can be caused there. Then we use movzx.
2245 (define_insn "*movqi_internal"
2246 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2247 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2248 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2250 switch (get_attr_type (insn))
2253 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2254 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2256 if (get_attr_mode (insn) == MODE_SI)
2257 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2259 return "mov{b}\t{%1, %0|%0, %1}";
2263 (cond [(and (eq_attr "alternative" "5")
2264 (not (match_operand:QI 1 "aligned_operand" "")))
2265 (const_string "imovx")
2266 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2268 (const_string "imov")
2269 (and (eq_attr "alternative" "3")
2270 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2272 (eq (symbol_ref "TARGET_QIMODE_MATH")
2274 (const_string "imov")
2275 (eq_attr "alternative" "3,5")
2276 (const_string "imovx")
2277 (and (ne (symbol_ref "TARGET_MOVX")
2279 (eq_attr "alternative" "2"))
2280 (const_string "imovx")
2282 (const_string "imov")))
2284 (cond [(eq_attr "alternative" "3,4,5")
2286 (eq_attr "alternative" "6")
2288 (eq_attr "type" "imovx")
2290 (and (eq_attr "type" "imov")
2291 (and (eq_attr "alternative" "0,1")
2292 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2294 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2296 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2299 ;; Avoid partial register stalls when not using QImode arithmetic
2300 (and (eq_attr "type" "imov")
2301 (and (eq_attr "alternative" "0,1")
2302 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2304 (eq (symbol_ref "TARGET_QIMODE_MATH")
2308 (const_string "QI")))])
2310 ;; Stores and loads of ax to arbitrary constant address.
2311 ;; We fake an second form of instruction to force reload to load address
2312 ;; into register when rax is not available
2313 (define_insn "*movabs<mode>_1"
2314 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2315 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2316 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2318 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2319 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2320 [(set_attr "type" "imov")
2321 (set_attr "modrm" "0,*")
2322 (set_attr "length_address" "8,0")
2323 (set_attr "length_immediate" "0,*")
2324 (set_attr "memory" "store")
2325 (set_attr "mode" "<MODE>")])
2327 (define_insn "*movabs<mode>_2"
2328 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2329 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2330 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2332 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2333 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2334 [(set_attr "type" "imov")
2335 (set_attr "modrm" "0,*")
2336 (set_attr "length_address" "8,0")
2337 (set_attr "length_immediate" "0")
2338 (set_attr "memory" "load")
2339 (set_attr "mode" "<MODE>")])
2341 (define_insn "*swap<mode>"
2342 [(set (match_operand:SWI48 0 "register_operand" "+r")
2343 (match_operand:SWI48 1 "register_operand" "+r"))
2347 "xchg{<imodesuffix>}\t%1, %0"
2348 [(set_attr "type" "imov")
2349 (set_attr "mode" "<MODE>")
2350 (set_attr "pent_pair" "np")
2351 (set_attr "athlon_decode" "vector")
2352 (set_attr "amdfam10_decode" "double")])
2354 (define_insn "*swap<mode>_1"
2355 [(set (match_operand:SWI12 0 "register_operand" "+r")
2356 (match_operand:SWI12 1 "register_operand" "+r"))
2359 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2361 [(set_attr "type" "imov")
2362 (set_attr "mode" "SI")
2363 (set_attr "pent_pair" "np")
2364 (set_attr "athlon_decode" "vector")
2365 (set_attr "amdfam10_decode" "double")])
2367 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2368 ;; is disabled for AMDFAM10
2369 (define_insn "*swap<mode>_2"
2370 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2371 (match_operand:SWI12 1 "register_operand" "+<r>"))
2374 "TARGET_PARTIAL_REG_STALL"
2375 "xchg{<imodesuffix>}\t%1, %0"
2376 [(set_attr "type" "imov")
2377 (set_attr "mode" "<MODE>")
2378 (set_attr "pent_pair" "np")
2379 (set_attr "athlon_decode" "vector")])
2381 (define_expand "movstrict<mode>"
2382 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2383 (match_operand:SWI12 1 "general_operand" ""))]
2386 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2388 /* Don't generate memory->memory moves, go through a register */
2389 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2390 operands[1] = force_reg (<MODE>mode, operands[1]);
2393 (define_insn "*movstrict<mode>_1"
2394 [(set (strict_low_part
2395 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2396 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2399 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "<MODE>")])
2403 (define_insn "*movstrict<mode>_xor"
2404 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2405 (match_operand:SWI12 1 "const0_operand" ""))
2406 (clobber (reg:CC FLAGS_REG))]
2408 "xor{<imodesuffix>}\t%0, %0"
2409 [(set_attr "type" "alu1")
2410 (set_attr "mode" "<MODE>")
2411 (set_attr "length_immediate" "0")])
2413 (define_insn "*mov<mode>_extv_1"
2414 [(set (match_operand:SWI24 0 "register_operand" "=R")
2415 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2419 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2420 [(set_attr "type" "imovx")
2421 (set_attr "mode" "SI")])
2423 (define_insn "*movqi_extv_1_rex64"
2424 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2425 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2430 switch (get_attr_type (insn))
2433 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2435 return "mov{b}\t{%h1, %0|%0, %h1}";
2439 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2440 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2441 (ne (symbol_ref "TARGET_MOVX")
2443 (const_string "imovx")
2444 (const_string "imov")))
2446 (if_then_else (eq_attr "type" "imovx")
2448 (const_string "QI")))])
2450 (define_insn "*movqi_extv_1"
2451 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2452 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2457 switch (get_attr_type (insn))
2460 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2462 return "mov{b}\t{%h1, %0|%0, %h1}";
2466 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2467 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2468 (ne (symbol_ref "TARGET_MOVX")
2470 (const_string "imovx")
2471 (const_string "imov")))
2473 (if_then_else (eq_attr "type" "imovx")
2475 (const_string "QI")))])
2477 (define_insn "*mov<mode>_extzv_1"
2478 [(set (match_operand:SWI48 0 "register_operand" "=R")
2479 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2483 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2484 [(set_attr "type" "imovx")
2485 (set_attr "mode" "SI")])
2487 (define_insn "*movqi_extzv_2_rex64"
2488 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2490 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2495 switch (get_attr_type (insn))
2498 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2500 return "mov{b}\t{%h1, %0|%0, %h1}";
2504 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2505 (ne (symbol_ref "TARGET_MOVX")
2507 (const_string "imovx")
2508 (const_string "imov")))
2510 (if_then_else (eq_attr "type" "imovx")
2512 (const_string "QI")))])
2514 (define_insn "*movqi_extzv_2"
2515 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2517 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2522 switch (get_attr_type (insn))
2525 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2527 return "mov{b}\t{%h1, %0|%0, %h1}";
2531 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2532 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2533 (ne (symbol_ref "TARGET_MOVX")
2535 (const_string "imovx")
2536 (const_string "imov")))
2538 (if_then_else (eq_attr "type" "imovx")
2540 (const_string "QI")))])
2542 (define_expand "mov<mode>_insv_1"
2543 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2546 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2548 (define_insn "*mov<mode>_insv_1_rex64"
2549 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2552 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2554 "mov{b}\t{%b1, %h0|%h0, %b1}"
2555 [(set_attr "type" "imov")
2556 (set_attr "mode" "QI")])
2558 (define_insn "*movsi_insv_1"
2559 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2562 (match_operand:SI 1 "general_operand" "Qmn"))]
2564 "mov{b}\t{%b1, %h0|%h0, %b1}"
2565 [(set_attr "type" "imov")
2566 (set_attr "mode" "QI")])
2568 (define_insn "*movqi_insv_2"
2569 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2572 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2575 "mov{b}\t{%h1, %h0|%h0, %h1}"
2576 [(set_attr "type" "imov")
2577 (set_attr "mode" "QI")])
2579 ;; Floating point push instructions.
2581 (define_insn "*pushtf"
2582 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2583 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2586 /* This insn should be already split before reg-stack. */
2589 [(set_attr "type" "multi")
2590 (set_attr "unit" "sse,*,*")
2591 (set_attr "mode" "TF,SI,SI")])
2594 [(set (match_operand:TF 0 "push_operand" "")
2595 (match_operand:TF 1 "sse_reg_operand" ""))]
2596 "TARGET_SSE2 && reload_completed"
2597 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2598 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2601 [(set (match_operand:TF 0 "push_operand" "")
2602 (match_operand:TF 1 "general_operand" ""))]
2603 "TARGET_SSE2 && reload_completed
2604 && !SSE_REG_P (operands[1])"
2606 "ix86_split_long_move (operands); DONE;")
2608 (define_insn "*pushxf"
2609 [(set (match_operand:XF 0 "push_operand" "=<,<")
2610 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2611 "optimize_function_for_speed_p (cfun)"
2613 /* This insn should be already split before reg-stack. */
2616 [(set_attr "type" "multi")
2617 (set_attr "unit" "i387,*")
2618 (set_attr "mode" "XF,SI")])
2620 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2621 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2622 ;; Pushing using integer instructions is longer except for constants
2623 ;; and direct memory references (assuming that any given constant is pushed
2624 ;; only once, but this ought to be handled elsewhere).
2626 (define_insn "*pushxf_nointeger"
2627 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2628 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2629 "optimize_function_for_size_p (cfun)"
2631 /* This insn should be already split before reg-stack. */
2634 [(set_attr "type" "multi")
2635 (set_attr "unit" "i387,*,*")
2636 (set_attr "mode" "XF,SI,SI")])
2639 [(set (match_operand:XF 0 "push_operand" "")
2640 (match_operand:XF 1 "fp_register_operand" ""))]
2642 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2643 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2644 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2647 [(set (match_operand:XF 0 "push_operand" "")
2648 (match_operand:XF 1 "general_operand" ""))]
2650 && !FP_REG_P (operands[1])"
2652 "ix86_split_long_move (operands); DONE;")
2654 (define_insn "*pushdf"
2655 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2656 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2657 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2659 /* This insn should be already split before reg-stack. */
2662 [(set_attr "type" "multi")
2663 (set_attr "unit" "i387,*,*")
2664 (set_attr "mode" "DF,SI,DF")])
2666 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2667 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2668 ;; On the average, pushdf using integers can be still shorter. Allow this
2669 ;; pattern for optimize_size too.
2671 (define_insn "*pushdf_nointeger"
2672 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2673 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2674 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2676 /* This insn should be already split before reg-stack. */
2679 [(set_attr "type" "multi")
2680 (set_attr "unit" "i387,*,*,*")
2681 (set_attr "mode" "DF,SI,SI,DF")])
2683 ;; %%% Kill this when call knows how to work this out.
2685 [(set (match_operand:DF 0 "push_operand" "")
2686 (match_operand:DF 1 "any_fp_register_operand" ""))]
2688 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2689 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2692 [(set (match_operand:DF 0 "push_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2695 && !ANY_FP_REG_P (operands[1])"
2697 "ix86_split_long_move (operands); DONE;")
2699 (define_insn "*pushsf_rex64"
2700 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2701 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2704 /* Anything else should be already split before reg-stack. */
2705 gcc_assert (which_alternative == 1);
2706 return "push{q}\t%q1";
2708 [(set_attr "type" "multi,push,multi")
2709 (set_attr "unit" "i387,*,*")
2710 (set_attr "mode" "SF,DI,SF")])
2712 (define_insn "*pushsf"
2713 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2717 /* Anything else should be already split before reg-stack. */
2718 gcc_assert (which_alternative == 1);
2719 return "push{l}\t%1";
2721 [(set_attr "type" "multi,push,multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "SF,SI,SF")])
2726 [(set (match_operand:SF 0 "push_operand" "")
2727 (match_operand:SF 1 "memory_operand" ""))]
2729 && MEM_P (operands[1])
2730 && (operands[2] = find_constant_src (insn))"
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:SF 0 "push_operand" "")
2737 (match_operand:SF 1 "any_fp_register_operand" ""))]
2739 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2740 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2741 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2743 ;; Floating point move instructions.
2745 (define_expand "movtf"
2746 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2747 (match_operand:TF 1 "nonimmediate_operand" ""))]
2750 ix86_expand_move (TFmode, operands);
2754 (define_expand "mov<mode>"
2755 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2756 (match_operand:X87MODEF 1 "general_operand" ""))]
2758 "ix86_expand_move (<MODE>mode, operands); DONE;")
2760 (define_insn "*movtf_internal"
2761 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2762 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2764 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2766 switch (which_alternative)
2770 if (get_attr_mode (insn) == MODE_V4SF)
2771 return "%vmovaps\t{%1, %0|%0, %1}";
2773 return "%vmovdqa\t{%1, %0|%0, %1}";
2775 if (get_attr_mode (insn) == MODE_V4SF)
2776 return "%vxorps\t%0, %d0";
2778 return "%vpxor\t%0, %d0";
2786 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2787 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2789 (cond [(eq_attr "alternative" "0,2")
2791 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2793 (const_string "V4SF")
2794 (const_string "TI"))
2795 (eq_attr "alternative" "1")
2797 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2799 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2801 (const_string "V4SF")
2802 (const_string "TI"))]
2803 (const_string "DI")))])
2806 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2807 (match_operand:TF 1 "general_operand" ""))]
2809 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2811 "ix86_split_long_move (operands); DONE;")
2813 (define_insn "*movxf_internal"
2814 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2815 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2816 "optimize_function_for_speed_p (cfun)
2817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2818 && (reload_in_progress || reload_completed
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || memory_operand (operands[0], XFmode))"
2822 switch (which_alternative)
2826 return output_387_reg_move (insn, operands);
2829 return standard_80387_constant_opcode (operands[1]);
2838 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839 (set_attr "mode" "XF,XF,XF,SI,SI")])
2841 ;; Do not use integer registers when optimizing for size
2842 (define_insn "*movxf_internal_nointeger"
2843 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2844 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2845 "optimize_function_for_size_p (cfun)
2846 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2847 && (reload_in_progress || reload_completed
2848 || standard_80387_constant_p (operands[1])
2849 || GET_CODE (operands[1]) != CONST_DOUBLE
2850 || memory_operand (operands[0], XFmode))"
2852 switch (which_alternative)
2856 return output_387_reg_move (insn, operands);
2859 return standard_80387_constant_opcode (operands[1]);
2867 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2868 (set_attr "mode" "XF,XF,XF,SI,SI")])
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2872 (match_operand:XF 1 "general_operand" ""))]
2874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2875 && ! (FP_REG_P (operands[0]) ||
2876 (GET_CODE (operands[0]) == SUBREG
2877 && FP_REG_P (SUBREG_REG (operands[0]))))
2878 && ! (FP_REG_P (operands[1]) ||
2879 (GET_CODE (operands[1]) == SUBREG
2880 && FP_REG_P (SUBREG_REG (operands[1]))))"
2882 "ix86_split_long_move (operands); DONE;")
2884 (define_insn "*movdf_internal_rex64"
2885 [(set (match_operand:DF 0 "nonimmediate_operand"
2886 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2887 (match_operand:DF 1 "general_operand"
2888 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2889 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890 && (reload_in_progress || reload_completed
2891 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2892 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2893 && optimize_function_for_size_p (cfun)
2894 && standard_80387_constant_p (operands[1]))
2895 || GET_CODE (operands[1]) != CONST_DOUBLE
2896 || memory_operand (operands[0], DFmode))"
2898 switch (which_alternative)
2902 return output_387_reg_move (insn, operands);
2905 return standard_80387_constant_opcode (operands[1]);
2912 switch (get_attr_mode (insn))
2915 return "%vxorps\t%0, %d0";
2917 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2918 return "%vxorps\t%0, %d0";
2920 return "%vxorpd\t%0, %d0";
2922 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2923 return "%vxorps\t%0, %d0";
2925 return "%vpxor\t%0, %d0";
2932 switch (get_attr_mode (insn))
2935 return "%vmovaps\t{%1, %0|%0, %1}";
2937 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2940 return "%vmovapd\t{%1, %0|%0, %1}";
2942 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2943 return "%vmovaps\t{%1, %0|%0, %1}";
2945 return "%vmovdqa\t{%1, %0|%0, %1}";
2947 return "%vmovq\t{%1, %0|%0, %1}";
2951 if (REG_P (operands[0]) && REG_P (operands[1]))
2952 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2954 return "vmovsd\t{%1, %0|%0, %1}";
2957 return "movsd\t{%1, %0|%0, %1}";
2959 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2961 return "%vmovlps\t{%1, %d0|%d0, %1}";
2968 return "%vmovd\t{%1, %0|%0, %1}";
2974 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2975 (set (attr "prefix")
2976 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2977 (const_string "orig")
2978 (const_string "maybe_vex")))
2979 (set (attr "prefix_data16")
2980 (if_then_else (eq_attr "mode" "V1DF")
2982 (const_string "*")))
2984 (cond [(eq_attr "alternative" "0,1,2")
2986 (eq_attr "alternative" "3,4,9,10")
2989 /* For SSE1, we have many fewer alternatives. */
2990 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2991 (cond [(eq_attr "alternative" "5,6")
2992 (const_string "V4SF")
2994 (const_string "V2SF"))
2996 /* xorps is one byte shorter. */
2997 (eq_attr "alternative" "5")
2998 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3000 (const_string "V4SF")
3001 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3005 (const_string "V2DF"))
3007 /* For architectures resolving dependencies on
3008 whole SSE registers use APD move to break dependency
3009 chains, otherwise use short move to avoid extra work.
3011 movaps encodes one byte shorter. */
3012 (eq_attr "alternative" "6")
3014 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3016 (const_string "V4SF")
3017 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019 (const_string "V2DF")
3021 (const_string "DF"))
3022 /* For architectures resolving dependencies on register
3023 parts we may avoid extra work to zero out upper part
3025 (eq_attr "alternative" "7")
3027 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3029 (const_string "V1DF")
3030 (const_string "DF"))
3032 (const_string "DF")))])
3034 (define_insn "*movdf_internal"
3035 [(set (match_operand:DF 0 "nonimmediate_operand"
3036 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3037 (match_operand:DF 1 "general_operand"
3038 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3039 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && optimize_function_for_speed_p (cfun)
3041 && TARGET_INTEGER_DFMODE_MOVES
3042 && (reload_in_progress || reload_completed
3043 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3044 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && optimize_function_for_size_p (cfun)
3046 && standard_80387_constant_p (operands[1]))
3047 || GET_CODE (operands[1]) != CONST_DOUBLE
3048 || memory_operand (operands[0], DFmode))"
3050 switch (which_alternative)
3054 return output_387_reg_move (insn, operands);
3057 return standard_80387_constant_opcode (operands[1]);
3064 switch (get_attr_mode (insn))
3067 return "xorps\t%0, %0";
3069 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3070 return "xorps\t%0, %0";
3072 return "xorpd\t%0, %0";
3074 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3075 return "xorps\t%0, %0";
3077 return "pxor\t%0, %0";
3084 switch (get_attr_mode (insn))
3087 return "movaps\t{%1, %0|%0, %1}";
3089 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3090 return "movaps\t{%1, %0|%0, %1}";
3092 return "movapd\t{%1, %0|%0, %1}";
3094 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3095 return "movaps\t{%1, %0|%0, %1}";
3097 return "movdqa\t{%1, %0|%0, %1}";
3099 return "movq\t{%1, %0|%0, %1}";
3101 return "movsd\t{%1, %0|%0, %1}";
3103 return "movlpd\t{%1, %0|%0, %1}";
3105 return "movlps\t{%1, %0|%0, %1}";
3114 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3115 (set (attr "prefix_data16")
3116 (if_then_else (eq_attr "mode" "V1DF")
3118 (const_string "*")))
3120 (cond [(eq_attr "alternative" "0,1,2")
3122 (eq_attr "alternative" "3,4")
3125 /* For SSE1, we have many fewer alternatives. */
3126 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3127 (cond [(eq_attr "alternative" "5,6")
3128 (const_string "V4SF")
3130 (const_string "V2SF"))
3132 /* xorps is one byte shorter. */
3133 (eq_attr "alternative" "5")
3134 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3136 (const_string "V4SF")
3137 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3141 (const_string "V2DF"))
3143 /* For architectures resolving dependencies on
3144 whole SSE registers use APD move to break dependency
3145 chains, otherwise use short move to avoid extra work.
3147 movaps encodes one byte shorter. */
3148 (eq_attr "alternative" "6")
3150 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3155 (const_string "V2DF")
3157 (const_string "DF"))
3158 /* For architectures resolving dependencies on register
3159 parts we may avoid extra work to zero out upper part
3161 (eq_attr "alternative" "7")
3163 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3165 (const_string "V1DF")
3166 (const_string "DF"))
3168 (const_string "DF")))])
3170 ;; Moving is usually shorter when only FP registers are used. This separate
3171 ;; movdf pattern avoids the use of integer registers for FP operations
3172 ;; when optimizing for size.
3174 (define_insn "*movdf_internal_nointeger"
3175 [(set (match_operand:DF 0 "nonimmediate_operand"
3176 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3177 (match_operand:DF 1 "general_operand"
3178 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3179 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3180 && ((optimize_function_for_size_p (cfun)
3181 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3182 && (reload_in_progress || reload_completed
3183 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185 && optimize_function_for_size_p (cfun)
3186 && !memory_operand (operands[0], DFmode)
3187 && standard_80387_constant_p (operands[1]))
3188 || GET_CODE (operands[1]) != CONST_DOUBLE
3189 || ((optimize_function_for_size_p (cfun)
3190 || !TARGET_MEMORY_MISMATCH_STALL
3191 || reload_in_progress || reload_completed)
3192 && memory_operand (operands[0], DFmode)))"
3194 switch (which_alternative)
3198 return output_387_reg_move (insn, operands);
3201 return standard_80387_constant_opcode (operands[1]);
3208 switch (get_attr_mode (insn))
3211 return "%vxorps\t%0, %d0";
3213 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3214 return "%vxorps\t%0, %d0";
3216 return "%vxorpd\t%0, %d0";
3218 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3219 return "%vxorps\t%0, %d0";
3221 return "%vpxor\t%0, %d0";
3228 switch (get_attr_mode (insn))
3231 return "%vmovaps\t{%1, %0|%0, %1}";
3233 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3234 return "%vmovaps\t{%1, %0|%0, %1}";
3236 return "%vmovapd\t{%1, %0|%0, %1}";
3238 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3239 return "%vmovaps\t{%1, %0|%0, %1}";
3241 return "%vmovdqa\t{%1, %0|%0, %1}";
3243 return "%vmovq\t{%1, %0|%0, %1}";
3247 if (REG_P (operands[0]) && REG_P (operands[1]))
3248 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3250 return "vmovsd\t{%1, %0|%0, %1}";
3253 return "movsd\t{%1, %0|%0, %1}";
3257 if (REG_P (operands[0]))
3258 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3260 return "vmovlpd\t{%1, %0|%0, %1}";
3263 return "movlpd\t{%1, %0|%0, %1}";
3267 if (REG_P (operands[0]))
3268 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3270 return "vmovlps\t{%1, %0|%0, %1}";
3273 return "movlps\t{%1, %0|%0, %1}";
3282 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3283 (set (attr "prefix")
3284 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3285 (const_string "orig")
3286 (const_string "maybe_vex")))
3287 (set (attr "prefix_data16")
3288 (if_then_else (eq_attr "mode" "V1DF")
3290 (const_string "*")))
3292 (cond [(eq_attr "alternative" "0,1,2")
3294 (eq_attr "alternative" "3,4")
3297 /* For SSE1, we have many fewer alternatives. */
3298 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3299 (cond [(eq_attr "alternative" "5,6")
3300 (const_string "V4SF")
3302 (const_string "V2SF"))
3304 /* xorps is one byte shorter. */
3305 (eq_attr "alternative" "5")
3306 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3308 (const_string "V4SF")
3309 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3313 (const_string "V2DF"))
3315 /* For architectures resolving dependencies on
3316 whole SSE registers use APD move to break dependency
3317 chains, otherwise use short move to avoid extra work.
3319 movaps encodes one byte shorter. */
3320 (eq_attr "alternative" "6")
3322 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3324 (const_string "V4SF")
3325 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3327 (const_string "V2DF")
3329 (const_string "DF"))
3330 /* For architectures resolving dependencies on register
3331 parts we may avoid extra work to zero out upper part
3333 (eq_attr "alternative" "7")
3335 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3337 (const_string "V1DF")
3338 (const_string "DF"))
3340 (const_string "DF")))])
3343 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3344 (match_operand:DF 1 "general_operand" ""))]
3346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3347 && ! (ANY_FP_REG_P (operands[0]) ||
3348 (GET_CODE (operands[0]) == SUBREG
3349 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3350 && ! (ANY_FP_REG_P (operands[1]) ||
3351 (GET_CODE (operands[1]) == SUBREG
3352 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3354 "ix86_split_long_move (operands); DONE;")
3356 (define_insn "*movsf_internal"
3357 [(set (match_operand:SF 0 "nonimmediate_operand"
3358 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3359 (match_operand:SF 1 "general_operand"
3360 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3361 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3362 && (reload_in_progress || reload_completed
3363 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3364 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3365 && standard_80387_constant_p (operands[1]))
3366 || GET_CODE (operands[1]) != CONST_DOUBLE
3367 || memory_operand (operands[0], SFmode))"
3369 switch (which_alternative)
3373 return output_387_reg_move (insn, operands);
3376 return standard_80387_constant_opcode (operands[1]);
3380 return "mov{l}\t{%1, %0|%0, %1}";
3382 if (get_attr_mode (insn) == MODE_TI)
3383 return "%vpxor\t%0, %d0";
3385 return "%vxorps\t%0, %d0";
3387 if (get_attr_mode (insn) == MODE_V4SF)
3388 return "%vmovaps\t{%1, %0|%0, %1}";
3390 return "%vmovss\t{%1, %d0|%d0, %1}";
3393 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3394 : "vmovss\t{%1, %0|%0, %1}";
3396 return "movss\t{%1, %0|%0, %1}";
3398 return "%vmovss\t{%1, %0|%0, %1}";
3400 case 9: case 10: case 14: case 15:
3401 return "movd\t{%1, %0|%0, %1}";
3403 return "%vmovd\t{%1, %0|%0, %1}";
3406 return "movq\t{%1, %0|%0, %1}";
3412 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3413 (set (attr "prefix")
3414 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3415 (const_string "maybe_vex")
3416 (const_string "orig")))
3418 (cond [(eq_attr "alternative" "3,4,9,10")
3420 (eq_attr "alternative" "5")
3422 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3424 (ne (symbol_ref "TARGET_SSE2")
3426 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3429 (const_string "V4SF"))
3430 /* For architectures resolving dependencies on
3431 whole SSE registers use APS move to break dependency
3432 chains, otherwise use short move to avoid extra work.
3434 Do the same for architectures resolving dependencies on
3435 the parts. While in DF mode it is better to always handle
3436 just register parts, the SF mode is different due to lack
3437 of instructions to load just part of the register. It is
3438 better to maintain the whole registers in single format
3439 to avoid problems on using packed logical operations. */
3440 (eq_attr "alternative" "6")
3442 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3444 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3446 (const_string "V4SF")
3447 (const_string "SF"))
3448 (eq_attr "alternative" "11")
3449 (const_string "DI")]
3450 (const_string "SF")))])
3453 [(set (match_operand 0 "register_operand" "")
3454 (match_operand 1 "memory_operand" ""))]
3456 && MEM_P (operands[1])
3457 && (GET_MODE (operands[0]) == TFmode
3458 || GET_MODE (operands[0]) == XFmode
3459 || GET_MODE (operands[0]) == DFmode
3460 || GET_MODE (operands[0]) == SFmode)
3461 && (operands[2] = find_constant_src (insn))"
3462 [(set (match_dup 0) (match_dup 2))]
3464 rtx c = operands[2];
3465 rtx r = operands[0];
3467 if (GET_CODE (r) == SUBREG)
3472 if (!standard_sse_constant_p (c))
3475 else if (FP_REG_P (r))
3477 if (!standard_80387_constant_p (c))
3480 else if (MMX_REG_P (r))
3485 [(set (match_operand 0 "register_operand" "")
3486 (float_extend (match_operand 1 "memory_operand" "")))]
3488 && MEM_P (operands[1])
3489 && (GET_MODE (operands[0]) == TFmode
3490 || GET_MODE (operands[0]) == XFmode
3491 || GET_MODE (operands[0]) == DFmode
3492 || GET_MODE (operands[0]) == SFmode)
3493 && (operands[2] = find_constant_src (insn))"
3494 [(set (match_dup 0) (match_dup 2))]
3496 rtx c = operands[2];
3497 rtx r = operands[0];
3499 if (GET_CODE (r) == SUBREG)
3504 if (!standard_sse_constant_p (c))
3507 else if (FP_REG_P (r))
3509 if (!standard_80387_constant_p (c))
3512 else if (MMX_REG_P (r))
3516 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3518 [(set (match_operand:X87MODEF 0 "register_operand" "")
3519 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3520 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3521 && (standard_80387_constant_p (operands[1]) == 8
3522 || standard_80387_constant_p (operands[1]) == 9)"
3523 [(set (match_dup 0)(match_dup 1))
3525 (neg:X87MODEF (match_dup 0)))]
3529 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3530 if (real_isnegzero (&r))
3531 operands[1] = CONST0_RTX (<MODE>mode);
3533 operands[1] = CONST1_RTX (<MODE>mode);
3536 (define_insn "swapxf"
3537 [(set (match_operand:XF 0 "register_operand" "+f")
3538 (match_operand:XF 1 "register_operand" "+f"))
3543 if (STACK_TOP_P (operands[0]))
3548 [(set_attr "type" "fxch")
3549 (set_attr "mode" "XF")])
3551 (define_insn "*swap<mode>"
3552 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3553 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3556 "TARGET_80387 || reload_completed"
3558 if (STACK_TOP_P (operands[0]))
3563 [(set_attr "type" "fxch")
3564 (set_attr "mode" "<MODE>")])
3566 ;; Zero extension instructions
3568 (define_expand "zero_extendsidi2"
3569 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3570 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3575 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3580 (define_insn "*zero_extendsidi2_rex64"
3581 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3583 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3586 mov\t{%k1, %k0|%k0, %k1}
3588 movd\t{%1, %0|%0, %1}
3589 movd\t{%1, %0|%0, %1}
3590 %vmovd\t{%1, %0|%0, %1}
3591 %vmovd\t{%1, %0|%0, %1}"
3592 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3593 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3594 (set_attr "prefix_0f" "0,*,*,*,*,*")
3595 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3598 [(set (match_operand:DI 0 "memory_operand" "")
3599 (zero_extend:DI (match_dup 0)))]
3601 [(set (match_dup 4) (const_int 0))]
3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3604 ;; %%% Kill me once multi-word ops are sane.
3605 (define_insn "zero_extendsidi2_1"
3606 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3608 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3609 (clobber (reg:CC FLAGS_REG))]
3615 movd\t{%1, %0|%0, %1}
3616 movd\t{%1, %0|%0, %1}
3617 %vmovd\t{%1, %0|%0, %1}
3618 %vmovd\t{%1, %0|%0, %1}"
3619 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3620 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3621 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3626 (clobber (reg:CC FLAGS_REG))]
3627 "!TARGET_64BIT && reload_completed
3628 && true_regnum (operands[0]) == true_regnum (operands[1])"
3629 [(set (match_dup 4) (const_int 0))]
3630 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3634 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3635 (clobber (reg:CC FLAGS_REG))]
3636 "!TARGET_64BIT && reload_completed
3637 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3638 [(set (match_dup 3) (match_dup 1))
3639 (set (match_dup 4) (const_int 0))]
3640 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3642 (define_insn "zero_extend<mode>di2"
3643 [(set (match_operand:DI 0 "register_operand" "=r")
3645 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3647 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3648 [(set_attr "type" "imovx")
3649 (set_attr "mode" "SI")])
3651 (define_expand "zero_extendhisi2"
3652 [(set (match_operand:SI 0 "register_operand" "")
3653 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3656 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3658 operands[1] = force_reg (HImode, operands[1]);
3659 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3664 (define_insn_and_split "zero_extendhisi2_and"
3665 [(set (match_operand:SI 0 "register_operand" "=r")
3666 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3667 (clobber (reg:CC FLAGS_REG))]
3668 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3670 "&& reload_completed"
3671 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3672 (clobber (reg:CC FLAGS_REG))])]
3674 [(set_attr "type" "alu1")
3675 (set_attr "mode" "SI")])
3677 (define_insn "*zero_extendhisi2_movzwl"
3678 [(set (match_operand:SI 0 "register_operand" "=r")
3679 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3680 "!TARGET_ZERO_EXTEND_WITH_AND
3681 || optimize_function_for_size_p (cfun)"
3682 "movz{wl|x}\t{%1, %0|%0, %1}"
3683 [(set_attr "type" "imovx")
3684 (set_attr "mode" "SI")])
3686 (define_expand "zero_extendqi<mode>2"
3688 [(set (match_operand:SWI24 0 "register_operand" "")
3689 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3690 (clobber (reg:CC FLAGS_REG))])])
3692 (define_insn "*zero_extendqi<mode>2_and"
3693 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3694 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3695 (clobber (reg:CC FLAGS_REG))]
3696 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3698 [(set_attr "type" "alu1")
3699 (set_attr "mode" "<MODE>")])
3701 ;; When source and destination does not overlap, clear destination
3702 ;; first and then do the movb
3704 [(set (match_operand:SWI24 0 "register_operand" "")
3705 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3706 (clobber (reg:CC FLAGS_REG))]
3708 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3709 && ANY_QI_REG_P (operands[0])
3710 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3711 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3712 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3714 operands[2] = gen_lowpart (QImode, operands[0]);
3715 ix86_expand_clear (operands[0]);
3718 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3719 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3720 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3721 (clobber (reg:CC FLAGS_REG))]
3722 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3724 [(set_attr "type" "imovx,alu1")
3725 (set_attr "mode" "<MODE>")])
3727 ;; For the movzbl case strip only the clobber
3729 [(set (match_operand:SWI24 0 "register_operand" "")
3730 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3731 (clobber (reg:CC FLAGS_REG))]
3733 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3734 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3736 (zero_extend:SWI24 (match_dup 1)))])
3738 ; zero extend to SImode to avoid partial register stalls
3739 (define_insn "*zero_extendqi<mode>2_movzbl"
3740 [(set (match_operand:SWI24 0 "register_operand" "=r")
3741 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3743 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3744 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3745 [(set_attr "type" "imovx")
3746 (set_attr "mode" "SI")])
3748 ;; Rest is handled by single and.
3750 [(set (match_operand:SWI24 0 "register_operand" "")
3751 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3752 (clobber (reg:CC FLAGS_REG))]
3754 && true_regnum (operands[0]) == true_regnum (operands[1])"
3755 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3756 (clobber (reg:CC FLAGS_REG))])])
3758 ;; Sign extension instructions
3760 (define_expand "extendsidi2"
3761 [(set (match_operand:DI 0 "register_operand" "")
3762 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3767 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3772 (define_insn "*extendsidi2_rex64"
3773 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3774 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3778 movs{lq|x}\t{%1, %0|%0, %1}"
3779 [(set_attr "type" "imovx")
3780 (set_attr "mode" "DI")
3781 (set_attr "prefix_0f" "0")
3782 (set_attr "modrm" "0,1")])
3784 (define_insn "extendsidi2_1"
3785 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3786 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3787 (clobber (reg:CC FLAGS_REG))
3788 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3792 ;; Extend to memory case when source register does die.
3794 [(set (match_operand:DI 0 "memory_operand" "")
3795 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3796 (clobber (reg:CC FLAGS_REG))
3797 (clobber (match_operand:SI 2 "register_operand" ""))]
3799 && dead_or_set_p (insn, operands[1])
3800 && !reg_mentioned_p (operands[1], operands[0]))"
3801 [(set (match_dup 3) (match_dup 1))
3802 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3803 (clobber (reg:CC FLAGS_REG))])
3804 (set (match_dup 4) (match_dup 1))]
3805 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3807 ;; Extend to memory case when source register does not die.
3809 [(set (match_operand:DI 0 "memory_operand" "")
3810 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3811 (clobber (reg:CC FLAGS_REG))
3812 (clobber (match_operand:SI 2 "register_operand" ""))]
3816 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3818 emit_move_insn (operands[3], operands[1]);
3820 /* Generate a cltd if possible and doing so it profitable. */
3821 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3822 && true_regnum (operands[1]) == AX_REG
3823 && true_regnum (operands[2]) == DX_REG)
3825 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3829 emit_move_insn (operands[2], operands[1]);
3830 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3832 emit_move_insn (operands[4], operands[2]);
3836 ;; Extend to register case. Optimize case where source and destination
3837 ;; registers match and cases where we can use cltd.
3839 [(set (match_operand:DI 0 "register_operand" "")
3840 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3841 (clobber (reg:CC FLAGS_REG))
3842 (clobber (match_scratch:SI 2 ""))]
3846 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3848 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3849 emit_move_insn (operands[3], operands[1]);
3851 /* Generate a cltd if possible and doing so it profitable. */
3852 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3853 && true_regnum (operands[3]) == AX_REG
3854 && true_regnum (operands[4]) == DX_REG)
3856 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3860 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3861 emit_move_insn (operands[4], operands[1]);
3863 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3867 (define_insn "extend<mode>di2"
3868 [(set (match_operand:DI 0 "register_operand" "=r")
3870 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3872 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3873 [(set_attr "type" "imovx")
3874 (set_attr "mode" "DI")])
3876 (define_insn "extendhisi2"
3877 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3878 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3881 switch (get_attr_prefix_0f (insn))
3884 return "{cwtl|cwde}";
3886 return "movs{wl|x}\t{%1, %0|%0, %1}";
3889 [(set_attr "type" "imovx")
3890 (set_attr "mode" "SI")
3891 (set (attr "prefix_0f")
3892 ;; movsx is short decodable while cwtl is vector decoded.
3893 (if_then_else (and (eq_attr "cpu" "!k6")
3894 (eq_attr "alternative" "0"))
3896 (const_string "1")))
3898 (if_then_else (eq_attr "prefix_0f" "0")
3900 (const_string "1")))])
3902 (define_insn "*extendhisi2_zext"
3903 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3906 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3909 switch (get_attr_prefix_0f (insn))
3912 return "{cwtl|cwde}";
3914 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3917 [(set_attr "type" "imovx")
3918 (set_attr "mode" "SI")
3919 (set (attr "prefix_0f")
3920 ;; movsx is short decodable while cwtl is vector decoded.
3921 (if_then_else (and (eq_attr "cpu" "!k6")
3922 (eq_attr "alternative" "0"))
3924 (const_string "1")))
3926 (if_then_else (eq_attr "prefix_0f" "0")
3928 (const_string "1")))])
3930 (define_insn "extendqisi2"
3931 [(set (match_operand:SI 0 "register_operand" "=r")
3932 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3934 "movs{bl|x}\t{%1, %0|%0, %1}"
3935 [(set_attr "type" "imovx")
3936 (set_attr "mode" "SI")])
3938 (define_insn "*extendqisi2_zext"
3939 [(set (match_operand:DI 0 "register_operand" "=r")
3941 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3943 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3944 [(set_attr "type" "imovx")
3945 (set_attr "mode" "SI")])
3947 (define_insn "extendqihi2"
3948 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3949 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3952 switch (get_attr_prefix_0f (insn))
3955 return "{cbtw|cbw}";
3957 return "movs{bw|x}\t{%1, %0|%0, %1}";
3960 [(set_attr "type" "imovx")
3961 (set_attr "mode" "HI")
3962 (set (attr "prefix_0f")
3963 ;; movsx is short decodable while cwtl is vector decoded.
3964 (if_then_else (and (eq_attr "cpu" "!k6")
3965 (eq_attr "alternative" "0"))
3967 (const_string "1")))
3969 (if_then_else (eq_attr "prefix_0f" "0")
3971 (const_string "1")))])
3973 ;; Conversions between float and double.
3975 ;; These are all no-ops in the model used for the 80387.
3976 ;; So just emit moves.
3978 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3980 [(set (match_operand:DF 0 "push_operand" "")
3981 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3983 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3984 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3987 [(set (match_operand:XF 0 "push_operand" "")
3988 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3990 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3991 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3992 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3994 (define_expand "extendsfdf2"
3995 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3996 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3997 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3999 /* ??? Needed for compress_float_constant since all fp constants
4000 are LEGITIMATE_CONSTANT_P. */
4001 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4003 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4004 && standard_80387_constant_p (operands[1]) > 0)
4006 operands[1] = simplify_const_unary_operation
4007 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4008 emit_move_insn_1 (operands[0], operands[1]);
4011 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4015 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4017 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4019 We do the conversion post reload to avoid producing of 128bit spills
4020 that might lead to ICE on 32bit target. The sequence unlikely combine
4023 [(set (match_operand:DF 0 "register_operand" "")
4025 (match_operand:SF 1 "nonimmediate_operand" "")))]
4026 "TARGET_USE_VECTOR_FP_CONVERTS
4027 && optimize_insn_for_speed_p ()
4028 && reload_completed && SSE_REG_P (operands[0])"
4033 (parallel [(const_int 0) (const_int 1)]))))]
4035 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4036 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4037 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4038 Try to avoid move when unpacking can be done in source. */
4039 if (REG_P (operands[1]))
4041 /* If it is unsafe to overwrite upper half of source, we need
4042 to move to destination and unpack there. */
4043 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4044 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4045 && true_regnum (operands[0]) != true_regnum (operands[1]))
4047 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4048 emit_move_insn (tmp, operands[1]);
4051 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4052 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4056 emit_insn (gen_vec_setv4sf_0 (operands[3],
4057 CONST0_RTX (V4SFmode), operands[1]));
4060 (define_insn "*extendsfdf2_mixed"
4061 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4063 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4064 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4066 switch (which_alternative)
4070 return output_387_reg_move (insn, operands);
4073 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4079 [(set_attr "type" "fmov,fmov,ssecvt")
4080 (set_attr "prefix" "orig,orig,maybe_vex")
4081 (set_attr "mode" "SF,XF,DF")])
4083 (define_insn "*extendsfdf2_sse"
4084 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4085 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4086 "TARGET_SSE2 && TARGET_SSE_MATH"
4087 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4088 [(set_attr "type" "ssecvt")
4089 (set_attr "prefix" "maybe_vex")
4090 (set_attr "mode" "DF")])
4092 (define_insn "*extendsfdf2_i387"
4093 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4094 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4096 "* return output_387_reg_move (insn, operands);"
4097 [(set_attr "type" "fmov")
4098 (set_attr "mode" "SF,XF")])
4100 (define_expand "extend<mode>xf2"
4101 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4102 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4105 /* ??? Needed for compress_float_constant since all fp constants
4106 are LEGITIMATE_CONSTANT_P. */
4107 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4109 if (standard_80387_constant_p (operands[1]) > 0)
4111 operands[1] = simplify_const_unary_operation
4112 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4113 emit_move_insn_1 (operands[0], operands[1]);
4116 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4120 (define_insn "*extend<mode>xf2_i387"
4121 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4123 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4125 "* return output_387_reg_move (insn, operands);"
4126 [(set_attr "type" "fmov")
4127 (set_attr "mode" "<MODE>,XF")])
4129 ;; %%% This seems bad bad news.
4130 ;; This cannot output into an f-reg because there is no way to be sure
4131 ;; of truncating in that case. Otherwise this is just like a simple move
4132 ;; insn. So we pretend we can output to a reg in order to get better
4133 ;; register preferencing, but we really use a stack slot.
4135 ;; Conversion from DFmode to SFmode.
4137 (define_expand "truncdfsf2"
4138 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4140 (match_operand:DF 1 "nonimmediate_operand" "")))]
4141 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4143 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4145 else if (flag_unsafe_math_optimizations)
4149 enum ix86_stack_slot slot = (virtuals_instantiated
4152 rtx temp = assign_386_stack_local (SFmode, slot);
4153 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4158 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4160 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4162 We do the conversion post reload to avoid producing of 128bit spills
4163 that might lead to ICE on 32bit target. The sequence unlikely combine
4166 [(set (match_operand:SF 0 "register_operand" "")
4168 (match_operand:DF 1 "nonimmediate_operand" "")))]
4169 "TARGET_USE_VECTOR_FP_CONVERTS
4170 && optimize_insn_for_speed_p ()
4171 && reload_completed && SSE_REG_P (operands[0])"
4174 (float_truncate:V2SF
4178 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4179 operands[3] = CONST0_RTX (V2SFmode);
4180 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4181 /* Use movsd for loading from memory, unpcklpd for registers.
4182 Try to avoid move when unpacking can be done in source, or SSE3
4183 movddup is available. */
4184 if (REG_P (operands[1]))
4187 && true_regnum (operands[0]) != true_regnum (operands[1])
4188 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4189 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4191 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4192 emit_move_insn (tmp, operands[1]);
4195 else if (!TARGET_SSE3)
4196 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4197 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4200 emit_insn (gen_sse2_loadlpd (operands[4],
4201 CONST0_RTX (V2DFmode), operands[1]));
4204 (define_expand "truncdfsf2_with_temp"
4205 [(parallel [(set (match_operand:SF 0 "" "")
4206 (float_truncate:SF (match_operand:DF 1 "" "")))
4207 (clobber (match_operand:SF 2 "" ""))])])
4209 (define_insn "*truncdfsf_fast_mixed"
4210 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4212 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4213 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4215 switch (which_alternative)
4218 return output_387_reg_move (insn, operands);
4220 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4225 [(set_attr "type" "fmov,ssecvt")
4226 (set_attr "prefix" "orig,maybe_vex")
4227 (set_attr "mode" "SF")])
4229 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4230 ;; because nothing we do here is unsafe.
4231 (define_insn "*truncdfsf_fast_sse"
4232 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4234 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4235 "TARGET_SSE2 && TARGET_SSE_MATH"
4236 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4237 [(set_attr "type" "ssecvt")
4238 (set_attr "prefix" "maybe_vex")
4239 (set_attr "mode" "SF")])
4241 (define_insn "*truncdfsf_fast_i387"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4244 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4245 "TARGET_80387 && flag_unsafe_math_optimizations"
4246 "* return output_387_reg_move (insn, operands);"
4247 [(set_attr "type" "fmov")
4248 (set_attr "mode" "SF")])
4250 (define_insn "*truncdfsf_mixed"
4251 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4253 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4254 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4255 "TARGET_MIX_SSE_I387"
4257 switch (which_alternative)
4260 return output_387_reg_move (insn, operands);
4262 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4268 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4269 (set_attr "unit" "*,*,i387,i387,i387")
4270 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4271 (set_attr "mode" "SF")])
4273 (define_insn "*truncdfsf_i387"
4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4276 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4277 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4280 switch (which_alternative)
4283 return output_387_reg_move (insn, operands);
4289 [(set_attr "type" "fmov,multi,multi,multi")
4290 (set_attr "unit" "*,i387,i387,i387")
4291 (set_attr "mode" "SF")])
4293 (define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4296 (match_operand:DF 1 "register_operand" "f")))]
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
4305 [(set (match_operand:SF 0 "register_operand" "")
4307 (match_operand:DF 1 "fp_register_operand" "")))
4308 (clobber (match_operand 2 "" ""))]
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
4312 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4314 ;; Conversion from XFmode to {SF,DF}mode
4316 (define_expand "truncxf<mode>2"
4317 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4318 (float_truncate:MODEF
4319 (match_operand:XF 1 "register_operand" "")))
4320 (clobber (match_dup 2))])]
4323 if (flag_unsafe_math_optimizations)
4325 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4326 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4327 if (reg != operands[0])
4328 emit_move_insn (operands[0], reg);
4333 enum ix86_stack_slot slot = (virtuals_instantiated
4336 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4343 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi,multi,multi")
4351 (set_attr "unit" "*,i387,i387,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4357 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "type" "fmov,multi,multi,multi")
4365 (set_attr "unit" "*,i387,i387,i387")
4366 (set_attr "mode" "DF")])
4368 (define_insn "truncxf<mode>2_i387_noop"
4369 [(set (match_operand:MODEF 0 "register_operand" "=f")
4370 (float_truncate:MODEF
4371 (match_operand:XF 1 "register_operand" "f")))]
4372 "TARGET_80387 && flag_unsafe_math_optimizations"
4373 "* return output_387_reg_move (insn, operands);"
4374 [(set_attr "type" "fmov")
4375 (set_attr "mode" "<MODE>")])
4377 (define_insn "*truncxf<mode>2_i387"
4378 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379 (float_truncate:MODEF
4380 (match_operand:XF 1 "register_operand" "f")))]
4382 "* return output_387_reg_move (insn, operands);"
4383 [(set_attr "type" "fmov")
4384 (set_attr "mode" "<MODE>")])
4387 [(set (match_operand:MODEF 0 "register_operand" "")
4388 (float_truncate:MODEF
4389 (match_operand:XF 1 "register_operand" "")))
4390 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391 "TARGET_80387 && reload_completed"
4392 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393 (set (match_dup 0) (match_dup 2))])
4396 [(set (match_operand:MODEF 0 "memory_operand" "")
4397 (float_truncate:MODEF
4398 (match_operand:XF 1 "register_operand" "")))
4399 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4401 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4403 ;; Signed conversion to DImode.
4405 (define_expand "fix_truncxfdi2"
4406 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4407 (fix:DI (match_operand:XF 1 "register_operand" "")))
4408 (clobber (reg:CC FLAGS_REG))])]
4413 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4418 (define_expand "fix_trunc<mode>di2"
4419 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4420 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4421 (clobber (reg:CC FLAGS_REG))])]
4422 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4425 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4427 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4430 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4432 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4433 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4434 if (out != operands[0])
4435 emit_move_insn (operands[0], out);
4440 ;; Signed conversion to SImode.
4442 (define_expand "fix_truncxfsi2"
4443 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4444 (fix:SI (match_operand:XF 1 "register_operand" "")))
4445 (clobber (reg:CC FLAGS_REG))])]
4450 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4455 (define_expand "fix_trunc<mode>si2"
4456 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4457 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4458 (clobber (reg:CC FLAGS_REG))])]
4459 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4462 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4464 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4467 if (SSE_FLOAT_MODE_P (<MODE>mode))
4469 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4470 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4471 if (out != operands[0])
4472 emit_move_insn (operands[0], out);
4477 ;; Signed conversion to HImode.
4479 (define_expand "fix_trunc<mode>hi2"
4480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4481 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4482 (clobber (reg:CC FLAGS_REG))])]
4484 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4488 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4493 ;; Unsigned conversion to SImode.
4495 (define_expand "fixuns_trunc<mode>si2"
4497 [(set (match_operand:SI 0 "register_operand" "")
4499 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4501 (clobber (match_scratch:<ssevecmode> 3 ""))
4502 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4503 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4505 enum machine_mode mode = <MODE>mode;
4506 enum machine_mode vecmode = <ssevecmode>mode;
4507 REAL_VALUE_TYPE TWO31r;
4510 if (optimize_insn_for_size_p ())
4513 real_ldexp (&TWO31r, &dconst1, 31);
4514 two31 = const_double_from_real_value (TWO31r, mode);
4515 two31 = ix86_build_const_vector (mode, true, two31);
4516 operands[2] = force_reg (vecmode, two31);
4519 (define_insn_and_split "*fixuns_trunc<mode>_1"
4520 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4522 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4523 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4524 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4525 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4526 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4527 && optimize_function_for_speed_p (cfun)"
4529 "&& reload_completed"
4532 ix86_split_convert_uns_si_sse (operands);
4536 ;; Unsigned conversion to HImode.
4537 ;; Without these patterns, we'll try the unsigned SI conversion which
4538 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4540 (define_expand "fixuns_trunc<mode>hi2"
4542 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4543 (set (match_operand:HI 0 "nonimmediate_operand" "")
4544 (subreg:HI (match_dup 2) 0))]
4545 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4546 "operands[2] = gen_reg_rtx (SImode);")
4548 ;; When SSE is available, it is always faster to use it!
4549 (define_insn "fix_trunc<mode>di_sse"
4550 [(set (match_operand:DI 0 "register_operand" "=r,r")
4551 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4552 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4553 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4554 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4555 [(set_attr "type" "sseicvt")
4556 (set_attr "prefix" "maybe_vex")
4557 (set_attr "prefix_rex" "1")
4558 (set_attr "mode" "<MODE>")
4559 (set_attr "athlon_decode" "double,vector")
4560 (set_attr "amdfam10_decode" "double,double")])
4562 (define_insn "fix_trunc<mode>si_sse"
4563 [(set (match_operand:SI 0 "register_operand" "=r,r")
4564 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565 "SSE_FLOAT_MODE_P (<MODE>mode)
4566 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "sseicvt")
4569 (set_attr "prefix" "maybe_vex")
4570 (set_attr "mode" "<MODE>")
4571 (set_attr "athlon_decode" "double,vector")
4572 (set_attr "amdfam10_decode" "double,double")])
4574 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4576 [(set (match_operand:MODEF 0 "register_operand" "")
4577 (match_operand:MODEF 1 "memory_operand" ""))
4578 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4579 (fix:SSEMODEI24 (match_dup 0)))]
4580 "TARGET_SHORTEN_X87_SSE
4581 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4582 && peep2_reg_dead_p (2, operands[0])"
4583 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4585 ;; Avoid vector decoded forms of the instruction.
4587 [(match_scratch:DF 2 "Y2")
4588 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4589 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4590 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4591 [(set (match_dup 2) (match_dup 1))
4592 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4595 [(match_scratch:SF 2 "x")
4596 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4597 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4598 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4599 [(set (match_dup 2) (match_dup 1))
4600 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4602 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4603 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4604 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4605 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4607 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && (TARGET_64BIT || <MODE>mode != DImode))
4610 && can_create_pseudo_p ()"
4615 if (memory_operand (operands[0], VOIDmode))
4616 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4619 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4620 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4626 [(set_attr "type" "fisttp")
4627 (set_attr "mode" "<MODE>")])
4629 (define_insn "fix_trunc<mode>_i387_fisttp"
4630 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4631 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4632 (clobber (match_scratch:XF 2 "=&1f"))]
4633 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4635 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4636 && (TARGET_64BIT || <MODE>mode != DImode))
4637 && TARGET_SSE_MATH)"
4638 "* return output_fix_trunc (insn, operands, 1);"
4639 [(set_attr "type" "fisttp")
4640 (set_attr "mode" "<MODE>")])
4642 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4643 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4644 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4645 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4646 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4647 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4649 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && (TARGET_64BIT || <MODE>mode != DImode))
4651 && TARGET_SSE_MATH)"
4653 [(set_attr "type" "fisttp")
4654 (set_attr "mode" "<MODE>")])
4657 [(set (match_operand:X87MODEI 0 "register_operand" "")
4658 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4660 (clobber (match_scratch 3 ""))]
4662 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4663 (clobber (match_dup 3))])
4664 (set (match_dup 0) (match_dup 2))])
4667 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4668 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4669 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4670 (clobber (match_scratch 3 ""))]
4672 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4673 (clobber (match_dup 3))])])
4675 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4676 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4677 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4678 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4679 ;; function in i386.c.
4680 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4681 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4682 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4683 (clobber (reg:CC FLAGS_REG))]
4684 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4687 && (TARGET_64BIT || <MODE>mode != DImode))
4688 && can_create_pseudo_p ()"
4693 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4695 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4696 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4697 if (memory_operand (operands[0], VOIDmode))
4698 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4699 operands[2], operands[3]));
4702 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4703 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4704 operands[2], operands[3],
4709 [(set_attr "type" "fistp")
4710 (set_attr "i387_cw" "trunc")
4711 (set_attr "mode" "<MODE>")])
4713 (define_insn "fix_truncdi_i387"
4714 [(set (match_operand:DI 0 "memory_operand" "=m")
4715 (fix:DI (match_operand 1 "register_operand" "f")))
4716 (use (match_operand:HI 2 "memory_operand" "m"))
4717 (use (match_operand:HI 3 "memory_operand" "m"))
4718 (clobber (match_scratch:XF 4 "=&1f"))]
4719 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4721 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4722 "* return output_fix_trunc (insn, operands, 0);"
4723 [(set_attr "type" "fistp")
4724 (set_attr "i387_cw" "trunc")
4725 (set_attr "mode" "DI")])
4727 (define_insn "fix_truncdi_i387_with_temp"
4728 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4729 (fix:DI (match_operand 1 "register_operand" "f,f")))
4730 (use (match_operand:HI 2 "memory_operand" "m,m"))
4731 (use (match_operand:HI 3 "memory_operand" "m,m"))
4732 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4733 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4736 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4738 [(set_attr "type" "fistp")
4739 (set_attr "i387_cw" "trunc")
4740 (set_attr "mode" "DI")])
4743 [(set (match_operand:DI 0 "register_operand" "")
4744 (fix:DI (match_operand 1 "register_operand" "")))
4745 (use (match_operand:HI 2 "memory_operand" ""))
4746 (use (match_operand:HI 3 "memory_operand" ""))
4747 (clobber (match_operand:DI 4 "memory_operand" ""))
4748 (clobber (match_scratch 5 ""))]
4750 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4753 (clobber (match_dup 5))])
4754 (set (match_dup 0) (match_dup 4))])
4757 [(set (match_operand:DI 0 "memory_operand" "")
4758 (fix:DI (match_operand 1 "register_operand" "")))
4759 (use (match_operand:HI 2 "memory_operand" ""))
4760 (use (match_operand:HI 3 "memory_operand" ""))
4761 (clobber (match_operand:DI 4 "memory_operand" ""))
4762 (clobber (match_scratch 5 ""))]
4764 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4767 (clobber (match_dup 5))])])
4769 (define_insn "fix_trunc<mode>_i387"
4770 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4771 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4772 (use (match_operand:HI 2 "memory_operand" "m"))
4773 (use (match_operand:HI 3 "memory_operand" "m"))]
4774 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4776 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4777 "* return output_fix_trunc (insn, operands, 0);"
4778 [(set_attr "type" "fistp")
4779 (set_attr "i387_cw" "trunc")
4780 (set_attr "mode" "<MODE>")])
4782 (define_insn "fix_trunc<mode>_i387_with_temp"
4783 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4784 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4785 (use (match_operand:HI 2 "memory_operand" "m,m"))
4786 (use (match_operand:HI 3 "memory_operand" "m,m"))
4787 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4788 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4790 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4792 [(set_attr "type" "fistp")
4793 (set_attr "i387_cw" "trunc")
4794 (set_attr "mode" "<MODE>")])
4797 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4798 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4799 (use (match_operand:HI 2 "memory_operand" ""))
4800 (use (match_operand:HI 3 "memory_operand" ""))
4801 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4803 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4805 (use (match_dup 3))])
4806 (set (match_dup 0) (match_dup 4))])
4809 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4810 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4811 (use (match_operand:HI 2 "memory_operand" ""))
4812 (use (match_operand:HI 3 "memory_operand" ""))
4813 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4815 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4817 (use (match_dup 3))])])
4819 (define_insn "x86_fnstcw_1"
4820 [(set (match_operand:HI 0 "memory_operand" "=m")
4821 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4824 [(set (attr "length")
4825 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4826 (set_attr "mode" "HI")
4827 (set_attr "unit" "i387")])
4829 (define_insn "x86_fldcw_1"
4830 [(set (reg:HI FPCR_REG)
4831 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4834 [(set (attr "length")
4835 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4836 (set_attr "mode" "HI")
4837 (set_attr "unit" "i387")
4838 (set_attr "athlon_decode" "vector")
4839 (set_attr "amdfam10_decode" "vector")])
4841 ;; Conversion between fixed point and floating point.
4843 ;; Even though we only accept memory inputs, the backend _really_
4844 ;; wants to be able to do this between registers.
4846 (define_expand "floathi<mode>2"
4847 [(set (match_operand:X87MODEF 0 "register_operand" "")
4848 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4851 || TARGET_MIX_SSE_I387)")
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*floathi<mode>2_1"
4855 [(set (match_operand:X87MODEF 0 "register_operand" "")
4856 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859 || TARGET_MIX_SSE_I387)
4860 && can_create_pseudo_p ()"
4863 [(parallel [(set (match_dup 0)
4864 (float:X87MODEF (match_dup 1)))
4865 (clobber (match_dup 2))])]
4866 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4868 (define_insn "*floathi<mode>2_i387_with_temp"
4869 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4870 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4871 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4874 || TARGET_MIX_SSE_I387)"
4876 [(set_attr "type" "fmov,multi")
4877 (set_attr "mode" "<MODE>")
4878 (set_attr "unit" "*,i387")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*floathi<mode>2_i387"
4882 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4883 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886 || TARGET_MIX_SSE_I387)"
4888 [(set_attr "type" "fmov")
4889 (set_attr "mode" "<MODE>")
4890 (set_attr "fp_int_src" "true")])
4893 [(set (match_operand:X87MODEF 0 "register_operand" "")
4894 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4895 (clobber (match_operand:HI 2 "memory_operand" ""))]
4897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4898 || TARGET_MIX_SSE_I387)
4899 && reload_completed"
4900 [(set (match_dup 2) (match_dup 1))
4901 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4904 [(set (match_operand:X87MODEF 0 "register_operand" "")
4905 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4906 (clobber (match_operand:HI 2 "memory_operand" ""))]
4908 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4909 || TARGET_MIX_SSE_I387)
4910 && reload_completed"
4911 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4913 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4914 [(set (match_operand:X87MODEF 0 "register_operand" "")
4916 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4918 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4921 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4922 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4923 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4925 rtx reg = gen_reg_rtx (XFmode);
4928 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4930 if (<X87MODEF:MODE>mode == SFmode)
4931 insn = gen_truncxfsf2 (operands[0], reg);
4932 else if (<X87MODEF:MODE>mode == DFmode)
4933 insn = gen_truncxfdf2 (operands[0], reg);
4942 ;; Pre-reload splitter to add memory clobber to the pattern.
4943 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4944 [(set (match_operand:X87MODEF 0 "register_operand" "")
4945 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4947 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4948 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950 || TARGET_MIX_SSE_I387))
4951 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4952 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4953 && ((<SSEMODEI24:MODE>mode == SImode
4954 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4955 && optimize_function_for_speed_p (cfun)
4956 && flag_trapping_math)
4957 || !(TARGET_INTER_UNIT_CONVERSIONS
4958 || optimize_function_for_size_p (cfun)))))
4959 && can_create_pseudo_p ()"
4962 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4963 (clobber (match_dup 2))])]
4965 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4967 /* Avoid store forwarding (partial memory) stall penalty
4968 by passing DImode value through XMM registers. */
4969 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4970 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4971 && optimize_function_for_speed_p (cfun))
4973 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4980 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4981 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4983 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4984 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4985 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4986 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4988 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4989 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4990 (set_attr "unit" "*,i387,*,*,*")
4991 (set_attr "athlon_decode" "*,*,double,direct,double")
4992 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4993 (set_attr "fp_int_src" "true")])
4995 (define_insn "*floatsi<mode>2_vector_mixed"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4997 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4998 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5003 [(set_attr "type" "fmov,sseicvt")
5004 (set_attr "mode" "<MODE>,<ssevecmode>")
5005 (set_attr "unit" "i387,*")
5006 (set_attr "athlon_decode" "*,direct")
5007 (set_attr "amdfam10_decode" "*,double")
5008 (set_attr "fp_int_src" "true")])
5010 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5011 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5013 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5014 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5015 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5018 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "unit" "*,i387,*,*")
5021 (set_attr "athlon_decode" "*,*,double,direct")
5022 (set_attr "amdfam10_decode" "*,*,vector,double")
5023 (set_attr "fp_int_src" "true")])
5026 [(set (match_operand:MODEF 0 "register_operand" "")
5027 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5028 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5029 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5030 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5031 && TARGET_INTER_UNIT_CONVERSIONS
5033 && (SSE_REG_P (operands[0])
5034 || (GET_CODE (operands[0]) == SUBREG
5035 && SSE_REG_P (operands[0])))"
5036 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5039 [(set (match_operand:MODEF 0 "register_operand" "")
5040 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5041 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5042 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5046 && (SSE_REG_P (operands[0])
5047 || (GET_CODE (operands[0]) == SUBREG
5048 && SSE_REG_P (operands[0])))"
5049 [(set (match_dup 2) (match_dup 1))
5050 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5052 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5053 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5055 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5056 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5057 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5058 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5061 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5062 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5063 [(set_attr "type" "fmov,sseicvt,sseicvt")
5064 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5065 (set_attr "mode" "<MODEF:MODE>")
5066 (set (attr "prefix_rex")
5068 (and (eq_attr "prefix" "maybe_vex")
5069 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5071 (const_string "*")))
5072 (set_attr "unit" "i387,*,*")
5073 (set_attr "athlon_decode" "*,double,direct")
5074 (set_attr "amdfam10_decode" "*,vector,double")
5075 (set_attr "fp_int_src" "true")])
5077 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5078 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5080 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5081 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5083 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5086 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5087 [(set_attr "type" "fmov,sseicvt")
5088 (set_attr "prefix" "orig,maybe_vex")
5089 (set_attr "mode" "<MODEF:MODE>")
5090 (set (attr "prefix_rex")
5092 (and (eq_attr "prefix" "maybe_vex")
5093 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5095 (const_string "*")))
5096 (set_attr "athlon_decode" "*,direct")
5097 (set_attr "amdfam10_decode" "*,double")
5098 (set_attr "fp_int_src" "true")])
5100 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5101 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5103 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5104 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5105 "TARGET_SSE2 && TARGET_SSE_MATH
5106 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5108 [(set_attr "type" "sseicvt")
5109 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5110 (set_attr "athlon_decode" "double,direct,double")
5111 (set_attr "amdfam10_decode" "vector,double,double")
5112 (set_attr "fp_int_src" "true")])
5114 (define_insn "*floatsi<mode>2_vector_sse"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5120 [(set_attr "type" "sseicvt")
5121 (set_attr "mode" "<MODE>")
5122 (set_attr "athlon_decode" "direct")
5123 (set_attr "amdfam10_decode" "double")
5124 (set_attr "fp_int_src" "true")])
5127 [(set (match_operand:MODEF 0 "register_operand" "")
5128 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5129 (clobber (match_operand:SI 2 "memory_operand" ""))]
5130 "TARGET_SSE2 && TARGET_SSE_MATH
5131 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5133 && (SSE_REG_P (operands[0])
5134 || (GET_CODE (operands[0]) == SUBREG
5135 && SSE_REG_P (operands[0])))"
5138 rtx op1 = operands[1];
5140 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5142 if (GET_CODE (op1) == SUBREG)
5143 op1 = SUBREG_REG (op1);
5145 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
5151 /* We can ignore possible trapping value in the
5152 high part of SSE register for non-trapping math. */
5153 else if (SSE_REG_P (op1) && !flag_trapping_math)
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5157 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5158 emit_move_insn (operands[2], operands[1]);
5159 emit_insn (gen_sse2_loadld (operands[4],
5160 CONST0_RTX (V4SImode), operands[2]));
5163 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5168 [(set (match_operand:MODEF 0 "register_operand" "")
5169 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5170 (clobber (match_operand:SI 2 "memory_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH
5172 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5174 && (SSE_REG_P (operands[0])
5175 || (GET_CODE (operands[0]) == SUBREG
5176 && SSE_REG_P (operands[0])))"
5179 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5183 emit_insn (gen_sse2_loadld (operands[4],
5184 CONST0_RTX (V4SImode), operands[1]));
5186 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5191 [(set (match_operand:MODEF 0 "register_operand" "")
5192 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5193 "TARGET_SSE2 && TARGET_SSE_MATH
5194 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5196 && (SSE_REG_P (operands[0])
5197 || (GET_CODE (operands[0]) == SUBREG
5198 && SSE_REG_P (operands[0])))"
5201 rtx op1 = operands[1];
5203 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5205 if (GET_CODE (op1) == SUBREG)
5206 op1 = SUBREG_REG (op1);
5208 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5210 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5211 emit_insn (gen_sse2_loadld (operands[4],
5212 CONST0_RTX (V4SImode), operands[1]));
5214 /* We can ignore possible trapping value in the
5215 high part of SSE register for non-trapping math. */
5216 else if (SSE_REG_P (op1) && !flag_trapping_math)
5217 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5221 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5226 [(set (match_operand:MODEF 0 "register_operand" "")
5227 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5228 "TARGET_SSE2 && TARGET_SSE_MATH
5229 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (operands[0])))"
5236 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5238 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5240 emit_insn (gen_sse2_loadld (operands[4],
5241 CONST0_RTX (V4SImode), operands[1]));
5243 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5247 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5248 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5250 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5251 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5252 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5255 [(set_attr "type" "sseicvt")
5256 (set_attr "mode" "<MODEF:MODE>")
5257 (set_attr "athlon_decode" "double,direct")
5258 (set_attr "amdfam10_decode" "vector,double")
5259 (set_attr "fp_int_src" "true")])
5261 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5262 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5264 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5265 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5267 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5268 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5269 [(set_attr "type" "sseicvt")
5270 (set_attr "prefix" "maybe_vex")
5271 (set_attr "mode" "<MODEF:MODE>")
5272 (set (attr "prefix_rex")
5274 (and (eq_attr "prefix" "maybe_vex")
5275 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5277 (const_string "*")))
5278 (set_attr "athlon_decode" "double,direct")
5279 (set_attr "amdfam10_decode" "vector,double")
5280 (set_attr "fp_int_src" "true")])
5283 [(set (match_operand:MODEF 0 "register_operand" "")
5284 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5285 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5286 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5288 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5290 && (SSE_REG_P (operands[0])
5291 || (GET_CODE (operands[0]) == SUBREG
5292 && SSE_REG_P (operands[0])))"
5293 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5296 [(set (match_operand:MODEF 0 "register_operand" "=x")
5298 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5299 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303 [(set_attr "type" "sseicvt")
5304 (set_attr "prefix" "maybe_vex")
5305 (set_attr "mode" "<MODEF:MODE>")
5306 (set (attr "prefix_rex")
5308 (and (eq_attr "prefix" "maybe_vex")
5309 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5311 (const_string "*")))
5312 (set_attr "athlon_decode" "direct")
5313 (set_attr "amdfam10_decode" "double")
5314 (set_attr "fp_int_src" "true")])
5317 [(set (match_operand:MODEF 0 "register_operand" "")
5318 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5319 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5320 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5322 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5324 && (SSE_REG_P (operands[0])
5325 || (GET_CODE (operands[0]) == SUBREG
5326 && SSE_REG_P (operands[0])))"
5327 [(set (match_dup 2) (match_dup 1))
5328 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5331 [(set (match_operand:MODEF 0 "register_operand" "")
5332 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5333 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5337 && (SSE_REG_P (operands[0])
5338 || (GET_CODE (operands[0]) == SUBREG
5339 && SSE_REG_P (operands[0])))"
5340 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5342 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5345 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5346 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5348 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5352 [(set_attr "type" "fmov,multi")
5353 (set_attr "mode" "<X87MODEF:MODE>")
5354 (set_attr "unit" "*,i387")
5355 (set_attr "fp_int_src" "true")])
5357 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5358 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5360 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5362 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5364 [(set_attr "type" "fmov")
5365 (set_attr "mode" "<X87MODEF:MODE>")
5366 (set_attr "fp_int_src" "true")])
5369 [(set (match_operand:X87MODEF 0 "register_operand" "")
5370 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5371 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5373 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5375 && FP_REG_P (operands[0])"
5376 [(set (match_dup 2) (match_dup 1))
5377 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5380 [(set (match_operand:X87MODEF 0 "register_operand" "")
5381 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5382 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5384 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5386 && FP_REG_P (operands[0])"
5387 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5389 ;; Avoid store forwarding (partial memory) stall penalty
5390 ;; by passing DImode value through XMM registers. */
5392 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5393 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5395 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5396 (clobber (match_scratch:V4SI 3 "=X,x"))
5397 (clobber (match_scratch:V4SI 4 "=X,x"))
5398 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5399 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5401 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5403 [(set_attr "type" "multi")
5404 (set_attr "mode" "<X87MODEF:MODE>")
5405 (set_attr "unit" "i387")
5406 (set_attr "fp_int_src" "true")])
5409 [(set (match_operand:X87MODEF 0 "register_operand" "")
5410 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5411 (clobber (match_scratch:V4SI 3 ""))
5412 (clobber (match_scratch:V4SI 4 ""))
5413 (clobber (match_operand:DI 2 "memory_operand" ""))]
5414 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5418 && FP_REG_P (operands[0])"
5419 [(set (match_dup 2) (match_dup 3))
5420 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5422 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5423 Assemble the 64-bit DImode value in an xmm register. */
5424 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5425 gen_rtx_SUBREG (SImode, operands[1], 0)));
5426 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5427 gen_rtx_SUBREG (SImode, operands[1], 4)));
5428 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5431 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5435 [(set (match_operand:X87MODEF 0 "register_operand" "")
5436 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5437 (clobber (match_scratch:V4SI 3 ""))
5438 (clobber (match_scratch:V4SI 4 ""))
5439 (clobber (match_operand:DI 2 "memory_operand" ""))]
5440 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5441 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5442 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5444 && FP_REG_P (operands[0])"
5445 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5447 ;; Avoid store forwarding (partial memory) stall penalty by extending
5448 ;; SImode value to DImode through XMM register instead of pushing two
5449 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5450 ;; targets benefit from this optimization. Also note that fild
5451 ;; loads from memory only.
5453 (define_insn "*floatunssi<mode>2_1"
5454 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5455 (unsigned_float:X87MODEF
5456 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5457 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5458 (clobber (match_scratch:SI 3 "=X,x"))]
5460 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5463 [(set_attr "type" "multi")
5464 (set_attr "mode" "<MODE>")])
5467 [(set (match_operand:X87MODEF 0 "register_operand" "")
5468 (unsigned_float:X87MODEF
5469 (match_operand:SI 1 "register_operand" "")))
5470 (clobber (match_operand:DI 2 "memory_operand" ""))
5471 (clobber (match_scratch:SI 3 ""))]
5473 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5475 && reload_completed"
5476 [(set (match_dup 2) (match_dup 1))
5478 (float:X87MODEF (match_dup 2)))]
5479 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (unsigned_float:X87MODEF
5484 (match_operand:SI 1 "memory_operand" "")))
5485 (clobber (match_operand:DI 2 "memory_operand" ""))
5486 (clobber (match_scratch:SI 3 ""))]
5488 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5490 && reload_completed"
5491 [(set (match_dup 2) (match_dup 3))
5493 (float:X87MODEF (match_dup 2)))]
5495 emit_move_insn (operands[3], operands[1]);
5496 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5499 (define_expand "floatunssi<mode>2"
5501 [(set (match_operand:X87MODEF 0 "register_operand" "")
5502 (unsigned_float:X87MODEF
5503 (match_operand:SI 1 "nonimmediate_operand" "")))
5504 (clobber (match_dup 2))
5505 (clobber (match_scratch:SI 3 ""))])]
5507 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5509 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5511 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5513 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5518 enum ix86_stack_slot slot = (virtuals_instantiated
5521 operands[2] = assign_386_stack_local (DImode, slot);
5525 (define_expand "floatunsdisf2"
5526 [(use (match_operand:SF 0 "register_operand" ""))
5527 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5528 "TARGET_64BIT && TARGET_SSE_MATH"
5529 "x86_emit_floatuns (operands); DONE;")
5531 (define_expand "floatunsdidf2"
5532 [(use (match_operand:DF 0 "register_operand" ""))
5533 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5534 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5535 && TARGET_SSE2 && TARGET_SSE_MATH"
5538 x86_emit_floatuns (operands);
5540 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5546 (define_expand "add<mode>3"
5547 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5548 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5549 (match_operand:SDWIM 2 "<general_operand>" "")))]
5551 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5553 (define_insn_and_split "*add<dwi>3_doubleword"
5554 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5556 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5557 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5558 (clobber (reg:CC FLAGS_REG))]
5559 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5562 [(parallel [(set (reg:CC FLAGS_REG)
5563 (unspec:CC [(match_dup 1) (match_dup 2)]
5566 (plus:DWIH (match_dup 1) (match_dup 2)))])
5567 (parallel [(set (match_dup 3)
5571 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5573 (clobber (reg:CC FLAGS_REG))])]
5574 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5576 (define_insn "*add<mode>3_cc"
5577 [(set (reg:CC FLAGS_REG)
5579 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5580 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5582 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5583 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5586 [(set_attr "type" "alu")
5587 (set_attr "mode" "<MODE>")])
5589 (define_insn "addqi3_cc"
5590 [(set (reg:CC FLAGS_REG)
5592 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5593 (match_operand:QI 2 "general_operand" "qn,qm")]
5595 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5596 (plus:QI (match_dup 1) (match_dup 2)))]
5597 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5598 "add{b}\t{%2, %0|%0, %2}"
5599 [(set_attr "type" "alu")
5600 (set_attr "mode" "QI")])
5602 (define_insn "*lea_1"
5603 [(set (match_operand:P 0 "register_operand" "=r")
5604 (match_operand:P 1 "no_seg_address_operand" "p"))]
5606 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5607 [(set_attr "type" "lea")
5608 (set_attr "mode" "<MODE>")])
5610 (define_insn "*lea_2"
5611 [(set (match_operand:SI 0 "register_operand" "=r")
5612 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5614 "lea{l}\t{%a1, %0|%0, %a1}"
5615 [(set_attr "type" "lea")
5616 (set_attr "mode" "SI")])
5618 (define_insn "*lea_2_zext"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5621 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5623 "lea{l}\t{%a1, %k0|%k0, %a1}"
5624 [(set_attr "type" "lea")
5625 (set_attr "mode" "SI")])
5627 (define_insn "*add<mode>_1"
5628 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5630 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5631 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5632 (clobber (reg:CC FLAGS_REG))]
5633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5635 switch (get_attr_type (insn))
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return "inc{<imodesuffix>}\t%0";
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return "dec{<imodesuffix>}\t%0";
5651 /* For most processors, ADD is faster than LEA. This alternative
5652 was added to use ADD as much as possible. */
5653 if (which_alternative == 2)
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5661 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5663 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5667 (cond [(eq_attr "alternative" "3")
5668 (const_string "lea")
5669 (match_operand:SWI48 2 "incdec_operand" "")
5670 (const_string "incdec")
5672 (const_string "alu")))
5673 (set (attr "length_immediate")
5675 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5677 (const_string "*")))
5678 (set_attr "mode" "<MODE>")])
5680 ;; It may seem that nonimmediate operand is proper one for operand 1.
5681 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5682 ;; we take care in ix86_binary_operator_ok to not allow two memory
5683 ;; operands so proper swapping will be done in reload. This allow
5684 ;; patterns constructed from addsi_1 to match.
5686 (define_insn "*addsi_1_zext"
5687 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5689 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5690 (match_operand:SI 2 "general_operand" "g,0,li"))))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5694 switch (get_attr_type (insn))
5700 if (operands[2] == const1_rtx)
5701 return "inc{l}\t%k0";
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{l}\t%k0";
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 1)
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5717 if (x86_maybe_negate_const_int (&operands[2], SImode))
5718 return "sub{l}\t{%2, %k0|%k0, %2}";
5720 return "add{l}\t{%2, %k0|%k0, %2}";
5724 (cond [(eq_attr "alternative" "2")
5725 (const_string "lea")
5726 (match_operand:SI 2 "incdec_operand" "")
5727 (const_string "incdec")
5729 (const_string "alu")))
5730 (set (attr "length_immediate")
5732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5734 (const_string "*")))
5735 (set_attr "mode" "SI")])
5737 (define_insn "*addhi_1"
5738 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5739 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5740 (match_operand:HI 2 "general_operand" "rn,rm")))
5741 (clobber (reg:CC FLAGS_REG))]
5742 "TARGET_PARTIAL_REG_STALL
5743 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5745 switch (get_attr_type (insn))
5748 if (operands[2] == const1_rtx)
5749 return "inc{w}\t%0";
5752 gcc_assert (operands[2] == constm1_rtx);
5753 return "dec{w}\t%0";
5757 if (x86_maybe_negate_const_int (&operands[2], HImode))
5758 return "sub{w}\t{%2, %0|%0, %2}";
5760 return "add{w}\t{%2, %0|%0, %2}";
5764 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set (attr "length_immediate")
5769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5771 (const_string "*")))
5772 (set_attr "mode" "HI")])
5774 (define_insn "*addhi_1_lea"
5775 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5776 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5777 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "!TARGET_PARTIAL_REG_STALL
5780 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 switch (get_attr_type (insn))
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 if (operands[2] == const1_rtx)
5790 return "inc{w}\t%0";
5793 gcc_assert (operands[2] == constm1_rtx);
5794 return "dec{w}\t%0";
5798 /* For most processors, ADD is faster than LEA. This alternative
5799 was added to use ADD as much as possible. */
5800 if (which_alternative == 2)
5803 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5806 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5807 if (x86_maybe_negate_const_int (&operands[2], HImode))
5808 return "sub{w}\t{%2, %0|%0, %2}";
5810 return "add{w}\t{%2, %0|%0, %2}";
5814 (cond [(eq_attr "alternative" "3")
5815 (const_string "lea")
5816 (match_operand:HI 2 "incdec_operand" "")
5817 (const_string "incdec")
5819 (const_string "alu")))
5820 (set (attr "length_immediate")
5822 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5824 (const_string "*")))
5825 (set_attr "mode" "HI,HI,HI,SI")])
5827 ;; %%% Potential partial reg stall on alternative 2. What to do?
5828 (define_insn "*addqi_1"
5829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5830 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5831 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "TARGET_PARTIAL_REG_STALL
5834 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5836 int widen = (which_alternative == 2);
5837 switch (get_attr_type (insn))
5840 if (operands[2] == const1_rtx)
5841 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5844 gcc_assert (operands[2] == constm1_rtx);
5845 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5849 if (x86_maybe_negate_const_int (&operands[2], QImode))
5852 return "sub{l}\t{%2, %k0|%k0, %2}";
5854 return "sub{b}\t{%2, %0|%0, %2}";
5857 return "add{l}\t{%k2, %k0|%k0, %k2}";
5859 return "add{b}\t{%2, %0|%0, %2}";
5863 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu")))
5866 (set (attr "length_immediate")
5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5870 (const_string "*")))
5871 (set_attr "mode" "QI,QI,SI")])
5873 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5874 (define_insn "*addqi_1_lea"
5875 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5876 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5877 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "!TARGET_PARTIAL_REG_STALL
5880 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5882 int widen = (which_alternative == 3 || which_alternative == 4);
5884 switch (get_attr_type (insn))
5890 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5891 if (operands[2] == const1_rtx)
5892 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5895 gcc_assert (operands[2] == constm1_rtx);
5896 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5900 /* For most processors, ADD is faster than LEA. These alternatives
5901 were added to use ADD as much as possible. */
5902 if (which_alternative == 2 || which_alternative == 4)
5905 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (x86_maybe_negate_const_int (&operands[2], QImode))
5912 return "sub{l}\t{%2, %k0|%k0, %2}";
5914 return "sub{b}\t{%2, %0|%0, %2}";
5917 return "add{l}\t{%k2, %k0|%k0, %k2}";
5919 return "add{b}\t{%2, %0|%0, %2}";
5923 (cond [(eq_attr "alternative" "5")
5924 (const_string "lea")
5925 (match_operand:QI 2 "incdec_operand" "")
5926 (const_string "incdec")
5928 (const_string "alu")))
5929 (set (attr "length_immediate")
5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5933 (const_string "*")))
5934 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5936 (define_insn "*addqi_1_slp"
5937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5938 (plus:QI (match_dup 0)
5939 (match_operand:QI 1 "general_operand" "qn,qnm")))
5940 (clobber (reg:CC FLAGS_REG))]
5941 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5944 switch (get_attr_type (insn))
5947 if (operands[1] == const1_rtx)
5948 return "inc{b}\t%0";
5951 gcc_assert (operands[1] == constm1_rtx);
5952 return "dec{b}\t%0";
5956 if (x86_maybe_negate_const_int (&operands[1], QImode))
5957 return "sub{b}\t{%1, %0|%0, %1}";
5959 return "add{b}\t{%1, %0|%0, %1}";
5963 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5964 (const_string "incdec")
5965 (const_string "alu1")))
5966 (set (attr "memory")
5967 (if_then_else (match_operand 1 "memory_operand" "")
5968 (const_string "load")
5969 (const_string "none")))
5970 (set_attr "mode" "QI")])
5972 ;; Convert lea to the lea pattern to avoid flags dependency.
5974 [(set (match_operand 0 "register_operand" "")
5975 (plus (match_operand 1 "register_operand" "")
5976 (match_operand 2 "nonmemory_operand" "")))
5977 (clobber (reg:CC FLAGS_REG))]
5978 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5982 enum machine_mode mode = GET_MODE (operands[0]);
5984 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5985 may confuse gen_lowpart. */
5988 operands[1] = gen_lowpart (Pmode, operands[1]);
5989 operands[2] = gen_lowpart (Pmode, operands[2]);
5992 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5994 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5995 operands[0] = gen_lowpart (SImode, operands[0]);
5997 if (TARGET_64BIT && mode != Pmode)
5998 pat = gen_rtx_SUBREG (SImode, pat, 0);
6000 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6004 ;; Convert lea to the lea pattern to avoid flags dependency.
6005 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6006 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6008 [(set (match_operand:DI 0 "register_operand" "")
6009 (plus:DI (match_operand:DI 1 "register_operand" "")
6010 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6011 (clobber (reg:CC FLAGS_REG))]
6012 "TARGET_64BIT && reload_completed
6013 && true_regnum (operands[0]) != true_regnum (operands[1])"
6015 (plus:DI (match_dup 1) (match_dup 2)))])
6017 ;; Convert lea to the lea pattern to avoid flags dependency.
6019 [(set (match_operand:DI 0 "register_operand" "")
6021 (plus:SI (match_operand:SI 1 "register_operand" "")
6022 (match_operand:SI 2 "nonmemory_operand" ""))))
6023 (clobber (reg:CC FLAGS_REG))]
6024 "TARGET_64BIT && reload_completed
6025 && ix86_lea_for_add_ok (insn, operands)"
6027 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6029 operands[1] = gen_lowpart (DImode, operands[1]);
6030 operands[2] = gen_lowpart (DImode, operands[2]);
6033 (define_insn "*add<mode>_2"
6034 [(set (reg FLAGS_REG)
6037 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6038 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6040 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6041 (plus:SWI (match_dup 1) (match_dup 2)))]
6042 "ix86_match_ccmode (insn, CCGOCmode)
6043 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6045 switch (get_attr_type (insn))
6048 if (operands[2] == const1_rtx)
6049 return "inc{<imodesuffix>}\t%0";
6052 gcc_assert (operands[2] == constm1_rtx);
6053 return "dec{<imodesuffix>}\t%0";
6057 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6058 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6060 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6064 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6065 (const_string "incdec")
6066 (const_string "alu")))
6067 (set (attr "length_immediate")
6069 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6071 (const_string "*")))
6072 (set_attr "mode" "<MODE>")])
6074 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6075 (define_insn "*addsi_2_zext"
6076 [(set (reg FLAGS_REG)
6078 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6079 (match_operand:SI 2 "general_operand" "g"))
6081 (set (match_operand:DI 0 "register_operand" "=r")
6082 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6083 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6084 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6086 switch (get_attr_type (insn))
6089 if (operands[2] == const1_rtx)
6090 return "inc{l}\t%k0";
6093 gcc_assert (operands[2] == constm1_rtx);
6094 return "dec{l}\t%k0";
6098 if (x86_maybe_negate_const_int (&operands[2], SImode))
6099 return "sub{l}\t{%2, %k0|%k0, %2}";
6101 return "add{l}\t{%2, %k0|%k0, %2}";
6105 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6112 (const_string "*")))
6113 (set_attr "mode" "SI")])
6115 (define_insn "*add<mode>_3"
6116 [(set (reg FLAGS_REG)
6118 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6119 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6120 (clobber (match_scratch:SWI 0 "=<r>"))]
6121 "ix86_match_ccmode (insn, CCZmode)
6122 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6124 switch (get_attr_type (insn))
6127 if (operands[2] == const1_rtx)
6128 return "inc{<imodesuffix>}\t%0";
6131 gcc_assert (operands[2] == constm1_rtx);
6132 return "dec{<imodesuffix>}\t%0";
6136 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6137 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6139 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6143 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set (attr "length_immediate")
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6150 (const_string "*")))
6151 (set_attr "mode" "<MODE>")])
6153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6154 (define_insn "*addsi_3_zext"
6155 [(set (reg FLAGS_REG)
6157 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6158 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6159 (set (match_operand:DI 0 "register_operand" "=r")
6160 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6161 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6162 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6164 switch (get_attr_type (insn))
6167 if (operands[2] == const1_rtx)
6168 return "inc{l}\t%k0";
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{l}\t%k0";
6176 if (x86_maybe_negate_const_int (&operands[2], SImode))
6177 return "sub{l}\t{%2, %k0|%k0, %2}";
6179 return "add{l}\t{%2, %k0|%k0, %2}";
6183 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184 (const_string "incdec")
6185 (const_string "alu")))
6186 (set (attr "length_immediate")
6188 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6190 (const_string "*")))
6191 (set_attr "mode" "SI")])
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6195 ; is matched then. We can't accept general immediate, because for
6196 ; case of overflows, the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6200 (define_insn "*adddi_4"
6201 [(set (reg FLAGS_REG)
6203 (match_operand:DI 1 "nonimmediate_operand" "0")
6204 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6205 (clobber (match_scratch:DI 0 "=rm"))]
6207 && ix86_match_ccmode (insn, CCGCmode)"
6209 switch (get_attr_type (insn))
6212 if (operands[2] == constm1_rtx)
6213 return "inc{q}\t%0";
6216 gcc_assert (operands[2] == const1_rtx);
6217 return "dec{q}\t%0";
6221 if (x86_maybe_negate_const_int (&operands[2], DImode))
6222 return "add{q}\t{%2, %0|%0, %2}";
6224 return "sub{q}\t{%2, %0|%0, %2}";
6228 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6229 (const_string "incdec")
6230 (const_string "alu")))
6231 (set (attr "length_immediate")
6233 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6235 (const_string "*")))
6236 (set_attr "mode" "DI")])
6238 ; For comparisons against 1, -1 and 128, we may generate better code
6239 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6240 ; is matched then. We can't accept general immediate, because for
6241 ; case of overflows, the result is messed up.
6242 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6243 ; only for comparisons not depending on it.
6245 (define_insn "*add<mode>_4"
6246 [(set (reg FLAGS_REG)
6248 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6249 (match_operand:SWI124 2 "const_int_operand" "n")))
6250 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6251 "ix86_match_ccmode (insn, CCGCmode)"
6253 switch (get_attr_type (insn))
6256 if (operands[2] == constm1_rtx)
6257 return "inc{<imodesuffix>}\t%0";
6260 gcc_assert (operands[2] == const1_rtx);
6261 return "dec{<imodesuffix>}\t%0";
6265 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6266 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6268 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6272 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set (attr "length_immediate")
6277 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6279 (const_string "*")))
6280 (set_attr "mode" "<MODE>")])
6282 (define_insn "*add<mode>_5"
6283 [(set (reg FLAGS_REG)
6286 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6287 (match_operand:SWI 2 "<general_operand>" "<g>"))
6289 (clobber (match_scratch:SWI 0 "=<r>"))]
6290 "ix86_match_ccmode (insn, CCGOCmode)
6291 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6293 switch (get_attr_type (insn))
6296 if (operands[2] == const1_rtx)
6297 return "inc{<imodesuffix>}\t%0";
6300 gcc_assert (operands[2] == constm1_rtx);
6301 return "dec{<imodesuffix>}\t%0";
6305 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6306 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6308 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6312 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set (attr "length_immediate")
6317 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6319 (const_string "*")))
6320 (set_attr "mode" "<MODE>")])
6322 (define_insn "*addqi_ext_1_rex64"
6323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6328 (match_operand 1 "ext_register_operand" "0")
6331 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6332 (clobber (reg:CC FLAGS_REG))]
6335 switch (get_attr_type (insn))
6338 if (operands[2] == const1_rtx)
6339 return "inc{b}\t%h0";
6342 gcc_assert (operands[2] == constm1_rtx);
6343 return "dec{b}\t%h0";
6347 return "add{b}\t{%2, %h0|%h0, %2}";
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
6354 (set_attr "modrm" "1")
6355 (set_attr "mode" "QI")])
6357 (define_insn "addqi_ext_1"
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363 (match_operand 1 "ext_register_operand" "0")
6366 (match_operand:QI 2 "general_operand" "Qmn")))
6367 (clobber (reg:CC FLAGS_REG))]
6370 switch (get_attr_type (insn))
6373 if (operands[2] == const1_rtx)
6374 return "inc{b}\t%h0";
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{b}\t%h0";
6382 return "add{b}\t{%2, %h0|%h0, %2}";
6386 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set_attr "modrm" "1")
6390 (set_attr "mode" "QI")])
6392 (define_insn "*addqi_ext_2"
6393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6398 (match_operand 1 "ext_register_operand" "%0")
6402 (match_operand 2 "ext_register_operand" "Q")
6405 (clobber (reg:CC FLAGS_REG))]
6407 "add{b}\t{%h2, %h0|%h0, %h2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "QI")])
6411 ;; The lea patterns for non-Pmodes needs to be matched by
6412 ;; several insns converted to real lea by splitters.
6414 (define_insn_and_split "*lea_general_1"
6415 [(set (match_operand 0 "register_operand" "=r")
6416 (plus (plus (match_operand 1 "index_register_operand" "l")
6417 (match_operand 2 "register_operand" "r"))
6418 (match_operand 3 "immediate_operand" "i")))]
6419 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6420 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6421 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6423 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6424 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6425 || GET_MODE (operands[3]) == VOIDmode)"
6427 "&& reload_completed"
6431 operands[0] = gen_lowpart (SImode, operands[0]);
6432 operands[1] = gen_lowpart (Pmode, operands[1]);
6433 operands[2] = gen_lowpart (Pmode, operands[2]);
6434 operands[3] = gen_lowpart (Pmode, operands[3]);
6435 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6437 if (Pmode != SImode)
6438 pat = gen_rtx_SUBREG (SImode, pat, 0);
6439 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6442 [(set_attr "type" "lea")
6443 (set_attr "mode" "SI")])
6445 (define_insn_and_split "*lea_general_1_zext"
6446 [(set (match_operand:DI 0 "register_operand" "=r")
6449 (match_operand:SI 1 "index_register_operand" "l")
6450 (match_operand:SI 2 "register_operand" "r"))
6451 (match_operand:SI 3 "immediate_operand" "i"))))]
6454 "&& reload_completed"
6456 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6458 (match_dup 3)) 0)))]
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[2] = gen_lowpart (Pmode, operands[2]);
6462 operands[3] = gen_lowpart (Pmode, operands[3]);
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6467 (define_insn_and_split "*lea_general_2"
6468 [(set (match_operand 0 "register_operand" "=r")
6469 (plus (mult (match_operand 1 "index_register_operand" "l")
6470 (match_operand 2 "const248_operand" "i"))
6471 (match_operand 3 "nonmemory_operand" "ri")))]
6472 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6473 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6474 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6475 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6476 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6477 || GET_MODE (operands[3]) == VOIDmode)"
6479 "&& reload_completed"
6483 operands[0] = gen_lowpart (SImode, operands[0]);
6484 operands[1] = gen_lowpart (Pmode, operands[1]);
6485 operands[3] = gen_lowpart (Pmode, operands[3]);
6486 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6488 if (Pmode != SImode)
6489 pat = gen_rtx_SUBREG (SImode, pat, 0);
6490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6493 [(set_attr "type" "lea")
6494 (set_attr "mode" "SI")])
6496 (define_insn_and_split "*lea_general_2_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6500 (match_operand:SI 1 "index_register_operand" "l")
6501 (match_operand:SI 2 "const248_operand" "n"))
6502 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6505 "&& reload_completed"
6507 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6509 (match_dup 3)) 0)))]
6511 operands[1] = gen_lowpart (Pmode, operands[1]);
6512 operands[3] = gen_lowpart (Pmode, operands[3]);
6514 [(set_attr "type" "lea")
6515 (set_attr "mode" "SI")])
6517 (define_insn_and_split "*lea_general_3"
6518 [(set (match_operand 0 "register_operand" "=r")
6519 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6520 (match_operand 2 "const248_operand" "i"))
6521 (match_operand 3 "register_operand" "r"))
6522 (match_operand 4 "immediate_operand" "i")))]
6523 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6524 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6525 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6527 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6529 "&& reload_completed"
6533 operands[0] = gen_lowpart (SImode, operands[0]);
6534 operands[1] = gen_lowpart (Pmode, operands[1]);
6535 operands[3] = gen_lowpart (Pmode, operands[3]);
6536 operands[4] = gen_lowpart (Pmode, operands[4]);
6537 pat = gen_rtx_PLUS (Pmode,
6538 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6542 if (Pmode != SImode)
6543 pat = gen_rtx_SUBREG (SImode, pat, 0);
6544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6547 [(set_attr "type" "lea")
6548 (set_attr "mode" "SI")])
6550 (define_insn_and_split "*lea_general_3_zext"
6551 [(set (match_operand:DI 0 "register_operand" "=r")
6555 (match_operand:SI 1 "index_register_operand" "l")
6556 (match_operand:SI 2 "const248_operand" "n"))
6557 (match_operand:SI 3 "register_operand" "r"))
6558 (match_operand:SI 4 "immediate_operand" "i"))))]
6561 "&& reload_completed"
6563 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6566 (match_dup 4)) 0)))]
6568 operands[1] = gen_lowpart (Pmode, operands[1]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6570 operands[4] = gen_lowpart (Pmode, operands[4]);
6572 [(set_attr "type" "lea")
6573 (set_attr "mode" "SI")])
6575 ;; Subtract instructions
6577 (define_expand "sub<mode>3"
6578 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6579 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6580 (match_operand:SDWIM 2 "<general_operand>" "")))]
6582 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6584 (define_insn_and_split "*sub<dwi>3_doubleword"
6585 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6587 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6588 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6589 (clobber (reg:CC FLAGS_REG))]
6590 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6593 [(parallel [(set (reg:CC FLAGS_REG)
6594 (compare:CC (match_dup 1) (match_dup 2)))
6596 (minus:DWIH (match_dup 1) (match_dup 2)))])
6597 (parallel [(set (match_dup 3)
6601 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6603 (clobber (reg:CC FLAGS_REG))])]
6604 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6606 (define_insn "*sub<mode>_1"
6607 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6609 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6610 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "mode" "<MODE>")])
6617 (define_insn "*subsi_1_zext"
6618 [(set (match_operand:DI 0 "register_operand" "=r")
6620 (minus:SI (match_operand:SI 1 "register_operand" "0")
6621 (match_operand:SI 2 "general_operand" "g"))))
6622 (clobber (reg:CC FLAGS_REG))]
6623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624 "sub{l}\t{%2, %k0|%k0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "SI")])
6628 (define_insn "*subqi_1_slp"
6629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6630 (minus:QI (match_dup 0)
6631 (match_operand:QI 1 "general_operand" "qn,qm")))
6632 (clobber (reg:CC FLAGS_REG))]
6633 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6634 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6635 "sub{b}\t{%1, %0|%0, %1}"
6636 [(set_attr "type" "alu1")
6637 (set_attr "mode" "QI")])
6639 (define_insn "*sub<mode>_2"
6640 [(set (reg FLAGS_REG)
6643 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6646 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6647 (minus:SWI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "<MODE>")])
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "g"))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6662 (minus:SI (match_dup 1)
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6670 (define_insn "*sub<mode>_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675 (minus:SWI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")])
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "g")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6688 (minus:SI (match_dup 1)
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{l}\t{%2, %1|%1, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "SI")])
6696 ;; Add with carry and subtract with borrow
6698 (define_expand "<plusminus_insn><mode>3_carry"
6700 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6702 (match_operand:SWI 1 "nonimmediate_operand" "")
6703 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6704 [(match_operand 3 "flags_reg_operand" "")
6706 (match_operand:SWI 2 "<general_operand>" ""))))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6710 (define_insn "*<plusminus_insn><mode>3_carry"
6711 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6713 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6715 (match_operator 3 "ix86_carry_flag_operator"
6716 [(reg FLAGS_REG) (const_int 0)])
6717 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6718 (clobber (reg:CC FLAGS_REG))]
6719 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6720 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "use_carry" "1")
6723 (set_attr "pent_pair" "pu")
6724 (set_attr "mode" "<MODE>")])
6726 (define_insn "*addsi3_carry_zext"
6727 [(set (match_operand:DI 0 "register_operand" "=r")
6729 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6730 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6731 [(reg FLAGS_REG) (const_int 0)])
6732 (match_operand:SI 2 "general_operand" "g")))))
6733 (clobber (reg:CC FLAGS_REG))]
6734 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6735 "adc{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "use_carry" "1")
6738 (set_attr "pent_pair" "pu")
6739 (set_attr "mode" "SI")])
6741 (define_insn "*subsi3_carry_zext"
6742 [(set (match_operand:DI 0 "register_operand" "=r")
6744 (minus:SI (match_operand:SI 1 "register_operand" "0")
6745 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6746 [(reg FLAGS_REG) (const_int 0)])
6747 (match_operand:SI 2 "general_operand" "g")))))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sbb{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "pent_pair" "pu")
6753 (set_attr "mode" "SI")])
6755 ;; Overflow setting add and subtract instructions
6757 (define_insn "*add<mode>3_cconly_overflow"
6758 [(set (reg:CCC FLAGS_REG)
6761 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6762 (match_operand:SWI 2 "<general_operand>" "<g>"))
6764 (clobber (match_scratch:SWI 0 "=<r>"))]
6765 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6766 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "mode" "<MODE>")])
6770 (define_insn "*sub<mode>3_cconly_overflow"
6771 [(set (reg:CCC FLAGS_REG)
6774 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6775 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6778 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6779 [(set_attr "type" "icmp")
6780 (set_attr "mode" "<MODE>")])
6782 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6783 [(set (reg:CCC FLAGS_REG)
6786 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6787 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6789 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6790 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6791 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6792 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6793 [(set_attr "type" "alu")
6794 (set_attr "mode" "<MODE>")])
6796 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6797 [(set (reg:CCC FLAGS_REG)
6800 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6801 (match_operand:SI 2 "general_operand" "g"))
6803 (set (match_operand:DI 0 "register_operand" "=r")
6804 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6805 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6806 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6807 [(set_attr "type" "alu")
6808 (set_attr "mode" "SI")])
6810 ;; The patterns that match these are at the end of this file.
6812 (define_expand "<plusminus_insn>xf3"
6813 [(set (match_operand:XF 0 "register_operand" "")
6815 (match_operand:XF 1 "register_operand" "")
6816 (match_operand:XF 2 "register_operand" "")))]
6819 (define_expand "<plusminus_insn><mode>3"
6820 [(set (match_operand:MODEF 0 "register_operand" "")
6822 (match_operand:MODEF 1 "register_operand" "")
6823 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6824 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6825 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6827 ;; Multiply instructions
6829 (define_expand "mul<mode>3"
6830 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6832 (match_operand:SWIM248 1 "register_operand" "")
6833 (match_operand:SWIM248 2 "<general_operand>" "")))
6834 (clobber (reg:CC FLAGS_REG))])])
6836 (define_expand "mulqi3"
6837 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6839 (match_operand:QI 1 "register_operand" "")
6840 (match_operand:QI 2 "nonimmediate_operand" "")))
6841 (clobber (reg:CC FLAGS_REG))])]
6842 "TARGET_QIMODE_MATH")
6845 ;; IMUL reg32/64, reg32/64, imm8 Direct
6846 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6847 ;; IMUL reg32/64, reg32/64, imm32 Direct
6848 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6849 ;; IMUL reg32/64, reg32/64 Direct
6850 ;; IMUL reg32/64, mem32/64 Direct
6852 (define_insn "*mul<mode>3_1"
6853 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6855 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6856 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6857 (clobber (reg:CC FLAGS_REG))]
6858 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6860 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6861 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6862 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6863 [(set_attr "type" "imul")
6864 (set_attr "prefix_0f" "0,0,1")
6865 (set (attr "athlon_decode")
6866 (cond [(eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (eq_attr "alternative" "1")
6869 (const_string "vector")
6870 (and (eq_attr "alternative" "2")
6871 (match_operand 1 "memory_operand" ""))
6872 (const_string "vector")]
6873 (const_string "direct")))
6874 (set (attr "amdfam10_decode")
6875 (cond [(and (eq_attr "alternative" "0,1")
6876 (match_operand 1 "memory_operand" ""))
6877 (const_string "vector")]
6878 (const_string "direct")))
6879 (set_attr "mode" "<MODE>")])
6881 (define_insn "*mulsi3_1_zext"
6882 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6884 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6885 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6886 (clobber (reg:CC FLAGS_REG))]
6888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6892 imul{l}\t{%2, %k0|%k0, %2}"
6893 [(set_attr "type" "imul")
6894 (set_attr "prefix_0f" "0,0,1")
6895 (set (attr "athlon_decode")
6896 (cond [(eq_attr "cpu" "athlon")
6897 (const_string "vector")
6898 (eq_attr "alternative" "1")
6899 (const_string "vector")
6900 (and (eq_attr "alternative" "2")
6901 (match_operand 1 "memory_operand" ""))
6902 (const_string "vector")]
6903 (const_string "direct")))
6904 (set (attr "amdfam10_decode")
6905 (cond [(and (eq_attr "alternative" "0,1")
6906 (match_operand 1 "memory_operand" ""))
6907 (const_string "vector")]
6908 (const_string "direct")))
6909 (set_attr "mode" "SI")])
6912 ;; IMUL reg16, reg16, imm8 VectorPath
6913 ;; IMUL reg16, mem16, imm8 VectorPath
6914 ;; IMUL reg16, reg16, imm16 VectorPath
6915 ;; IMUL reg16, mem16, imm16 VectorPath
6916 ;; IMUL reg16, reg16 Direct
6917 ;; IMUL reg16, mem16 Direct
6919 (define_insn "*mulhi3_1"
6920 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6921 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6922 (match_operand:HI 2 "general_operand" "K,n,mr")))
6923 (clobber (reg:CC FLAGS_REG))]
6925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6927 imul{w}\t{%2, %1, %0|%0, %1, %2}
6928 imul{w}\t{%2, %1, %0|%0, %1, %2}
6929 imul{w}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "imul")
6931 (set_attr "prefix_0f" "0,0,1")
6932 (set (attr "athlon_decode")
6933 (cond [(eq_attr "cpu" "athlon")
6934 (const_string "vector")
6935 (eq_attr "alternative" "1,2")
6936 (const_string "vector")]
6937 (const_string "direct")))
6938 (set (attr "amdfam10_decode")
6939 (cond [(eq_attr "alternative" "0,1")
6940 (const_string "vector")]
6941 (const_string "direct")))
6942 (set_attr "mode" "HI")])
6948 (define_insn "*mulqi3_1"
6949 [(set (match_operand:QI 0 "register_operand" "=a")
6950 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6951 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6952 (clobber (reg:CC FLAGS_REG))]
6954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6956 [(set_attr "type" "imul")
6957 (set_attr "length_immediate" "0")
6958 (set (attr "athlon_decode")
6959 (if_then_else (eq_attr "cpu" "athlon")
6960 (const_string "vector")
6961 (const_string "direct")))
6962 (set_attr "amdfam10_decode" "direct")
6963 (set_attr "mode" "QI")])
6965 (define_expand "<u>mul<mode><dwi>3"
6966 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6969 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6971 (match_operand:DWIH 2 "register_operand" ""))))
6972 (clobber (reg:CC FLAGS_REG))])])
6974 (define_expand "<u>mulqihi3"
6975 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6978 (match_operand:QI 1 "nonimmediate_operand" ""))
6980 (match_operand:QI 2 "register_operand" ""))))
6981 (clobber (reg:CC FLAGS_REG))])]
6982 "TARGET_QIMODE_MATH")
6984 (define_insn "*<u>mul<mode><dwi>3_1"
6985 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6988 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6990 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6991 (clobber (reg:CC FLAGS_REG))]
6992 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993 "<sgnprefix>mul{<imodesuffix>}\t%2"
6994 [(set_attr "type" "imul")
6995 (set_attr "length_immediate" "0")
6996 (set (attr "athlon_decode")
6997 (if_then_else (eq_attr "cpu" "athlon")
6998 (const_string "vector")
6999 (const_string "double")))
7000 (set_attr "amdfam10_decode" "double")
7001 (set_attr "mode" "<MODE>")])
7003 (define_insn "*<u>mulqihi3_1"
7004 [(set (match_operand:HI 0 "register_operand" "=a")
7007 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7009 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7010 (clobber (reg:CC FLAGS_REG))]
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7013 "<sgnprefix>mul{b}\t%2"
7014 [(set_attr "type" "imul")
7015 (set_attr "length_immediate" "0")
7016 (set (attr "athlon_decode")
7017 (if_then_else (eq_attr "cpu" "athlon")
7018 (const_string "vector")
7019 (const_string "direct")))
7020 (set_attr "amdfam10_decode" "direct")
7021 (set_attr "mode" "QI")])
7023 (define_expand "<s>mul<mode>3_highpart"
7024 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7029 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7031 (match_operand:SWI48 2 "register_operand" "")))
7033 (clobber (match_scratch:SWI48 3 ""))
7034 (clobber (reg:CC FLAGS_REG))])]
7036 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7038 (define_insn "*<s>muldi3_highpart_1"
7039 [(set (match_operand:DI 0 "register_operand" "=d")
7044 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7046 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7048 (clobber (match_scratch:DI 3 "=1"))
7049 (clobber (reg:CC FLAGS_REG))]
7051 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7052 "<sgnprefix>mul{q}\t%2"
7053 [(set_attr "type" "imul")
7054 (set_attr "length_immediate" "0")
7055 (set (attr "athlon_decode")
7056 (if_then_else (eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (const_string "double")))
7059 (set_attr "amdfam10_decode" "double")
7060 (set_attr "mode" "DI")])
7062 (define_insn "*<s>mulsi3_highpart_1"
7063 [(set (match_operand:SI 0 "register_operand" "=d")
7068 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7070 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7072 (clobber (match_scratch:SI 3 "=1"))
7073 (clobber (reg:CC FLAGS_REG))]
7074 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075 "<sgnprefix>mul{l}\t%2"
7076 [(set_attr "type" "imul")
7077 (set_attr "length_immediate" "0")
7078 (set (attr "athlon_decode")
7079 (if_then_else (eq_attr "cpu" "athlon")
7080 (const_string "vector")
7081 (const_string "double")))
7082 (set_attr "amdfam10_decode" "double")
7083 (set_attr "mode" "SI")])
7085 (define_insn "*<s>mulsi3_highpart_zext"
7086 [(set (match_operand:DI 0 "register_operand" "=d")
7087 (zero_extend:DI (truncate:SI
7089 (mult:DI (any_extend:DI
7090 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7092 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7094 (clobber (match_scratch:SI 3 "=1"))
7095 (clobber (reg:CC FLAGS_REG))]
7097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098 "<sgnprefix>mul{l}\t%2"
7099 [(set_attr "type" "imul")
7100 (set_attr "length_immediate" "0")
7101 (set (attr "athlon_decode")
7102 (if_then_else (eq_attr "cpu" "athlon")
7103 (const_string "vector")
7104 (const_string "double")))
7105 (set_attr "amdfam10_decode" "double")
7106 (set_attr "mode" "SI")])
7108 ;; The patterns that match these are at the end of this file.
7110 (define_expand "mulxf3"
7111 [(set (match_operand:XF 0 "register_operand" "")
7112 (mult:XF (match_operand:XF 1 "register_operand" "")
7113 (match_operand:XF 2 "register_operand" "")))]
7116 (define_expand "mul<mode>3"
7117 [(set (match_operand:MODEF 0 "register_operand" "")
7118 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7119 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7120 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7121 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7123 ;; Divide instructions
7125 ;; The patterns that match these are at the end of this file.
7127 (define_expand "divxf3"
7128 [(set (match_operand:XF 0 "register_operand" "")
7129 (div:XF (match_operand:XF 1 "register_operand" "")
7130 (match_operand:XF 2 "register_operand" "")))]
7133 (define_expand "divdf3"
7134 [(set (match_operand:DF 0 "register_operand" "")
7135 (div:DF (match_operand:DF 1 "register_operand" "")
7136 (match_operand:DF 2 "nonimmediate_operand" "")))]
7137 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7138 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7140 (define_expand "divsf3"
7141 [(set (match_operand:SF 0 "register_operand" "")
7142 (div:SF (match_operand:SF 1 "register_operand" "")
7143 (match_operand:SF 2 "nonimmediate_operand" "")))]
7144 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7147 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7148 && flag_finite_math_only && !flag_trapping_math
7149 && flag_unsafe_math_optimizations)
7151 ix86_emit_swdivsf (operands[0], operands[1],
7152 operands[2], SFmode);
7157 ;; Divmod instructions.
7159 (define_expand "divmod<mode>4"
7160 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7162 (match_operand:SWIM248 1 "register_operand" "")
7163 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7164 (set (match_operand:SWIM248 3 "register_operand" "")
7165 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7166 (clobber (reg:CC FLAGS_REG))])])
7168 ;; Split with 8bit unsigned divide:
7169 ;; if (dividend an divisor are in [0-255])
7170 ;; use 8bit unsigned integer divide
7172 ;; use original integer divide
7174 [(set (match_operand:SWI48 0 "register_operand" "")
7175 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7176 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7177 (set (match_operand:SWI48 1 "register_operand" "")
7178 (mod:SWI48 (match_dup 2) (match_dup 3)))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "TARGET_USE_8BIT_IDIV
7181 && TARGET_QIMODE_MATH
7182 && can_create_pseudo_p ()
7183 && !optimize_insn_for_size_p ()"
7185 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7187 (define_insn_and_split "divmod<mode>4_1"
7188 [(set (match_operand:SWI48 0 "register_operand" "=a")
7189 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7190 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWI48 1 "register_operand" "=&d")
7192 (mod:SWI48 (match_dup 2) (match_dup 3)))
7193 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7194 (clobber (reg:CC FLAGS_REG))]
7198 [(parallel [(set (match_dup 1)
7199 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7200 (clobber (reg:CC FLAGS_REG))])
7201 (parallel [(set (match_dup 0)
7202 (div:SWI48 (match_dup 2) (match_dup 3)))
7204 (mod:SWI48 (match_dup 2) (match_dup 3)))
7206 (clobber (reg:CC FLAGS_REG))])]
7208 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7210 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7211 operands[4] = operands[2];
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7222 (define_insn_and_split "*divmod<mode>4"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7232 [(parallel [(set (match_dup 1)
7233 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7234 (clobber (reg:CC FLAGS_REG))])
7235 (parallel [(set (match_dup 0)
7236 (div:SWIM248 (match_dup 2) (match_dup 3)))
7238 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7240 (clobber (reg:CC FLAGS_REG))])]
7242 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7244 if (<MODE>mode != HImode
7245 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7246 operands[4] = operands[2];
7249 /* Avoid use of cltd in favor of a mov+shift. */
7250 emit_move_insn (operands[1], operands[2]);
7251 operands[4] = operands[1];
7254 [(set_attr "type" "multi")
7255 (set_attr "mode" "<MODE>")])
7257 (define_insn "*divmod<mode>4_noext"
7258 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7259 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7260 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7261 (set (match_operand:SWIM248 1 "register_operand" "=d")
7262 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7263 (use (match_operand:SWIM248 4 "register_operand" "1"))
7264 (clobber (reg:CC FLAGS_REG))]
7266 "idiv{<imodesuffix>}\t%3"
7267 [(set_attr "type" "idiv")
7268 (set_attr "mode" "<MODE>")])
7270 (define_expand "divmodqi4"
7271 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7273 (match_operand:QI 1 "register_operand" "")
7274 (match_operand:QI 2 "nonimmediate_operand" "")))
7275 (set (match_operand:QI 3 "register_operand" "")
7276 (mod:QI (match_dup 1) (match_dup 2)))
7277 (clobber (reg:CC FLAGS_REG))])]
7278 "TARGET_QIMODE_MATH"
7283 tmp0 = gen_reg_rtx (HImode);
7284 tmp1 = gen_reg_rtx (HImode);
7286 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7288 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7289 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7291 /* Extract remainder from AH. */
7292 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7293 insn = emit_move_insn (operands[3], tmp1);
7295 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7296 set_unique_reg_note (insn, REG_EQUAL, mod);
7298 /* Extract quotient from AL. */
7299 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7301 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7302 set_unique_reg_note (insn, REG_EQUAL, div);
7307 ;; Divide AX by r/m8, with result stored in
7310 ;; Change div/mod to HImode and extend the second argument to HImode
7311 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7312 ;; combine may fail.
7313 (define_insn "divmodhiqi3"
7314 [(set (match_operand:HI 0 "register_operand" "=a")
7319 (mod:HI (match_operand:HI 1 "register_operand" "0")
7321 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7325 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "TARGET_QIMODE_MATH"
7329 [(set_attr "type" "idiv")
7330 (set_attr "mode" "QI")])
7332 (define_expand "udivmod<mode>4"
7333 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7335 (match_operand:SWIM248 1 "register_operand" "")
7336 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7337 (set (match_operand:SWIM248 3 "register_operand" "")
7338 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7339 (clobber (reg:CC FLAGS_REG))])])
7341 ;; Split with 8bit unsigned divide:
7342 ;; if (dividend an divisor are in [0-255])
7343 ;; use 8bit unsigned integer divide
7345 ;; use original integer divide
7347 [(set (match_operand:SWI48 0 "register_operand" "")
7348 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7349 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7350 (set (match_operand:SWI48 1 "register_operand" "")
7351 (umod:SWI48 (match_dup 2) (match_dup 3)))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "TARGET_USE_8BIT_IDIV
7354 && TARGET_QIMODE_MATH
7355 && can_create_pseudo_p ()
7356 && !optimize_insn_for_size_p ()"
7358 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7360 (define_insn_and_split "udivmod<mode>4_1"
7361 [(set (match_operand:SWI48 0 "register_operand" "=a")
7362 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7363 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7364 (set (match_operand:SWI48 1 "register_operand" "=&d")
7365 (umod:SWI48 (match_dup 2) (match_dup 3)))
7366 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7367 (clobber (reg:CC FLAGS_REG))]
7371 [(set (match_dup 1) (const_int 0))
7372 (parallel [(set (match_dup 0)
7373 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7375 (umod:SWI48 (match_dup 2) (match_dup 3)))
7377 (clobber (reg:CC FLAGS_REG))])]
7379 [(set_attr "type" "multi")
7380 (set_attr "mode" "<MODE>")])
7382 (define_insn_and_split "*udivmod<mode>4"
7383 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7384 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7385 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7386 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7387 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7388 (clobber (reg:CC FLAGS_REG))]
7392 [(set (match_dup 1) (const_int 0))
7393 (parallel [(set (match_dup 0)
7394 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7396 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7398 (clobber (reg:CC FLAGS_REG))])]
7400 [(set_attr "type" "multi")
7401 (set_attr "mode" "<MODE>")])
7403 (define_insn "*udivmod<mode>4_noext"
7404 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7405 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7406 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7407 (set (match_operand:SWIM248 1 "register_operand" "=d")
7408 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7409 (use (match_operand:SWIM248 4 "register_operand" "1"))
7410 (clobber (reg:CC FLAGS_REG))]
7412 "div{<imodesuffix>}\t%3"
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "<MODE>")])
7416 (define_expand "udivmodqi4"
7417 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7419 (match_operand:QI 1 "register_operand" "")
7420 (match_operand:QI 2 "nonimmediate_operand" "")))
7421 (set (match_operand:QI 3 "register_operand" "")
7422 (umod:QI (match_dup 1) (match_dup 2)))
7423 (clobber (reg:CC FLAGS_REG))])]
7424 "TARGET_QIMODE_MATH"
7429 tmp0 = gen_reg_rtx (HImode);
7430 tmp1 = gen_reg_rtx (HImode);
7432 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7434 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7435 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7437 /* Extract remainder from AH. */
7438 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7439 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7440 insn = emit_move_insn (operands[3], tmp1);
7442 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7443 set_unique_reg_note (insn, REG_EQUAL, mod);
7445 /* Extract quotient from AL. */
7446 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7448 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7449 set_unique_reg_note (insn, REG_EQUAL, div);
7454 (define_insn "udivmodhiqi3"
7455 [(set (match_operand:HI 0 "register_operand" "=a")
7460 (mod:HI (match_operand:HI 1 "register_operand" "0")
7462 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7466 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7467 (clobber (reg:CC FLAGS_REG))]
7468 "TARGET_QIMODE_MATH"
7470 [(set_attr "type" "idiv")
7471 (set_attr "mode" "QI")])
7473 ;; We cannot use div/idiv for double division, because it causes
7474 ;; "division by zero" on the overflow and that's not what we expect
7475 ;; from truncate. Because true (non truncating) double division is
7476 ;; never generated, we can't create this insn anyway.
7479 ; [(set (match_operand:SI 0 "register_operand" "=a")
7481 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7483 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7484 ; (set (match_operand:SI 3 "register_operand" "=d")
7486 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7487 ; (clobber (reg:CC FLAGS_REG))]
7489 ; "div{l}\t{%2, %0|%0, %2}"
7490 ; [(set_attr "type" "idiv")])
7492 ;;- Logical AND instructions
7494 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7495 ;; Note that this excludes ah.
7497 (define_expand "testsi_ccno_1"
7498 [(set (reg:CCNO FLAGS_REG)
7500 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7501 (match_operand:SI 1 "nonmemory_operand" ""))
7504 (define_expand "testqi_ccz_1"
7505 [(set (reg:CCZ FLAGS_REG)
7506 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7507 (match_operand:QI 1 "nonmemory_operand" ""))
7510 (define_expand "testdi_ccno_1"
7511 [(set (reg:CCNO FLAGS_REG)
7513 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7514 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7516 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7518 (define_insn "*testdi_1"
7519 [(set (reg FLAGS_REG)
7522 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7523 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7525 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7528 test{l}\t{%k1, %k0|%k0, %k1}
7529 test{l}\t{%k1, %k0|%k0, %k1}
7530 test{q}\t{%1, %0|%0, %1}
7531 test{q}\t{%1, %0|%0, %1}
7532 test{q}\t{%1, %0|%0, %1}"
7533 [(set_attr "type" "test")
7534 (set_attr "modrm" "0,1,0,1,1")
7535 (set_attr "mode" "SI,SI,DI,DI,DI")])
7537 (define_insn "*testqi_1_maybe_si"
7538 [(set (reg FLAGS_REG)
7541 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7542 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7544 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7545 && ix86_match_ccmode (insn,
7546 CONST_INT_P (operands[1])
7547 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7549 if (which_alternative == 3)
7551 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7552 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7553 return "test{l}\t{%1, %k0|%k0, %1}";
7555 return "test{b}\t{%1, %0|%0, %1}";
7557 [(set_attr "type" "test")
7558 (set_attr "modrm" "0,1,1,1")
7559 (set_attr "mode" "QI,QI,QI,SI")
7560 (set_attr "pent_pair" "uv,np,uv,np")])
7562 (define_insn "*test<mode>_1"
7563 [(set (reg FLAGS_REG)
7566 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7567 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7569 "ix86_match_ccmode (insn, CCNOmode)
7570 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7571 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7572 [(set_attr "type" "test")
7573 (set_attr "modrm" "0,1,1")
7574 (set_attr "mode" "<MODE>")
7575 (set_attr "pent_pair" "uv,np,uv")])
7577 (define_expand "testqi_ext_ccno_0"
7578 [(set (reg:CCNO FLAGS_REG)
7582 (match_operand 0 "ext_register_operand" "")
7585 (match_operand 1 "const_int_operand" ""))
7588 (define_insn "*testqi_ext_0"
7589 [(set (reg FLAGS_REG)
7593 (match_operand 0 "ext_register_operand" "Q")
7596 (match_operand 1 "const_int_operand" "n"))
7598 "ix86_match_ccmode (insn, CCNOmode)"
7599 "test{b}\t{%1, %h0|%h0, %1}"
7600 [(set_attr "type" "test")
7601 (set_attr "mode" "QI")
7602 (set_attr "length_immediate" "1")
7603 (set_attr "modrm" "1")
7604 (set_attr "pent_pair" "np")])
7606 (define_insn "*testqi_ext_1_rex64"
7607 [(set (reg FLAGS_REG)
7611 (match_operand 0 "ext_register_operand" "Q")
7615 (match_operand:QI 1 "register_operand" "Q")))
7617 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7618 "test{b}\t{%1, %h0|%h0, %1}"
7619 [(set_attr "type" "test")
7620 (set_attr "mode" "QI")])
7622 (define_insn "*testqi_ext_1"
7623 [(set (reg FLAGS_REG)
7627 (match_operand 0 "ext_register_operand" "Q")
7631 (match_operand:QI 1 "general_operand" "Qm")))
7633 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7634 "test{b}\t{%1, %h0|%h0, %1}"
7635 [(set_attr "type" "test")
7636 (set_attr "mode" "QI")])
7638 (define_insn "*testqi_ext_2"
7639 [(set (reg FLAGS_REG)
7643 (match_operand 0 "ext_register_operand" "Q")
7647 (match_operand 1 "ext_register_operand" "Q")
7651 "ix86_match_ccmode (insn, CCNOmode)"
7652 "test{b}\t{%h1, %h0|%h0, %h1}"
7653 [(set_attr "type" "test")
7654 (set_attr "mode" "QI")])
7656 (define_insn "*testqi_ext_3_rex64"
7657 [(set (reg FLAGS_REG)
7658 (compare (zero_extract:DI
7659 (match_operand 0 "nonimmediate_operand" "rm")
7660 (match_operand:DI 1 "const_int_operand" "")
7661 (match_operand:DI 2 "const_int_operand" ""))
7664 && ix86_match_ccmode (insn, CCNOmode)
7665 && INTVAL (operands[1]) > 0
7666 && INTVAL (operands[2]) >= 0
7667 /* Ensure that resulting mask is zero or sign extended operand. */
7668 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7669 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7670 && INTVAL (operands[1]) > 32))
7671 && (GET_MODE (operands[0]) == SImode
7672 || GET_MODE (operands[0]) == DImode
7673 || GET_MODE (operands[0]) == HImode
7674 || GET_MODE (operands[0]) == QImode)"
7677 ;; Combine likes to form bit extractions for some tests. Humor it.
7678 (define_insn "*testqi_ext_3"
7679 [(set (reg FLAGS_REG)
7680 (compare (zero_extract:SI
7681 (match_operand 0 "nonimmediate_operand" "rm")
7682 (match_operand:SI 1 "const_int_operand" "")
7683 (match_operand:SI 2 "const_int_operand" ""))
7685 "ix86_match_ccmode (insn, CCNOmode)
7686 && INTVAL (operands[1]) > 0
7687 && INTVAL (operands[2]) >= 0
7688 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7689 && (GET_MODE (operands[0]) == SImode
7690 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7691 || GET_MODE (operands[0]) == HImode
7692 || GET_MODE (operands[0]) == QImode)"
7696 [(set (match_operand 0 "flags_reg_operand" "")
7697 (match_operator 1 "compare_operator"
7699 (match_operand 2 "nonimmediate_operand" "")
7700 (match_operand 3 "const_int_operand" "")
7701 (match_operand 4 "const_int_operand" ""))
7703 "ix86_match_ccmode (insn, CCNOmode)"
7704 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7706 rtx val = operands[2];
7707 HOST_WIDE_INT len = INTVAL (operands[3]);
7708 HOST_WIDE_INT pos = INTVAL (operands[4]);
7710 enum machine_mode mode, submode;
7712 mode = GET_MODE (val);
7715 /* ??? Combine likes to put non-volatile mem extractions in QImode
7716 no matter the size of the test. So find a mode that works. */
7717 if (! MEM_VOLATILE_P (val))
7719 mode = smallest_mode_for_size (pos + len, MODE_INT);
7720 val = adjust_address (val, mode, 0);
7723 else if (GET_CODE (val) == SUBREG
7724 && (submode = GET_MODE (SUBREG_REG (val)),
7725 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7726 && pos + len <= GET_MODE_BITSIZE (submode)
7727 && GET_MODE_CLASS (submode) == MODE_INT)
7729 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7731 val = SUBREG_REG (val);
7733 else if (mode == HImode && pos + len <= 8)
7735 /* Small HImode tests can be converted to QImode. */
7737 val = gen_lowpart (QImode, val);
7740 if (len == HOST_BITS_PER_WIDE_INT)
7743 mask = ((HOST_WIDE_INT)1 << len) - 1;
7746 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7749 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7750 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7751 ;; this is relatively important trick.
7752 ;; Do the conversion only post-reload to avoid limiting of the register class
7755 [(set (match_operand 0 "flags_reg_operand" "")
7756 (match_operator 1 "compare_operator"
7757 [(and (match_operand 2 "register_operand" "")
7758 (match_operand 3 "const_int_operand" ""))
7761 && QI_REG_P (operands[2])
7762 && GET_MODE (operands[2]) != QImode
7763 && ((ix86_match_ccmode (insn, CCZmode)
7764 && !(INTVAL (operands[3]) & ~(255 << 8)))
7765 || (ix86_match_ccmode (insn, CCNOmode)
7766 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7769 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7772 "operands[2] = gen_lowpart (SImode, operands[2]);
7773 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7776 [(set (match_operand 0 "flags_reg_operand" "")
7777 (match_operator 1 "compare_operator"
7778 [(and (match_operand 2 "nonimmediate_operand" "")
7779 (match_operand 3 "const_int_operand" ""))
7782 && GET_MODE (operands[2]) != QImode
7783 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7784 && ((ix86_match_ccmode (insn, CCZmode)
7785 && !(INTVAL (operands[3]) & ~255))
7786 || (ix86_match_ccmode (insn, CCNOmode)
7787 && !(INTVAL (operands[3]) & ~127)))"
7789 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7791 "operands[2] = gen_lowpart (QImode, operands[2]);
7792 operands[3] = gen_lowpart (QImode, operands[3]);")
7794 ;; %%% This used to optimize known byte-wide and operations to memory,
7795 ;; and sometimes to QImode registers. If this is considered useful,
7796 ;; it should be done with splitters.
7798 (define_expand "and<mode>3"
7799 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7800 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7801 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7803 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7805 (define_insn "*anddi_1"
7806 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7808 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7809 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7813 switch (get_attr_type (insn))
7817 enum machine_mode mode;
7819 gcc_assert (CONST_INT_P (operands[2]));
7820 if (INTVAL (operands[2]) == 0xff)
7824 gcc_assert (INTVAL (operands[2]) == 0xffff);
7828 operands[1] = gen_lowpart (mode, operands[1]);
7830 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7832 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7837 if (get_attr_mode (insn) == MODE_SI)
7838 return "and{l}\t{%k2, %k0|%k0, %k2}";
7840 return "and{q}\t{%2, %0|%0, %2}";
7843 [(set_attr "type" "alu,alu,alu,imovx")
7844 (set_attr "length_immediate" "*,*,*,0")
7845 (set (attr "prefix_rex")
7847 (and (eq_attr "type" "imovx")
7848 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7849 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7851 (const_string "*")))
7852 (set_attr "mode" "SI,DI,DI,SI")])
7854 (define_insn "*andsi_1"
7855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7856 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7857 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "ix86_binary_operator_ok (AND, SImode, operands)"
7861 switch (get_attr_type (insn))
7865 enum machine_mode mode;
7867 gcc_assert (CONST_INT_P (operands[2]));
7868 if (INTVAL (operands[2]) == 0xff)
7872 gcc_assert (INTVAL (operands[2]) == 0xffff);
7876 operands[1] = gen_lowpart (mode, operands[1]);
7878 return "movz{bl|x}\t{%1, %0|%0, %1}";
7880 return "movz{wl|x}\t{%1, %0|%0, %1}";
7884 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7885 return "and{l}\t{%2, %0|%0, %2}";
7888 [(set_attr "type" "alu,alu,imovx")
7889 (set (attr "prefix_rex")
7891 (and (eq_attr "type" "imovx")
7892 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7893 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7895 (const_string "*")))
7896 (set_attr "length_immediate" "*,*,0")
7897 (set_attr "mode" "SI")])
7899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7900 (define_insn "*andsi_1_zext"
7901 [(set (match_operand:DI 0 "register_operand" "=r")
7903 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7904 (match_operand:SI 2 "general_operand" "g"))))
7905 (clobber (reg:CC FLAGS_REG))]
7906 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7907 "and{l}\t{%2, %k0|%k0, %2}"
7908 [(set_attr "type" "alu")
7909 (set_attr "mode" "SI")])
7911 (define_insn "*andhi_1"
7912 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7913 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7914 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7915 (clobber (reg:CC FLAGS_REG))]
7916 "ix86_binary_operator_ok (AND, HImode, operands)"
7918 switch (get_attr_type (insn))
7921 gcc_assert (CONST_INT_P (operands[2]));
7922 gcc_assert (INTVAL (operands[2]) == 0xff);
7923 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7928 return "and{w}\t{%2, %0|%0, %2}";
7931 [(set_attr "type" "alu,alu,imovx")
7932 (set_attr "length_immediate" "*,*,0")
7933 (set (attr "prefix_rex")
7935 (and (eq_attr "type" "imovx")
7936 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7938 (const_string "*")))
7939 (set_attr "mode" "HI,HI,SI")])
7941 ;; %%% Potential partial reg stall on alternative 2. What to do?
7942 (define_insn "*andqi_1"
7943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7944 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7945 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7946 (clobber (reg:CC FLAGS_REG))]
7947 "ix86_binary_operator_ok (AND, QImode, operands)"
7949 and{b}\t{%2, %0|%0, %2}
7950 and{b}\t{%2, %0|%0, %2}
7951 and{l}\t{%k2, %k0|%k0, %k2}"
7952 [(set_attr "type" "alu")
7953 (set_attr "mode" "QI,QI,SI")])
7955 (define_insn "*andqi_1_slp"
7956 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7957 (and:QI (match_dup 0)
7958 (match_operand:QI 1 "general_operand" "qn,qmn")))
7959 (clobber (reg:CC FLAGS_REG))]
7960 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7962 "and{b}\t{%1, %0|%0, %1}"
7963 [(set_attr "type" "alu1")
7964 (set_attr "mode" "QI")])
7967 [(set (match_operand 0 "register_operand" "")
7969 (const_int -65536)))
7970 (clobber (reg:CC FLAGS_REG))]
7971 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7972 || optimize_function_for_size_p (cfun)"
7973 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7974 "operands[1] = gen_lowpart (HImode, operands[0]);")
7977 [(set (match_operand 0 "ext_register_operand" "")
7980 (clobber (reg:CC FLAGS_REG))]
7981 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7982 && reload_completed"
7983 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7984 "operands[1] = gen_lowpart (QImode, operands[0]);")
7987 [(set (match_operand 0 "ext_register_operand" "")
7989 (const_int -65281)))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && reload_completed"
7993 [(parallel [(set (zero_extract:SI (match_dup 0)
7997 (zero_extract:SI (match_dup 0)
8000 (zero_extract:SI (match_dup 0)
8003 (clobber (reg:CC FLAGS_REG))])]
8004 "operands[0] = gen_lowpart (SImode, operands[0]);")
8006 (define_insn "*anddi_2"
8007 [(set (reg FLAGS_REG)
8010 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8011 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8013 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8014 (and:DI (match_dup 1) (match_dup 2)))]
8015 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8016 && ix86_binary_operator_ok (AND, DImode, operands)"
8018 and{l}\t{%k2, %k0|%k0, %k2}
8019 and{q}\t{%2, %0|%0, %2}
8020 and{q}\t{%2, %0|%0, %2}"
8021 [(set_attr "type" "alu")
8022 (set_attr "mode" "SI,DI,DI")])
8024 (define_insn "*andqi_2_maybe_si"
8025 [(set (reg FLAGS_REG)
8027 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8028 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8030 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8031 (and:QI (match_dup 1) (match_dup 2)))]
8032 "ix86_binary_operator_ok (AND, QImode, operands)
8033 && ix86_match_ccmode (insn,
8034 CONST_INT_P (operands[2])
8035 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8037 if (which_alternative == 2)
8039 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8040 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8041 return "and{l}\t{%2, %k0|%k0, %2}";
8043 return "and{b}\t{%2, %0|%0, %2}";
8045 [(set_attr "type" "alu")
8046 (set_attr "mode" "QI,QI,SI")])
8048 (define_insn "*and<mode>_2"
8049 [(set (reg FLAGS_REG)
8050 (compare (and:SWI124
8051 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8052 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8054 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8055 (and:SWI124 (match_dup 1) (match_dup 2)))]
8056 "ix86_match_ccmode (insn, CCNOmode)
8057 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8058 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8059 [(set_attr "type" "alu")
8060 (set_attr "mode" "<MODE>")])
8062 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8063 (define_insn "*andsi_2_zext"
8064 [(set (reg FLAGS_REG)
8066 (match_operand:SI 1 "nonimmediate_operand" "%0")
8067 (match_operand:SI 2 "general_operand" "g"))
8069 (set (match_operand:DI 0 "register_operand" "=r")
8070 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8071 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8072 && ix86_binary_operator_ok (AND, SImode, operands)"
8073 "and{l}\t{%2, %k0|%k0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "SI")])
8077 (define_insn "*andqi_2_slp"
8078 [(set (reg FLAGS_REG)
8080 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8081 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8083 (set (strict_low_part (match_dup 0))
8084 (and:QI (match_dup 0) (match_dup 1)))]
8085 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && ix86_match_ccmode (insn, CCNOmode)
8087 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8088 "and{b}\t{%1, %0|%0, %1}"
8089 [(set_attr "type" "alu1")
8090 (set_attr "mode" "QI")])
8092 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8093 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8094 ;; for a QImode operand, which of course failed.
8095 (define_insn "andqi_ext_0"
8096 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8101 (match_operand 1 "ext_register_operand" "0")
8104 (match_operand 2 "const_int_operand" "n")))
8105 (clobber (reg:CC FLAGS_REG))]
8107 "and{b}\t{%2, %h0|%h0, %2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "length_immediate" "1")
8110 (set_attr "modrm" "1")
8111 (set_attr "mode" "QI")])
8113 ;; Generated by peephole translating test to and. This shows up
8114 ;; often in fp comparisons.
8115 (define_insn "*andqi_ext_0_cc"
8116 [(set (reg FLAGS_REG)
8120 (match_operand 1 "ext_register_operand" "0")
8123 (match_operand 2 "const_int_operand" "n"))
8125 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8134 "ix86_match_ccmode (insn, CCNOmode)"
8135 "and{b}\t{%2, %h0|%h0, %2}"
8136 [(set_attr "type" "alu")
8137 (set_attr "length_immediate" "1")
8138 (set_attr "modrm" "1")
8139 (set_attr "mode" "QI")])
8141 (define_insn "*andqi_ext_1_rex64"
8142 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8147 (match_operand 1 "ext_register_operand" "0")
8151 (match_operand 2 "ext_register_operand" "Q"))))
8152 (clobber (reg:CC FLAGS_REG))]
8154 "and{b}\t{%2, %h0|%h0, %2}"
8155 [(set_attr "type" "alu")
8156 (set_attr "length_immediate" "0")
8157 (set_attr "mode" "QI")])
8159 (define_insn "*andqi_ext_1"
8160 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8165 (match_operand 1 "ext_register_operand" "0")
8169 (match_operand:QI 2 "general_operand" "Qm"))))
8170 (clobber (reg:CC FLAGS_REG))]
8172 "and{b}\t{%2, %h0|%h0, %2}"
8173 [(set_attr "type" "alu")
8174 (set_attr "length_immediate" "0")
8175 (set_attr "mode" "QI")])
8177 (define_insn "*andqi_ext_2"
8178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8183 (match_operand 1 "ext_register_operand" "%0")
8187 (match_operand 2 "ext_register_operand" "Q")
8190 (clobber (reg:CC FLAGS_REG))]
8192 "and{b}\t{%h2, %h0|%h0, %h2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "length_immediate" "0")
8195 (set_attr "mode" "QI")])
8197 ;; Convert wide AND instructions with immediate operand to shorter QImode
8198 ;; equivalents when possible.
8199 ;; Don't do the splitting with memory operands, since it introduces risk
8200 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8201 ;; for size, but that can (should?) be handled by generic code instead.
8203 [(set (match_operand 0 "register_operand" "")
8204 (and (match_operand 1 "register_operand" "")
8205 (match_operand 2 "const_int_operand" "")))
8206 (clobber (reg:CC FLAGS_REG))]
8208 && QI_REG_P (operands[0])
8209 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8210 && !(~INTVAL (operands[2]) & ~(255 << 8))
8211 && GET_MODE (operands[0]) != QImode"
8212 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8213 (and:SI (zero_extract:SI (match_dup 1)
8214 (const_int 8) (const_int 8))
8216 (clobber (reg:CC FLAGS_REG))])]
8217 "operands[0] = gen_lowpart (SImode, operands[0]);
8218 operands[1] = gen_lowpart (SImode, operands[1]);
8219 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8221 ;; Since AND can be encoded with sign extended immediate, this is only
8222 ;; profitable when 7th bit is not set.
8224 [(set (match_operand 0 "register_operand" "")
8225 (and (match_operand 1 "general_operand" "")
8226 (match_operand 2 "const_int_operand" "")))
8227 (clobber (reg:CC FLAGS_REG))]
8229 && ANY_QI_REG_P (operands[0])
8230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8231 && !(~INTVAL (operands[2]) & ~255)
8232 && !(INTVAL (operands[2]) & 128)
8233 && GET_MODE (operands[0]) != QImode"
8234 [(parallel [(set (strict_low_part (match_dup 0))
8235 (and:QI (match_dup 1)
8237 (clobber (reg:CC FLAGS_REG))])]
8238 "operands[0] = gen_lowpart (QImode, operands[0]);
8239 operands[1] = gen_lowpart (QImode, operands[1]);
8240 operands[2] = gen_lowpart (QImode, operands[2]);")
8242 ;; Logical inclusive and exclusive OR instructions
8244 ;; %%% This used to optimize known byte-wide and operations to memory.
8245 ;; If this is considered useful, it should be done with splitters.
8247 (define_expand "<code><mode>3"
8248 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8249 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8250 (match_operand:SWIM 2 "<general_operand>" "")))]
8252 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8254 (define_insn "*<code><mode>_1"
8255 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8257 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8258 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8261 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "mode" "<MODE>")])
8265 ;; %%% Potential partial reg stall on alternative 2. What to do?
8266 (define_insn "*<code>qi_1"
8267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8268 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8269 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8273 <logic>{b}\t{%2, %0|%0, %2}
8274 <logic>{b}\t{%2, %0|%0, %2}
8275 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8276 [(set_attr "type" "alu")
8277 (set_attr "mode" "QI,QI,SI")])
8279 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8280 (define_insn "*<code>si_1_zext"
8281 [(set (match_operand:DI 0 "register_operand" "=r")
8283 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8284 (match_operand:SI 2 "general_operand" "g"))))
8285 (clobber (reg:CC FLAGS_REG))]
8286 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8287 "<logic>{l}\t{%2, %k0|%k0, %2}"
8288 [(set_attr "type" "alu")
8289 (set_attr "mode" "SI")])
8291 (define_insn "*<code>si_1_zext_imm"
8292 [(set (match_operand:DI 0 "register_operand" "=r")
8294 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8295 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8298 "<logic>{l}\t{%2, %k0|%k0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "SI")])
8302 (define_insn "*<code>qi_1_slp"
8303 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8304 (any_or:QI (match_dup 0)
8305 (match_operand:QI 1 "general_operand" "qmn,qn")))
8306 (clobber (reg:CC FLAGS_REG))]
8307 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8308 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8309 "<logic>{b}\t{%1, %0|%0, %1}"
8310 [(set_attr "type" "alu1")
8311 (set_attr "mode" "QI")])
8313 (define_insn "*<code><mode>_2"
8314 [(set (reg FLAGS_REG)
8315 (compare (any_or:SWI
8316 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8317 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8319 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8320 (any_or:SWI (match_dup 1) (match_dup 2)))]
8321 "ix86_match_ccmode (insn, CCNOmode)
8322 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8323 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "<MODE>")])
8327 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8328 ;; ??? Special case for immediate operand is missing - it is tricky.
8329 (define_insn "*<code>si_2_zext"
8330 [(set (reg FLAGS_REG)
8331 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8332 (match_operand:SI 2 "general_operand" "g"))
8334 (set (match_operand:DI 0 "register_operand" "=r")
8335 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8336 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8337 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8338 "<logic>{l}\t{%2, %k0|%k0, %2}"
8339 [(set_attr "type" "alu")
8340 (set_attr "mode" "SI")])
8342 (define_insn "*<code>si_2_zext_imm"
8343 [(set (reg FLAGS_REG)
8345 (match_operand:SI 1 "nonimmediate_operand" "%0")
8346 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8348 (set (match_operand:DI 0 "register_operand" "=r")
8349 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8350 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8352 "<logic>{l}\t{%2, %k0|%k0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "SI")])
8356 (define_insn "*<code>qi_2_slp"
8357 [(set (reg FLAGS_REG)
8358 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8359 (match_operand:QI 1 "general_operand" "qmn,qn"))
8361 (set (strict_low_part (match_dup 0))
8362 (any_or:QI (match_dup 0) (match_dup 1)))]
8363 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364 && ix86_match_ccmode (insn, CCNOmode)
8365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8366 "<logic>{b}\t{%1, %0|%0, %1}"
8367 [(set_attr "type" "alu1")
8368 (set_attr "mode" "QI")])
8370 (define_insn "*<code><mode>_3"
8371 [(set (reg FLAGS_REG)
8372 (compare (any_or:SWI
8373 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8374 (match_operand:SWI 2 "<general_operand>" "<g>"))
8376 (clobber (match_scratch:SWI 0 "=<r>"))]
8377 "ix86_match_ccmode (insn, CCNOmode)
8378 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8379 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "<MODE>")])
8383 (define_insn "*<code>qi_ext_0"
8384 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389 (match_operand 1 "ext_register_operand" "0")
8392 (match_operand 2 "const_int_operand" "n")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8395 "<logic>{b}\t{%2, %h0|%h0, %2}"
8396 [(set_attr "type" "alu")
8397 (set_attr "length_immediate" "1")
8398 (set_attr "modrm" "1")
8399 (set_attr "mode" "QI")])
8401 (define_insn "*<code>qi_ext_1_rex64"
8402 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8407 (match_operand 1 "ext_register_operand" "0")
8411 (match_operand 2 "ext_register_operand" "Q"))))
8412 (clobber (reg:CC FLAGS_REG))]
8414 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8415 "<logic>{b}\t{%2, %h0|%h0, %2}"
8416 [(set_attr "type" "alu")
8417 (set_attr "length_immediate" "0")
8418 (set_attr "mode" "QI")])
8420 (define_insn "*<code>qi_ext_1"
8421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8426 (match_operand 1 "ext_register_operand" "0")
8430 (match_operand:QI 2 "general_operand" "Qm"))))
8431 (clobber (reg:CC FLAGS_REG))]
8433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8434 "<logic>{b}\t{%2, %h0|%h0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8439 (define_insn "*<code>qi_ext_2"
8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8447 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8450 (clobber (reg:CC FLAGS_REG))]
8451 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8452 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8453 [(set_attr "type" "alu")
8454 (set_attr "length_immediate" "0")
8455 (set_attr "mode" "QI")])
8458 [(set (match_operand 0 "register_operand" "")
8459 (any_or (match_operand 1 "register_operand" "")
8460 (match_operand 2 "const_int_operand" "")))
8461 (clobber (reg:CC FLAGS_REG))]
8463 && QI_REG_P (operands[0])
8464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8465 && !(INTVAL (operands[2]) & ~(255 << 8))
8466 && GET_MODE (operands[0]) != QImode"
8467 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8468 (any_or:SI (zero_extract:SI (match_dup 1)
8469 (const_int 8) (const_int 8))
8471 (clobber (reg:CC FLAGS_REG))])]
8472 "operands[0] = gen_lowpart (SImode, operands[0]);
8473 operands[1] = gen_lowpart (SImode, operands[1]);
8474 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8476 ;; Since OR can be encoded with sign extended immediate, this is only
8477 ;; profitable when 7th bit is set.
8479 [(set (match_operand 0 "register_operand" "")
8480 (any_or (match_operand 1 "general_operand" "")
8481 (match_operand 2 "const_int_operand" "")))
8482 (clobber (reg:CC FLAGS_REG))]
8484 && ANY_QI_REG_P (operands[0])
8485 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8486 && !(INTVAL (operands[2]) & ~255)
8487 && (INTVAL (operands[2]) & 128)
8488 && GET_MODE (operands[0]) != QImode"
8489 [(parallel [(set (strict_low_part (match_dup 0))
8490 (any_or:QI (match_dup 1)
8492 (clobber (reg:CC FLAGS_REG))])]
8493 "operands[0] = gen_lowpart (QImode, operands[0]);
8494 operands[1] = gen_lowpart (QImode, operands[1]);
8495 operands[2] = gen_lowpart (QImode, operands[2]);")
8497 (define_expand "xorqi_cc_ext_1"
8499 (set (reg:CCNO FLAGS_REG)
8503 (match_operand 1 "ext_register_operand" "")
8506 (match_operand:QI 2 "general_operand" ""))
8508 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8518 (define_insn "*xorqi_cc_ext_1_rex64"
8519 [(set (reg FLAGS_REG)
8523 (match_operand 1 "ext_register_operand" "0")
8526 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8528 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8538 "xor{b}\t{%2, %h0|%h0, %2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "modrm" "1")
8541 (set_attr "mode" "QI")])
8543 (define_insn "*xorqi_cc_ext_1"
8544 [(set (reg FLAGS_REG)
8548 (match_operand 1 "ext_register_operand" "0")
8551 (match_operand:QI 2 "general_operand" "qmn"))
8553 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8562 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8563 "xor{b}\t{%2, %h0|%h0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "modrm" "1")
8566 (set_attr "mode" "QI")])
8568 ;; Negation instructions
8570 (define_expand "neg<mode>2"
8571 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8572 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8574 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8576 (define_insn_and_split "*neg<dwi>2_doubleword"
8577 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8578 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8584 [(set (reg:CCZ FLAGS_REG)
8585 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8586 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8589 (plus:DWIH (match_dup 3)
8590 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8592 (clobber (reg:CC FLAGS_REG))])
8595 (neg:DWIH (match_dup 2)))
8596 (clobber (reg:CC FLAGS_REG))])]
8597 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8599 (define_insn "*neg<mode>2_1"
8600 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8601 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8604 "neg{<imodesuffix>}\t%0"
8605 [(set_attr "type" "negnot")
8606 (set_attr "mode" "<MODE>")])
8608 ;; Combine is quite creative about this pattern.
8609 (define_insn "*negsi2_1_zext"
8610 [(set (match_operand:DI 0 "register_operand" "=r")
8612 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8615 (clobber (reg:CC FLAGS_REG))]
8616 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8618 [(set_attr "type" "negnot")
8619 (set_attr "mode" "SI")])
8621 ;; The problem with neg is that it does not perform (compare x 0),
8622 ;; it really performs (compare 0 x), which leaves us with the zero
8623 ;; flag being the only useful item.
8625 (define_insn "*neg<mode>2_cmpz"
8626 [(set (reg:CCZ FLAGS_REG)
8628 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8630 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8631 (neg:SWI (match_dup 1)))]
8632 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8633 "neg{<imodesuffix>}\t%0"
8634 [(set_attr "type" "negnot")
8635 (set_attr "mode" "<MODE>")])
8637 (define_insn "*negsi2_cmpz_zext"
8638 [(set (reg:CCZ FLAGS_REG)
8642 (match_operand:DI 1 "register_operand" "0")
8646 (set (match_operand:DI 0 "register_operand" "=r")
8647 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8650 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8652 [(set_attr "type" "negnot")
8653 (set_attr "mode" "SI")])
8655 ;; Changing of sign for FP values is doable using integer unit too.
8657 (define_expand "<code><mode>2"
8658 [(set (match_operand:X87MODEF 0 "register_operand" "")
8659 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8660 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8661 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8663 (define_insn "*absneg<mode>2_mixed"
8664 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8665 (match_operator:MODEF 3 "absneg_operator"
8666 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8667 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8672 (define_insn "*absneg<mode>2_sse"
8673 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8674 (match_operator:MODEF 3 "absneg_operator"
8675 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8676 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8681 (define_insn "*absneg<mode>2_i387"
8682 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8683 (match_operator:X87MODEF 3 "absneg_operator"
8684 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8685 (use (match_operand 2 "" ""))
8686 (clobber (reg:CC FLAGS_REG))]
8687 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8690 (define_expand "<code>tf2"
8691 [(set (match_operand:TF 0 "register_operand" "")
8692 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8694 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8696 (define_insn "*absnegtf2_sse"
8697 [(set (match_operand:TF 0 "register_operand" "=x,x")
8698 (match_operator:TF 3 "absneg_operator"
8699 [(match_operand:TF 1 "register_operand" "0,x")]))
8700 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8701 (clobber (reg:CC FLAGS_REG))]
8705 ;; Splitters for fp abs and neg.
8708 [(set (match_operand 0 "fp_register_operand" "")
8709 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8710 (use (match_operand 2 "" ""))
8711 (clobber (reg:CC FLAGS_REG))]
8713 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8716 [(set (match_operand 0 "register_operand" "")
8717 (match_operator 3 "absneg_operator"
8718 [(match_operand 1 "register_operand" "")]))
8719 (use (match_operand 2 "nonimmediate_operand" ""))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "reload_completed && SSE_REG_P (operands[0])"
8722 [(set (match_dup 0) (match_dup 3))]
8724 enum machine_mode mode = GET_MODE (operands[0]);
8725 enum machine_mode vmode = GET_MODE (operands[2]);
8728 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8729 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8730 if (operands_match_p (operands[0], operands[2]))
8733 operands[1] = operands[2];
8736 if (GET_CODE (operands[3]) == ABS)
8737 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8739 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8744 [(set (match_operand:SF 0 "register_operand" "")
8745 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8746 (use (match_operand:V4SF 2 "" ""))
8747 (clobber (reg:CC FLAGS_REG))]
8749 [(parallel [(set (match_dup 0) (match_dup 1))
8750 (clobber (reg:CC FLAGS_REG))])]
8753 operands[0] = gen_lowpart (SImode, operands[0]);
8754 if (GET_CODE (operands[1]) == ABS)
8756 tmp = gen_int_mode (0x7fffffff, SImode);
8757 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8761 tmp = gen_int_mode (0x80000000, SImode);
8762 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8768 [(set (match_operand:DF 0 "register_operand" "")
8769 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8770 (use (match_operand 2 "" ""))
8771 (clobber (reg:CC FLAGS_REG))]
8773 [(parallel [(set (match_dup 0) (match_dup 1))
8774 (clobber (reg:CC FLAGS_REG))])]
8779 tmp = gen_lowpart (DImode, operands[0]);
8780 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8783 if (GET_CODE (operands[1]) == ABS)
8786 tmp = gen_rtx_NOT (DImode, tmp);
8790 operands[0] = gen_highpart (SImode, operands[0]);
8791 if (GET_CODE (operands[1]) == ABS)
8793 tmp = gen_int_mode (0x7fffffff, SImode);
8794 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8798 tmp = gen_int_mode (0x80000000, SImode);
8799 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8806 [(set (match_operand:XF 0 "register_operand" "")
8807 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8808 (use (match_operand 2 "" ""))
8809 (clobber (reg:CC FLAGS_REG))]
8811 [(parallel [(set (match_dup 0) (match_dup 1))
8812 (clobber (reg:CC FLAGS_REG))])]
8815 operands[0] = gen_rtx_REG (SImode,
8816 true_regnum (operands[0])
8817 + (TARGET_64BIT ? 1 : 2));
8818 if (GET_CODE (operands[1]) == ABS)
8820 tmp = GEN_INT (0x7fff);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8825 tmp = GEN_INT (0x8000);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8831 ;; Conditionalize these after reload. If they match before reload, we
8832 ;; lose the clobber and ability to use integer instructions.
8834 (define_insn "*<code><mode>2_1"
8835 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8836 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8838 && (reload_completed
8839 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8840 "f<absneg_mnemonic>"
8841 [(set_attr "type" "fsgn")
8842 (set_attr "mode" "<MODE>")])
8844 (define_insn "*<code>extendsfdf2"
8845 [(set (match_operand:DF 0 "register_operand" "=f")
8846 (absneg:DF (float_extend:DF
8847 (match_operand:SF 1 "register_operand" "0"))))]
8848 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8849 "f<absneg_mnemonic>"
8850 [(set_attr "type" "fsgn")
8851 (set_attr "mode" "DF")])
8853 (define_insn "*<code>extendsfxf2"
8854 [(set (match_operand:XF 0 "register_operand" "=f")
8855 (absneg:XF (float_extend:XF
8856 (match_operand:SF 1 "register_operand" "0"))))]
8858 "f<absneg_mnemonic>"
8859 [(set_attr "type" "fsgn")
8860 (set_attr "mode" "XF")])
8862 (define_insn "*<code>extenddfxf2"
8863 [(set (match_operand:XF 0 "register_operand" "=f")
8864 (absneg:XF (float_extend:XF
8865 (match_operand:DF 1 "register_operand" "0"))))]
8867 "f<absneg_mnemonic>"
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "XF")])
8871 ;; Copysign instructions
8873 (define_mode_iterator CSGNMODE [SF DF TF])
8874 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8876 (define_expand "copysign<mode>3"
8877 [(match_operand:CSGNMODE 0 "register_operand" "")
8878 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8879 (match_operand:CSGNMODE 2 "register_operand" "")]
8880 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8881 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8882 "ix86_expand_copysign (operands); DONE;")
8884 (define_insn_and_split "copysign<mode>3_const"
8885 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8887 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8888 (match_operand:CSGNMODE 2 "register_operand" "0")
8889 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8891 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8892 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8894 "&& reload_completed"
8896 "ix86_split_copysign_const (operands); DONE;")
8898 (define_insn "copysign<mode>3_var"
8899 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8901 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8902 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8903 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8904 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8906 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8912 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8914 [(match_operand:CSGNMODE 2 "register_operand" "")
8915 (match_operand:CSGNMODE 3 "register_operand" "")
8916 (match_operand:<CSGNVMODE> 4 "" "")
8917 (match_operand:<CSGNVMODE> 5 "" "")]
8919 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8920 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8921 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8922 && reload_completed"
8924 "ix86_split_copysign_var (operands); DONE;")
8926 ;; One complement instructions
8928 (define_expand "one_cmpl<mode>2"
8929 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8930 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8932 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8934 (define_insn "*one_cmpl<mode>2_1"
8935 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8936 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8937 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8938 "not{<imodesuffix>}\t%0"
8939 [(set_attr "type" "negnot")
8940 (set_attr "mode" "<MODE>")])
8942 ;; %%% Potential partial reg stall on alternative 1. What to do?
8943 (define_insn "*one_cmplqi2_1"
8944 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8945 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8946 "ix86_unary_operator_ok (NOT, QImode, operands)"
8950 [(set_attr "type" "negnot")
8951 (set_attr "mode" "QI,SI")])
8953 ;; ??? Currently never generated - xor is used instead.
8954 (define_insn "*one_cmplsi2_1_zext"
8955 [(set (match_operand:DI 0 "register_operand" "=r")
8957 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8958 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8960 [(set_attr "type" "negnot")
8961 (set_attr "mode" "SI")])
8963 (define_insn "*one_cmpl<mode>2_2"
8964 [(set (reg FLAGS_REG)
8965 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8967 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8968 (not:SWI (match_dup 1)))]
8969 "ix86_match_ccmode (insn, CCNOmode)
8970 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8972 [(set_attr "type" "alu1")
8973 (set_attr "mode" "<MODE>")])
8976 [(set (match_operand 0 "flags_reg_operand" "")
8977 (match_operator 2 "compare_operator"
8978 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8980 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8981 (not:SWI (match_dup 3)))]
8982 "ix86_match_ccmode (insn, CCNOmode)"
8983 [(parallel [(set (match_dup 0)
8984 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8987 (xor:SWI (match_dup 3) (const_int -1)))])])
8989 ;; ??? Currently never generated - xor is used instead.
8990 (define_insn "*one_cmplsi2_2_zext"
8991 [(set (reg FLAGS_REG)
8992 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8994 (set (match_operand:DI 0 "register_operand" "=r")
8995 (zero_extend:DI (not:SI (match_dup 1))))]
8996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8997 && ix86_unary_operator_ok (NOT, SImode, operands)"
8999 [(set_attr "type" "alu1")
9000 (set_attr "mode" "SI")])
9003 [(set (match_operand 0 "flags_reg_operand" "")
9004 (match_operator 2 "compare_operator"
9005 [(not:SI (match_operand:SI 3 "register_operand" ""))
9007 (set (match_operand:DI 1 "register_operand" "")
9008 (zero_extend:DI (not:SI (match_dup 3))))]
9009 "ix86_match_ccmode (insn, CCNOmode)"
9010 [(parallel [(set (match_dup 0)
9011 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9014 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9016 ;; Shift instructions
9018 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9019 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9020 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9021 ;; from the assembler input.
9023 ;; This instruction shifts the target reg/mem as usual, but instead of
9024 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9025 ;; is a left shift double, bits are taken from the high order bits of
9026 ;; reg, else if the insn is a shift right double, bits are taken from the
9027 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9028 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9030 ;; Since sh[lr]d does not change the `reg' operand, that is done
9031 ;; separately, making all shifts emit pairs of shift double and normal
9032 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9033 ;; support a 63 bit shift, each shift where the count is in a reg expands
9034 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9036 ;; If the shift count is a constant, we need never emit more than one
9037 ;; shift pair, instead using moves and sign extension for counts greater
9040 (define_expand "ashl<mode>3"
9041 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9042 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9043 (match_operand:QI 2 "nonmemory_operand" "")))]
9045 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9047 (define_insn "*ashl<mode>3_doubleword"
9048 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9049 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9050 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9051 (clobber (reg:CC FLAGS_REG))]
9054 [(set_attr "type" "multi")])
9057 [(set (match_operand:DWI 0 "register_operand" "")
9058 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9059 (match_operand:QI 2 "nonmemory_operand" "")))
9060 (clobber (reg:CC FLAGS_REG))]
9061 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9063 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9065 ;; By default we don't ask for a scratch register, because when DWImode
9066 ;; values are manipulated, registers are already at a premium. But if
9067 ;; we have one handy, we won't turn it away.
9070 [(match_scratch:DWIH 3 "r")
9071 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9073 (match_operand:<DWI> 1 "nonmemory_operand" "")
9074 (match_operand:QI 2 "nonmemory_operand" "")))
9075 (clobber (reg:CC FLAGS_REG))])
9079 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9081 (define_insn "x86_64_shld"
9082 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9083 (ior:DI (ashift:DI (match_dup 0)
9084 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9086 (minus:QI (const_int 64) (match_dup 2)))))
9087 (clobber (reg:CC FLAGS_REG))]
9089 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9090 [(set_attr "type" "ishift")
9091 (set_attr "prefix_0f" "1")
9092 (set_attr "mode" "DI")
9093 (set_attr "athlon_decode" "vector")
9094 (set_attr "amdfam10_decode" "vector")])
9096 (define_insn "x86_shld"
9097 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9098 (ior:SI (ashift:SI (match_dup 0)
9099 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9100 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9101 (minus:QI (const_int 32) (match_dup 2)))))
9102 (clobber (reg:CC FLAGS_REG))]
9104 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9105 [(set_attr "type" "ishift")
9106 (set_attr "prefix_0f" "1")
9107 (set_attr "mode" "SI")
9108 (set_attr "pent_pair" "np")
9109 (set_attr "athlon_decode" "vector")
9110 (set_attr "amdfam10_decode" "vector")])
9112 (define_expand "x86_shift<mode>_adj_1"
9113 [(set (reg:CCZ FLAGS_REG)
9114 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9117 (set (match_operand:SWI48 0 "register_operand" "")
9118 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9119 (match_operand:SWI48 1 "register_operand" "")
9122 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9123 (match_operand:SWI48 3 "register_operand" "r")
9126 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9128 (define_expand "x86_shift<mode>_adj_2"
9129 [(use (match_operand:SWI48 0 "register_operand" ""))
9130 (use (match_operand:SWI48 1 "register_operand" ""))
9131 (use (match_operand:QI 2 "register_operand" ""))]
9134 rtx label = gen_label_rtx ();
9137 emit_insn (gen_testqi_ccz_1 (operands[2],
9138 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9140 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9141 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9142 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9143 gen_rtx_LABEL_REF (VOIDmode, label),
9145 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9146 JUMP_LABEL (tmp) = label;
9148 emit_move_insn (operands[0], operands[1]);
9149 ix86_expand_clear (operands[1]);
9152 LABEL_NUSES (label) = 1;
9157 (define_insn "*ashl<mode>3_1"
9158 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9159 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9160 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9161 (clobber (reg:CC FLAGS_REG))]
9162 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9164 switch (get_attr_type (insn))
9170 gcc_assert (operands[2] == const1_rtx);
9171 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9172 return "add{<imodesuffix>}\t%0, %0";
9175 if (operands[2] == const1_rtx
9176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9177 return "sal{<imodesuffix>}\t%0";
9179 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9183 (cond [(eq_attr "alternative" "1")
9184 (const_string "lea")
9185 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9187 (match_operand 0 "register_operand" ""))
9188 (match_operand 2 "const1_operand" ""))
9189 (const_string "alu")
9191 (const_string "ishift")))
9192 (set (attr "length_immediate")
9194 (ior (eq_attr "type" "alu")
9195 (and (eq_attr "type" "ishift")
9196 (and (match_operand 2 "const1_operand" "")
9197 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9200 (const_string "*")))
9201 (set_attr "mode" "<MODE>")])
9203 (define_insn "*ashlsi3_1_zext"
9204 [(set (match_operand:DI 0 "register_operand" "=r,r")
9206 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9207 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9208 (clobber (reg:CC FLAGS_REG))]
9209 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9211 switch (get_attr_type (insn))
9217 gcc_assert (operands[2] == const1_rtx);
9218 return "add{l}\t%k0, %k0";
9221 if (operands[2] == const1_rtx
9222 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9223 return "sal{l}\t%k0";
9225 return "sal{l}\t{%2, %k0|%k0, %2}";
9229 (cond [(eq_attr "alternative" "1")
9230 (const_string "lea")
9231 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9233 (match_operand 2 "const1_operand" ""))
9234 (const_string "alu")
9236 (const_string "ishift")))
9237 (set (attr "length_immediate")
9239 (ior (eq_attr "type" "alu")
9240 (and (eq_attr "type" "ishift")
9241 (and (match_operand 2 "const1_operand" "")
9242 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9245 (const_string "*")))
9246 (set_attr "mode" "SI")])
9248 (define_insn "*ashlhi3_1"
9249 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9250 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9251 (match_operand:QI 2 "nonmemory_operand" "cI")))
9252 (clobber (reg:CC FLAGS_REG))]
9253 "TARGET_PARTIAL_REG_STALL
9254 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9256 switch (get_attr_type (insn))
9259 gcc_assert (operands[2] == const1_rtx);
9260 return "add{w}\t%0, %0";
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{w}\t%0";
9267 return "sal{w}\t{%2, %0|%0, %2}";
9271 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9277 (const_string "ishift")))
9278 (set (attr "length_immediate")
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9286 (const_string "*")))
9287 (set_attr "mode" "HI")])
9289 (define_insn "*ashlhi3_1_lea"
9290 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9291 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9292 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "!TARGET_PARTIAL_REG_STALL
9295 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9297 switch (get_attr_type (insn))
9303 gcc_assert (operands[2] == const1_rtx);
9304 return "add{w}\t%0, %0";
9307 if (operands[2] == const1_rtx
9308 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9309 return "sal{w}\t%0";
9311 return "sal{w}\t{%2, %0|%0, %2}";
9315 (cond [(eq_attr "alternative" "1")
9316 (const_string "lea")
9317 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9319 (match_operand 0 "register_operand" ""))
9320 (match_operand 2 "const1_operand" ""))
9321 (const_string "alu")
9323 (const_string "ishift")))
9324 (set (attr "length_immediate")
9326 (ior (eq_attr "type" "alu")
9327 (and (eq_attr "type" "ishift")
9328 (and (match_operand 2 "const1_operand" "")
9329 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9332 (const_string "*")))
9333 (set_attr "mode" "HI,SI")])
9335 (define_insn "*ashlqi3_1"
9336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9337 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9338 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9339 (clobber (reg:CC FLAGS_REG))]
9340 "TARGET_PARTIAL_REG_STALL
9341 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9343 switch (get_attr_type (insn))
9346 gcc_assert (operands[2] == const1_rtx);
9347 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9348 return "add{l}\t%k0, %k0";
9350 return "add{b}\t%0, %0";
9353 if (operands[2] == const1_rtx
9354 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9356 if (get_attr_mode (insn) == MODE_SI)
9357 return "sal{l}\t%k0";
9359 return "sal{b}\t%0";
9363 if (get_attr_mode (insn) == MODE_SI)
9364 return "sal{l}\t{%2, %k0|%k0, %2}";
9366 return "sal{b}\t{%2, %0|%0, %2}";
9371 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9373 (match_operand 0 "register_operand" ""))
9374 (match_operand 2 "const1_operand" ""))
9375 (const_string "alu")
9377 (const_string "ishift")))
9378 (set (attr "length_immediate")
9380 (ior (eq_attr "type" "alu")
9381 (and (eq_attr "type" "ishift")
9382 (and (match_operand 2 "const1_operand" "")
9383 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9386 (const_string "*")))
9387 (set_attr "mode" "QI,SI")])
9389 ;; %%% Potential partial reg stall on alternative 2. What to do?
9390 (define_insn "*ashlqi3_1_lea"
9391 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9392 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9393 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "!TARGET_PARTIAL_REG_STALL
9396 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9398 switch (get_attr_type (insn))
9404 gcc_assert (operands[2] == const1_rtx);
9405 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9406 return "add{l}\t%k0, %k0";
9408 return "add{b}\t%0, %0";
9411 if (operands[2] == const1_rtx
9412 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9414 if (get_attr_mode (insn) == MODE_SI)
9415 return "sal{l}\t%k0";
9417 return "sal{b}\t%0";
9421 if (get_attr_mode (insn) == MODE_SI)
9422 return "sal{l}\t{%2, %k0|%k0, %2}";
9424 return "sal{b}\t{%2, %0|%0, %2}";
9429 (cond [(eq_attr "alternative" "2")
9430 (const_string "lea")
9431 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9433 (match_operand 0 "register_operand" ""))
9434 (match_operand 2 "const1_operand" ""))
9435 (const_string "alu")
9437 (const_string "ishift")))
9438 (set (attr "length_immediate")
9440 (ior (eq_attr "type" "alu")
9441 (and (eq_attr "type" "ishift")
9442 (and (match_operand 2 "const1_operand" "")
9443 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9446 (const_string "*")))
9447 (set_attr "mode" "QI,SI,SI")])
9449 (define_insn "*ashlqi3_1_slp"
9450 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9451 (ashift:QI (match_dup 0)
9452 (match_operand:QI 1 "nonmemory_operand" "cI")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "(optimize_function_for_size_p (cfun)
9455 || !TARGET_PARTIAL_FLAG_REG_STALL
9456 || (operands[1] == const1_rtx
9458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9460 switch (get_attr_type (insn))
9463 gcc_assert (operands[1] == const1_rtx);
9464 return "add{b}\t%0, %0";
9467 if (operands[1] == const1_rtx
9468 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9469 return "sal{b}\t%0";
9471 return "sal{b}\t{%1, %0|%0, %1}";
9475 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9477 (match_operand 0 "register_operand" ""))
9478 (match_operand 1 "const1_operand" ""))
9479 (const_string "alu")
9481 (const_string "ishift1")))
9482 (set (attr "length_immediate")
9484 (ior (eq_attr "type" "alu")
9485 (and (eq_attr "type" "ishift1")
9486 (and (match_operand 1 "const1_operand" "")
9487 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9490 (const_string "*")))
9491 (set_attr "mode" "QI")])
9493 ;; Convert lea to the lea pattern to avoid flags dependency.
9495 [(set (match_operand 0 "register_operand" "")
9496 (ashift (match_operand 1 "index_register_operand" "")
9497 (match_operand:QI 2 "const_int_operand" "")))
9498 (clobber (reg:CC FLAGS_REG))]
9500 && true_regnum (operands[0]) != true_regnum (operands[1])"
9504 enum machine_mode mode = GET_MODE (operands[0]);
9507 operands[1] = gen_lowpart (Pmode, operands[1]);
9508 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9510 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9512 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9513 operands[0] = gen_lowpart (SImode, operands[0]);
9515 if (TARGET_64BIT && mode != Pmode)
9516 pat = gen_rtx_SUBREG (SImode, pat, 0);
9518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9522 ;; Convert lea to the lea pattern to avoid flags dependency.
9524 [(set (match_operand:DI 0 "register_operand" "")
9526 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9527 (match_operand:QI 2 "const_int_operand" ""))))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "TARGET_64BIT && reload_completed
9530 && true_regnum (operands[0]) != true_regnum (operands[1])"
9532 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9534 operands[1] = gen_lowpart (DImode, operands[1]);
9535 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9538 ;; This pattern can't accept a variable shift count, since shifts by
9539 ;; zero don't affect the flags. We assume that shifts by constant
9540 ;; zero are optimized away.
9541 (define_insn "*ashl<mode>3_cmp"
9542 [(set (reg FLAGS_REG)
9544 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9545 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9547 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9548 (ashift:SWI (match_dup 1) (match_dup 2)))]
9549 "(optimize_function_for_size_p (cfun)
9550 || !TARGET_PARTIAL_FLAG_REG_STALL
9551 || (operands[2] == const1_rtx
9553 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9554 && ix86_match_ccmode (insn, CCGOCmode)
9555 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9557 switch (get_attr_type (insn))
9560 gcc_assert (operands[2] == const1_rtx);
9561 return "add{<imodesuffix>}\t%0, %0";
9564 if (operands[2] == const1_rtx
9565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566 return "sal{<imodesuffix>}\t%0";
9568 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9574 (match_operand 0 "register_operand" ""))
9575 (match_operand 2 "const1_operand" ""))
9576 (const_string "alu")
9578 (const_string "ishift")))
9579 (set (attr "length_immediate")
9581 (ior (eq_attr "type" "alu")
9582 (and (eq_attr "type" "ishift")
9583 (and (match_operand 2 "const1_operand" "")
9584 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9587 (const_string "*")))
9588 (set_attr "mode" "<MODE>")])
9590 (define_insn "*ashlsi3_cmp_zext"
9591 [(set (reg FLAGS_REG)
9593 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9594 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9596 (set (match_operand:DI 0 "register_operand" "=r")
9597 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9599 && (optimize_function_for_size_p (cfun)
9600 || !TARGET_PARTIAL_FLAG_REG_STALL
9601 || (operands[2] == const1_rtx
9603 || TARGET_DOUBLE_WITH_ADD)))
9604 && ix86_match_ccmode (insn, CCGOCmode)
9605 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9607 switch (get_attr_type (insn))
9610 gcc_assert (operands[2] == const1_rtx);
9611 return "add{l}\t%k0, %k0";
9614 if (operands[2] == const1_rtx
9615 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9616 return "sal{l}\t%k0";
9618 return "sal{l}\t{%2, %k0|%k0, %2}";
9622 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9624 (match_operand 2 "const1_operand" ""))
9625 (const_string "alu")
9627 (const_string "ishift")))
9628 (set (attr "length_immediate")
9630 (ior (eq_attr "type" "alu")
9631 (and (eq_attr "type" "ishift")
9632 (and (match_operand 2 "const1_operand" "")
9633 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9636 (const_string "*")))
9637 (set_attr "mode" "SI")])
9639 (define_insn "*ashl<mode>3_cconly"
9640 [(set (reg FLAGS_REG)
9642 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9643 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9645 (clobber (match_scratch:SWI 0 "=<r>"))]
9646 "(optimize_function_for_size_p (cfun)
9647 || !TARGET_PARTIAL_FLAG_REG_STALL
9648 || (operands[2] == const1_rtx
9650 || TARGET_DOUBLE_WITH_ADD)))
9651 && ix86_match_ccmode (insn, CCGOCmode)
9652 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9654 switch (get_attr_type (insn))
9657 gcc_assert (operands[2] == const1_rtx);
9658 return "add{<imodesuffix>}\t%0, %0";
9661 if (operands[2] == const1_rtx
9662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663 return "sal{<imodesuffix>}\t%0";
9665 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9669 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9671 (match_operand 0 "register_operand" ""))
9672 (match_operand 2 "const1_operand" ""))
9673 (const_string "alu")
9675 (const_string "ishift")))
9676 (set (attr "length_immediate")
9678 (ior (eq_attr "type" "alu")
9679 (and (eq_attr "type" "ishift")
9680 (and (match_operand 2 "const1_operand" "")
9681 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9684 (const_string "*")))
9685 (set_attr "mode" "<MODE>")])
9687 ;; See comment above `ashl<mode>3' about how this works.
9689 (define_expand "<shiftrt_insn><mode>3"
9690 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9691 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9692 (match_operand:QI 2 "nonmemory_operand" "")))]
9694 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9696 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9697 [(set (match_operand:DWI 0 "register_operand" "=r")
9698 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9699 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9700 (clobber (reg:CC FLAGS_REG))]
9703 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9705 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9706 [(set_attr "type" "multi")])
9708 ;; By default we don't ask for a scratch register, because when DWImode
9709 ;; values are manipulated, registers are already at a premium. But if
9710 ;; we have one handy, we won't turn it away.
9713 [(match_scratch:DWIH 3 "r")
9714 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9716 (match_operand:<DWI> 1 "register_operand" "")
9717 (match_operand:QI 2 "nonmemory_operand" "")))
9718 (clobber (reg:CC FLAGS_REG))])
9722 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9724 (define_insn "x86_64_shrd"
9725 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9726 (ior:DI (ashiftrt:DI (match_dup 0)
9727 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9728 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9729 (minus:QI (const_int 64) (match_dup 2)))))
9730 (clobber (reg:CC FLAGS_REG))]
9732 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9733 [(set_attr "type" "ishift")
9734 (set_attr "prefix_0f" "1")
9735 (set_attr "mode" "DI")
9736 (set_attr "athlon_decode" "vector")
9737 (set_attr "amdfam10_decode" "vector")])
9739 (define_insn "x86_shrd"
9740 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9741 (ior:SI (ashiftrt:SI (match_dup 0)
9742 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9743 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9744 (minus:QI (const_int 32) (match_dup 2)))))
9745 (clobber (reg:CC FLAGS_REG))]
9747 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9748 [(set_attr "type" "ishift")
9749 (set_attr "prefix_0f" "1")
9750 (set_attr "mode" "SI")
9751 (set_attr "pent_pair" "np")
9752 (set_attr "athlon_decode" "vector")
9753 (set_attr "amdfam10_decode" "vector")])
9755 (define_insn "ashrdi3_cvt"
9756 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9757 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9758 (match_operand:QI 2 "const_int_operand" "")))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_64BIT && INTVAL (operands[2]) == 63
9761 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9762 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9765 sar{q}\t{%2, %0|%0, %2}"
9766 [(set_attr "type" "imovx,ishift")
9767 (set_attr "prefix_0f" "0,*")
9768 (set_attr "length_immediate" "0,*")
9769 (set_attr "modrm" "0,1")
9770 (set_attr "mode" "DI")])
9772 (define_insn "ashrsi3_cvt"
9773 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9774 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9775 (match_operand:QI 2 "const_int_operand" "")))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "INTVAL (operands[2]) == 31
9778 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9779 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9782 sar{l}\t{%2, %0|%0, %2}"
9783 [(set_attr "type" "imovx,ishift")
9784 (set_attr "prefix_0f" "0,*")
9785 (set_attr "length_immediate" "0,*")
9786 (set_attr "modrm" "0,1")
9787 (set_attr "mode" "SI")])
9789 (define_insn "*ashrsi3_cvt_zext"
9790 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9792 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9793 (match_operand:QI 2 "const_int_operand" ""))))
9794 (clobber (reg:CC FLAGS_REG))]
9795 "TARGET_64BIT && INTVAL (operands[2]) == 31
9796 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9797 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9800 sar{l}\t{%2, %k0|%k0, %2}"
9801 [(set_attr "type" "imovx,ishift")
9802 (set_attr "prefix_0f" "0,*")
9803 (set_attr "length_immediate" "0,*")
9804 (set_attr "modrm" "0,1")
9805 (set_attr "mode" "SI")])
9807 (define_expand "x86_shift<mode>_adj_3"
9808 [(use (match_operand:SWI48 0 "register_operand" ""))
9809 (use (match_operand:SWI48 1 "register_operand" ""))
9810 (use (match_operand:QI 2 "register_operand" ""))]
9813 rtx label = gen_label_rtx ();
9816 emit_insn (gen_testqi_ccz_1 (operands[2],
9817 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9819 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9820 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9821 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9822 gen_rtx_LABEL_REF (VOIDmode, label),
9824 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9825 JUMP_LABEL (tmp) = label;
9827 emit_move_insn (operands[0], operands[1]);
9828 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9829 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9831 LABEL_NUSES (label) = 1;
9836 (define_insn "*<shiftrt_insn><mode>3_1"
9837 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9838 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9839 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9843 if (operands[2] == const1_rtx
9844 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845 return "<shiftrt>{<imodesuffix>}\t%0";
9847 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9849 [(set_attr "type" "ishift")
9850 (set (attr "length_immediate")
9852 (and (match_operand 2 "const1_operand" "")
9853 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9856 (const_string "*")))
9857 (set_attr "mode" "<MODE>")])
9859 (define_insn "*<shiftrt_insn>si3_1_zext"
9860 [(set (match_operand:DI 0 "register_operand" "=r")
9862 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9863 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9864 (clobber (reg:CC FLAGS_REG))]
9865 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shiftrt>{l}\t%k0";
9871 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9876 (and (match_operand 2 "const1_operand" "")
9877 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9880 (const_string "*")))
9881 (set_attr "mode" "SI")])
9883 (define_insn "*<shiftrt_insn>qi3_1_slp"
9884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9885 (any_shiftrt:QI (match_dup 0)
9886 (match_operand:QI 1 "nonmemory_operand" "cI")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "(optimize_function_for_size_p (cfun)
9889 || !TARGET_PARTIAL_REG_STALL
9890 || (operands[1] == const1_rtx
9893 if (operands[1] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shiftrt>{b}\t%0";
9897 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9899 [(set_attr "type" "ishift1")
9900 (set (attr "length_immediate")
9902 (and (match_operand 1 "const1_operand" "")
9903 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9906 (const_string "*")))
9907 (set_attr "mode" "QI")])
9909 ;; This pattern can't accept a variable shift count, since shifts by
9910 ;; zero don't affect the flags. We assume that shifts by constant
9911 ;; zero are optimized away.
9912 (define_insn "*<shiftrt_insn><mode>3_cmp"
9913 [(set (reg FLAGS_REG)
9916 (match_operand:SWI 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9921 "(optimize_function_for_size_p (cfun)
9922 || !TARGET_PARTIAL_FLAG_REG_STALL
9923 || (operands[2] == const1_rtx
9925 && ix86_match_ccmode (insn, CCGOCmode)
9926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9928 if (operands[2] == const1_rtx
9929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9930 return "<shiftrt>{<imodesuffix>}\t%0";
9932 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9934 [(set_attr "type" "ishift")
9935 (set (attr "length_immediate")
9937 (and (match_operand 2 "const1_operand" "")
9938 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9941 (const_string "*")))
9942 (set_attr "mode" "<MODE>")])
9944 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9945 [(set (reg FLAGS_REG)
9947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9950 (set (match_operand:DI 0 "register_operand" "=r")
9951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9953 && (optimize_function_for_size_p (cfun)
9954 || !TARGET_PARTIAL_FLAG_REG_STALL
9955 || (operands[2] == const1_rtx
9957 && ix86_match_ccmode (insn, CCGOCmode)
9958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9960 if (operands[2] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962 return "<shiftrt>{l}\t%k0";
9964 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9966 [(set_attr "type" "ishift")
9967 (set (attr "length_immediate")
9969 (and (match_operand 2 "const1_operand" "")
9970 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9973 (const_string "*")))
9974 (set_attr "mode" "SI")])
9976 (define_insn "*<shiftrt_insn><mode>3_cconly"
9977 [(set (reg FLAGS_REG)
9980 (match_operand:SWI 1 "nonimmediate_operand" "0")
9981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9983 (clobber (match_scratch:SWI 0 "=<r>"))]
9984 "(optimize_function_for_size_p (cfun)
9985 || !TARGET_PARTIAL_FLAG_REG_STALL
9986 || (operands[2] == const1_rtx
9988 && ix86_match_ccmode (insn, CCGOCmode)
9989 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9991 if (operands[2] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993 return "<shiftrt>{<imodesuffix>}\t%0";
9995 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9997 [(set_attr "type" "ishift")
9998 (set (attr "length_immediate")
10000 (and (match_operand 2 "const1_operand" "")
10001 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10004 (const_string "*")))
10005 (set_attr "mode" "<MODE>")])
10007 ;; Rotate instructions
10009 (define_expand "<rotate_insn>ti3"
10010 [(set (match_operand:TI 0 "register_operand" "")
10011 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10012 (match_operand:QI 2 "nonmemory_operand" "")))]
10015 if (const_1_to_63_operand (operands[2], VOIDmode))
10016 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10017 (operands[0], operands[1], operands[2]));
10024 (define_expand "<rotate_insn>di3"
10025 [(set (match_operand:DI 0 "shiftdi_operand" "")
10026 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10027 (match_operand:QI 2 "nonmemory_operand" "")))]
10031 ix86_expand_binary_operator (<CODE>, DImode, operands);
10032 else if (const_1_to_31_operand (operands[2], VOIDmode))
10033 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10034 (operands[0], operands[1], operands[2]));
10041 (define_expand "<rotate_insn><mode>3"
10042 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10043 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10044 (match_operand:QI 2 "nonmemory_operand" "")))]
10046 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10048 ;; Implement rotation using two double-precision
10049 ;; shift instructions and a scratch register.
10051 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10052 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10053 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10054 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10055 (clobber (reg:CC FLAGS_REG))
10056 (clobber (match_scratch:DWIH 3 "=&r"))]
10060 [(set (match_dup 3) (match_dup 4))
10062 [(set (match_dup 4)
10063 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10064 (lshiftrt:DWIH (match_dup 5)
10065 (minus:QI (match_dup 6) (match_dup 2)))))
10066 (clobber (reg:CC FLAGS_REG))])
10068 [(set (match_dup 5)
10069 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10070 (lshiftrt:DWIH (match_dup 3)
10071 (minus:QI (match_dup 6) (match_dup 2)))))
10072 (clobber (reg:CC FLAGS_REG))])]
10074 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10076 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10079 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10080 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10081 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10082 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10083 (clobber (reg:CC FLAGS_REG))
10084 (clobber (match_scratch:DWIH 3 "=&r"))]
10088 [(set (match_dup 3) (match_dup 4))
10090 [(set (match_dup 4)
10091 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10092 (ashift:DWIH (match_dup 5)
10093 (minus:QI (match_dup 6) (match_dup 2)))))
10094 (clobber (reg:CC FLAGS_REG))])
10096 [(set (match_dup 5)
10097 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10098 (ashift:DWIH (match_dup 3)
10099 (minus:QI (match_dup 6) (match_dup 2)))))
10100 (clobber (reg:CC FLAGS_REG))])]
10102 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10104 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10107 (define_insn "*<rotate_insn><mode>3_1"
10108 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10109 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10110 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10111 (clobber (reg:CC FLAGS_REG))]
10112 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116 return "<rotate>{<imodesuffix>}\t%0";
10118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10120 [(set_attr "type" "rotate")
10121 (set (attr "length_immediate")
10123 (and (match_operand 2 "const1_operand" "")
10124 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10127 (const_string "*")))
10128 (set_attr "mode" "<MODE>")])
10130 (define_insn "*<rotate_insn>si3_1_zext"
10131 [(set (match_operand:DI 0 "register_operand" "=r")
10133 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10134 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10135 (clobber (reg:CC FLAGS_REG))]
10136 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10138 if (operands[2] == const1_rtx
10139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10140 return "<rotate>{l}\t%k0";
10142 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10144 [(set_attr "type" "rotate")
10145 (set (attr "length_immediate")
10147 (and (match_operand 2 "const1_operand" "")
10148 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10151 (const_string "*")))
10152 (set_attr "mode" "SI")])
10154 (define_insn "*<rotate_insn>qi3_1_slp"
10155 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10156 (any_rotate:QI (match_dup 0)
10157 (match_operand:QI 1 "nonmemory_operand" "cI")))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "(optimize_function_for_size_p (cfun)
10160 || !TARGET_PARTIAL_REG_STALL
10161 || (operands[1] == const1_rtx
10162 && TARGET_SHIFT1))"
10164 if (operands[1] == const1_rtx
10165 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10166 return "<rotate>{b}\t%0";
10168 return "<rotate>{b}\t{%1, %0|%0, %1}";
10170 [(set_attr "type" "rotate1")
10171 (set (attr "length_immediate")
10173 (and (match_operand 1 "const1_operand" "")
10174 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10177 (const_string "*")))
10178 (set_attr "mode" "QI")])
10181 [(set (match_operand:HI 0 "register_operand" "")
10182 (any_rotate:HI (match_dup 0) (const_int 8)))
10183 (clobber (reg:CC FLAGS_REG))]
10185 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10186 [(parallel [(set (strict_low_part (match_dup 0))
10187 (bswap:HI (match_dup 0)))
10188 (clobber (reg:CC FLAGS_REG))])])
10190 ;; Bit set / bit test instructions
10192 (define_expand "extv"
10193 [(set (match_operand:SI 0 "register_operand" "")
10194 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10195 (match_operand:SI 2 "const8_operand" "")
10196 (match_operand:SI 3 "const8_operand" "")))]
10199 /* Handle extractions from %ah et al. */
10200 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10203 /* From mips.md: extract_bit_field doesn't verify that our source
10204 matches the predicate, so check it again here. */
10205 if (! ext_register_operand (operands[1], VOIDmode))
10209 (define_expand "extzv"
10210 [(set (match_operand:SI 0 "register_operand" "")
10211 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10212 (match_operand:SI 2 "const8_operand" "")
10213 (match_operand:SI 3 "const8_operand" "")))]
10216 /* Handle extractions from %ah et al. */
10217 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10220 /* From mips.md: extract_bit_field doesn't verify that our source
10221 matches the predicate, so check it again here. */
10222 if (! ext_register_operand (operands[1], VOIDmode))
10226 (define_expand "insv"
10227 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10228 (match_operand 1 "const8_operand" "")
10229 (match_operand 2 "const8_operand" ""))
10230 (match_operand 3 "register_operand" ""))]
10233 rtx (*gen_mov_insv_1) (rtx, rtx);
10235 /* Handle insertions to %ah et al. */
10236 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10239 /* From mips.md: insert_bit_field doesn't verify that our source
10240 matches the predicate, so check it again here. */
10241 if (! ext_register_operand (operands[0], VOIDmode))
10244 gen_mov_insv_1 = (TARGET_64BIT
10245 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10247 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10251 ;; %%% bts, btr, btc, bt.
10252 ;; In general these instructions are *slow* when applied to memory,
10253 ;; since they enforce atomic operation. When applied to registers,
10254 ;; it depends on the cpu implementation. They're never faster than
10255 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10256 ;; no point. But in 64-bit, we can't hold the relevant immediates
10257 ;; within the instruction itself, so operating on bits in the high
10258 ;; 32-bits of a register becomes easier.
10260 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10261 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10262 ;; negdf respectively, so they can never be disabled entirely.
10264 (define_insn "*btsq"
10265 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10267 (match_operand:DI 1 "const_0_to_63_operand" ""))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10271 "bts{q}\t{%1, %0|%0, %1}"
10272 [(set_attr "type" "alu1")
10273 (set_attr "prefix_0f" "1")
10274 (set_attr "mode" "DI")])
10276 (define_insn "*btrq"
10277 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10279 (match_operand:DI 1 "const_0_to_63_operand" ""))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10283 "btr{q}\t{%1, %0|%0, %1}"
10284 [(set_attr "type" "alu1")
10285 (set_attr "prefix_0f" "1")
10286 (set_attr "mode" "DI")])
10288 (define_insn "*btcq"
10289 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10291 (match_operand:DI 1 "const_0_to_63_operand" ""))
10292 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10295 "btc{q}\t{%1, %0|%0, %1}"
10296 [(set_attr "type" "alu1")
10297 (set_attr "prefix_0f" "1")
10298 (set_attr "mode" "DI")])
10300 ;; Allow Nocona to avoid these instructions if a register is available.
10303 [(match_scratch:DI 2 "r")
10304 (parallel [(set (zero_extract:DI
10305 (match_operand:DI 0 "register_operand" "")
10307 (match_operand:DI 1 "const_0_to_63_operand" ""))
10309 (clobber (reg:CC FLAGS_REG))])]
10310 "TARGET_64BIT && !TARGET_USE_BT"
10313 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10316 if (HOST_BITS_PER_WIDE_INT >= 64)
10317 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10318 else if (i < HOST_BITS_PER_WIDE_INT)
10319 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10321 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10323 op1 = immed_double_const (lo, hi, DImode);
10326 emit_move_insn (operands[2], op1);
10330 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10335 [(match_scratch:DI 2 "r")
10336 (parallel [(set (zero_extract:DI
10337 (match_operand:DI 0 "register_operand" "")
10339 (match_operand:DI 1 "const_0_to_63_operand" ""))
10341 (clobber (reg:CC FLAGS_REG))])]
10342 "TARGET_64BIT && !TARGET_USE_BT"
10345 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10348 if (HOST_BITS_PER_WIDE_INT >= 64)
10349 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10350 else if (i < HOST_BITS_PER_WIDE_INT)
10351 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10353 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10355 op1 = immed_double_const (~lo, ~hi, DImode);
10358 emit_move_insn (operands[2], op1);
10362 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10367 [(match_scratch:DI 2 "r")
10368 (parallel [(set (zero_extract:DI
10369 (match_operand:DI 0 "register_operand" "")
10371 (match_operand:DI 1 "const_0_to_63_operand" ""))
10372 (not:DI (zero_extract:DI
10373 (match_dup 0) (const_int 1) (match_dup 1))))
10374 (clobber (reg:CC FLAGS_REG))])]
10375 "TARGET_64BIT && !TARGET_USE_BT"
10378 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10381 if (HOST_BITS_PER_WIDE_INT >= 64)
10382 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10383 else if (i < HOST_BITS_PER_WIDE_INT)
10384 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10386 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10388 op1 = immed_double_const (lo, hi, DImode);
10391 emit_move_insn (operands[2], op1);
10395 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10399 (define_insn "*bt<mode>"
10400 [(set (reg:CCC FLAGS_REG)
10402 (zero_extract:SWI48
10403 (match_operand:SWI48 0 "register_operand" "r")
10405 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10407 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10408 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10409 [(set_attr "type" "alu1")
10410 (set_attr "prefix_0f" "1")
10411 (set_attr "mode" "<MODE>")])
10413 ;; Store-flag instructions.
10415 ;; For all sCOND expanders, also expand the compare or test insn that
10416 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10418 (define_insn_and_split "*setcc_di_1"
10419 [(set (match_operand:DI 0 "register_operand" "=q")
10420 (match_operator:DI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10422 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10424 "&& reload_completed"
10425 [(set (match_dup 2) (match_dup 1))
10426 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10428 PUT_MODE (operands[1], QImode);
10429 operands[2] = gen_lowpart (QImode, operands[0]);
10432 (define_insn_and_split "*setcc_si_1_and"
10433 [(set (match_operand:SI 0 "register_operand" "=q")
10434 (match_operator:SI 1 "ix86_comparison_operator"
10435 [(reg FLAGS_REG) (const_int 0)]))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "!TARGET_PARTIAL_REG_STALL
10438 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10440 "&& reload_completed"
10441 [(set (match_dup 2) (match_dup 1))
10442 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10443 (clobber (reg:CC FLAGS_REG))])]
10445 PUT_MODE (operands[1], QImode);
10446 operands[2] = gen_lowpart (QImode, operands[0]);
10449 (define_insn_and_split "*setcc_si_1_movzbl"
10450 [(set (match_operand:SI 0 "register_operand" "=q")
10451 (match_operator:SI 1 "ix86_comparison_operator"
10452 [(reg FLAGS_REG) (const_int 0)]))]
10453 "!TARGET_PARTIAL_REG_STALL
10454 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10456 "&& reload_completed"
10457 [(set (match_dup 2) (match_dup 1))
10458 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10460 PUT_MODE (operands[1], QImode);
10461 operands[2] = gen_lowpart (QImode, operands[0]);
10464 (define_insn "*setcc_qi"
10465 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10466 (match_operator:QI 1 "ix86_comparison_operator"
10467 [(reg FLAGS_REG) (const_int 0)]))]
10470 [(set_attr "type" "setcc")
10471 (set_attr "mode" "QI")])
10473 (define_insn "*setcc_qi_slp"
10474 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10475 (match_operator:QI 1 "ix86_comparison_operator"
10476 [(reg FLAGS_REG) (const_int 0)]))]
10479 [(set_attr "type" "setcc")
10480 (set_attr "mode" "QI")])
10482 ;; In general it is not safe to assume too much about CCmode registers,
10483 ;; so simplify-rtx stops when it sees a second one. Under certain
10484 ;; conditions this is safe on x86, so help combine not create
10491 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10492 (ne:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10496 [(set (match_dup 0) (match_dup 1))]
10497 "PUT_MODE (operands[1], QImode);")
10500 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10501 (ne:QI (match_operator 1 "ix86_comparison_operator"
10502 [(reg FLAGS_REG) (const_int 0)])
10505 [(set (match_dup 0) (match_dup 1))]
10506 "PUT_MODE (operands[1], QImode);")
10509 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10510 (eq:QI (match_operator 1 "ix86_comparison_operator"
10511 [(reg FLAGS_REG) (const_int 0)])
10514 [(set (match_dup 0) (match_dup 1))]
10516 rtx new_op1 = copy_rtx (operands[1]);
10517 operands[1] = new_op1;
10518 PUT_MODE (new_op1, QImode);
10519 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10520 GET_MODE (XEXP (new_op1, 0))));
10522 /* Make sure that (a) the CCmode we have for the flags is strong
10523 enough for the reversed compare or (b) we have a valid FP compare. */
10524 if (! ix86_comparison_operator (new_op1, VOIDmode))
10529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10530 (eq:QI (match_operator 1 "ix86_comparison_operator"
10531 [(reg FLAGS_REG) (const_int 0)])
10534 [(set (match_dup 0) (match_dup 1))]
10536 rtx new_op1 = copy_rtx (operands[1]);
10537 operands[1] = new_op1;
10538 PUT_MODE (new_op1, QImode);
10539 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10540 GET_MODE (XEXP (new_op1, 0))));
10542 /* Make sure that (a) the CCmode we have for the flags is strong
10543 enough for the reversed compare or (b) we have a valid FP compare. */
10544 if (! ix86_comparison_operator (new_op1, VOIDmode))
10548 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10549 ;; subsequent logical operations are used to imitate conditional moves.
10550 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10553 (define_insn "*avx_setcc<mode>"
10554 [(set (match_operand:MODEF 0 "register_operand" "=x")
10555 (match_operator:MODEF 1 "avx_comparison_float_operator"
10556 [(match_operand:MODEF 2 "register_operand" "x")
10557 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10559 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10560 [(set_attr "type" "ssecmp")
10561 (set_attr "prefix" "vex")
10562 (set_attr "length_immediate" "1")
10563 (set_attr "mode" "<MODE>")])
10565 (define_insn "*sse_setcc<mode>"
10566 [(set (match_operand:MODEF 0 "register_operand" "=x")
10567 (match_operator:MODEF 1 "sse_comparison_operator"
10568 [(match_operand:MODEF 2 "register_operand" "0")
10569 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10570 "SSE_FLOAT_MODE_P (<MODE>mode)"
10571 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10572 [(set_attr "type" "ssecmp")
10573 (set_attr "length_immediate" "1")
10574 (set_attr "mode" "<MODE>")])
10576 ;; Basic conditional jump instructions.
10577 ;; We ignore the overflow flag for signed branch instructions.
10579 (define_insn "*jcc_1"
10581 (if_then_else (match_operator 1 "ix86_comparison_operator"
10582 [(reg FLAGS_REG) (const_int 0)])
10583 (label_ref (match_operand 0 "" ""))
10587 [(set_attr "type" "ibr")
10588 (set_attr "modrm" "0")
10589 (set (attr "length")
10590 (if_then_else (and (ge (minus (match_dup 0) (pc))
10592 (lt (minus (match_dup 0) (pc))
10597 (define_insn "*jcc_2"
10599 (if_then_else (match_operator 1 "ix86_comparison_operator"
10600 [(reg FLAGS_REG) (const_int 0)])
10602 (label_ref (match_operand 0 "" ""))))]
10605 [(set_attr "type" "ibr")
10606 (set_attr "modrm" "0")
10607 (set (attr "length")
10608 (if_then_else (and (ge (minus (match_dup 0) (pc))
10610 (lt (minus (match_dup 0) (pc))
10615 ;; In general it is not safe to assume too much about CCmode registers,
10616 ;; so simplify-rtx stops when it sees a second one. Under certain
10617 ;; conditions this is safe on x86, so help combine not create
10625 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10626 [(reg FLAGS_REG) (const_int 0)])
10628 (label_ref (match_operand 1 "" ""))
10632 (if_then_else (match_dup 0)
10633 (label_ref (match_dup 1))
10635 "PUT_MODE (operands[0], VOIDmode);")
10639 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)])
10642 (label_ref (match_operand 1 "" ""))
10646 (if_then_else (match_dup 0)
10647 (label_ref (match_dup 1))
10650 rtx new_op0 = copy_rtx (operands[0]);
10651 operands[0] = new_op0;
10652 PUT_MODE (new_op0, VOIDmode);
10653 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10654 GET_MODE (XEXP (new_op0, 0))));
10656 /* Make sure that (a) the CCmode we have for the flags is strong
10657 enough for the reversed compare or (b) we have a valid FP compare. */
10658 if (! ix86_comparison_operator (new_op0, VOIDmode))
10662 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10663 ;; pass generates from shift insn with QImode operand. Actually, the mode
10664 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10665 ;; appropriate modulo of the bit offset value.
10667 (define_insn_and_split "*jcc_bt<mode>"
10669 (if_then_else (match_operator 0 "bt_comparison_operator"
10670 [(zero_extract:SWI48
10671 (match_operand:SWI48 1 "register_operand" "r")
10674 (match_operand:QI 2 "register_operand" "r")))
10676 (label_ref (match_operand 3 "" ""))
10678 (clobber (reg:CC FLAGS_REG))]
10679 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10682 [(set (reg:CCC FLAGS_REG)
10684 (zero_extract:SWI48
10690 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10691 (label_ref (match_dup 3))
10694 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10696 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10699 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10700 ;; also for DImode, this is what combine produces.
10701 (define_insn_and_split "*jcc_bt<mode>_mask"
10703 (if_then_else (match_operator 0 "bt_comparison_operator"
10704 [(zero_extract:SWI48
10705 (match_operand:SWI48 1 "register_operand" "r")
10708 (match_operand:SI 2 "register_operand" "r")
10709 (match_operand:SI 3 "const_int_operand" "n")))])
10710 (label_ref (match_operand 4 "" ""))
10712 (clobber (reg:CC FLAGS_REG))]
10713 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10715 == GET_MODE_BITSIZE (<MODE>mode)-1"
10718 [(set (reg:CCC FLAGS_REG)
10720 (zero_extract:SWI48
10726 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10727 (label_ref (match_dup 4))
10730 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10732 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10735 (define_insn_and_split "*jcc_btsi_1"
10737 (if_then_else (match_operator 0 "bt_comparison_operator"
10740 (match_operand:SI 1 "register_operand" "r")
10741 (match_operand:QI 2 "register_operand" "r"))
10744 (label_ref (match_operand 3 "" ""))
10746 (clobber (reg:CC FLAGS_REG))]
10747 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10750 [(set (reg:CCC FLAGS_REG)
10758 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10759 (label_ref (match_dup 3))
10762 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10764 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10767 ;; avoid useless masking of bit offset operand
10768 (define_insn_and_split "*jcc_btsi_mask_1"
10771 (match_operator 0 "bt_comparison_operator"
10774 (match_operand:SI 1 "register_operand" "r")
10777 (match_operand:SI 2 "register_operand" "r")
10778 (match_operand:SI 3 "const_int_operand" "n")) 0))
10781 (label_ref (match_operand 4 "" ""))
10783 (clobber (reg:CC FLAGS_REG))]
10784 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10785 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10788 [(set (reg:CCC FLAGS_REG)
10796 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10797 (label_ref (match_dup 4))
10799 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10801 ;; Define combination compare-and-branch fp compare instructions to help
10804 (define_insn "*fp_jcc_1_387"
10806 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10807 [(match_operand 1 "register_operand" "f")
10808 (match_operand 2 "nonimmediate_operand" "fm")])
10809 (label_ref (match_operand 3 "" ""))
10811 (clobber (reg:CCFP FPSR_REG))
10812 (clobber (reg:CCFP FLAGS_REG))
10813 (clobber (match_scratch:HI 4 "=a"))]
10815 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10816 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10817 && SELECT_CC_MODE (GET_CODE (operands[0]),
10818 operands[1], operands[2]) == CCFPmode
10822 (define_insn "*fp_jcc_1r_387"
10824 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10825 [(match_operand 1 "register_operand" "f")
10826 (match_operand 2 "nonimmediate_operand" "fm")])
10828 (label_ref (match_operand 3 "" ""))))
10829 (clobber (reg:CCFP FPSR_REG))
10830 (clobber (reg:CCFP FLAGS_REG))
10831 (clobber (match_scratch:HI 4 "=a"))]
10833 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10835 && SELECT_CC_MODE (GET_CODE (operands[0]),
10836 operands[1], operands[2]) == CCFPmode
10840 (define_insn "*fp_jcc_2_387"
10842 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10843 [(match_operand 1 "register_operand" "f")
10844 (match_operand 2 "register_operand" "f")])
10845 (label_ref (match_operand 3 "" ""))
10847 (clobber (reg:CCFP FPSR_REG))
10848 (clobber (reg:CCFP FLAGS_REG))
10849 (clobber (match_scratch:HI 4 "=a"))]
10850 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10851 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10855 (define_insn "*fp_jcc_2r_387"
10857 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10858 [(match_operand 1 "register_operand" "f")
10859 (match_operand 2 "register_operand" "f")])
10861 (label_ref (match_operand 3 "" ""))))
10862 (clobber (reg:CCFP FPSR_REG))
10863 (clobber (reg:CCFP FLAGS_REG))
10864 (clobber (match_scratch:HI 4 "=a"))]
10865 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10866 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10870 (define_insn "*fp_jcc_3_387"
10872 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10873 [(match_operand 1 "register_operand" "f")
10874 (match_operand 2 "const0_operand" "")])
10875 (label_ref (match_operand 3 "" ""))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))
10879 (clobber (match_scratch:HI 4 "=a"))]
10880 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10881 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10882 && SELECT_CC_MODE (GET_CODE (operands[0]),
10883 operands[1], operands[2]) == CCFPmode
10889 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890 [(match_operand 1 "register_operand" "")
10891 (match_operand 2 "nonimmediate_operand" "")])
10892 (match_operand 3 "" "")
10893 (match_operand 4 "" "")))
10894 (clobber (reg:CCFP FPSR_REG))
10895 (clobber (reg:CCFP FLAGS_REG))]
10899 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10900 operands[3], operands[4], NULL_RTX, NULL_RTX);
10906 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10907 [(match_operand 1 "register_operand" "")
10908 (match_operand 2 "general_operand" "")])
10909 (match_operand 3 "" "")
10910 (match_operand 4 "" "")))
10911 (clobber (reg:CCFP FPSR_REG))
10912 (clobber (reg:CCFP FLAGS_REG))
10913 (clobber (match_scratch:HI 5 "=a"))]
10917 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10918 operands[3], operands[4], operands[5], NULL_RTX);
10922 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10923 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10924 ;; with a precedence over other operators and is always put in the first
10925 ;; place. Swap condition and operands to match ficom instruction.
10927 (define_insn "*fp_jcc_4_<mode>_387"
10930 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10931 [(match_operator 1 "float_operator"
10932 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10933 (match_operand 3 "register_operand" "f,f")])
10934 (label_ref (match_operand 4 "" ""))
10936 (clobber (reg:CCFP FPSR_REG))
10937 (clobber (reg:CCFP FLAGS_REG))
10938 (clobber (match_scratch:HI 5 "=a,a"))]
10939 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10940 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10941 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10942 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10949 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10950 [(match_operator 1 "float_operator"
10951 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10952 (match_operand 3 "register_operand" "")])
10953 (match_operand 4 "" "")
10954 (match_operand 5 "" "")))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 6 "=a"))]
10961 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10963 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10964 operands[3], operands[7],
10965 operands[4], operands[5], operands[6], NULL_RTX);
10969 ;; %%% Kill this when reload knows how to do it.
10973 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10974 [(match_operator 1 "float_operator"
10975 [(match_operand:X87MODEI12 2 "register_operand" "")])
10976 (match_operand 3 "register_operand" "")])
10977 (match_operand 4 "" "")
10978 (match_operand 5 "" "")))
10979 (clobber (reg:CCFP FPSR_REG))
10980 (clobber (reg:CCFP FLAGS_REG))
10981 (clobber (match_scratch:HI 6 "=a"))]
10985 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10986 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10988 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10989 operands[3], operands[7],
10990 operands[4], operands[5], operands[6], operands[2]);
10994 ;; Unconditional and other jump instructions
10996 (define_insn "jump"
10998 (label_ref (match_operand 0 "" "")))]
11001 [(set_attr "type" "ibr")
11002 (set (attr "length")
11003 (if_then_else (and (ge (minus (match_dup 0) (pc))
11005 (lt (minus (match_dup 0) (pc))
11009 (set_attr "modrm" "0")])
11011 (define_expand "indirect_jump"
11012 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11016 (define_insn "*indirect_jump"
11017 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11020 [(set_attr "type" "ibr")
11021 (set_attr "length_immediate" "0")])
11023 (define_expand "tablejump"
11024 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11025 (use (label_ref (match_operand 1 "" "")))])]
11028 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11029 relative. Convert the relative address to an absolute address. */
11033 enum rtx_code code;
11035 /* We can't use @GOTOFF for text labels on VxWorks;
11036 see gotoff_operand. */
11037 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11041 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11043 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11047 op1 = pic_offset_table_rtx;
11052 op0 = pic_offset_table_rtx;
11056 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11061 (define_insn "*tablejump_1"
11062 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11063 (use (label_ref (match_operand 1 "" "")))]
11066 [(set_attr "type" "ibr")
11067 (set_attr "length_immediate" "0")])
11069 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11072 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11073 (set (match_operand:QI 1 "register_operand" "")
11074 (match_operator:QI 2 "ix86_comparison_operator"
11075 [(reg FLAGS_REG) (const_int 0)]))
11076 (set (match_operand 3 "q_regs_operand" "")
11077 (zero_extend (match_dup 1)))]
11078 "(peep2_reg_dead_p (3, operands[1])
11079 || operands_match_p (operands[1], operands[3]))
11080 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11081 [(set (match_dup 4) (match_dup 0))
11082 (set (strict_low_part (match_dup 5))
11085 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11086 operands[5] = gen_lowpart (QImode, operands[3]);
11087 ix86_expand_clear (operands[3]);
11090 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11093 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11094 (set (match_operand:QI 1 "register_operand" "")
11095 (match_operator:QI 2 "ix86_comparison_operator"
11096 [(reg FLAGS_REG) (const_int 0)]))
11097 (parallel [(set (match_operand 3 "q_regs_operand" "")
11098 (zero_extend (match_dup 1)))
11099 (clobber (reg:CC FLAGS_REG))])]
11100 "(peep2_reg_dead_p (3, operands[1])
11101 || operands_match_p (operands[1], operands[3]))
11102 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11103 [(set (match_dup 4) (match_dup 0))
11104 (set (strict_low_part (match_dup 5))
11107 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11108 operands[5] = gen_lowpart (QImode, operands[3]);
11109 ix86_expand_clear (operands[3]);
11112 ;; Call instructions.
11114 ;; The predicates normally associated with named expanders are not properly
11115 ;; checked for calls. This is a bug in the generic code, but it isn't that
11116 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11118 ;; P6 processors will jump to the address after the decrement when %esp
11119 ;; is used as a call operand, so they will execute return address as a code.
11120 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11122 ;; Call subroutine returning no value.
11124 (define_expand "call_pop"
11125 [(parallel [(call (match_operand:QI 0 "" "")
11126 (match_operand:SI 1 "" ""))
11127 (set (reg:SI SP_REG)
11128 (plus:SI (reg:SI SP_REG)
11129 (match_operand:SI 3 "" "")))])]
11132 ix86_expand_call (NULL, operands[0], operands[1],
11133 operands[2], operands[3], 0);
11137 (define_insn "*call_pop_0"
11138 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11139 (match_operand:SI 1 "" ""))
11140 (set (reg:SI SP_REG)
11141 (plus:SI (reg:SI SP_REG)
11142 (match_operand:SI 2 "immediate_operand" "")))]
11145 if (SIBLING_CALL_P (insn))
11148 return "call\t%P0";
11150 [(set_attr "type" "call")])
11152 (define_insn "*call_pop_1"
11153 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11154 (match_operand:SI 1 "" ""))
11155 (set (reg:SI SP_REG)
11156 (plus:SI (reg:SI SP_REG)
11157 (match_operand:SI 2 "immediate_operand" "i")))]
11158 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11160 if (constant_call_address_operand (operands[0], Pmode))
11161 return "call\t%P0";
11162 return "call\t%A0";
11164 [(set_attr "type" "call")])
11166 (define_insn "*sibcall_pop_1"
11167 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11168 (match_operand:SI 1 "" ""))
11169 (set (reg:SI SP_REG)
11170 (plus:SI (reg:SI SP_REG)
11171 (match_operand:SI 2 "immediate_operand" "i,i")))]
11172 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11176 [(set_attr "type" "call")])
11178 (define_expand "call"
11179 [(call (match_operand:QI 0 "" "")
11180 (match_operand 1 "" ""))
11181 (use (match_operand 2 "" ""))]
11184 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11188 (define_expand "sibcall"
11189 [(call (match_operand:QI 0 "" "")
11190 (match_operand 1 "" ""))
11191 (use (match_operand 2 "" ""))]
11194 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11198 (define_insn "*call_0"
11199 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11200 (match_operand 1 "" ""))]
11203 if (SIBLING_CALL_P (insn))
11206 return "call\t%P0";
11208 [(set_attr "type" "call")])
11210 (define_insn "*call_1"
11211 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11212 (match_operand 1 "" ""))]
11213 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11215 if (constant_call_address_operand (operands[0], Pmode))
11216 return "call\t%P0";
11217 return "call\t%A0";
11219 [(set_attr "type" "call")])
11221 (define_insn "*sibcall_1"
11222 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11223 (match_operand 1 "" ""))]
11224 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11228 [(set_attr "type" "call")])
11230 (define_insn "*call_1_rex64"
11231 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11232 (match_operand 1 "" ""))]
11233 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11234 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11236 if (constant_call_address_operand (operands[0], Pmode))
11237 return "call\t%P0";
11238 return "call\t%A0";
11240 [(set_attr "type" "call")])
11242 (define_insn "*call_1_rex64_ms_sysv"
11243 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11244 (match_operand 1 "" ""))
11245 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11246 (clobber (reg:TI XMM6_REG))
11247 (clobber (reg:TI XMM7_REG))
11248 (clobber (reg:TI XMM8_REG))
11249 (clobber (reg:TI XMM9_REG))
11250 (clobber (reg:TI XMM10_REG))
11251 (clobber (reg:TI XMM11_REG))
11252 (clobber (reg:TI XMM12_REG))
11253 (clobber (reg:TI XMM13_REG))
11254 (clobber (reg:TI XMM14_REG))
11255 (clobber (reg:TI XMM15_REG))
11256 (clobber (reg:DI SI_REG))
11257 (clobber (reg:DI DI_REG))]
11258 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11260 if (constant_call_address_operand (operands[0], Pmode))
11261 return "call\t%P0";
11262 return "call\t%A0";
11264 [(set_attr "type" "call")])
11266 (define_insn "*call_1_rex64_large"
11267 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11268 (match_operand 1 "" ""))]
11269 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11271 [(set_attr "type" "call")])
11273 (define_insn "*sibcall_1_rex64"
11274 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11275 (match_operand 1 "" ""))]
11276 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11280 [(set_attr "type" "call")])
11282 ;; Call subroutine, returning value in operand 0
11283 (define_expand "call_value_pop"
11284 [(parallel [(set (match_operand 0 "" "")
11285 (call (match_operand:QI 1 "" "")
11286 (match_operand:SI 2 "" "")))
11287 (set (reg:SI SP_REG)
11288 (plus:SI (reg:SI SP_REG)
11289 (match_operand:SI 4 "" "")))])]
11292 ix86_expand_call (operands[0], operands[1], operands[2],
11293 operands[3], operands[4], 0);
11297 (define_expand "call_value"
11298 [(set (match_operand 0 "" "")
11299 (call (match_operand:QI 1 "" "")
11300 (match_operand:SI 2 "" "")))
11301 (use (match_operand:SI 3 "" ""))]
11302 ;; Operand 3 is not used on the i386.
11305 ix86_expand_call (operands[0], operands[1], operands[2],
11306 operands[3], NULL, 0);
11310 (define_expand "sibcall_value"
11311 [(set (match_operand 0 "" "")
11312 (call (match_operand:QI 1 "" "")
11313 (match_operand:SI 2 "" "")))
11314 (use (match_operand:SI 3 "" ""))]
11315 ;; Operand 3 is not used on the i386.
11318 ix86_expand_call (operands[0], operands[1], operands[2],
11319 operands[3], NULL, 1);
11323 ;; Call subroutine returning any type.
11325 (define_expand "untyped_call"
11326 [(parallel [(call (match_operand 0 "" "")
11328 (match_operand 1 "" "")
11329 (match_operand 2 "" "")])]
11334 /* In order to give reg-stack an easier job in validating two
11335 coprocessor registers as containing a possible return value,
11336 simply pretend the untyped call returns a complex long double
11339 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11340 and should have the default ABI. */
11342 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11343 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11344 operands[0], const0_rtx,
11345 GEN_INT ((TARGET_64BIT
11346 ? (ix86_abi == SYSV_ABI
11347 ? X86_64_SSE_REGPARM_MAX
11348 : X86_64_MS_SSE_REGPARM_MAX)
11349 : X86_32_SSE_REGPARM_MAX)
11353 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11355 rtx set = XVECEXP (operands[2], 0, i);
11356 emit_move_insn (SET_DEST (set), SET_SRC (set));
11359 /* The optimizer does not know that the call sets the function value
11360 registers we stored in the result block. We avoid problems by
11361 claiming that all hard registers are used and clobbered at this
11363 emit_insn (gen_blockage ());
11368 ;; Prologue and epilogue instructions
11370 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11371 ;; all of memory. This blocks insns from being moved across this point.
11373 (define_insn "blockage"
11374 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11377 [(set_attr "length" "0")])
11379 ;; Do not schedule instructions accessing memory across this point.
11381 (define_expand "memory_blockage"
11382 [(set (match_dup 0)
11383 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11386 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11387 MEM_VOLATILE_P (operands[0]) = 1;
11390 (define_insn "*memory_blockage"
11391 [(set (match_operand:BLK 0 "" "")
11392 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11395 [(set_attr "length" "0")])
11397 ;; As USE insns aren't meaningful after reload, this is used instead
11398 ;; to prevent deleting instructions setting registers for PIC code
11399 (define_insn "prologue_use"
11400 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11403 [(set_attr "length" "0")])
11405 ;; Insn emitted into the body of a function to return from a function.
11406 ;; This is only done if the function's epilogue is known to be simple.
11407 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11409 (define_expand "return"
11411 "ix86_can_use_return_insn_p ()"
11413 if (crtl->args.pops_args)
11415 rtx popc = GEN_INT (crtl->args.pops_args);
11416 emit_jump_insn (gen_return_pop_internal (popc));
11421 (define_insn "return_internal"
11425 [(set_attr "length" "1")
11426 (set_attr "atom_unit" "jeu")
11427 (set_attr "length_immediate" "0")
11428 (set_attr "modrm" "0")])
11430 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11431 ;; instruction Athlon and K8 have.
11433 (define_insn "return_internal_long"
11435 (unspec [(const_int 0)] UNSPEC_REP)]
11438 [(set_attr "length" "2")
11439 (set_attr "atom_unit" "jeu")
11440 (set_attr "length_immediate" "0")
11441 (set_attr "prefix_rep" "1")
11442 (set_attr "modrm" "0")])
11444 (define_insn "return_pop_internal"
11446 (use (match_operand:SI 0 "const_int_operand" ""))]
11449 [(set_attr "length" "3")
11450 (set_attr "atom_unit" "jeu")
11451 (set_attr "length_immediate" "2")
11452 (set_attr "modrm" "0")])
11454 (define_insn "return_indirect_internal"
11456 (use (match_operand:SI 0 "register_operand" "r"))]
11459 [(set_attr "type" "ibr")
11460 (set_attr "length_immediate" "0")])
11466 [(set_attr "length" "1")
11467 (set_attr "length_immediate" "0")
11468 (set_attr "modrm" "0")])
11470 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11471 (define_insn "nops"
11472 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11476 int num = INTVAL (operands[0]);
11478 gcc_assert (num >= 1 && num <= 8);
11481 fputs ("\tnop\n", asm_out_file);
11485 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11486 (set_attr "length_immediate" "0")
11487 (set_attr "modrm" "0")])
11489 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11490 ;; branch prediction penalty for the third jump in a 16-byte
11494 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11497 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11498 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11500 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11501 The align insn is used to avoid 3 jump instructions in the row to improve
11502 branch prediction and the benefits hardly outweigh the cost of extra 8
11503 nops on the average inserted by full alignment pseudo operation. */
11507 [(set_attr "length" "16")])
11509 (define_expand "prologue"
11512 "ix86_expand_prologue (); DONE;")
11514 (define_insn "set_got"
11515 [(set (match_operand:SI 0 "register_operand" "=r")
11516 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11517 (clobber (reg:CC FLAGS_REG))]
11519 "* return output_set_got (operands[0], NULL_RTX);"
11520 [(set_attr "type" "multi")
11521 (set_attr "length" "12")])
11523 (define_insn "set_got_labelled"
11524 [(set (match_operand:SI 0 "register_operand" "=r")
11525 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11527 (clobber (reg:CC FLAGS_REG))]
11529 "* return output_set_got (operands[0], operands[1]);"
11530 [(set_attr "type" "multi")
11531 (set_attr "length" "12")])
11533 (define_insn "set_got_rex64"
11534 [(set (match_operand:DI 0 "register_operand" "=r")
11535 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11537 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11538 [(set_attr "type" "lea")
11539 (set_attr "length_address" "4")
11540 (set_attr "mode" "DI")])
11542 (define_insn "set_rip_rex64"
11543 [(set (match_operand:DI 0 "register_operand" "=r")
11544 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11546 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11547 [(set_attr "type" "lea")
11548 (set_attr "length_address" "4")
11549 (set_attr "mode" "DI")])
11551 (define_insn "set_got_offset_rex64"
11552 [(set (match_operand:DI 0 "register_operand" "=r")
11554 [(label_ref (match_operand 1 "" ""))]
11555 UNSPEC_SET_GOT_OFFSET))]
11557 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11558 [(set_attr "type" "imov")
11559 (set_attr "length_immediate" "0")
11560 (set_attr "length_address" "8")
11561 (set_attr "mode" "DI")])
11563 (define_expand "epilogue"
11566 "ix86_expand_epilogue (1); DONE;")
11568 (define_expand "sibcall_epilogue"
11571 "ix86_expand_epilogue (0); DONE;")
11573 (define_expand "eh_return"
11574 [(use (match_operand 0 "register_operand" ""))]
11577 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11579 /* Tricky bit: we write the address of the handler to which we will
11580 be returning into someone else's stack frame, one word below the
11581 stack address we wish to restore. */
11582 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11583 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11584 tmp = gen_rtx_MEM (Pmode, tmp);
11585 emit_move_insn (tmp, ra);
11587 emit_jump_insn (gen_eh_return_internal ());
11592 (define_insn_and_split "eh_return_internal"
11596 "epilogue_completed"
11598 "ix86_expand_epilogue (2); DONE;")
11600 (define_insn "leave"
11601 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11602 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11603 (clobber (mem:BLK (scratch)))]
11606 [(set_attr "type" "leave")])
11608 (define_insn "leave_rex64"
11609 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11610 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11611 (clobber (mem:BLK (scratch)))]
11614 [(set_attr "type" "leave")])
11616 ;; Handle -fsplit-stack.
11618 (define_expand "split_stack_prologue"
11622 ix86_expand_split_stack_prologue ();
11626 ;; In order to support the call/return predictor, we use a return
11627 ;; instruction which the middle-end doesn't see.
11628 (define_insn "split_stack_return"
11629 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11630 UNSPEC_STACK_CHECK)]
11633 if (operands[0] == const0_rtx)
11638 [(set_attr "atom_unit" "jeu")
11639 (set_attr "modrm" "0")
11640 (set (attr "length")
11641 (if_then_else (match_operand:SI 0 "const0_operand" "")
11644 (set (attr "length_immediate")
11645 (if_then_else (match_operand:SI 0 "const0_operand" "")
11649 ;; If there are operand 0 bytes available on the stack, jump to
11652 (define_expand "split_stack_space_check"
11653 [(set (pc) (if_then_else
11654 (ltu (minus (reg SP_REG)
11655 (match_operand 0 "register_operand" ""))
11656 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11657 (label_ref (match_operand 1 "" ""))
11661 rtx reg, size, limit;
11663 reg = gen_reg_rtx (Pmode);
11664 size = force_reg (Pmode, operands[0]);
11665 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11666 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11667 UNSPEC_STACK_CHECK);
11668 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11669 ix86_expand_branch (GEU, reg, limit, operands[1]);
11674 ;; Bit manipulation instructions.
11676 (define_expand "ffs<mode>2"
11677 [(set (match_dup 2) (const_int -1))
11678 (parallel [(set (reg:CCZ FLAGS_REG)
11680 (match_operand:SWI48 1 "nonimmediate_operand" "")
11682 (set (match_operand:SWI48 0 "register_operand" "")
11683 (ctz:SWI48 (match_dup 1)))])
11684 (set (match_dup 0) (if_then_else:SWI48
11685 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11688 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11689 (clobber (reg:CC FLAGS_REG))])]
11692 if (<MODE>mode == SImode && !TARGET_CMOVE)
11694 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11697 operands[2] = gen_reg_rtx (<MODE>mode);
11700 (define_insn_and_split "ffssi2_no_cmove"
11701 [(set (match_operand:SI 0 "register_operand" "=r")
11702 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11703 (clobber (match_scratch:SI 2 "=&q"))
11704 (clobber (reg:CC FLAGS_REG))]
11707 "&& reload_completed"
11708 [(parallel [(set (reg:CCZ FLAGS_REG)
11709 (compare:CCZ (match_dup 1) (const_int 0)))
11710 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11711 (set (strict_low_part (match_dup 3))
11712 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11713 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11714 (clobber (reg:CC FLAGS_REG))])
11715 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11716 (clobber (reg:CC FLAGS_REG))])
11717 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11718 (clobber (reg:CC FLAGS_REG))])]
11720 operands[3] = gen_lowpart (QImode, operands[2]);
11721 ix86_expand_clear (operands[2]);
11724 (define_insn "*ffs<mode>_1"
11725 [(set (reg:CCZ FLAGS_REG)
11726 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11728 (set (match_operand:SWI48 0 "register_operand" "=r")
11729 (ctz:SWI48 (match_dup 1)))]
11731 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11732 [(set_attr "type" "alu1")
11733 (set_attr "prefix_0f" "1")
11734 (set_attr "mode" "<MODE>")])
11736 (define_insn "ctz<mode>2"
11737 [(set (match_operand:SWI48 0 "register_operand" "=r")
11738 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11739 (clobber (reg:CC FLAGS_REG))]
11741 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11742 [(set_attr "type" "alu1")
11743 (set_attr "prefix_0f" "1")
11744 (set_attr "mode" "<MODE>")])
11746 (define_expand "clz<mode>2"
11748 [(set (match_operand:SWI248 0 "register_operand" "")
11751 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11752 (clobber (reg:CC FLAGS_REG))])
11754 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11755 (clobber (reg:CC FLAGS_REG))])]
11760 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11763 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11766 (define_insn "clz<mode>2_abm"
11767 [(set (match_operand:SWI248 0 "register_operand" "=r")
11768 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11769 (clobber (reg:CC FLAGS_REG))]
11771 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11772 [(set_attr "prefix_rep" "1")
11773 (set_attr "type" "bitmanip")
11774 (set_attr "mode" "<MODE>")])
11776 (define_insn "bsr_rex64"
11777 [(set (match_operand:DI 0 "register_operand" "=r")
11778 (minus:DI (const_int 63)
11779 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11780 (clobber (reg:CC FLAGS_REG))]
11782 "bsr{q}\t{%1, %0|%0, %1}"
11783 [(set_attr "type" "alu1")
11784 (set_attr "prefix_0f" "1")
11785 (set_attr "mode" "DI")])
11788 [(set (match_operand:SI 0 "register_operand" "=r")
11789 (minus:SI (const_int 31)
11790 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11791 (clobber (reg:CC FLAGS_REG))]
11793 "bsr{l}\t{%1, %0|%0, %1}"
11794 [(set_attr "type" "alu1")
11795 (set_attr "prefix_0f" "1")
11796 (set_attr "mode" "SI")])
11798 (define_insn "*bsrhi"
11799 [(set (match_operand:HI 0 "register_operand" "=r")
11800 (minus:HI (const_int 15)
11801 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11802 (clobber (reg:CC FLAGS_REG))]
11804 "bsr{w}\t{%1, %0|%0, %1}"
11805 [(set_attr "type" "alu1")
11806 (set_attr "prefix_0f" "1")
11807 (set_attr "mode" "HI")])
11809 (define_insn "popcount<mode>2"
11810 [(set (match_operand:SWI248 0 "register_operand" "=r")
11812 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11813 (clobber (reg:CC FLAGS_REG))]
11817 return "popcnt\t{%1, %0|%0, %1}";
11819 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11822 [(set_attr "prefix_rep" "1")
11823 (set_attr "type" "bitmanip")
11824 (set_attr "mode" "<MODE>")])
11826 (define_insn "*popcount<mode>2_cmp"
11827 [(set (reg FLAGS_REG)
11830 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11832 (set (match_operand:SWI248 0 "register_operand" "=r")
11833 (popcount:SWI248 (match_dup 1)))]
11834 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11837 return "popcnt\t{%1, %0|%0, %1}";
11839 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11842 [(set_attr "prefix_rep" "1")
11843 (set_attr "type" "bitmanip")
11844 (set_attr "mode" "<MODE>")])
11846 (define_insn "*popcountsi2_cmp_zext"
11847 [(set (reg FLAGS_REG)
11849 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11851 (set (match_operand:DI 0 "register_operand" "=r")
11852 (zero_extend:DI(popcount:SI (match_dup 1))))]
11853 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11856 return "popcnt\t{%1, %0|%0, %1}";
11858 return "popcnt{l}\t{%1, %0|%0, %1}";
11861 [(set_attr "prefix_rep" "1")
11862 (set_attr "type" "bitmanip")
11863 (set_attr "mode" "SI")])
11865 (define_expand "bswap<mode>2"
11866 [(set (match_operand:SWI48 0 "register_operand" "")
11867 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11870 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11872 rtx x = operands[0];
11874 emit_move_insn (x, operands[1]);
11875 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11876 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11877 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11882 (define_insn "*bswap<mode>2_movbe"
11883 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11884 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11886 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11889 movbe\t{%1, %0|%0, %1}
11890 movbe\t{%1, %0|%0, %1}"
11891 [(set_attr "type" "bitmanip,imov,imov")
11892 (set_attr "modrm" "0,1,1")
11893 (set_attr "prefix_0f" "*,1,1")
11894 (set_attr "prefix_extra" "*,1,1")
11895 (set_attr "mode" "<MODE>")])
11897 (define_insn "*bswap<mode>2_1"
11898 [(set (match_operand:SWI48 0 "register_operand" "=r")
11899 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11902 [(set_attr "type" "bitmanip")
11903 (set_attr "modrm" "0")
11904 (set_attr "mode" "<MODE>")])
11906 (define_insn "*bswaphi_lowpart_1"
11907 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11908 (bswap:HI (match_dup 0)))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11912 xchg{b}\t{%h0, %b0|%b0, %h0}
11913 rol{w}\t{$8, %0|%0, 8}"
11914 [(set_attr "length" "2,4")
11915 (set_attr "mode" "QI,HI")])
11917 (define_insn "bswaphi_lowpart"
11918 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11919 (bswap:HI (match_dup 0)))
11920 (clobber (reg:CC FLAGS_REG))]
11922 "rol{w}\t{$8, %0|%0, 8}"
11923 [(set_attr "length" "4")
11924 (set_attr "mode" "HI")])
11926 (define_expand "paritydi2"
11927 [(set (match_operand:DI 0 "register_operand" "")
11928 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11931 rtx scratch = gen_reg_rtx (QImode);
11934 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11935 NULL_RTX, operands[1]));
11937 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11938 gen_rtx_REG (CCmode, FLAGS_REG),
11940 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11943 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11946 rtx tmp = gen_reg_rtx (SImode);
11948 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11949 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11954 (define_expand "paritysi2"
11955 [(set (match_operand:SI 0 "register_operand" "")
11956 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11959 rtx scratch = gen_reg_rtx (QImode);
11962 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11964 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11965 gen_rtx_REG (CCmode, FLAGS_REG),
11967 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11969 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11973 (define_insn_and_split "paritydi2_cmp"
11974 [(set (reg:CC FLAGS_REG)
11975 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11977 (clobber (match_scratch:DI 0 "=r"))
11978 (clobber (match_scratch:SI 1 "=&r"))
11979 (clobber (match_scratch:HI 2 "=Q"))]
11982 "&& reload_completed"
11984 [(set (match_dup 1)
11985 (xor:SI (match_dup 1) (match_dup 4)))
11986 (clobber (reg:CC FLAGS_REG))])
11988 [(set (reg:CC FLAGS_REG)
11989 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11990 (clobber (match_dup 1))
11991 (clobber (match_dup 2))])]
11993 operands[4] = gen_lowpart (SImode, operands[3]);
11997 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11998 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12001 operands[1] = gen_highpart (SImode, operands[3]);
12004 (define_insn_and_split "paritysi2_cmp"
12005 [(set (reg:CC FLAGS_REG)
12006 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12008 (clobber (match_scratch:SI 0 "=r"))
12009 (clobber (match_scratch:HI 1 "=&Q"))]
12012 "&& reload_completed"
12014 [(set (match_dup 1)
12015 (xor:HI (match_dup 1) (match_dup 3)))
12016 (clobber (reg:CC FLAGS_REG))])
12018 [(set (reg:CC FLAGS_REG)
12019 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12020 (clobber (match_dup 1))])]
12022 operands[3] = gen_lowpart (HImode, operands[2]);
12024 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12025 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12028 (define_insn "*parityhi2_cmp"
12029 [(set (reg:CC FLAGS_REG)
12030 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12032 (clobber (match_scratch:HI 0 "=Q"))]
12034 "xor{b}\t{%h0, %b0|%b0, %h0}"
12035 [(set_attr "length" "2")
12036 (set_attr "mode" "HI")])
12038 ;; Thread-local storage patterns for ELF.
12040 ;; Note that these code sequences must appear exactly as shown
12041 ;; in order to allow linker relaxation.
12043 (define_insn "*tls_global_dynamic_32_gnu"
12044 [(set (match_operand:SI 0 "register_operand" "=a")
12045 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046 (match_operand:SI 2 "tls_symbolic_operand" "")
12047 (match_operand:SI 3 "call_insn_operand" "")]
12049 (clobber (match_scratch:SI 4 "=d"))
12050 (clobber (match_scratch:SI 5 "=c"))
12051 (clobber (reg:CC FLAGS_REG))]
12052 "!TARGET_64BIT && TARGET_GNU_TLS"
12053 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12054 [(set_attr "type" "multi")
12055 (set_attr "length" "12")])
12057 (define_expand "tls_global_dynamic_32"
12058 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12061 (match_operand:SI 1 "tls_symbolic_operand" "")
12064 (clobber (match_scratch:SI 4 ""))
12065 (clobber (match_scratch:SI 5 ""))
12066 (clobber (reg:CC FLAGS_REG))])]
12070 operands[2] = pic_offset_table_rtx;
12073 operands[2] = gen_reg_rtx (Pmode);
12074 emit_insn (gen_set_got (operands[2]));
12076 if (TARGET_GNU2_TLS)
12078 emit_insn (gen_tls_dynamic_gnu2_32
12079 (operands[0], operands[1], operands[2]));
12082 operands[3] = ix86_tls_get_addr ();
12085 (define_insn "*tls_global_dynamic_64"
12086 [(set (match_operand:DI 0 "register_operand" "=a")
12087 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12088 (match_operand:DI 3 "" "")))
12089 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12092 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12093 [(set_attr "type" "multi")
12094 (set_attr "length" "16")])
12096 (define_expand "tls_global_dynamic_64"
12097 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12098 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12099 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12103 if (TARGET_GNU2_TLS)
12105 emit_insn (gen_tls_dynamic_gnu2_64
12106 (operands[0], operands[1]));
12109 operands[2] = ix86_tls_get_addr ();
12112 (define_insn "*tls_local_dynamic_base_32_gnu"
12113 [(set (match_operand:SI 0 "register_operand" "=a")
12114 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12115 (match_operand:SI 2 "call_insn_operand" "")]
12116 UNSPEC_TLS_LD_BASE))
12117 (clobber (match_scratch:SI 3 "=d"))
12118 (clobber (match_scratch:SI 4 "=c"))
12119 (clobber (reg:CC FLAGS_REG))]
12120 "!TARGET_64BIT && TARGET_GNU_TLS"
12121 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12122 [(set_attr "type" "multi")
12123 (set_attr "length" "11")])
12125 (define_expand "tls_local_dynamic_base_32"
12126 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12127 (unspec:SI [(match_dup 1) (match_dup 2)]
12128 UNSPEC_TLS_LD_BASE))
12129 (clobber (match_scratch:SI 3 ""))
12130 (clobber (match_scratch:SI 4 ""))
12131 (clobber (reg:CC FLAGS_REG))])]
12135 operands[1] = pic_offset_table_rtx;
12138 operands[1] = gen_reg_rtx (Pmode);
12139 emit_insn (gen_set_got (operands[1]));
12141 if (TARGET_GNU2_TLS)
12143 emit_insn (gen_tls_dynamic_gnu2_32
12144 (operands[0], ix86_tls_module_base (), operands[1]));
12147 operands[2] = ix86_tls_get_addr ();
12150 (define_insn "*tls_local_dynamic_base_64"
12151 [(set (match_operand:DI 0 "register_operand" "=a")
12152 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12153 (match_operand:DI 2 "" "")))
12154 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12156 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12157 [(set_attr "type" "multi")
12158 (set_attr "length" "12")])
12160 (define_expand "tls_local_dynamic_base_64"
12161 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12162 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12163 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12166 if (TARGET_GNU2_TLS)
12168 emit_insn (gen_tls_dynamic_gnu2_64
12169 (operands[0], ix86_tls_module_base ()));
12172 operands[1] = ix86_tls_get_addr ();
12175 ;; Local dynamic of a single variable is a lose. Show combine how
12176 ;; to convert that back to global dynamic.
12178 (define_insn_and_split "*tls_local_dynamic_32_once"
12179 [(set (match_operand:SI 0 "register_operand" "=a")
12180 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12181 (match_operand:SI 2 "call_insn_operand" "")]
12182 UNSPEC_TLS_LD_BASE)
12183 (const:SI (unspec:SI
12184 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12186 (clobber (match_scratch:SI 4 "=d"))
12187 (clobber (match_scratch:SI 5 "=c"))
12188 (clobber (reg:CC FLAGS_REG))]
12192 [(parallel [(set (match_dup 0)
12193 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12195 (clobber (match_dup 4))
12196 (clobber (match_dup 5))
12197 (clobber (reg:CC FLAGS_REG))])])
12199 ;; Segment register for the thread base ptr load
12200 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12202 ;; Load and add the thread base pointer from %gs:0.
12203 (define_insn "*load_tp_<mode>"
12204 [(set (match_operand:P 0 "register_operand" "=r")
12205 (unspec:P [(const_int 0)] UNSPEC_TP))]
12207 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12208 [(set_attr "type" "imov")
12209 (set_attr "modrm" "0")
12210 (set_attr "length" "7")
12211 (set_attr "memory" "load")
12212 (set_attr "imm_disp" "false")])
12214 (define_insn "*add_tp_<mode>"
12215 [(set (match_operand:P 0 "register_operand" "=r")
12216 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12217 (match_operand:P 1 "register_operand" "0")))
12218 (clobber (reg:CC FLAGS_REG))]
12220 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12221 [(set_attr "type" "alu")
12222 (set_attr "modrm" "0")
12223 (set_attr "length" "7")
12224 (set_attr "memory" "load")
12225 (set_attr "imm_disp" "false")])
12227 ;; GNU2 TLS patterns can be split.
12229 (define_expand "tls_dynamic_gnu2_32"
12230 [(set (match_dup 3)
12231 (plus:SI (match_operand:SI 2 "register_operand" "")
12233 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12236 [(set (match_operand:SI 0 "register_operand" "")
12237 (unspec:SI [(match_dup 1) (match_dup 3)
12238 (match_dup 2) (reg:SI SP_REG)]
12240 (clobber (reg:CC FLAGS_REG))])]
12241 "!TARGET_64BIT && TARGET_GNU2_TLS"
12243 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12244 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12247 (define_insn "*tls_dynamic_lea_32"
12248 [(set (match_operand:SI 0 "register_operand" "=r")
12249 (plus:SI (match_operand:SI 1 "register_operand" "b")
12251 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12252 UNSPEC_TLSDESC))))]
12253 "!TARGET_64BIT && TARGET_GNU2_TLS"
12254 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12255 [(set_attr "type" "lea")
12256 (set_attr "mode" "SI")
12257 (set_attr "length" "6")
12258 (set_attr "length_address" "4")])
12260 (define_insn "*tls_dynamic_call_32"
12261 [(set (match_operand:SI 0 "register_operand" "=a")
12262 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12263 (match_operand:SI 2 "register_operand" "0")
12264 ;; we have to make sure %ebx still points to the GOT
12265 (match_operand:SI 3 "register_operand" "b")
12268 (clobber (reg:CC FLAGS_REG))]
12269 "!TARGET_64BIT && TARGET_GNU2_TLS"
12270 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12271 [(set_attr "type" "call")
12272 (set_attr "length" "2")
12273 (set_attr "length_address" "0")])
12275 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12276 [(set (match_operand:SI 0 "register_operand" "=&a")
12278 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12279 (match_operand:SI 4 "" "")
12280 (match_operand:SI 2 "register_operand" "b")
12283 (const:SI (unspec:SI
12284 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12286 (clobber (reg:CC FLAGS_REG))]
12287 "!TARGET_64BIT && TARGET_GNU2_TLS"
12290 [(set (match_dup 0) (match_dup 5))]
12292 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12293 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12296 (define_expand "tls_dynamic_gnu2_64"
12297 [(set (match_dup 2)
12298 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12301 [(set (match_operand:DI 0 "register_operand" "")
12302 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12304 (clobber (reg:CC FLAGS_REG))])]
12305 "TARGET_64BIT && TARGET_GNU2_TLS"
12307 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12308 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12311 (define_insn "*tls_dynamic_lea_64"
12312 [(set (match_operand:DI 0 "register_operand" "=r")
12313 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12315 "TARGET_64BIT && TARGET_GNU2_TLS"
12316 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12317 [(set_attr "type" "lea")
12318 (set_attr "mode" "DI")
12319 (set_attr "length" "7")
12320 (set_attr "length_address" "4")])
12322 (define_insn "*tls_dynamic_call_64"
12323 [(set (match_operand:DI 0 "register_operand" "=a")
12324 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12325 (match_operand:DI 2 "register_operand" "0")
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_64BIT && TARGET_GNU2_TLS"
12330 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12331 [(set_attr "type" "call")
12332 (set_attr "length" "2")
12333 (set_attr "length_address" "0")])
12335 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12336 [(set (match_operand:DI 0 "register_operand" "=&a")
12338 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12339 (match_operand:DI 3 "" "")
12342 (const:DI (unspec:DI
12343 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12345 (clobber (reg:CC FLAGS_REG))]
12346 "TARGET_64BIT && TARGET_GNU2_TLS"
12349 [(set (match_dup 0) (match_dup 4))]
12351 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12352 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12355 ;; These patterns match the binary 387 instructions for addM3, subM3,
12356 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12357 ;; SFmode. The first is the normal insn, the second the same insn but
12358 ;; with one operand a conversion, and the third the same insn but with
12359 ;; the other operand a conversion. The conversion may be SFmode or
12360 ;; SImode if the target mode DFmode, but only SImode if the target mode
12363 ;; Gcc is slightly more smart about handling normal two address instructions
12364 ;; so use special patterns for add and mull.
12366 (define_insn "*fop_<mode>_comm_mixed_avx"
12367 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12368 (match_operator:MODEF 3 "binary_fp_operator"
12369 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12370 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12371 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12372 && COMMUTATIVE_ARITH_P (operands[3])
12373 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12374 "* return output_387_binary_op (insn, operands);"
12375 [(set (attr "type")
12376 (if_then_else (eq_attr "alternative" "1")
12377 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12378 (const_string "ssemul")
12379 (const_string "sseadd"))
12380 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12381 (const_string "fmul")
12382 (const_string "fop"))))
12383 (set_attr "prefix" "orig,maybe_vex")
12384 (set_attr "mode" "<MODE>")])
12386 (define_insn "*fop_<mode>_comm_mixed"
12387 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12388 (match_operator:MODEF 3 "binary_fp_operator"
12389 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12390 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12392 && COMMUTATIVE_ARITH_P (operands[3])
12393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12394 "* return output_387_binary_op (insn, operands);"
12395 [(set (attr "type")
12396 (if_then_else (eq_attr "alternative" "1")
12397 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12398 (const_string "ssemul")
12399 (const_string "sseadd"))
12400 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12401 (const_string "fmul")
12402 (const_string "fop"))))
12403 (set_attr "mode" "<MODE>")])
12405 (define_insn "*fop_<mode>_comm_avx"
12406 [(set (match_operand:MODEF 0 "register_operand" "=x")
12407 (match_operator:MODEF 3 "binary_fp_operator"
12408 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12409 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12410 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12411 && COMMUTATIVE_ARITH_P (operands[3])
12412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12413 "* return output_387_binary_op (insn, operands);"
12414 [(set (attr "type")
12415 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12416 (const_string "ssemul")
12417 (const_string "sseadd")))
12418 (set_attr "prefix" "vex")
12419 (set_attr "mode" "<MODE>")])
12421 (define_insn "*fop_<mode>_comm_sse"
12422 [(set (match_operand:MODEF 0 "register_operand" "=x")
12423 (match_operator:MODEF 3 "binary_fp_operator"
12424 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12425 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12427 && COMMUTATIVE_ARITH_P (operands[3])
12428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12429 "* return output_387_binary_op (insn, operands);"
12430 [(set (attr "type")
12431 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12432 (const_string "ssemul")
12433 (const_string "sseadd")))
12434 (set_attr "mode" "<MODE>")])
12436 (define_insn "*fop_<mode>_comm_i387"
12437 [(set (match_operand:MODEF 0 "register_operand" "=f")
12438 (match_operator:MODEF 3 "binary_fp_operator"
12439 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12440 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12441 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12442 && COMMUTATIVE_ARITH_P (operands[3])
12443 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12444 "* return output_387_binary_op (insn, operands);"
12445 [(set (attr "type")
12446 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12447 (const_string "fmul")
12448 (const_string "fop")))
12449 (set_attr "mode" "<MODE>")])
12451 (define_insn "*fop_<mode>_1_mixed_avx"
12452 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12453 (match_operator:MODEF 3 "binary_fp_operator"
12454 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12455 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12456 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12457 && !COMMUTATIVE_ARITH_P (operands[3])
12458 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12459 "* return output_387_binary_op (insn, operands);"
12460 [(set (attr "type")
12461 (cond [(and (eq_attr "alternative" "2")
12462 (match_operand:MODEF 3 "mult_operator" ""))
12463 (const_string "ssemul")
12464 (and (eq_attr "alternative" "2")
12465 (match_operand:MODEF 3 "div_operator" ""))
12466 (const_string "ssediv")
12467 (eq_attr "alternative" "2")
12468 (const_string "sseadd")
12469 (match_operand:MODEF 3 "mult_operator" "")
12470 (const_string "fmul")
12471 (match_operand:MODEF 3 "div_operator" "")
12472 (const_string "fdiv")
12474 (const_string "fop")))
12475 (set_attr "prefix" "orig,orig,maybe_vex")
12476 (set_attr "mode" "<MODE>")])
12478 (define_insn "*fop_<mode>_1_mixed"
12479 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12480 (match_operator:MODEF 3 "binary_fp_operator"
12481 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12482 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12483 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12484 && !COMMUTATIVE_ARITH_P (operands[3])
12485 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12486 "* return output_387_binary_op (insn, operands);"
12487 [(set (attr "type")
12488 (cond [(and (eq_attr "alternative" "2")
12489 (match_operand:MODEF 3 "mult_operator" ""))
12490 (const_string "ssemul")
12491 (and (eq_attr "alternative" "2")
12492 (match_operand:MODEF 3 "div_operator" ""))
12493 (const_string "ssediv")
12494 (eq_attr "alternative" "2")
12495 (const_string "sseadd")
12496 (match_operand:MODEF 3 "mult_operator" "")
12497 (const_string "fmul")
12498 (match_operand:MODEF 3 "div_operator" "")
12499 (const_string "fdiv")
12501 (const_string "fop")))
12502 (set_attr "mode" "<MODE>")])
12504 (define_insn "*rcpsf2_sse"
12505 [(set (match_operand:SF 0 "register_operand" "=x")
12506 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12509 "%vrcpss\t{%1, %d0|%d0, %1}"
12510 [(set_attr "type" "sse")
12511 (set_attr "atom_sse_attr" "rcp")
12512 (set_attr "prefix" "maybe_vex")
12513 (set_attr "mode" "SF")])
12515 (define_insn "*fop_<mode>_1_avx"
12516 [(set (match_operand:MODEF 0 "register_operand" "=x")
12517 (match_operator:MODEF 3 "binary_fp_operator"
12518 [(match_operand:MODEF 1 "register_operand" "x")
12519 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12520 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12521 && !COMMUTATIVE_ARITH_P (operands[3])"
12522 "* return output_387_binary_op (insn, operands);"
12523 [(set (attr "type")
12524 (cond [(match_operand:MODEF 3 "mult_operator" "")
12525 (const_string "ssemul")
12526 (match_operand:MODEF 3 "div_operator" "")
12527 (const_string "ssediv")
12529 (const_string "sseadd")))
12530 (set_attr "prefix" "vex")
12531 (set_attr "mode" "<MODE>")])
12533 (define_insn "*fop_<mode>_1_sse"
12534 [(set (match_operand:MODEF 0 "register_operand" "=x")
12535 (match_operator:MODEF 3 "binary_fp_operator"
12536 [(match_operand:MODEF 1 "register_operand" "0")
12537 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12538 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12539 && !COMMUTATIVE_ARITH_P (operands[3])"
12540 "* return output_387_binary_op (insn, operands);"
12541 [(set (attr "type")
12542 (cond [(match_operand:MODEF 3 "mult_operator" "")
12543 (const_string "ssemul")
12544 (match_operand:MODEF 3 "div_operator" "")
12545 (const_string "ssediv")
12547 (const_string "sseadd")))
12548 (set_attr "mode" "<MODE>")])
12550 ;; This pattern is not fully shadowed by the pattern above.
12551 (define_insn "*fop_<mode>_1_i387"
12552 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12553 (match_operator:MODEF 3 "binary_fp_operator"
12554 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12555 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12556 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12557 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12558 && !COMMUTATIVE_ARITH_P (operands[3])
12559 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12560 "* return output_387_binary_op (insn, operands);"
12561 [(set (attr "type")
12562 (cond [(match_operand:MODEF 3 "mult_operator" "")
12563 (const_string "fmul")
12564 (match_operand:MODEF 3 "div_operator" "")
12565 (const_string "fdiv")
12567 (const_string "fop")))
12568 (set_attr "mode" "<MODE>")])
12570 ;; ??? Add SSE splitters for these!
12571 (define_insn "*fop_<MODEF:mode>_2_i387"
12572 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12573 (match_operator:MODEF 3 "binary_fp_operator"
12575 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12576 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12577 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12578 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12579 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12580 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12581 [(set (attr "type")
12582 (cond [(match_operand:MODEF 3 "mult_operator" "")
12583 (const_string "fmul")
12584 (match_operand:MODEF 3 "div_operator" "")
12585 (const_string "fdiv")
12587 (const_string "fop")))
12588 (set_attr "fp_int_src" "true")
12589 (set_attr "mode" "<X87MODEI12:MODE>")])
12591 (define_insn "*fop_<MODEF:mode>_3_i387"
12592 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12593 (match_operator:MODEF 3 "binary_fp_operator"
12594 [(match_operand:MODEF 1 "register_operand" "0,0")
12596 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12597 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12598 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12599 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12600 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12601 [(set (attr "type")
12602 (cond [(match_operand:MODEF 3 "mult_operator" "")
12603 (const_string "fmul")
12604 (match_operand:MODEF 3 "div_operator" "")
12605 (const_string "fdiv")
12607 (const_string "fop")))
12608 (set_attr "fp_int_src" "true")
12609 (set_attr "mode" "<MODE>")])
12611 (define_insn "*fop_df_4_i387"
12612 [(set (match_operand:DF 0 "register_operand" "=f,f")
12613 (match_operator:DF 3 "binary_fp_operator"
12615 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12616 (match_operand:DF 2 "register_operand" "0,f")]))]
12617 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12618 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12620 "* return output_387_binary_op (insn, operands);"
12621 [(set (attr "type")
12622 (cond [(match_operand:DF 3 "mult_operator" "")
12623 (const_string "fmul")
12624 (match_operand:DF 3 "div_operator" "")
12625 (const_string "fdiv")
12627 (const_string "fop")))
12628 (set_attr "mode" "SF")])
12630 (define_insn "*fop_df_5_i387"
12631 [(set (match_operand:DF 0 "register_operand" "=f,f")
12632 (match_operator:DF 3 "binary_fp_operator"
12633 [(match_operand:DF 1 "register_operand" "0,f")
12635 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12636 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12637 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12638 "* return output_387_binary_op (insn, operands);"
12639 [(set (attr "type")
12640 (cond [(match_operand:DF 3 "mult_operator" "")
12641 (const_string "fmul")
12642 (match_operand:DF 3 "div_operator" "")
12643 (const_string "fdiv")
12645 (const_string "fop")))
12646 (set_attr "mode" "SF")])
12648 (define_insn "*fop_df_6_i387"
12649 [(set (match_operand:DF 0 "register_operand" "=f,f")
12650 (match_operator:DF 3 "binary_fp_operator"
12652 (match_operand:SF 1 "register_operand" "0,f"))
12654 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12655 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12656 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12657 "* return output_387_binary_op (insn, operands);"
12658 [(set (attr "type")
12659 (cond [(match_operand:DF 3 "mult_operator" "")
12660 (const_string "fmul")
12661 (match_operand:DF 3 "div_operator" "")
12662 (const_string "fdiv")
12664 (const_string "fop")))
12665 (set_attr "mode" "SF")])
12667 (define_insn "*fop_xf_comm_i387"
12668 [(set (match_operand:XF 0 "register_operand" "=f")
12669 (match_operator:XF 3 "binary_fp_operator"
12670 [(match_operand:XF 1 "register_operand" "%0")
12671 (match_operand:XF 2 "register_operand" "f")]))]
12673 && COMMUTATIVE_ARITH_P (operands[3])"
12674 "* return output_387_binary_op (insn, operands);"
12675 [(set (attr "type")
12676 (if_then_else (match_operand:XF 3 "mult_operator" "")
12677 (const_string "fmul")
12678 (const_string "fop")))
12679 (set_attr "mode" "XF")])
12681 (define_insn "*fop_xf_1_i387"
12682 [(set (match_operand:XF 0 "register_operand" "=f,f")
12683 (match_operator:XF 3 "binary_fp_operator"
12684 [(match_operand:XF 1 "register_operand" "0,f")
12685 (match_operand:XF 2 "register_operand" "f,0")]))]
12687 && !COMMUTATIVE_ARITH_P (operands[3])"
12688 "* return output_387_binary_op (insn, operands);"
12689 [(set (attr "type")
12690 (cond [(match_operand:XF 3 "mult_operator" "")
12691 (const_string "fmul")
12692 (match_operand:XF 3 "div_operator" "")
12693 (const_string "fdiv")
12695 (const_string "fop")))
12696 (set_attr "mode" "XF")])
12698 (define_insn "*fop_xf_2_i387"
12699 [(set (match_operand:XF 0 "register_operand" "=f,f")
12700 (match_operator:XF 3 "binary_fp_operator"
12702 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12703 (match_operand:XF 2 "register_operand" "0,0")]))]
12704 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12706 [(set (attr "type")
12707 (cond [(match_operand:XF 3 "mult_operator" "")
12708 (const_string "fmul")
12709 (match_operand:XF 3 "div_operator" "")
12710 (const_string "fdiv")
12712 (const_string "fop")))
12713 (set_attr "fp_int_src" "true")
12714 (set_attr "mode" "<MODE>")])
12716 (define_insn "*fop_xf_3_i387"
12717 [(set (match_operand:XF 0 "register_operand" "=f,f")
12718 (match_operator:XF 3 "binary_fp_operator"
12719 [(match_operand:XF 1 "register_operand" "0,0")
12721 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12722 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12723 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12724 [(set (attr "type")
12725 (cond [(match_operand:XF 3 "mult_operator" "")
12726 (const_string "fmul")
12727 (match_operand:XF 3 "div_operator" "")
12728 (const_string "fdiv")
12730 (const_string "fop")))
12731 (set_attr "fp_int_src" "true")
12732 (set_attr "mode" "<MODE>")])
12734 (define_insn "*fop_xf_4_i387"
12735 [(set (match_operand:XF 0 "register_operand" "=f,f")
12736 (match_operator:XF 3 "binary_fp_operator"
12738 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12739 (match_operand:XF 2 "register_operand" "0,f")]))]
12741 "* return output_387_binary_op (insn, operands);"
12742 [(set (attr "type")
12743 (cond [(match_operand:XF 3 "mult_operator" "")
12744 (const_string "fmul")
12745 (match_operand:XF 3 "div_operator" "")
12746 (const_string "fdiv")
12748 (const_string "fop")))
12749 (set_attr "mode" "<MODE>")])
12751 (define_insn "*fop_xf_5_i387"
12752 [(set (match_operand:XF 0 "register_operand" "=f,f")
12753 (match_operator:XF 3 "binary_fp_operator"
12754 [(match_operand:XF 1 "register_operand" "0,f")
12756 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12758 "* return output_387_binary_op (insn, operands);"
12759 [(set (attr "type")
12760 (cond [(match_operand:XF 3 "mult_operator" "")
12761 (const_string "fmul")
12762 (match_operand:XF 3 "div_operator" "")
12763 (const_string "fdiv")
12765 (const_string "fop")))
12766 (set_attr "mode" "<MODE>")])
12768 (define_insn "*fop_xf_6_i387"
12769 [(set (match_operand:XF 0 "register_operand" "=f,f")
12770 (match_operator:XF 3 "binary_fp_operator"
12772 (match_operand:MODEF 1 "register_operand" "0,f"))
12774 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12776 "* return output_387_binary_op (insn, operands);"
12777 [(set (attr "type")
12778 (cond [(match_operand:XF 3 "mult_operator" "")
12779 (const_string "fmul")
12780 (match_operand:XF 3 "div_operator" "")
12781 (const_string "fdiv")
12783 (const_string "fop")))
12784 (set_attr "mode" "<MODE>")])
12787 [(set (match_operand 0 "register_operand" "")
12788 (match_operator 3 "binary_fp_operator"
12789 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12790 (match_operand 2 "register_operand" "")]))]
12792 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12793 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12796 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12797 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12798 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12799 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12800 GET_MODE (operands[3]),
12803 ix86_free_from_memory (GET_MODE (operands[1]));
12808 [(set (match_operand 0 "register_operand" "")
12809 (match_operator 3 "binary_fp_operator"
12810 [(match_operand 1 "register_operand" "")
12811 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12813 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12814 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12817 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12818 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12819 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12820 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12821 GET_MODE (operands[3]),
12824 ix86_free_from_memory (GET_MODE (operands[2]));
12828 ;; FPU special functions.
12830 ;; This pattern implements a no-op XFmode truncation for
12831 ;; all fancy i386 XFmode math functions.
12833 (define_insn "truncxf<mode>2_i387_noop_unspec"
12834 [(set (match_operand:MODEF 0 "register_operand" "=f")
12835 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12836 UNSPEC_TRUNC_NOOP))]
12837 "TARGET_USE_FANCY_MATH_387"
12838 "* return output_387_reg_move (insn, operands);"
12839 [(set_attr "type" "fmov")
12840 (set_attr "mode" "<MODE>")])
12842 (define_insn "sqrtxf2"
12843 [(set (match_operand:XF 0 "register_operand" "=f")
12844 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12845 "TARGET_USE_FANCY_MATH_387"
12847 [(set_attr "type" "fpspc")
12848 (set_attr "mode" "XF")
12849 (set_attr "athlon_decode" "direct")
12850 (set_attr "amdfam10_decode" "direct")])
12852 (define_insn "sqrt_extend<mode>xf2_i387"
12853 [(set (match_operand:XF 0 "register_operand" "=f")
12856 (match_operand:MODEF 1 "register_operand" "0"))))]
12857 "TARGET_USE_FANCY_MATH_387"
12859 [(set_attr "type" "fpspc")
12860 (set_attr "mode" "XF")
12861 (set_attr "athlon_decode" "direct")
12862 (set_attr "amdfam10_decode" "direct")])
12864 (define_insn "*rsqrtsf2_sse"
12865 [(set (match_operand:SF 0 "register_operand" "=x")
12866 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12869 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12870 [(set_attr "type" "sse")
12871 (set_attr "atom_sse_attr" "rcp")
12872 (set_attr "prefix" "maybe_vex")
12873 (set_attr "mode" "SF")])
12875 (define_expand "rsqrtsf2"
12876 [(set (match_operand:SF 0 "register_operand" "")
12877 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12881 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12885 (define_insn "*sqrt<mode>2_sse"
12886 [(set (match_operand:MODEF 0 "register_operand" "=x")
12888 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12889 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12890 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12891 [(set_attr "type" "sse")
12892 (set_attr "atom_sse_attr" "sqrt")
12893 (set_attr "prefix" "maybe_vex")
12894 (set_attr "mode" "<MODE>")
12895 (set_attr "athlon_decode" "*")
12896 (set_attr "amdfam10_decode" "*")])
12898 (define_expand "sqrt<mode>2"
12899 [(set (match_operand:MODEF 0 "register_operand" "")
12901 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12902 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12905 if (<MODE>mode == SFmode
12906 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12907 && flag_finite_math_only && !flag_trapping_math
12908 && flag_unsafe_math_optimizations)
12910 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12914 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12916 rtx op0 = gen_reg_rtx (XFmode);
12917 rtx op1 = force_reg (<MODE>mode, operands[1]);
12919 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12920 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12925 (define_insn "fpremxf4_i387"
12926 [(set (match_operand:XF 0 "register_operand" "=f")
12927 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12928 (match_operand:XF 3 "register_operand" "1")]
12930 (set (match_operand:XF 1 "register_operand" "=u")
12931 (unspec:XF [(match_dup 2) (match_dup 3)]
12933 (set (reg:CCFP FPSR_REG)
12934 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12936 "TARGET_USE_FANCY_MATH_387"
12938 [(set_attr "type" "fpspc")
12939 (set_attr "mode" "XF")])
12941 (define_expand "fmodxf3"
12942 [(use (match_operand:XF 0 "register_operand" ""))
12943 (use (match_operand:XF 1 "general_operand" ""))
12944 (use (match_operand:XF 2 "general_operand" ""))]
12945 "TARGET_USE_FANCY_MATH_387"
12947 rtx label = gen_label_rtx ();
12949 rtx op1 = gen_reg_rtx (XFmode);
12950 rtx op2 = gen_reg_rtx (XFmode);
12952 emit_move_insn (op2, operands[2]);
12953 emit_move_insn (op1, operands[1]);
12955 emit_label (label);
12956 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12957 ix86_emit_fp_unordered_jump (label);
12958 LABEL_NUSES (label) = 1;
12960 emit_move_insn (operands[0], op1);
12964 (define_expand "fmod<mode>3"
12965 [(use (match_operand:MODEF 0 "register_operand" ""))
12966 (use (match_operand:MODEF 1 "general_operand" ""))
12967 (use (match_operand:MODEF 2 "general_operand" ""))]
12968 "TARGET_USE_FANCY_MATH_387"
12970 rtx (*gen_truncxf) (rtx, rtx);
12972 rtx label = gen_label_rtx ();
12974 rtx op1 = gen_reg_rtx (XFmode);
12975 rtx op2 = gen_reg_rtx (XFmode);
12977 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12980 emit_label (label);
12981 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12982 ix86_emit_fp_unordered_jump (label);
12983 LABEL_NUSES (label) = 1;
12985 /* Truncate the result properly for strict SSE math. */
12986 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12987 && !TARGET_MIX_SSE_I387)
12988 gen_truncxf = gen_truncxf<mode>2;
12990 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12992 emit_insn (gen_truncxf (operands[0], op1));
12996 (define_insn "fprem1xf4_i387"
12997 [(set (match_operand:XF 0 "register_operand" "=f")
12998 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12999 (match_operand:XF 3 "register_operand" "1")]
13001 (set (match_operand:XF 1 "register_operand" "=u")
13002 (unspec:XF [(match_dup 2) (match_dup 3)]
13004 (set (reg:CCFP FPSR_REG)
13005 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13007 "TARGET_USE_FANCY_MATH_387"
13009 [(set_attr "type" "fpspc")
13010 (set_attr "mode" "XF")])
13012 (define_expand "remainderxf3"
13013 [(use (match_operand:XF 0 "register_operand" ""))
13014 (use (match_operand:XF 1 "general_operand" ""))
13015 (use (match_operand:XF 2 "general_operand" ""))]
13016 "TARGET_USE_FANCY_MATH_387"
13018 rtx label = gen_label_rtx ();
13020 rtx op1 = gen_reg_rtx (XFmode);
13021 rtx op2 = gen_reg_rtx (XFmode);
13023 emit_move_insn (op2, operands[2]);
13024 emit_move_insn (op1, operands[1]);
13026 emit_label (label);
13027 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13028 ix86_emit_fp_unordered_jump (label);
13029 LABEL_NUSES (label) = 1;
13031 emit_move_insn (operands[0], op1);
13035 (define_expand "remainder<mode>3"
13036 [(use (match_operand:MODEF 0 "register_operand" ""))
13037 (use (match_operand:MODEF 1 "general_operand" ""))
13038 (use (match_operand:MODEF 2 "general_operand" ""))]
13039 "TARGET_USE_FANCY_MATH_387"
13041 rtx (*gen_truncxf) (rtx, rtx);
13043 rtx label = gen_label_rtx ();
13045 rtx op1 = gen_reg_rtx (XFmode);
13046 rtx op2 = gen_reg_rtx (XFmode);
13048 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13049 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13051 emit_label (label);
13053 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13054 ix86_emit_fp_unordered_jump (label);
13055 LABEL_NUSES (label) = 1;
13057 /* Truncate the result properly for strict SSE math. */
13058 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13059 && !TARGET_MIX_SSE_I387)
13060 gen_truncxf = gen_truncxf<mode>2;
13062 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13064 emit_insn (gen_truncxf (operands[0], op1));
13068 (define_insn "*sinxf2_i387"
13069 [(set (match_operand:XF 0 "register_operand" "=f")
13070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13071 "TARGET_USE_FANCY_MATH_387
13072 && flag_unsafe_math_optimizations"
13074 [(set_attr "type" "fpspc")
13075 (set_attr "mode" "XF")])
13077 (define_insn "*sin_extend<mode>xf2_i387"
13078 [(set (match_operand:XF 0 "register_operand" "=f")
13079 (unspec:XF [(float_extend:XF
13080 (match_operand:MODEF 1 "register_operand" "0"))]
13082 "TARGET_USE_FANCY_MATH_387
13083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084 || TARGET_MIX_SSE_I387)
13085 && flag_unsafe_math_optimizations"
13087 [(set_attr "type" "fpspc")
13088 (set_attr "mode" "XF")])
13090 (define_insn "*cosxf2_i387"
13091 [(set (match_operand:XF 0 "register_operand" "=f")
13092 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13093 "TARGET_USE_FANCY_MATH_387
13094 && flag_unsafe_math_optimizations"
13096 [(set_attr "type" "fpspc")
13097 (set_attr "mode" "XF")])
13099 (define_insn "*cos_extend<mode>xf2_i387"
13100 [(set (match_operand:XF 0 "register_operand" "=f")
13101 (unspec:XF [(float_extend:XF
13102 (match_operand:MODEF 1 "register_operand" "0"))]
13104 "TARGET_USE_FANCY_MATH_387
13105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13106 || TARGET_MIX_SSE_I387)
13107 && flag_unsafe_math_optimizations"
13109 [(set_attr "type" "fpspc")
13110 (set_attr "mode" "XF")])
13112 ;; When sincos pattern is defined, sin and cos builtin functions will be
13113 ;; expanded to sincos pattern with one of its outputs left unused.
13114 ;; CSE pass will figure out if two sincos patterns can be combined,
13115 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13116 ;; depending on the unused output.
13118 (define_insn "sincosxf3"
13119 [(set (match_operand:XF 0 "register_operand" "=f")
13120 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13121 UNSPEC_SINCOS_COS))
13122 (set (match_operand:XF 1 "register_operand" "=u")
13123 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13124 "TARGET_USE_FANCY_MATH_387
13125 && flag_unsafe_math_optimizations"
13127 [(set_attr "type" "fpspc")
13128 (set_attr "mode" "XF")])
13131 [(set (match_operand:XF 0 "register_operand" "")
13132 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13133 UNSPEC_SINCOS_COS))
13134 (set (match_operand:XF 1 "register_operand" "")
13135 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13136 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13137 && !(reload_completed || reload_in_progress)"
13138 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13141 [(set (match_operand:XF 0 "register_operand" "")
13142 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13143 UNSPEC_SINCOS_COS))
13144 (set (match_operand:XF 1 "register_operand" "")
13145 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13146 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13147 && !(reload_completed || reload_in_progress)"
13148 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13150 (define_insn "sincos_extend<mode>xf3_i387"
13151 [(set (match_operand:XF 0 "register_operand" "=f")
13152 (unspec:XF [(float_extend:XF
13153 (match_operand:MODEF 2 "register_operand" "0"))]
13154 UNSPEC_SINCOS_COS))
13155 (set (match_operand:XF 1 "register_operand" "=u")
13156 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13157 "TARGET_USE_FANCY_MATH_387
13158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13159 || TARGET_MIX_SSE_I387)
13160 && flag_unsafe_math_optimizations"
13162 [(set_attr "type" "fpspc")
13163 (set_attr "mode" "XF")])
13166 [(set (match_operand:XF 0 "register_operand" "")
13167 (unspec:XF [(float_extend:XF
13168 (match_operand:MODEF 2 "register_operand" ""))]
13169 UNSPEC_SINCOS_COS))
13170 (set (match_operand:XF 1 "register_operand" "")
13171 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13172 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13173 && !(reload_completed || reload_in_progress)"
13174 [(set (match_dup 1)
13175 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13178 [(set (match_operand:XF 0 "register_operand" "")
13179 (unspec:XF [(float_extend:XF
13180 (match_operand:MODEF 2 "register_operand" ""))]
13181 UNSPEC_SINCOS_COS))
13182 (set (match_operand:XF 1 "register_operand" "")
13183 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13184 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13185 && !(reload_completed || reload_in_progress)"
13186 [(set (match_dup 0)
13187 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13189 (define_expand "sincos<mode>3"
13190 [(use (match_operand:MODEF 0 "register_operand" ""))
13191 (use (match_operand:MODEF 1 "register_operand" ""))
13192 (use (match_operand:MODEF 2 "register_operand" ""))]
13193 "TARGET_USE_FANCY_MATH_387
13194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13195 || TARGET_MIX_SSE_I387)
13196 && flag_unsafe_math_optimizations"
13198 rtx op0 = gen_reg_rtx (XFmode);
13199 rtx op1 = gen_reg_rtx (XFmode);
13201 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13203 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13207 (define_insn "fptanxf4_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f")
13209 (match_operand:XF 3 "const_double_operand" "F"))
13210 (set (match_operand:XF 1 "register_operand" "=u")
13211 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13213 "TARGET_USE_FANCY_MATH_387
13214 && flag_unsafe_math_optimizations
13215 && standard_80387_constant_p (operands[3]) == 2"
13217 [(set_attr "type" "fpspc")
13218 (set_attr "mode" "XF")])
13220 (define_insn "fptan_extend<mode>xf4_i387"
13221 [(set (match_operand:MODEF 0 "register_operand" "=f")
13222 (match_operand:MODEF 3 "const_double_operand" "F"))
13223 (set (match_operand:XF 1 "register_operand" "=u")
13224 (unspec:XF [(float_extend:XF
13225 (match_operand:MODEF 2 "register_operand" "0"))]
13227 "TARGET_USE_FANCY_MATH_387
13228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13229 || TARGET_MIX_SSE_I387)
13230 && flag_unsafe_math_optimizations
13231 && standard_80387_constant_p (operands[3]) == 2"
13233 [(set_attr "type" "fpspc")
13234 (set_attr "mode" "XF")])
13236 (define_expand "tanxf2"
13237 [(use (match_operand:XF 0 "register_operand" ""))
13238 (use (match_operand:XF 1 "register_operand" ""))]
13239 "TARGET_USE_FANCY_MATH_387
13240 && flag_unsafe_math_optimizations"
13242 rtx one = gen_reg_rtx (XFmode);
13243 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13245 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13249 (define_expand "tan<mode>2"
13250 [(use (match_operand:MODEF 0 "register_operand" ""))
13251 (use (match_operand:MODEF 1 "register_operand" ""))]
13252 "TARGET_USE_FANCY_MATH_387
13253 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13254 || TARGET_MIX_SSE_I387)
13255 && flag_unsafe_math_optimizations"
13257 rtx op0 = gen_reg_rtx (XFmode);
13259 rtx one = gen_reg_rtx (<MODE>mode);
13260 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13262 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13263 operands[1], op2));
13264 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13268 (define_insn "*fpatanxf3_i387"
13269 [(set (match_operand:XF 0 "register_operand" "=f")
13270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13271 (match_operand:XF 2 "register_operand" "u")]
13273 (clobber (match_scratch:XF 3 "=2"))]
13274 "TARGET_USE_FANCY_MATH_387
13275 && flag_unsafe_math_optimizations"
13277 [(set_attr "type" "fpspc")
13278 (set_attr "mode" "XF")])
13280 (define_insn "fpatan_extend<mode>xf3_i387"
13281 [(set (match_operand:XF 0 "register_operand" "=f")
13282 (unspec:XF [(float_extend:XF
13283 (match_operand:MODEF 1 "register_operand" "0"))
13285 (match_operand:MODEF 2 "register_operand" "u"))]
13287 (clobber (match_scratch:XF 3 "=2"))]
13288 "TARGET_USE_FANCY_MATH_387
13289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13290 || TARGET_MIX_SSE_I387)
13291 && flag_unsafe_math_optimizations"
13293 [(set_attr "type" "fpspc")
13294 (set_attr "mode" "XF")])
13296 (define_expand "atan2xf3"
13297 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13298 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13299 (match_operand:XF 1 "register_operand" "")]
13301 (clobber (match_scratch:XF 3 ""))])]
13302 "TARGET_USE_FANCY_MATH_387
13303 && flag_unsafe_math_optimizations")
13305 (define_expand "atan2<mode>3"
13306 [(use (match_operand:MODEF 0 "register_operand" ""))
13307 (use (match_operand:MODEF 1 "register_operand" ""))
13308 (use (match_operand:MODEF 2 "register_operand" ""))]
13309 "TARGET_USE_FANCY_MATH_387
13310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13311 || TARGET_MIX_SSE_I387)
13312 && flag_unsafe_math_optimizations"
13314 rtx op0 = gen_reg_rtx (XFmode);
13316 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13321 (define_expand "atanxf2"
13322 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13323 (unspec:XF [(match_dup 2)
13324 (match_operand:XF 1 "register_operand" "")]
13326 (clobber (match_scratch:XF 3 ""))])]
13327 "TARGET_USE_FANCY_MATH_387
13328 && flag_unsafe_math_optimizations"
13330 operands[2] = gen_reg_rtx (XFmode);
13331 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13334 (define_expand "atan<mode>2"
13335 [(use (match_operand:MODEF 0 "register_operand" ""))
13336 (use (match_operand:MODEF 1 "register_operand" ""))]
13337 "TARGET_USE_FANCY_MATH_387
13338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13339 || TARGET_MIX_SSE_I387)
13340 && flag_unsafe_math_optimizations"
13342 rtx op0 = gen_reg_rtx (XFmode);
13344 rtx op2 = gen_reg_rtx (<MODE>mode);
13345 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13347 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13352 (define_expand "asinxf2"
13353 [(set (match_dup 2)
13354 (mult:XF (match_operand:XF 1 "register_operand" "")
13356 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13357 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13358 (parallel [(set (match_operand:XF 0 "register_operand" "")
13359 (unspec:XF [(match_dup 5) (match_dup 1)]
13361 (clobber (match_scratch:XF 6 ""))])]
13362 "TARGET_USE_FANCY_MATH_387
13363 && flag_unsafe_math_optimizations"
13367 if (optimize_insn_for_size_p ())
13370 for (i = 2; i < 6; i++)
13371 operands[i] = gen_reg_rtx (XFmode);
13373 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13376 (define_expand "asin<mode>2"
13377 [(use (match_operand:MODEF 0 "register_operand" ""))
13378 (use (match_operand:MODEF 1 "general_operand" ""))]
13379 "TARGET_USE_FANCY_MATH_387
13380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13381 || TARGET_MIX_SSE_I387)
13382 && flag_unsafe_math_optimizations"
13384 rtx op0 = gen_reg_rtx (XFmode);
13385 rtx op1 = gen_reg_rtx (XFmode);
13387 if (optimize_insn_for_size_p ())
13390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13391 emit_insn (gen_asinxf2 (op0, op1));
13392 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13396 (define_expand "acosxf2"
13397 [(set (match_dup 2)
13398 (mult:XF (match_operand:XF 1 "register_operand" "")
13400 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13401 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13402 (parallel [(set (match_operand:XF 0 "register_operand" "")
13403 (unspec:XF [(match_dup 1) (match_dup 5)]
13405 (clobber (match_scratch:XF 6 ""))])]
13406 "TARGET_USE_FANCY_MATH_387
13407 && flag_unsafe_math_optimizations"
13411 if (optimize_insn_for_size_p ())
13414 for (i = 2; i < 6; i++)
13415 operands[i] = gen_reg_rtx (XFmode);
13417 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13420 (define_expand "acos<mode>2"
13421 [(use (match_operand:MODEF 0 "register_operand" ""))
13422 (use (match_operand:MODEF 1 "general_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387
13424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425 || TARGET_MIX_SSE_I387)
13426 && flag_unsafe_math_optimizations"
13428 rtx op0 = gen_reg_rtx (XFmode);
13429 rtx op1 = gen_reg_rtx (XFmode);
13431 if (optimize_insn_for_size_p ())
13434 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13435 emit_insn (gen_acosxf2 (op0, op1));
13436 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13440 (define_insn "fyl2xxf3_i387"
13441 [(set (match_operand:XF 0 "register_operand" "=f")
13442 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13443 (match_operand:XF 2 "register_operand" "u")]
13445 (clobber (match_scratch:XF 3 "=2"))]
13446 "TARGET_USE_FANCY_MATH_387
13447 && flag_unsafe_math_optimizations"
13449 [(set_attr "type" "fpspc")
13450 (set_attr "mode" "XF")])
13452 (define_insn "fyl2x_extend<mode>xf3_i387"
13453 [(set (match_operand:XF 0 "register_operand" "=f")
13454 (unspec:XF [(float_extend:XF
13455 (match_operand:MODEF 1 "register_operand" "0"))
13456 (match_operand:XF 2 "register_operand" "u")]
13458 (clobber (match_scratch:XF 3 "=2"))]
13459 "TARGET_USE_FANCY_MATH_387
13460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461 || TARGET_MIX_SSE_I387)
13462 && flag_unsafe_math_optimizations"
13464 [(set_attr "type" "fpspc")
13465 (set_attr "mode" "XF")])
13467 (define_expand "logxf2"
13468 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13469 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13470 (match_dup 2)] UNSPEC_FYL2X))
13471 (clobber (match_scratch:XF 3 ""))])]
13472 "TARGET_USE_FANCY_MATH_387
13473 && flag_unsafe_math_optimizations"
13475 operands[2] = gen_reg_rtx (XFmode);
13476 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13479 (define_expand "log<mode>2"
13480 [(use (match_operand:MODEF 0 "register_operand" ""))
13481 (use (match_operand:MODEF 1 "register_operand" ""))]
13482 "TARGET_USE_FANCY_MATH_387
13483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13484 || TARGET_MIX_SSE_I387)
13485 && flag_unsafe_math_optimizations"
13487 rtx op0 = gen_reg_rtx (XFmode);
13489 rtx op2 = gen_reg_rtx (XFmode);
13490 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13492 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13497 (define_expand "log10xf2"
13498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13499 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13500 (match_dup 2)] UNSPEC_FYL2X))
13501 (clobber (match_scratch:XF 3 ""))])]
13502 "TARGET_USE_FANCY_MATH_387
13503 && flag_unsafe_math_optimizations"
13505 operands[2] = gen_reg_rtx (XFmode);
13506 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13509 (define_expand "log10<mode>2"
13510 [(use (match_operand:MODEF 0 "register_operand" ""))
13511 (use (match_operand:MODEF 1 "register_operand" ""))]
13512 "TARGET_USE_FANCY_MATH_387
13513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514 || TARGET_MIX_SSE_I387)
13515 && flag_unsafe_math_optimizations"
13517 rtx op0 = gen_reg_rtx (XFmode);
13519 rtx op2 = gen_reg_rtx (XFmode);
13520 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13522 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13527 (define_expand "log2xf2"
13528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13530 (match_dup 2)] UNSPEC_FYL2X))
13531 (clobber (match_scratch:XF 3 ""))])]
13532 "TARGET_USE_FANCY_MATH_387
13533 && flag_unsafe_math_optimizations"
13535 operands[2] = gen_reg_rtx (XFmode);
13536 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13539 (define_expand "log2<mode>2"
13540 [(use (match_operand:MODEF 0 "register_operand" ""))
13541 (use (match_operand:MODEF 1 "register_operand" ""))]
13542 "TARGET_USE_FANCY_MATH_387
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
13545 && flag_unsafe_math_optimizations"
13547 rtx op0 = gen_reg_rtx (XFmode);
13549 rtx op2 = gen_reg_rtx (XFmode);
13550 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13552 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13557 (define_insn "fyl2xp1xf3_i387"
13558 [(set (match_operand:XF 0 "register_operand" "=f")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13560 (match_operand:XF 2 "register_operand" "u")]
13562 (clobber (match_scratch:XF 3 "=2"))]
13563 "TARGET_USE_FANCY_MATH_387
13564 && flag_unsafe_math_optimizations"
13566 [(set_attr "type" "fpspc")
13567 (set_attr "mode" "XF")])
13569 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13570 [(set (match_operand:XF 0 "register_operand" "=f")
13571 (unspec:XF [(float_extend:XF
13572 (match_operand:MODEF 1 "register_operand" "0"))
13573 (match_operand:XF 2 "register_operand" "u")]
13575 (clobber (match_scratch:XF 3 "=2"))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578 || TARGET_MIX_SSE_I387)
13579 && flag_unsafe_math_optimizations"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13584 (define_expand "log1pxf2"
13585 [(use (match_operand:XF 0 "register_operand" ""))
13586 (use (match_operand:XF 1 "register_operand" ""))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && flag_unsafe_math_optimizations"
13590 if (optimize_insn_for_size_p ())
13593 ix86_emit_i387_log1p (operands[0], operands[1]);
13597 (define_expand "log1p<mode>2"
13598 [(use (match_operand:MODEF 0 "register_operand" ""))
13599 (use (match_operand:MODEF 1 "register_operand" ""))]
13600 "TARGET_USE_FANCY_MATH_387
13601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13602 || TARGET_MIX_SSE_I387)
13603 && flag_unsafe_math_optimizations"
13607 if (optimize_insn_for_size_p ())
13610 op0 = gen_reg_rtx (XFmode);
13612 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13614 ix86_emit_i387_log1p (op0, operands[1]);
13615 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13619 (define_insn "fxtractxf3_i387"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13622 UNSPEC_XTRACT_FRACT))
13623 (set (match_operand:XF 1 "register_operand" "=u")
13624 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13625 "TARGET_USE_FANCY_MATH_387
13626 && flag_unsafe_math_optimizations"
13628 [(set_attr "type" "fpspc")
13629 (set_attr "mode" "XF")])
13631 (define_insn "fxtract_extend<mode>xf3_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (unspec:XF [(float_extend:XF
13634 (match_operand:MODEF 2 "register_operand" "0"))]
13635 UNSPEC_XTRACT_FRACT))
13636 (set (match_operand:XF 1 "register_operand" "=u")
13637 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13638 "TARGET_USE_FANCY_MATH_387
13639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640 || TARGET_MIX_SSE_I387)
13641 && flag_unsafe_math_optimizations"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")])
13646 (define_expand "logbxf2"
13647 [(parallel [(set (match_dup 2)
13648 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13649 UNSPEC_XTRACT_FRACT))
13650 (set (match_operand:XF 0 "register_operand" "")
13651 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13652 "TARGET_USE_FANCY_MATH_387
13653 && flag_unsafe_math_optimizations"
13654 "operands[2] = gen_reg_rtx (XFmode);")
13656 (define_expand "logb<mode>2"
13657 [(use (match_operand:MODEF 0 "register_operand" ""))
13658 (use (match_operand:MODEF 1 "register_operand" ""))]
13659 "TARGET_USE_FANCY_MATH_387
13660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13661 || TARGET_MIX_SSE_I387)
13662 && flag_unsafe_math_optimizations"
13664 rtx op0 = gen_reg_rtx (XFmode);
13665 rtx op1 = gen_reg_rtx (XFmode);
13667 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13668 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13672 (define_expand "ilogbxf2"
13673 [(use (match_operand:SI 0 "register_operand" ""))
13674 (use (match_operand:XF 1 "register_operand" ""))]
13675 "TARGET_USE_FANCY_MATH_387
13676 && flag_unsafe_math_optimizations"
13680 if (optimize_insn_for_size_p ())
13683 op0 = gen_reg_rtx (XFmode);
13684 op1 = gen_reg_rtx (XFmode);
13686 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13687 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13691 (define_expand "ilogb<mode>2"
13692 [(use (match_operand:SI 0 "register_operand" ""))
13693 (use (match_operand:MODEF 1 "register_operand" ""))]
13694 "TARGET_USE_FANCY_MATH_387
13695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13696 || TARGET_MIX_SSE_I387)
13697 && flag_unsafe_math_optimizations"
13701 if (optimize_insn_for_size_p ())
13704 op0 = gen_reg_rtx (XFmode);
13705 op1 = gen_reg_rtx (XFmode);
13707 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13708 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13712 (define_insn "*f2xm1xf2_i387"
13713 [(set (match_operand:XF 0 "register_operand" "=f")
13714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13716 "TARGET_USE_FANCY_MATH_387
13717 && flag_unsafe_math_optimizations"
13719 [(set_attr "type" "fpspc")
13720 (set_attr "mode" "XF")])
13722 (define_insn "*fscalexf4_i387"
13723 [(set (match_operand:XF 0 "register_operand" "=f")
13724 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13725 (match_operand:XF 3 "register_operand" "1")]
13726 UNSPEC_FSCALE_FRACT))
13727 (set (match_operand:XF 1 "register_operand" "=u")
13728 (unspec:XF [(match_dup 2) (match_dup 3)]
13729 UNSPEC_FSCALE_EXP))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && flag_unsafe_math_optimizations"
13733 [(set_attr "type" "fpspc")
13734 (set_attr "mode" "XF")])
13736 (define_expand "expNcorexf3"
13737 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13738 (match_operand:XF 2 "register_operand" "")))
13739 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13740 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13741 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13742 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13743 (parallel [(set (match_operand:XF 0 "register_operand" "")
13744 (unspec:XF [(match_dup 8) (match_dup 4)]
13745 UNSPEC_FSCALE_FRACT))
13747 (unspec:XF [(match_dup 8) (match_dup 4)]
13748 UNSPEC_FSCALE_EXP))])]
13749 "TARGET_USE_FANCY_MATH_387
13750 && flag_unsafe_math_optimizations"
13754 if (optimize_insn_for_size_p ())
13757 for (i = 3; i < 10; i++)
13758 operands[i] = gen_reg_rtx (XFmode);
13760 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13763 (define_expand "expxf2"
13764 [(use (match_operand:XF 0 "register_operand" ""))
13765 (use (match_operand:XF 1 "register_operand" ""))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && flag_unsafe_math_optimizations"
13771 if (optimize_insn_for_size_p ())
13774 op2 = gen_reg_rtx (XFmode);
13775 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13777 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13781 (define_expand "exp<mode>2"
13782 [(use (match_operand:MODEF 0 "register_operand" ""))
13783 (use (match_operand:MODEF 1 "general_operand" ""))]
13784 "TARGET_USE_FANCY_MATH_387
13785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13786 || TARGET_MIX_SSE_I387)
13787 && flag_unsafe_math_optimizations"
13791 if (optimize_insn_for_size_p ())
13794 op0 = gen_reg_rtx (XFmode);
13795 op1 = gen_reg_rtx (XFmode);
13797 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13798 emit_insn (gen_expxf2 (op0, op1));
13799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13803 (define_expand "exp10xf2"
13804 [(use (match_operand:XF 0 "register_operand" ""))
13805 (use (match_operand:XF 1 "register_operand" ""))]
13806 "TARGET_USE_FANCY_MATH_387
13807 && flag_unsafe_math_optimizations"
13811 if (optimize_insn_for_size_p ())
13814 op2 = gen_reg_rtx (XFmode);
13815 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13817 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13821 (define_expand "exp10<mode>2"
13822 [(use (match_operand:MODEF 0 "register_operand" ""))
13823 (use (match_operand:MODEF 1 "general_operand" ""))]
13824 "TARGET_USE_FANCY_MATH_387
13825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13826 || TARGET_MIX_SSE_I387)
13827 && flag_unsafe_math_optimizations"
13831 if (optimize_insn_for_size_p ())
13834 op0 = gen_reg_rtx (XFmode);
13835 op1 = gen_reg_rtx (XFmode);
13837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13838 emit_insn (gen_exp10xf2 (op0, op1));
13839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13843 (define_expand "exp2xf2"
13844 [(use (match_operand:XF 0 "register_operand" ""))
13845 (use (match_operand:XF 1 "register_operand" ""))]
13846 "TARGET_USE_FANCY_MATH_387
13847 && flag_unsafe_math_optimizations"
13851 if (optimize_insn_for_size_p ())
13854 op2 = gen_reg_rtx (XFmode);
13855 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13857 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13861 (define_expand "exp2<mode>2"
13862 [(use (match_operand:MODEF 0 "register_operand" ""))
13863 (use (match_operand:MODEF 1 "general_operand" ""))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866 || TARGET_MIX_SSE_I387)
13867 && flag_unsafe_math_optimizations"
13871 if (optimize_insn_for_size_p ())
13874 op0 = gen_reg_rtx (XFmode);
13875 op1 = gen_reg_rtx (XFmode);
13877 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13878 emit_insn (gen_exp2xf2 (op0, op1));
13879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13883 (define_expand "expm1xf2"
13884 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13886 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13887 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13888 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13889 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13890 (parallel [(set (match_dup 7)
13891 (unspec:XF [(match_dup 6) (match_dup 4)]
13892 UNSPEC_FSCALE_FRACT))
13894 (unspec:XF [(match_dup 6) (match_dup 4)]
13895 UNSPEC_FSCALE_EXP))])
13896 (parallel [(set (match_dup 10)
13897 (unspec:XF [(match_dup 9) (match_dup 8)]
13898 UNSPEC_FSCALE_FRACT))
13899 (set (match_dup 11)
13900 (unspec:XF [(match_dup 9) (match_dup 8)]
13901 UNSPEC_FSCALE_EXP))])
13902 (set (match_dup 12) (minus:XF (match_dup 10)
13903 (float_extend:XF (match_dup 13))))
13904 (set (match_operand:XF 0 "register_operand" "")
13905 (plus:XF (match_dup 12) (match_dup 7)))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13911 if (optimize_insn_for_size_p ())
13914 for (i = 2; i < 13; i++)
13915 operands[i] = gen_reg_rtx (XFmode);
13918 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13920 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13923 (define_expand "expm1<mode>2"
13924 [(use (match_operand:MODEF 0 "register_operand" ""))
13925 (use (match_operand:MODEF 1 "general_operand" ""))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928 || TARGET_MIX_SSE_I387)
13929 && flag_unsafe_math_optimizations"
13933 if (optimize_insn_for_size_p ())
13936 op0 = gen_reg_rtx (XFmode);
13937 op1 = gen_reg_rtx (XFmode);
13939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13940 emit_insn (gen_expm1xf2 (op0, op1));
13941 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13945 (define_expand "ldexpxf3"
13946 [(set (match_dup 3)
13947 (float:XF (match_operand:SI 2 "register_operand" "")))
13948 (parallel [(set (match_operand:XF 0 " register_operand" "")
13949 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13951 UNSPEC_FSCALE_FRACT))
13953 (unspec:XF [(match_dup 1) (match_dup 3)]
13954 UNSPEC_FSCALE_EXP))])]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13958 if (optimize_insn_for_size_p ())
13961 operands[3] = gen_reg_rtx (XFmode);
13962 operands[4] = gen_reg_rtx (XFmode);
13965 (define_expand "ldexp<mode>3"
13966 [(use (match_operand:MODEF 0 "register_operand" ""))
13967 (use (match_operand:MODEF 1 "general_operand" ""))
13968 (use (match_operand:SI 2 "register_operand" ""))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13971 || TARGET_MIX_SSE_I387)
13972 && flag_unsafe_math_optimizations"
13976 if (optimize_insn_for_size_p ())
13979 op0 = gen_reg_rtx (XFmode);
13980 op1 = gen_reg_rtx (XFmode);
13982 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13983 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13988 (define_expand "scalbxf3"
13989 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13990 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13991 (match_operand:XF 2 "register_operand" "")]
13992 UNSPEC_FSCALE_FRACT))
13994 (unspec:XF [(match_dup 1) (match_dup 2)]
13995 UNSPEC_FSCALE_EXP))])]
13996 "TARGET_USE_FANCY_MATH_387
13997 && flag_unsafe_math_optimizations"
13999 if (optimize_insn_for_size_p ())
14002 operands[3] = gen_reg_rtx (XFmode);
14005 (define_expand "scalb<mode>3"
14006 [(use (match_operand:MODEF 0 "register_operand" ""))
14007 (use (match_operand:MODEF 1 "general_operand" ""))
14008 (use (match_operand:MODEF 2 "general_operand" ""))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations"
14016 if (optimize_insn_for_size_p ())
14019 op0 = gen_reg_rtx (XFmode);
14020 op1 = gen_reg_rtx (XFmode);
14021 op2 = gen_reg_rtx (XFmode);
14023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14024 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14025 emit_insn (gen_scalbxf3 (op0, op1, op2));
14026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14030 (define_expand "significandxf2"
14031 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14032 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14033 UNSPEC_XTRACT_FRACT))
14035 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14036 "TARGET_USE_FANCY_MATH_387
14037 && flag_unsafe_math_optimizations"
14038 "operands[2] = gen_reg_rtx (XFmode);")
14040 (define_expand "significand<mode>2"
14041 [(use (match_operand:MODEF 0 "register_operand" ""))
14042 (use (match_operand:MODEF 1 "register_operand" ""))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045 || TARGET_MIX_SSE_I387)
14046 && flag_unsafe_math_optimizations"
14048 rtx op0 = gen_reg_rtx (XFmode);
14049 rtx op1 = gen_reg_rtx (XFmode);
14051 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14057 (define_insn "sse4_1_round<mode>2"
14058 [(set (match_operand:MODEF 0 "register_operand" "=x")
14059 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14060 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14063 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14064 [(set_attr "type" "ssecvt")
14065 (set_attr "prefix_extra" "1")
14066 (set_attr "prefix" "maybe_vex")
14067 (set_attr "mode" "<MODE>")])
14069 (define_insn "rintxf2"
14070 [(set (match_operand:XF 0 "register_operand" "=f")
14071 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14073 "TARGET_USE_FANCY_MATH_387
14074 && flag_unsafe_math_optimizations"
14076 [(set_attr "type" "fpspc")
14077 (set_attr "mode" "XF")])
14079 (define_expand "rint<mode>2"
14080 [(use (match_operand:MODEF 0 "register_operand" ""))
14081 (use (match_operand:MODEF 1 "register_operand" ""))]
14082 "(TARGET_USE_FANCY_MATH_387
14083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14084 || TARGET_MIX_SSE_I387)
14085 && flag_unsafe_math_optimizations)
14086 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14087 && !flag_trapping_math)"
14089 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14090 && !flag_trapping_math)
14092 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14095 emit_insn (gen_sse4_1_round<mode>2
14096 (operands[0], operands[1], GEN_INT (0x04)));
14098 ix86_expand_rint (operand0, operand1);
14102 rtx op0 = gen_reg_rtx (XFmode);
14103 rtx op1 = gen_reg_rtx (XFmode);
14105 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14106 emit_insn (gen_rintxf2 (op0, op1));
14108 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14113 (define_expand "round<mode>2"
14114 [(match_operand:MODEF 0 "register_operand" "")
14115 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14116 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14117 && !flag_trapping_math && !flag_rounding_math"
14119 if (optimize_insn_for_size_p ())
14121 if (TARGET_64BIT || (<MODE>mode != DFmode))
14122 ix86_expand_round (operand0, operand1);
14124 ix86_expand_rounddf_32 (operand0, operand1);
14128 (define_insn_and_split "*fistdi2_1"
14129 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14130 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14132 "TARGET_USE_FANCY_MATH_387
14133 && can_create_pseudo_p ()"
14138 if (memory_operand (operands[0], VOIDmode))
14139 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14142 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14143 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14148 [(set_attr "type" "fpspc")
14149 (set_attr "mode" "DI")])
14151 (define_insn "fistdi2"
14152 [(set (match_operand:DI 0 "memory_operand" "=m")
14153 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14155 (clobber (match_scratch:XF 2 "=&1f"))]
14156 "TARGET_USE_FANCY_MATH_387"
14157 "* return output_fix_trunc (insn, operands, 0);"
14158 [(set_attr "type" "fpspc")
14159 (set_attr "mode" "DI")])
14161 (define_insn "fistdi2_with_temp"
14162 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14163 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14165 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14166 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14167 "TARGET_USE_FANCY_MATH_387"
14169 [(set_attr "type" "fpspc")
14170 (set_attr "mode" "DI")])
14173 [(set (match_operand:DI 0 "register_operand" "")
14174 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14176 (clobber (match_operand:DI 2 "memory_operand" ""))
14177 (clobber (match_scratch 3 ""))]
14179 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14180 (clobber (match_dup 3))])
14181 (set (match_dup 0) (match_dup 2))])
14184 [(set (match_operand:DI 0 "memory_operand" "")
14185 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14187 (clobber (match_operand:DI 2 "memory_operand" ""))
14188 (clobber (match_scratch 3 ""))]
14190 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14191 (clobber (match_dup 3))])])
14193 (define_insn_and_split "*fist<mode>2_1"
14194 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14195 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14197 "TARGET_USE_FANCY_MATH_387
14198 && can_create_pseudo_p ()"
14203 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14204 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "<MODE>")])
14211 (define_insn "fist<mode>2"
14212 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14213 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14215 "TARGET_USE_FANCY_MATH_387"
14216 "* return output_fix_trunc (insn, operands, 0);"
14217 [(set_attr "type" "fpspc")
14218 (set_attr "mode" "<MODE>")])
14220 (define_insn "fist<mode>2_with_temp"
14221 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14222 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14224 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14225 "TARGET_USE_FANCY_MATH_387"
14227 [(set_attr "type" "fpspc")
14228 (set_attr "mode" "<MODE>")])
14231 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14232 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14234 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14236 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14237 (set (match_dup 0) (match_dup 2))])
14240 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14241 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14243 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14245 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14247 (define_expand "lrintxf<mode>2"
14248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14249 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14251 "TARGET_USE_FANCY_MATH_387")
14253 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14254 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14255 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14256 UNSPEC_FIX_NOTRUNC))]
14257 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14258 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14260 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14261 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14262 (match_operand:MODEF 1 "register_operand" "")]
14263 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14264 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14265 && !flag_trapping_math && !flag_rounding_math"
14267 if (optimize_insn_for_size_p ())
14269 ix86_expand_lround (operand0, operand1);
14273 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14274 (define_insn_and_split "frndintxf2_floor"
14275 [(set (match_operand:XF 0 "register_operand" "")
14276 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14277 UNSPEC_FRNDINT_FLOOR))
14278 (clobber (reg:CC FLAGS_REG))]
14279 "TARGET_USE_FANCY_MATH_387
14280 && flag_unsafe_math_optimizations
14281 && can_create_pseudo_p ()"
14286 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14288 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14289 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14291 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14292 operands[2], operands[3]));
14295 [(set_attr "type" "frndint")
14296 (set_attr "i387_cw" "floor")
14297 (set_attr "mode" "XF")])
14299 (define_insn "frndintxf2_floor_i387"
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14302 UNSPEC_FRNDINT_FLOOR))
14303 (use (match_operand:HI 2 "memory_operand" "m"))
14304 (use (match_operand:HI 3 "memory_operand" "m"))]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14307 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14308 [(set_attr "type" "frndint")
14309 (set_attr "i387_cw" "floor")
14310 (set_attr "mode" "XF")])
14312 (define_expand "floorxf2"
14313 [(use (match_operand:XF 0 "register_operand" ""))
14314 (use (match_operand:XF 1 "register_operand" ""))]
14315 "TARGET_USE_FANCY_MATH_387
14316 && flag_unsafe_math_optimizations"
14318 if (optimize_insn_for_size_p ())
14320 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14324 (define_expand "floor<mode>2"
14325 [(use (match_operand:MODEF 0 "register_operand" ""))
14326 (use (match_operand:MODEF 1 "register_operand" ""))]
14327 "(TARGET_USE_FANCY_MATH_387
14328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329 || TARGET_MIX_SSE_I387)
14330 && flag_unsafe_math_optimizations)
14331 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332 && !flag_trapping_math)"
14334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14335 && !flag_trapping_math
14336 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14338 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14341 emit_insn (gen_sse4_1_round<mode>2
14342 (operands[0], operands[1], GEN_INT (0x01)));
14343 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14344 ix86_expand_floorceil (operand0, operand1, true);
14346 ix86_expand_floorceildf_32 (operand0, operand1, true);
14352 if (optimize_insn_for_size_p ())
14355 op0 = gen_reg_rtx (XFmode);
14356 op1 = gen_reg_rtx (XFmode);
14357 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14358 emit_insn (gen_frndintxf2_floor (op0, op1));
14360 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14365 (define_insn_and_split "*fist<mode>2_floor_1"
14366 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14367 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14368 UNSPEC_FIST_FLOOR))
14369 (clobber (reg:CC FLAGS_REG))]
14370 "TARGET_USE_FANCY_MATH_387
14371 && flag_unsafe_math_optimizations
14372 && can_create_pseudo_p ()"
14377 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14379 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14380 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14381 if (memory_operand (operands[0], VOIDmode))
14382 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14383 operands[2], operands[3]));
14386 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14387 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14388 operands[2], operands[3],
14393 [(set_attr "type" "fistp")
14394 (set_attr "i387_cw" "floor")
14395 (set_attr "mode" "<MODE>")])
14397 (define_insn "fistdi2_floor"
14398 [(set (match_operand:DI 0 "memory_operand" "=m")
14399 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14400 UNSPEC_FIST_FLOOR))
14401 (use (match_operand:HI 2 "memory_operand" "m"))
14402 (use (match_operand:HI 3 "memory_operand" "m"))
14403 (clobber (match_scratch:XF 4 "=&1f"))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && flag_unsafe_math_optimizations"
14406 "* return output_fix_trunc (insn, operands, 0);"
14407 [(set_attr "type" "fistp")
14408 (set_attr "i387_cw" "floor")
14409 (set_attr "mode" "DI")])
14411 (define_insn "fistdi2_floor_with_temp"
14412 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14413 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14414 UNSPEC_FIST_FLOOR))
14415 (use (match_operand:HI 2 "memory_operand" "m,m"))
14416 (use (match_operand:HI 3 "memory_operand" "m,m"))
14417 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14418 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14419 "TARGET_USE_FANCY_MATH_387
14420 && flag_unsafe_math_optimizations"
14422 [(set_attr "type" "fistp")
14423 (set_attr "i387_cw" "floor")
14424 (set_attr "mode" "DI")])
14427 [(set (match_operand:DI 0 "register_operand" "")
14428 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429 UNSPEC_FIST_FLOOR))
14430 (use (match_operand:HI 2 "memory_operand" ""))
14431 (use (match_operand:HI 3 "memory_operand" ""))
14432 (clobber (match_operand:DI 4 "memory_operand" ""))
14433 (clobber (match_scratch 5 ""))]
14435 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14436 (use (match_dup 2))
14437 (use (match_dup 3))
14438 (clobber (match_dup 5))])
14439 (set (match_dup 0) (match_dup 4))])
14442 [(set (match_operand:DI 0 "memory_operand" "")
14443 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14444 UNSPEC_FIST_FLOOR))
14445 (use (match_operand:HI 2 "memory_operand" ""))
14446 (use (match_operand:HI 3 "memory_operand" ""))
14447 (clobber (match_operand:DI 4 "memory_operand" ""))
14448 (clobber (match_scratch 5 ""))]
14450 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14451 (use (match_dup 2))
14452 (use (match_dup 3))
14453 (clobber (match_dup 5))])])
14455 (define_insn "fist<mode>2_floor"
14456 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14457 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14458 UNSPEC_FIST_FLOOR))
14459 (use (match_operand:HI 2 "memory_operand" "m"))
14460 (use (match_operand:HI 3 "memory_operand" "m"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14463 "* return output_fix_trunc (insn, operands, 0);"
14464 [(set_attr "type" "fistp")
14465 (set_attr "i387_cw" "floor")
14466 (set_attr "mode" "<MODE>")])
14468 (define_insn "fist<mode>2_floor_with_temp"
14469 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14470 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14471 UNSPEC_FIST_FLOOR))
14472 (use (match_operand:HI 2 "memory_operand" "m,m"))
14473 (use (match_operand:HI 3 "memory_operand" "m,m"))
14474 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14475 "TARGET_USE_FANCY_MATH_387
14476 && flag_unsafe_math_optimizations"
14478 [(set_attr "type" "fistp")
14479 (set_attr "i387_cw" "floor")
14480 (set_attr "mode" "<MODE>")])
14483 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14484 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14485 UNSPEC_FIST_FLOOR))
14486 (use (match_operand:HI 2 "memory_operand" ""))
14487 (use (match_operand:HI 3 "memory_operand" ""))
14488 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14490 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14491 UNSPEC_FIST_FLOOR))
14492 (use (match_dup 2))
14493 (use (match_dup 3))])
14494 (set (match_dup 0) (match_dup 4))])
14497 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14498 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14499 UNSPEC_FIST_FLOOR))
14500 (use (match_operand:HI 2 "memory_operand" ""))
14501 (use (match_operand:HI 3 "memory_operand" ""))
14502 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14504 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14505 UNSPEC_FIST_FLOOR))
14506 (use (match_dup 2))
14507 (use (match_dup 3))])])
14509 (define_expand "lfloorxf<mode>2"
14510 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14511 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14512 UNSPEC_FIST_FLOOR))
14513 (clobber (reg:CC FLAGS_REG))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14516 && flag_unsafe_math_optimizations")
14518 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14519 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14520 (match_operand:MODEF 1 "register_operand" "")]
14521 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14522 && !flag_trapping_math"
14524 if (TARGET_64BIT && optimize_insn_for_size_p ())
14526 ix86_expand_lfloorceil (operand0, operand1, true);
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_ceil"
14532 [(set (match_operand:XF 0 "register_operand" "")
14533 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534 UNSPEC_FRNDINT_CEIL))
14535 (clobber (reg:CC FLAGS_REG))]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations
14538 && can_create_pseudo_p ()"
14543 ix86_optimize_mode_switching[I387_CEIL] = 1;
14545 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14548 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14549 operands[2], operands[3]));
14552 [(set_attr "type" "frndint")
14553 (set_attr "i387_cw" "ceil")
14554 (set_attr "mode" "XF")])
14556 (define_insn "frndintxf2_ceil_i387"
14557 [(set (match_operand:XF 0 "register_operand" "=f")
14558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559 UNSPEC_FRNDINT_CEIL))
14560 (use (match_operand:HI 2 "memory_operand" "m"))
14561 (use (match_operand:HI 3 "memory_operand" "m"))]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14564 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565 [(set_attr "type" "frndint")
14566 (set_attr "i387_cw" "ceil")
14567 (set_attr "mode" "XF")])
14569 (define_expand "ceilxf2"
14570 [(use (match_operand:XF 0 "register_operand" ""))
14571 (use (match_operand:XF 1 "register_operand" ""))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && flag_unsafe_math_optimizations"
14575 if (optimize_insn_for_size_p ())
14577 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14581 (define_expand "ceil<mode>2"
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "register_operand" ""))]
14584 "(TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations)
14588 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589 && !flag_trapping_math)"
14591 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592 && !flag_trapping_math
14593 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14596 emit_insn (gen_sse4_1_round<mode>2
14597 (operands[0], operands[1], GEN_INT (0x02)));
14598 else if (optimize_insn_for_size_p ())
14600 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601 ix86_expand_floorceil (operand0, operand1, false);
14603 ix86_expand_floorceildf_32 (operand0, operand1, false);
14609 if (optimize_insn_for_size_p ())
14612 op0 = gen_reg_rtx (XFmode);
14613 op1 = gen_reg_rtx (XFmode);
14614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615 emit_insn (gen_frndintxf2_ceil (op0, op1));
14617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14622 (define_insn_and_split "*fist<mode>2_ceil_1"
14623 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14626 (clobber (reg:CC FLAGS_REG))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations
14629 && can_create_pseudo_p ()"
14634 ix86_optimize_mode_switching[I387_CEIL] = 1;
14636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14638 if (memory_operand (operands[0], VOIDmode))
14639 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14640 operands[2], operands[3]));
14643 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14645 operands[2], operands[3],
14650 [(set_attr "type" "fistp")
14651 (set_attr "i387_cw" "ceil")
14652 (set_attr "mode" "<MODE>")])
14654 (define_insn "fistdi2_ceil"
14655 [(set (match_operand:DI 0 "memory_operand" "=m")
14656 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14658 (use (match_operand:HI 2 "memory_operand" "m"))
14659 (use (match_operand:HI 3 "memory_operand" "m"))
14660 (clobber (match_scratch:XF 4 "=&1f"))]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14663 "* return output_fix_trunc (insn, operands, 0);"
14664 [(set_attr "type" "fistp")
14665 (set_attr "i387_cw" "ceil")
14666 (set_attr "mode" "DI")])
14668 (define_insn "fistdi2_ceil_with_temp"
14669 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14672 (use (match_operand:HI 2 "memory_operand" "m,m"))
14673 (use (match_operand:HI 3 "memory_operand" "m,m"))
14674 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676 "TARGET_USE_FANCY_MATH_387
14677 && flag_unsafe_math_optimizations"
14679 [(set_attr "type" "fistp")
14680 (set_attr "i387_cw" "ceil")
14681 (set_attr "mode" "DI")])
14684 [(set (match_operand:DI 0 "register_operand" "")
14685 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14687 (use (match_operand:HI 2 "memory_operand" ""))
14688 (use (match_operand:HI 3 "memory_operand" ""))
14689 (clobber (match_operand:DI 4 "memory_operand" ""))
14690 (clobber (match_scratch 5 ""))]
14692 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14693 (use (match_dup 2))
14694 (use (match_dup 3))
14695 (clobber (match_dup 5))])
14696 (set (match_dup 0) (match_dup 4))])
14699 [(set (match_operand:DI 0 "memory_operand" "")
14700 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14702 (use (match_operand:HI 2 "memory_operand" ""))
14703 (use (match_operand:HI 3 "memory_operand" ""))
14704 (clobber (match_operand:DI 4 "memory_operand" ""))
14705 (clobber (match_scratch 5 ""))]
14707 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14708 (use (match_dup 2))
14709 (use (match_dup 3))
14710 (clobber (match_dup 5))])])
14712 (define_insn "fist<mode>2_ceil"
14713 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14714 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14716 (use (match_operand:HI 2 "memory_operand" "m"))
14717 (use (match_operand:HI 3 "memory_operand" "m"))]
14718 "TARGET_USE_FANCY_MATH_387
14719 && flag_unsafe_math_optimizations"
14720 "* return output_fix_trunc (insn, operands, 0);"
14721 [(set_attr "type" "fistp")
14722 (set_attr "i387_cw" "ceil")
14723 (set_attr "mode" "<MODE>")])
14725 (define_insn "fist<mode>2_ceil_with_temp"
14726 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14727 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14729 (use (match_operand:HI 2 "memory_operand" "m,m"))
14730 (use (match_operand:HI 3 "memory_operand" "m,m"))
14731 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14732 "TARGET_USE_FANCY_MATH_387
14733 && flag_unsafe_math_optimizations"
14735 [(set_attr "type" "fistp")
14736 (set_attr "i387_cw" "ceil")
14737 (set_attr "mode" "<MODE>")])
14740 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14743 (use (match_operand:HI 2 "memory_operand" ""))
14744 (use (match_operand:HI 3 "memory_operand" ""))
14745 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14747 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14749 (use (match_dup 2))
14750 (use (match_dup 3))])
14751 (set (match_dup 0) (match_dup 4))])
14754 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14755 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14757 (use (match_operand:HI 2 "memory_operand" ""))
14758 (use (match_operand:HI 3 "memory_operand" ""))
14759 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14761 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14763 (use (match_dup 2))
14764 (use (match_dup 3))])])
14766 (define_expand "lceilxf<mode>2"
14767 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14768 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14770 (clobber (reg:CC FLAGS_REG))])]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14773 && flag_unsafe_math_optimizations")
14775 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14776 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14777 (match_operand:MODEF 1 "register_operand" "")]
14778 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14779 && !flag_trapping_math"
14781 ix86_expand_lfloorceil (operand0, operand1, false);
14785 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14786 (define_insn_and_split "frndintxf2_trunc"
14787 [(set (match_operand:XF 0 "register_operand" "")
14788 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14789 UNSPEC_FRNDINT_TRUNC))
14790 (clobber (reg:CC FLAGS_REG))]
14791 "TARGET_USE_FANCY_MATH_387
14792 && flag_unsafe_math_optimizations
14793 && can_create_pseudo_p ()"
14798 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14800 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14801 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14803 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14804 operands[2], operands[3]));
14807 [(set_attr "type" "frndint")
14808 (set_attr "i387_cw" "trunc")
14809 (set_attr "mode" "XF")])
14811 (define_insn "frndintxf2_trunc_i387"
14812 [(set (match_operand:XF 0 "register_operand" "=f")
14813 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14814 UNSPEC_FRNDINT_TRUNC))
14815 (use (match_operand:HI 2 "memory_operand" "m"))
14816 (use (match_operand:HI 3 "memory_operand" "m"))]
14817 "TARGET_USE_FANCY_MATH_387
14818 && flag_unsafe_math_optimizations"
14819 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14820 [(set_attr "type" "frndint")
14821 (set_attr "i387_cw" "trunc")
14822 (set_attr "mode" "XF")])
14824 (define_expand "btruncxf2"
14825 [(use (match_operand:XF 0 "register_operand" ""))
14826 (use (match_operand:XF 1 "register_operand" ""))]
14827 "TARGET_USE_FANCY_MATH_387
14828 && flag_unsafe_math_optimizations"
14830 if (optimize_insn_for_size_p ())
14832 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14836 (define_expand "btrunc<mode>2"
14837 [(use (match_operand:MODEF 0 "register_operand" ""))
14838 (use (match_operand:MODEF 1 "register_operand" ""))]
14839 "(TARGET_USE_FANCY_MATH_387
14840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14841 || TARGET_MIX_SSE_I387)
14842 && flag_unsafe_math_optimizations)
14843 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math)"
14846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14847 && !flag_trapping_math
14848 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14851 emit_insn (gen_sse4_1_round<mode>2
14852 (operands[0], operands[1], GEN_INT (0x03)));
14853 else if (optimize_insn_for_size_p ())
14855 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14856 ix86_expand_trunc (operand0, operand1);
14858 ix86_expand_truncdf_32 (operand0, operand1);
14864 if (optimize_insn_for_size_p ())
14867 op0 = gen_reg_rtx (XFmode);
14868 op1 = gen_reg_rtx (XFmode);
14869 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14870 emit_insn (gen_frndintxf2_trunc (op0, op1));
14872 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14877 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14878 (define_insn_and_split "frndintxf2_mask_pm"
14879 [(set (match_operand:XF 0 "register_operand" "")
14880 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14881 UNSPEC_FRNDINT_MASK_PM))
14882 (clobber (reg:CC FLAGS_REG))]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations
14885 && can_create_pseudo_p ()"
14890 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14895 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14896 operands[2], operands[3]));
14899 [(set_attr "type" "frndint")
14900 (set_attr "i387_cw" "mask_pm")
14901 (set_attr "mode" "XF")])
14903 (define_insn "frndintxf2_mask_pm_i387"
14904 [(set (match_operand:XF 0 "register_operand" "=f")
14905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14906 UNSPEC_FRNDINT_MASK_PM))
14907 (use (match_operand:HI 2 "memory_operand" "m"))
14908 (use (match_operand:HI 3 "memory_operand" "m"))]
14909 "TARGET_USE_FANCY_MATH_387
14910 && flag_unsafe_math_optimizations"
14911 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14912 [(set_attr "type" "frndint")
14913 (set_attr "i387_cw" "mask_pm")
14914 (set_attr "mode" "XF")])
14916 (define_expand "nearbyintxf2"
14917 [(use (match_operand:XF 0 "register_operand" ""))
14918 (use (match_operand:XF 1 "register_operand" ""))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations"
14922 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14926 (define_expand "nearbyint<mode>2"
14927 [(use (match_operand:MODEF 0 "register_operand" ""))
14928 (use (match_operand:MODEF 1 "register_operand" ""))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931 || TARGET_MIX_SSE_I387)
14932 && flag_unsafe_math_optimizations"
14934 rtx op0 = gen_reg_rtx (XFmode);
14935 rtx op1 = gen_reg_rtx (XFmode);
14937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14938 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14940 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14944 (define_insn "fxam<mode>2_i387"
14945 [(set (match_operand:HI 0 "register_operand" "=a")
14947 [(match_operand:X87MODEF 1 "register_operand" "f")]
14949 "TARGET_USE_FANCY_MATH_387"
14950 "fxam\n\tfnstsw\t%0"
14951 [(set_attr "type" "multi")
14952 (set_attr "length" "4")
14953 (set_attr "unit" "i387")
14954 (set_attr "mode" "<MODE>")])
14956 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14957 [(set (match_operand:HI 0 "register_operand" "")
14959 [(match_operand:MODEF 1 "memory_operand" "")]
14961 "TARGET_USE_FANCY_MATH_387
14962 && can_create_pseudo_p ()"
14965 [(set (match_dup 2)(match_dup 1))
14967 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14969 operands[2] = gen_reg_rtx (<MODE>mode);
14971 MEM_VOLATILE_P (operands[1]) = 1;
14973 [(set_attr "type" "multi")
14974 (set_attr "unit" "i387")
14975 (set_attr "mode" "<MODE>")])
14977 (define_expand "isinfxf2"
14978 [(use (match_operand:SI 0 "register_operand" ""))
14979 (use (match_operand:XF 1 "register_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && TARGET_C99_FUNCTIONS"
14983 rtx mask = GEN_INT (0x45);
14984 rtx val = GEN_INT (0x05);
14988 rtx scratch = gen_reg_rtx (HImode);
14989 rtx res = gen_reg_rtx (QImode);
14991 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14993 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14994 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14995 cond = gen_rtx_fmt_ee (EQ, QImode,
14996 gen_rtx_REG (CCmode, FLAGS_REG),
14998 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14999 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15003 (define_expand "isinf<mode>2"
15004 [(use (match_operand:SI 0 "register_operand" ""))
15005 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15006 "TARGET_USE_FANCY_MATH_387
15007 && TARGET_C99_FUNCTIONS
15008 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15010 rtx mask = GEN_INT (0x45);
15011 rtx val = GEN_INT (0x05);
15015 rtx scratch = gen_reg_rtx (HImode);
15016 rtx res = gen_reg_rtx (QImode);
15018 /* Remove excess precision by forcing value through memory. */
15019 if (memory_operand (operands[1], VOIDmode))
15020 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15023 enum ix86_stack_slot slot = (virtuals_instantiated
15026 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15028 emit_move_insn (temp, operands[1]);
15029 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15032 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15033 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15034 cond = gen_rtx_fmt_ee (EQ, QImode,
15035 gen_rtx_REG (CCmode, FLAGS_REG),
15037 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15038 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15042 (define_expand "signbitxf2"
15043 [(use (match_operand:SI 0 "register_operand" ""))
15044 (use (match_operand:XF 1 "register_operand" ""))]
15045 "TARGET_USE_FANCY_MATH_387"
15047 rtx scratch = gen_reg_rtx (HImode);
15049 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15050 emit_insn (gen_andsi3 (operands[0],
15051 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15055 (define_insn "movmsk_df"
15056 [(set (match_operand:SI 0 "register_operand" "=r")
15058 [(match_operand:DF 1 "register_operand" "x")]
15060 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15061 "%vmovmskpd\t{%1, %0|%0, %1}"
15062 [(set_attr "type" "ssemov")
15063 (set_attr "prefix" "maybe_vex")
15064 (set_attr "mode" "DF")])
15066 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15067 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15068 (define_expand "signbitdf2"
15069 [(use (match_operand:SI 0 "register_operand" ""))
15070 (use (match_operand:DF 1 "register_operand" ""))]
15071 "TARGET_USE_FANCY_MATH_387
15072 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15074 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15076 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15077 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15081 rtx scratch = gen_reg_rtx (HImode);
15083 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15084 emit_insn (gen_andsi3 (operands[0],
15085 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15090 (define_expand "signbitsf2"
15091 [(use (match_operand:SI 0 "register_operand" ""))
15092 (use (match_operand:SF 1 "register_operand" ""))]
15093 "TARGET_USE_FANCY_MATH_387
15094 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15096 rtx scratch = gen_reg_rtx (HImode);
15098 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15099 emit_insn (gen_andsi3 (operands[0],
15100 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15104 ;; Block operation instructions
15107 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15110 [(set_attr "length" "1")
15111 (set_attr "length_immediate" "0")
15112 (set_attr "modrm" "0")])
15114 (define_expand "movmemsi"
15115 [(use (match_operand:BLK 0 "memory_operand" ""))
15116 (use (match_operand:BLK 1 "memory_operand" ""))
15117 (use (match_operand:SI 2 "nonmemory_operand" ""))
15118 (use (match_operand:SI 3 "const_int_operand" ""))
15119 (use (match_operand:SI 4 "const_int_operand" ""))
15120 (use (match_operand:SI 5 "const_int_operand" ""))]
15123 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15124 operands[4], operands[5]))
15130 (define_expand "movmemdi"
15131 [(use (match_operand:BLK 0 "memory_operand" ""))
15132 (use (match_operand:BLK 1 "memory_operand" ""))
15133 (use (match_operand:DI 2 "nonmemory_operand" ""))
15134 (use (match_operand:DI 3 "const_int_operand" ""))
15135 (use (match_operand:SI 4 "const_int_operand" ""))
15136 (use (match_operand:SI 5 "const_int_operand" ""))]
15139 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15140 operands[4], operands[5]))
15146 ;; Most CPUs don't like single string operations
15147 ;; Handle this case here to simplify previous expander.
15149 (define_expand "strmov"
15150 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15151 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15152 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15153 (clobber (reg:CC FLAGS_REG))])
15154 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15155 (clobber (reg:CC FLAGS_REG))])]
15158 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15160 /* If .md ever supports :P for Pmode, these can be directly
15161 in the pattern above. */
15162 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15163 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15165 /* Can't use this if the user has appropriated esi or edi. */
15166 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15167 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15169 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15170 operands[2], operands[3],
15171 operands[5], operands[6]));
15175 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15178 (define_expand "strmov_singleop"
15179 [(parallel [(set (match_operand 1 "memory_operand" "")
15180 (match_operand 3 "memory_operand" ""))
15181 (set (match_operand 0 "register_operand" "")
15182 (match_operand 4 "" ""))
15183 (set (match_operand 2 "register_operand" "")
15184 (match_operand 5 "" ""))])]
15186 "ix86_current_function_needs_cld = 1;")
15188 (define_insn "*strmovdi_rex_1"
15189 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15190 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15191 (set (match_operand:DI 0 "register_operand" "=D")
15192 (plus:DI (match_dup 2)
15194 (set (match_operand:DI 1 "register_operand" "=S")
15195 (plus:DI (match_dup 3)
15199 [(set_attr "type" "str")
15200 (set_attr "mode" "DI")
15201 (set_attr "memory" "both")])
15203 (define_insn "*strmovsi_1"
15204 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15205 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15206 (set (match_operand:SI 0 "register_operand" "=D")
15207 (plus:SI (match_dup 2)
15209 (set (match_operand:SI 1 "register_operand" "=S")
15210 (plus:SI (match_dup 3)
15214 [(set_attr "type" "str")
15215 (set_attr "mode" "SI")
15216 (set_attr "memory" "both")])
15218 (define_insn "*strmovsi_rex_1"
15219 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15220 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15221 (set (match_operand:DI 0 "register_operand" "=D")
15222 (plus:DI (match_dup 2)
15224 (set (match_operand:DI 1 "register_operand" "=S")
15225 (plus:DI (match_dup 3)
15229 [(set_attr "type" "str")
15230 (set_attr "mode" "SI")
15231 (set_attr "memory" "both")])
15233 (define_insn "*strmovhi_1"
15234 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15235 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15236 (set (match_operand:SI 0 "register_operand" "=D")
15237 (plus:SI (match_dup 2)
15239 (set (match_operand:SI 1 "register_operand" "=S")
15240 (plus:SI (match_dup 3)
15244 [(set_attr "type" "str")
15245 (set_attr "memory" "both")
15246 (set_attr "mode" "HI")])
15248 (define_insn "*strmovhi_rex_1"
15249 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15250 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15251 (set (match_operand:DI 0 "register_operand" "=D")
15252 (plus:DI (match_dup 2)
15254 (set (match_operand:DI 1 "register_operand" "=S")
15255 (plus:DI (match_dup 3)
15259 [(set_attr "type" "str")
15260 (set_attr "memory" "both")
15261 (set_attr "mode" "HI")])
15263 (define_insn "*strmovqi_1"
15264 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15265 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15266 (set (match_operand:SI 0 "register_operand" "=D")
15267 (plus:SI (match_dup 2)
15269 (set (match_operand:SI 1 "register_operand" "=S")
15270 (plus:SI (match_dup 3)
15274 [(set_attr "type" "str")
15275 (set_attr "memory" "both")
15276 (set_attr "mode" "QI")])
15278 (define_insn "*strmovqi_rex_1"
15279 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15280 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15281 (set (match_operand:DI 0 "register_operand" "=D")
15282 (plus:DI (match_dup 2)
15284 (set (match_operand:DI 1 "register_operand" "=S")
15285 (plus:DI (match_dup 3)
15289 [(set_attr "type" "str")
15290 (set_attr "memory" "both")
15291 (set_attr "prefix_rex" "0")
15292 (set_attr "mode" "QI")])
15294 (define_expand "rep_mov"
15295 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15296 (set (match_operand 0 "register_operand" "")
15297 (match_operand 5 "" ""))
15298 (set (match_operand 2 "register_operand" "")
15299 (match_operand 6 "" ""))
15300 (set (match_operand 1 "memory_operand" "")
15301 (match_operand 3 "memory_operand" ""))
15302 (use (match_dup 4))])]
15304 "ix86_current_function_needs_cld = 1;")
15306 (define_insn "*rep_movdi_rex64"
15307 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15308 (set (match_operand:DI 0 "register_operand" "=D")
15309 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15311 (match_operand:DI 3 "register_operand" "0")))
15312 (set (match_operand:DI 1 "register_operand" "=S")
15313 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15314 (match_operand:DI 4 "register_operand" "1")))
15315 (set (mem:BLK (match_dup 3))
15316 (mem:BLK (match_dup 4)))
15317 (use (match_dup 5))]
15320 [(set_attr "type" "str")
15321 (set_attr "prefix_rep" "1")
15322 (set_attr "memory" "both")
15323 (set_attr "mode" "DI")])
15325 (define_insn "*rep_movsi"
15326 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15327 (set (match_operand:SI 0 "register_operand" "=D")
15328 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15330 (match_operand:SI 3 "register_operand" "0")))
15331 (set (match_operand:SI 1 "register_operand" "=S")
15332 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15333 (match_operand:SI 4 "register_operand" "1")))
15334 (set (mem:BLK (match_dup 3))
15335 (mem:BLK (match_dup 4)))
15336 (use (match_dup 5))]
15338 "rep{%;} movs{l|d}"
15339 [(set_attr "type" "str")
15340 (set_attr "prefix_rep" "1")
15341 (set_attr "memory" "both")
15342 (set_attr "mode" "SI")])
15344 (define_insn "*rep_movsi_rex64"
15345 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15346 (set (match_operand:DI 0 "register_operand" "=D")
15347 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15349 (match_operand:DI 3 "register_operand" "0")))
15350 (set (match_operand:DI 1 "register_operand" "=S")
15351 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15352 (match_operand:DI 4 "register_operand" "1")))
15353 (set (mem:BLK (match_dup 3))
15354 (mem:BLK (match_dup 4)))
15355 (use (match_dup 5))]
15357 "rep{%;} movs{l|d}"
15358 [(set_attr "type" "str")
15359 (set_attr "prefix_rep" "1")
15360 (set_attr "memory" "both")
15361 (set_attr "mode" "SI")])
15363 (define_insn "*rep_movqi"
15364 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15365 (set (match_operand:SI 0 "register_operand" "=D")
15366 (plus:SI (match_operand:SI 3 "register_operand" "0")
15367 (match_operand:SI 5 "register_operand" "2")))
15368 (set (match_operand:SI 1 "register_operand" "=S")
15369 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15370 (set (mem:BLK (match_dup 3))
15371 (mem:BLK (match_dup 4)))
15372 (use (match_dup 5))]
15375 [(set_attr "type" "str")
15376 (set_attr "prefix_rep" "1")
15377 (set_attr "memory" "both")
15378 (set_attr "mode" "SI")])
15380 (define_insn "*rep_movqi_rex64"
15381 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15382 (set (match_operand:DI 0 "register_operand" "=D")
15383 (plus:DI (match_operand:DI 3 "register_operand" "0")
15384 (match_operand:DI 5 "register_operand" "2")))
15385 (set (match_operand:DI 1 "register_operand" "=S")
15386 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15387 (set (mem:BLK (match_dup 3))
15388 (mem:BLK (match_dup 4)))
15389 (use (match_dup 5))]
15392 [(set_attr "type" "str")
15393 (set_attr "prefix_rep" "1")
15394 (set_attr "memory" "both")
15395 (set_attr "mode" "SI")])
15397 (define_expand "setmemsi"
15398 [(use (match_operand:BLK 0 "memory_operand" ""))
15399 (use (match_operand:SI 1 "nonmemory_operand" ""))
15400 (use (match_operand 2 "const_int_operand" ""))
15401 (use (match_operand 3 "const_int_operand" ""))
15402 (use (match_operand:SI 4 "const_int_operand" ""))
15403 (use (match_operand:SI 5 "const_int_operand" ""))]
15406 if (ix86_expand_setmem (operands[0], operands[1],
15407 operands[2], operands[3],
15408 operands[4], operands[5]))
15414 (define_expand "setmemdi"
15415 [(use (match_operand:BLK 0 "memory_operand" ""))
15416 (use (match_operand:DI 1 "nonmemory_operand" ""))
15417 (use (match_operand 2 "const_int_operand" ""))
15418 (use (match_operand 3 "const_int_operand" ""))
15419 (use (match_operand 4 "const_int_operand" ""))
15420 (use (match_operand 5 "const_int_operand" ""))]
15423 if (ix86_expand_setmem (operands[0], operands[1],
15424 operands[2], operands[3],
15425 operands[4], operands[5]))
15431 ;; Most CPUs don't like single string operations
15432 ;; Handle this case here to simplify previous expander.
15434 (define_expand "strset"
15435 [(set (match_operand 1 "memory_operand" "")
15436 (match_operand 2 "register_operand" ""))
15437 (parallel [(set (match_operand 0 "register_operand" "")
15439 (clobber (reg:CC FLAGS_REG))])]
15442 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15443 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15445 /* If .md ever supports :P for Pmode, this can be directly
15446 in the pattern above. */
15447 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15448 GEN_INT (GET_MODE_SIZE (GET_MODE
15450 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15452 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15458 (define_expand "strset_singleop"
15459 [(parallel [(set (match_operand 1 "memory_operand" "")
15460 (match_operand 2 "register_operand" ""))
15461 (set (match_operand 0 "register_operand" "")
15462 (match_operand 3 "" ""))])]
15464 "ix86_current_function_needs_cld = 1;")
15466 (define_insn "*strsetdi_rex_1"
15467 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15468 (match_operand:DI 2 "register_operand" "a"))
15469 (set (match_operand:DI 0 "register_operand" "=D")
15470 (plus:DI (match_dup 1)
15474 [(set_attr "type" "str")
15475 (set_attr "memory" "store")
15476 (set_attr "mode" "DI")])
15478 (define_insn "*strsetsi_1"
15479 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15480 (match_operand:SI 2 "register_operand" "a"))
15481 (set (match_operand:SI 0 "register_operand" "=D")
15482 (plus:SI (match_dup 1)
15486 [(set_attr "type" "str")
15487 (set_attr "memory" "store")
15488 (set_attr "mode" "SI")])
15490 (define_insn "*strsetsi_rex_1"
15491 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15492 (match_operand:SI 2 "register_operand" "a"))
15493 (set (match_operand:DI 0 "register_operand" "=D")
15494 (plus:DI (match_dup 1)
15498 [(set_attr "type" "str")
15499 (set_attr "memory" "store")
15500 (set_attr "mode" "SI")])
15502 (define_insn "*strsethi_1"
15503 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15504 (match_operand:HI 2 "register_operand" "a"))
15505 (set (match_operand:SI 0 "register_operand" "=D")
15506 (plus:SI (match_dup 1)
15510 [(set_attr "type" "str")
15511 (set_attr "memory" "store")
15512 (set_attr "mode" "HI")])
15514 (define_insn "*strsethi_rex_1"
15515 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15516 (match_operand:HI 2 "register_operand" "a"))
15517 (set (match_operand:DI 0 "register_operand" "=D")
15518 (plus:DI (match_dup 1)
15522 [(set_attr "type" "str")
15523 (set_attr "memory" "store")
15524 (set_attr "mode" "HI")])
15526 (define_insn "*strsetqi_1"
15527 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15528 (match_operand:QI 2 "register_operand" "a"))
15529 (set (match_operand:SI 0 "register_operand" "=D")
15530 (plus:SI (match_dup 1)
15534 [(set_attr "type" "str")
15535 (set_attr "memory" "store")
15536 (set_attr "mode" "QI")])
15538 (define_insn "*strsetqi_rex_1"
15539 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15540 (match_operand:QI 2 "register_operand" "a"))
15541 (set (match_operand:DI 0 "register_operand" "=D")
15542 (plus:DI (match_dup 1)
15546 [(set_attr "type" "str")
15547 (set_attr "memory" "store")
15548 (set_attr "prefix_rex" "0")
15549 (set_attr "mode" "QI")])
15551 (define_expand "rep_stos"
15552 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15553 (set (match_operand 0 "register_operand" "")
15554 (match_operand 4 "" ""))
15555 (set (match_operand 2 "memory_operand" "") (const_int 0))
15556 (use (match_operand 3 "register_operand" ""))
15557 (use (match_dup 1))])]
15559 "ix86_current_function_needs_cld = 1;")
15561 (define_insn "*rep_stosdi_rex64"
15562 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15563 (set (match_operand:DI 0 "register_operand" "=D")
15564 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15566 (match_operand:DI 3 "register_operand" "0")))
15567 (set (mem:BLK (match_dup 3))
15569 (use (match_operand:DI 2 "register_operand" "a"))
15570 (use (match_dup 4))]
15573 [(set_attr "type" "str")
15574 (set_attr "prefix_rep" "1")
15575 (set_attr "memory" "store")
15576 (set_attr "mode" "DI")])
15578 (define_insn "*rep_stossi"
15579 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15580 (set (match_operand:SI 0 "register_operand" "=D")
15581 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15583 (match_operand:SI 3 "register_operand" "0")))
15584 (set (mem:BLK (match_dup 3))
15586 (use (match_operand:SI 2 "register_operand" "a"))
15587 (use (match_dup 4))]
15589 "rep{%;} stos{l|d}"
15590 [(set_attr "type" "str")
15591 (set_attr "prefix_rep" "1")
15592 (set_attr "memory" "store")
15593 (set_attr "mode" "SI")])
15595 (define_insn "*rep_stossi_rex64"
15596 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15597 (set (match_operand:DI 0 "register_operand" "=D")
15598 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15600 (match_operand:DI 3 "register_operand" "0")))
15601 (set (mem:BLK (match_dup 3))
15603 (use (match_operand:SI 2 "register_operand" "a"))
15604 (use (match_dup 4))]
15606 "rep{%;} stos{l|d}"
15607 [(set_attr "type" "str")
15608 (set_attr "prefix_rep" "1")
15609 (set_attr "memory" "store")
15610 (set_attr "mode" "SI")])
15612 (define_insn "*rep_stosqi"
15613 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15614 (set (match_operand:SI 0 "register_operand" "=D")
15615 (plus:SI (match_operand:SI 3 "register_operand" "0")
15616 (match_operand:SI 4 "register_operand" "1")))
15617 (set (mem:BLK (match_dup 3))
15619 (use (match_operand:QI 2 "register_operand" "a"))
15620 (use (match_dup 4))]
15623 [(set_attr "type" "str")
15624 (set_attr "prefix_rep" "1")
15625 (set_attr "memory" "store")
15626 (set_attr "mode" "QI")])
15628 (define_insn "*rep_stosqi_rex64"
15629 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15630 (set (match_operand:DI 0 "register_operand" "=D")
15631 (plus:DI (match_operand:DI 3 "register_operand" "0")
15632 (match_operand:DI 4 "register_operand" "1")))
15633 (set (mem:BLK (match_dup 3))
15635 (use (match_operand:QI 2 "register_operand" "a"))
15636 (use (match_dup 4))]
15639 [(set_attr "type" "str")
15640 (set_attr "prefix_rep" "1")
15641 (set_attr "memory" "store")
15642 (set_attr "prefix_rex" "0")
15643 (set_attr "mode" "QI")])
15645 (define_expand "cmpstrnsi"
15646 [(set (match_operand:SI 0 "register_operand" "")
15647 (compare:SI (match_operand:BLK 1 "general_operand" "")
15648 (match_operand:BLK 2 "general_operand" "")))
15649 (use (match_operand 3 "general_operand" ""))
15650 (use (match_operand 4 "immediate_operand" ""))]
15653 rtx addr1, addr2, out, outlow, count, countreg, align;
15655 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15658 /* Can't use this if the user has appropriated esi or edi. */
15659 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15664 out = gen_reg_rtx (SImode);
15666 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15667 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15668 if (addr1 != XEXP (operands[1], 0))
15669 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15670 if (addr2 != XEXP (operands[2], 0))
15671 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15673 count = operands[3];
15674 countreg = ix86_zero_extend_to_Pmode (count);
15676 /* %%% Iff we are testing strict equality, we can use known alignment
15677 to good advantage. This may be possible with combine, particularly
15678 once cc0 is dead. */
15679 align = operands[4];
15681 if (CONST_INT_P (count))
15683 if (INTVAL (count) == 0)
15685 emit_move_insn (operands[0], const0_rtx);
15688 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15689 operands[1], operands[2]));
15693 rtx (*gen_cmp) (rtx, rtx);
15695 gen_cmp = (TARGET_64BIT
15696 ? gen_cmpdi_1 : gen_cmpsi_1);
15698 emit_insn (gen_cmp (countreg, countreg));
15699 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15700 operands[1], operands[2]));
15703 outlow = gen_lowpart (QImode, out);
15704 emit_insn (gen_cmpintqi (outlow));
15705 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15707 if (operands[0] != out)
15708 emit_move_insn (operands[0], out);
15713 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15715 (define_expand "cmpintqi"
15716 [(set (match_dup 1)
15717 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15719 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15720 (parallel [(set (match_operand:QI 0 "register_operand" "")
15721 (minus:QI (match_dup 1)
15723 (clobber (reg:CC FLAGS_REG))])]
15725 "operands[1] = gen_reg_rtx (QImode);
15726 operands[2] = gen_reg_rtx (QImode);")
15728 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15729 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15731 (define_expand "cmpstrnqi_nz_1"
15732 [(parallel [(set (reg:CC FLAGS_REG)
15733 (compare:CC (match_operand 4 "memory_operand" "")
15734 (match_operand 5 "memory_operand" "")))
15735 (use (match_operand 2 "register_operand" ""))
15736 (use (match_operand:SI 3 "immediate_operand" ""))
15737 (clobber (match_operand 0 "register_operand" ""))
15738 (clobber (match_operand 1 "register_operand" ""))
15739 (clobber (match_dup 2))])]
15741 "ix86_current_function_needs_cld = 1;")
15743 (define_insn "*cmpstrnqi_nz_1"
15744 [(set (reg:CC FLAGS_REG)
15745 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15746 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15747 (use (match_operand:SI 6 "register_operand" "2"))
15748 (use (match_operand:SI 3 "immediate_operand" "i"))
15749 (clobber (match_operand:SI 0 "register_operand" "=S"))
15750 (clobber (match_operand:SI 1 "register_operand" "=D"))
15751 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15754 [(set_attr "type" "str")
15755 (set_attr "mode" "QI")
15756 (set_attr "prefix_rep" "1")])
15758 (define_insn "*cmpstrnqi_nz_rex_1"
15759 [(set (reg:CC FLAGS_REG)
15760 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15761 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15762 (use (match_operand:DI 6 "register_operand" "2"))
15763 (use (match_operand:SI 3 "immediate_operand" "i"))
15764 (clobber (match_operand:DI 0 "register_operand" "=S"))
15765 (clobber (match_operand:DI 1 "register_operand" "=D"))
15766 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15769 [(set_attr "type" "str")
15770 (set_attr "mode" "QI")
15771 (set_attr "prefix_rex" "0")
15772 (set_attr "prefix_rep" "1")])
15774 ;; The same, but the count is not known to not be zero.
15776 (define_expand "cmpstrnqi_1"
15777 [(parallel [(set (reg:CC FLAGS_REG)
15778 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15780 (compare:CC (match_operand 4 "memory_operand" "")
15781 (match_operand 5 "memory_operand" ""))
15783 (use (match_operand:SI 3 "immediate_operand" ""))
15784 (use (reg:CC FLAGS_REG))
15785 (clobber (match_operand 0 "register_operand" ""))
15786 (clobber (match_operand 1 "register_operand" ""))
15787 (clobber (match_dup 2))])]
15789 "ix86_current_function_needs_cld = 1;")
15791 (define_insn "*cmpstrnqi_1"
15792 [(set (reg:CC FLAGS_REG)
15793 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15795 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15796 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15798 (use (match_operand:SI 3 "immediate_operand" "i"))
15799 (use (reg:CC FLAGS_REG))
15800 (clobber (match_operand:SI 0 "register_operand" "=S"))
15801 (clobber (match_operand:SI 1 "register_operand" "=D"))
15802 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15805 [(set_attr "type" "str")
15806 (set_attr "mode" "QI")
15807 (set_attr "prefix_rep" "1")])
15809 (define_insn "*cmpstrnqi_rex_1"
15810 [(set (reg:CC FLAGS_REG)
15811 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15813 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15814 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15816 (use (match_operand:SI 3 "immediate_operand" "i"))
15817 (use (reg:CC FLAGS_REG))
15818 (clobber (match_operand:DI 0 "register_operand" "=S"))
15819 (clobber (match_operand:DI 1 "register_operand" "=D"))
15820 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15823 [(set_attr "type" "str")
15824 (set_attr "mode" "QI")
15825 (set_attr "prefix_rex" "0")
15826 (set_attr "prefix_rep" "1")])
15828 (define_expand "strlensi"
15829 [(set (match_operand:SI 0 "register_operand" "")
15830 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15831 (match_operand:QI 2 "immediate_operand" "")
15832 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15835 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15841 (define_expand "strlendi"
15842 [(set (match_operand:DI 0 "register_operand" "")
15843 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15844 (match_operand:QI 2 "immediate_operand" "")
15845 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15848 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15854 (define_expand "strlenqi_1"
15855 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15856 (clobber (match_operand 1 "register_operand" ""))
15857 (clobber (reg:CC FLAGS_REG))])]
15859 "ix86_current_function_needs_cld = 1;")
15861 (define_insn "*strlenqi_1"
15862 [(set (match_operand:SI 0 "register_operand" "=&c")
15863 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15864 (match_operand:QI 2 "register_operand" "a")
15865 (match_operand:SI 3 "immediate_operand" "i")
15866 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15867 (clobber (match_operand:SI 1 "register_operand" "=D"))
15868 (clobber (reg:CC FLAGS_REG))]
15871 [(set_attr "type" "str")
15872 (set_attr "mode" "QI")
15873 (set_attr "prefix_rep" "1")])
15875 (define_insn "*strlenqi_rex_1"
15876 [(set (match_operand:DI 0 "register_operand" "=&c")
15877 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15878 (match_operand:QI 2 "register_operand" "a")
15879 (match_operand:DI 3 "immediate_operand" "i")
15880 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15881 (clobber (match_operand:DI 1 "register_operand" "=D"))
15882 (clobber (reg:CC FLAGS_REG))]
15885 [(set_attr "type" "str")
15886 (set_attr "mode" "QI")
15887 (set_attr "prefix_rex" "0")
15888 (set_attr "prefix_rep" "1")])
15890 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15891 ;; handled in combine, but it is not currently up to the task.
15892 ;; When used for their truth value, the cmpstrn* expanders generate
15901 ;; The intermediate three instructions are unnecessary.
15903 ;; This one handles cmpstrn*_nz_1...
15906 (set (reg:CC FLAGS_REG)
15907 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15908 (mem:BLK (match_operand 5 "register_operand" ""))))
15909 (use (match_operand 6 "register_operand" ""))
15910 (use (match_operand:SI 3 "immediate_operand" ""))
15911 (clobber (match_operand 0 "register_operand" ""))
15912 (clobber (match_operand 1 "register_operand" ""))
15913 (clobber (match_operand 2 "register_operand" ""))])
15914 (set (match_operand:QI 7 "register_operand" "")
15915 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15916 (set (match_operand:QI 8 "register_operand" "")
15917 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15918 (set (reg FLAGS_REG)
15919 (compare (match_dup 7) (match_dup 8)))
15921 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15923 (set (reg:CC FLAGS_REG)
15924 (compare:CC (mem:BLK (match_dup 4))
15925 (mem:BLK (match_dup 5))))
15926 (use (match_dup 6))
15927 (use (match_dup 3))
15928 (clobber (match_dup 0))
15929 (clobber (match_dup 1))
15930 (clobber (match_dup 2))])])
15932 ;; ...and this one handles cmpstrn*_1.
15935 (set (reg:CC FLAGS_REG)
15936 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15938 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15939 (mem:BLK (match_operand 5 "register_operand" "")))
15941 (use (match_operand:SI 3 "immediate_operand" ""))
15942 (use (reg:CC FLAGS_REG))
15943 (clobber (match_operand 0 "register_operand" ""))
15944 (clobber (match_operand 1 "register_operand" ""))
15945 (clobber (match_operand 2 "register_operand" ""))])
15946 (set (match_operand:QI 7 "register_operand" "")
15947 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15948 (set (match_operand:QI 8 "register_operand" "")
15949 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15950 (set (reg FLAGS_REG)
15951 (compare (match_dup 7) (match_dup 8)))
15953 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15955 (set (reg:CC FLAGS_REG)
15956 (if_then_else:CC (ne (match_dup 6)
15958 (compare:CC (mem:BLK (match_dup 4))
15959 (mem:BLK (match_dup 5)))
15961 (use (match_dup 3))
15962 (use (reg:CC FLAGS_REG))
15963 (clobber (match_dup 0))
15964 (clobber (match_dup 1))
15965 (clobber (match_dup 2))])])
15967 ;; Conditional move instructions.
15969 (define_expand "mov<mode>cc"
15970 [(set (match_operand:SWIM 0 "register_operand" "")
15971 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15972 (match_operand:SWIM 2 "general_operand" "")
15973 (match_operand:SWIM 3 "general_operand" "")))]
15975 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15977 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15978 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15979 ;; So just document what we're doing explicitly.
15981 (define_expand "x86_mov<mode>cc_0_m1"
15983 [(set (match_operand:SWI48 0 "register_operand" "")
15984 (if_then_else:SWI48
15985 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15986 [(match_operand 1 "flags_reg_operand" "")
15990 (clobber (reg:CC FLAGS_REG))])])
15992 (define_insn "*x86_mov<mode>cc_0_m1"
15993 [(set (match_operand:SWI48 0 "register_operand" "=r")
15994 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15995 [(reg FLAGS_REG) (const_int 0)])
15998 (clobber (reg:CC FLAGS_REG))]
16000 "sbb{<imodesuffix>}\t%0, %0"
16001 ; Since we don't have the proper number of operands for an alu insn,
16002 ; fill in all the blanks.
16003 [(set_attr "type" "alu")
16004 (set_attr "use_carry" "1")
16005 (set_attr "pent_pair" "pu")
16006 (set_attr "memory" "none")
16007 (set_attr "imm_disp" "false")
16008 (set_attr "mode" "<MODE>")
16009 (set_attr "length_immediate" "0")])
16011 (define_insn "*x86_mov<mode>cc_0_m1_se"
16012 [(set (match_operand:SWI48 0 "register_operand" "=r")
16013 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16014 [(reg FLAGS_REG) (const_int 0)])
16017 (clobber (reg:CC FLAGS_REG))]
16019 "sbb{<imodesuffix>}\t%0, %0"
16020 [(set_attr "type" "alu")
16021 (set_attr "use_carry" "1")
16022 (set_attr "pent_pair" "pu")
16023 (set_attr "memory" "none")
16024 (set_attr "imm_disp" "false")
16025 (set_attr "mode" "<MODE>")
16026 (set_attr "length_immediate" "0")])
16028 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16029 [(set (match_operand:SWI48 0 "register_operand" "=r")
16030 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16031 [(reg FLAGS_REG) (const_int 0)])))]
16033 "sbb{<imodesuffix>}\t%0, %0"
16034 [(set_attr "type" "alu")
16035 (set_attr "use_carry" "1")
16036 (set_attr "pent_pair" "pu")
16037 (set_attr "memory" "none")
16038 (set_attr "imm_disp" "false")
16039 (set_attr "mode" "<MODE>")
16040 (set_attr "length_immediate" "0")])
16042 (define_insn "*mov<mode>cc_noc"
16043 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16044 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16046 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16047 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16048 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16050 cmov%O2%C1\t{%2, %0|%0, %2}
16051 cmov%O2%c1\t{%3, %0|%0, %3}"
16052 [(set_attr "type" "icmov")
16053 (set_attr "mode" "<MODE>")])
16055 (define_insn_and_split "*movqicc_noc"
16056 [(set (match_operand:QI 0 "register_operand" "=r,r")
16057 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16058 [(match_operand 4 "flags_reg_operand" "")
16060 (match_operand:QI 2 "register_operand" "r,0")
16061 (match_operand:QI 3 "register_operand" "0,r")))]
16062 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16064 "&& reload_completed"
16065 [(set (match_dup 0)
16066 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16069 "operands[0] = gen_lowpart (SImode, operands[0]);
16070 operands[2] = gen_lowpart (SImode, operands[2]);
16071 operands[3] = gen_lowpart (SImode, operands[3]);"
16072 [(set_attr "type" "icmov")
16073 (set_attr "mode" "SI")])
16075 (define_expand "mov<mode>cc"
16076 [(set (match_operand:X87MODEF 0 "register_operand" "")
16077 (if_then_else:X87MODEF
16078 (match_operand 1 "ix86_fp_comparison_operator" "")
16079 (match_operand:X87MODEF 2 "register_operand" "")
16080 (match_operand:X87MODEF 3 "register_operand" "")))]
16081 "(TARGET_80387 && TARGET_CMOVE)
16082 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16083 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16085 (define_insn "*movsfcc_1_387"
16086 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16087 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16088 [(reg FLAGS_REG) (const_int 0)])
16089 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16090 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16091 "TARGET_80387 && TARGET_CMOVE
16092 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16094 fcmov%F1\t{%2, %0|%0, %2}
16095 fcmov%f1\t{%3, %0|%0, %3}
16096 cmov%O2%C1\t{%2, %0|%0, %2}
16097 cmov%O2%c1\t{%3, %0|%0, %3}"
16098 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16099 (set_attr "mode" "SF,SF,SI,SI")])
16101 (define_insn "*movdfcc_1"
16102 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16103 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16104 [(reg FLAGS_REG) (const_int 0)])
16105 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16106 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16107 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16108 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16110 fcmov%F1\t{%2, %0|%0, %2}
16111 fcmov%f1\t{%3, %0|%0, %3}
16114 [(set_attr "type" "fcmov,fcmov,multi,multi")
16115 (set_attr "mode" "DF")])
16117 (define_insn "*movdfcc_1_rex64"
16118 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16119 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16120 [(reg FLAGS_REG) (const_int 0)])
16121 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16122 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16123 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16124 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16126 fcmov%F1\t{%2, %0|%0, %2}
16127 fcmov%f1\t{%3, %0|%0, %3}
16128 cmov%O2%C1\t{%2, %0|%0, %2}
16129 cmov%O2%c1\t{%3, %0|%0, %3}"
16130 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16131 (set_attr "mode" "DF")])
16134 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16135 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16136 [(match_operand 4 "flags_reg_operand" "")
16138 (match_operand:DF 2 "nonimmediate_operand" "")
16139 (match_operand:DF 3 "nonimmediate_operand" "")))]
16140 "!TARGET_64BIT && reload_completed"
16141 [(set (match_dup 2)
16142 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16146 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16150 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16151 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16154 (define_insn "*movxfcc_1"
16155 [(set (match_operand:XF 0 "register_operand" "=f,f")
16156 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16157 [(reg FLAGS_REG) (const_int 0)])
16158 (match_operand:XF 2 "register_operand" "f,0")
16159 (match_operand:XF 3 "register_operand" "0,f")))]
16160 "TARGET_80387 && TARGET_CMOVE"
16162 fcmov%F1\t{%2, %0|%0, %2}
16163 fcmov%f1\t{%3, %0|%0, %3}"
16164 [(set_attr "type" "fcmov")
16165 (set_attr "mode" "XF")])
16167 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16168 ;; the scalar versions to have only XMM registers as operands.
16170 ;; XOP conditional move
16171 (define_insn "*xop_pcmov_<mode>"
16172 [(set (match_operand:MODEF 0 "register_operand" "=x")
16173 (if_then_else:MODEF
16174 (match_operand:MODEF 1 "register_operand" "x")
16175 (match_operand:MODEF 2 "register_operand" "x")
16176 (match_operand:MODEF 3 "register_operand" "x")))]
16178 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16179 [(set_attr "type" "sse4arg")])
16181 ;; These versions of the min/max patterns are intentionally ignorant of
16182 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16183 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16184 ;; are undefined in this condition, we're certain this is correct.
16186 (define_insn "*avx_<code><mode>3"
16187 [(set (match_operand:MODEF 0 "register_operand" "=x")
16189 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16190 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16191 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16192 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16193 [(set_attr "type" "sseadd")
16194 (set_attr "prefix" "vex")
16195 (set_attr "mode" "<MODE>")])
16197 (define_insn "<code><mode>3"
16198 [(set (match_operand:MODEF 0 "register_operand" "=x")
16200 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16201 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16202 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16203 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16204 [(set_attr "type" "sseadd")
16205 (set_attr "mode" "<MODE>")])
16207 ;; These versions of the min/max patterns implement exactly the operations
16208 ;; min = (op1 < op2 ? op1 : op2)
16209 ;; max = (!(op1 < op2) ? op1 : op2)
16210 ;; Their operands are not commutative, and thus they may be used in the
16211 ;; presence of -0.0 and NaN.
16213 (define_insn "*avx_ieee_smin<mode>3"
16214 [(set (match_operand:MODEF 0 "register_operand" "=x")
16216 [(match_operand:MODEF 1 "register_operand" "x")
16217 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16219 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16220 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16221 [(set_attr "type" "sseadd")
16222 (set_attr "prefix" "vex")
16223 (set_attr "mode" "<MODE>")])
16225 (define_insn "*ieee_smin<mode>3"
16226 [(set (match_operand:MODEF 0 "register_operand" "=x")
16228 [(match_operand:MODEF 1 "register_operand" "0")
16229 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16231 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16232 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16233 [(set_attr "type" "sseadd")
16234 (set_attr "mode" "<MODE>")])
16236 (define_insn "*avx_ieee_smax<mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x")
16239 [(match_operand:MODEF 1 "register_operand" "0")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16242 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16244 [(set_attr "type" "sseadd")
16245 (set_attr "prefix" "vex")
16246 (set_attr "mode" "<MODE>")])
16248 (define_insn "*ieee_smax<mode>3"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16251 [(match_operand:MODEF 1 "register_operand" "0")
16252 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16254 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16255 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16256 [(set_attr "type" "sseadd")
16257 (set_attr "mode" "<MODE>")])
16259 ;; Make two stack loads independent:
16261 ;; fld %st(0) -> fld bb
16262 ;; fmul bb fmul %st(1), %st
16264 ;; Actually we only match the last two instructions for simplicity.
16266 [(set (match_operand 0 "fp_register_operand" "")
16267 (match_operand 1 "fp_register_operand" ""))
16269 (match_operator 2 "binary_fp_operator"
16271 (match_operand 3 "memory_operand" "")]))]
16272 "REGNO (operands[0]) != REGNO (operands[1])"
16273 [(set (match_dup 0) (match_dup 3))
16274 (set (match_dup 0) (match_dup 4))]
16276 ;; The % modifier is not operational anymore in peephole2's, so we have to
16277 ;; swap the operands manually in the case of addition and multiplication.
16278 "if (COMMUTATIVE_ARITH_P (operands[2]))
16279 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16280 GET_MODE (operands[2]),
16281 operands[0], operands[1]);
16283 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16284 GET_MODE (operands[2]),
16285 operands[1], operands[0]);")
16287 ;; Conditional addition patterns
16288 (define_expand "add<mode>cc"
16289 [(match_operand:SWI 0 "register_operand" "")
16290 (match_operand 1 "ordered_comparison_operator" "")
16291 (match_operand:SWI 2 "register_operand" "")
16292 (match_operand:SWI 3 "const_int_operand" "")]
16294 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16296 ;; Misc patterns (?)
16298 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16299 ;; Otherwise there will be nothing to keep
16301 ;; [(set (reg ebp) (reg esp))]
16302 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16303 ;; (clobber (eflags)]
16304 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16306 ;; in proper program order.
16308 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16309 [(set (match_operand:P 0 "register_operand" "=r,r")
16310 (plus:P (match_operand:P 1 "register_operand" "0,r")
16311 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16312 (clobber (reg:CC FLAGS_REG))
16313 (clobber (mem:BLK (scratch)))]
16316 switch (get_attr_type (insn))
16319 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16322 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16323 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16324 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16326 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16329 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16330 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16333 [(set (attr "type")
16334 (cond [(and (eq_attr "alternative" "0")
16335 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16336 (const_string "alu")
16337 (match_operand:<MODE> 2 "const0_operand" "")
16338 (const_string "imov")
16340 (const_string "lea")))
16341 (set (attr "length_immediate")
16342 (cond [(eq_attr "type" "imov")
16344 (and (eq_attr "type" "alu")
16345 (match_operand 2 "const128_operand" ""))
16348 (const_string "*")))
16349 (set_attr "mode" "<MODE>")])
16351 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16352 [(set (match_operand:P 0 "register_operand" "=r")
16353 (minus:P (match_operand:P 1 "register_operand" "0")
16354 (match_operand:P 2 "register_operand" "r")))
16355 (clobber (reg:CC FLAGS_REG))
16356 (clobber (mem:BLK (scratch)))]
16358 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16359 [(set_attr "type" "alu")
16360 (set_attr "mode" "<MODE>")])
16362 (define_insn "allocate_stack_worker_probe_<mode>"
16363 [(set (match_operand:P 0 "register_operand" "=a")
16364 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16365 UNSPECV_STACK_PROBE))
16366 (clobber (reg:CC FLAGS_REG))]
16367 "ix86_target_stack_probe ()"
16368 "call\t___chkstk_ms"
16369 [(set_attr "type" "multi")
16370 (set_attr "length" "5")])
16372 (define_expand "allocate_stack"
16373 [(match_operand 0 "register_operand" "")
16374 (match_operand 1 "general_operand" "")]
16375 "ix86_target_stack_probe ()"
16379 #ifndef CHECK_STACK_LIMIT
16380 #define CHECK_STACK_LIMIT 0
16383 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16384 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16386 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16387 stack_pointer_rtx, 0, OPTAB_DIRECT);
16388 if (x != stack_pointer_rtx)
16389 emit_move_insn (stack_pointer_rtx, x);
16393 x = copy_to_mode_reg (Pmode, operands[1]);
16395 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16397 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16398 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16399 stack_pointer_rtx, 0, OPTAB_DIRECT);
16400 if (x != stack_pointer_rtx)
16401 emit_move_insn (stack_pointer_rtx, x);
16404 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16408 ;; Use IOR for stack probes, this is shorter.
16409 (define_expand "probe_stack"
16410 [(match_operand 0 "memory_operand" "")]
16413 rtx (*gen_ior3) (rtx, rtx, rtx);
16415 gen_ior3 = (GET_MODE (operands[0]) == DImode
16416 ? gen_iordi3 : gen_iorsi3);
16418 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16422 (define_insn "adjust_stack_and_probe<mode>"
16423 [(set (match_operand:P 0 "register_operand" "=r")
16424 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16425 UNSPECV_PROBE_STACK_RANGE))
16426 (set (reg:P SP_REG)
16427 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16428 (clobber (reg:CC FLAGS_REG))
16429 (clobber (mem:BLK (scratch)))]
16431 "* return output_adjust_stack_and_probe (operands[0]);"
16432 [(set_attr "type" "multi")])
16434 (define_insn "probe_stack_range<mode>"
16435 [(set (match_operand:P 0 "register_operand" "=r")
16436 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16437 (match_operand:P 2 "const_int_operand" "n")]
16438 UNSPECV_PROBE_STACK_RANGE))
16439 (clobber (reg:CC FLAGS_REG))]
16441 "* return output_probe_stack_range (operands[0], operands[2]);"
16442 [(set_attr "type" "multi")])
16444 (define_expand "builtin_setjmp_receiver"
16445 [(label_ref (match_operand 0 "" ""))]
16446 "!TARGET_64BIT && flag_pic"
16452 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16453 rtx label_rtx = gen_label_rtx ();
16454 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16455 xops[0] = xops[1] = picreg;
16456 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16457 ix86_expand_binary_operator (MINUS, SImode, xops);
16461 emit_insn (gen_set_got (pic_offset_table_rtx));
16465 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16468 [(set (match_operand 0 "register_operand" "")
16469 (match_operator 3 "promotable_binary_operator"
16470 [(match_operand 1 "register_operand" "")
16471 (match_operand 2 "aligned_operand" "")]))
16472 (clobber (reg:CC FLAGS_REG))]
16473 "! TARGET_PARTIAL_REG_STALL && reload_completed
16474 && ((GET_MODE (operands[0]) == HImode
16475 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16476 /* ??? next two lines just !satisfies_constraint_K (...) */
16477 || !CONST_INT_P (operands[2])
16478 || satisfies_constraint_K (operands[2])))
16479 || (GET_MODE (operands[0]) == QImode
16480 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16481 [(parallel [(set (match_dup 0)
16482 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16483 (clobber (reg:CC FLAGS_REG))])]
16484 "operands[0] = gen_lowpart (SImode, operands[0]);
16485 operands[1] = gen_lowpart (SImode, operands[1]);
16486 if (GET_CODE (operands[3]) != ASHIFT)
16487 operands[2] = gen_lowpart (SImode, operands[2]);
16488 PUT_MODE (operands[3], SImode);")
16490 ; Promote the QImode tests, as i386 has encoding of the AND
16491 ; instruction with 32-bit sign-extended immediate and thus the
16492 ; instruction size is unchanged, except in the %eax case for
16493 ; which it is increased by one byte, hence the ! optimize_size.
16495 [(set (match_operand 0 "flags_reg_operand" "")
16496 (match_operator 2 "compare_operator"
16497 [(and (match_operand 3 "aligned_operand" "")
16498 (match_operand 4 "const_int_operand" ""))
16500 (set (match_operand 1 "register_operand" "")
16501 (and (match_dup 3) (match_dup 4)))]
16502 "! TARGET_PARTIAL_REG_STALL && reload_completed
16503 && optimize_insn_for_speed_p ()
16504 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16505 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16506 /* Ensure that the operand will remain sign-extended immediate. */
16507 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16508 [(parallel [(set (match_dup 0)
16509 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16512 (and:SI (match_dup 3) (match_dup 4)))])]
16515 = gen_int_mode (INTVAL (operands[4])
16516 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16517 operands[1] = gen_lowpart (SImode, operands[1]);
16518 operands[3] = gen_lowpart (SImode, operands[3]);
16521 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16522 ; the TEST instruction with 32-bit sign-extended immediate and thus
16523 ; the instruction size would at least double, which is not what we
16524 ; want even with ! optimize_size.
16526 [(set (match_operand 0 "flags_reg_operand" "")
16527 (match_operator 1 "compare_operator"
16528 [(and (match_operand:HI 2 "aligned_operand" "")
16529 (match_operand:HI 3 "const_int_operand" ""))
16531 "! TARGET_PARTIAL_REG_STALL && reload_completed
16532 && ! TARGET_FAST_PREFIX
16533 && optimize_insn_for_speed_p ()
16534 /* Ensure that the operand will remain sign-extended immediate. */
16535 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16536 [(set (match_dup 0)
16537 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16541 = gen_int_mode (INTVAL (operands[3])
16542 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16543 operands[2] = gen_lowpart (SImode, operands[2]);
16547 [(set (match_operand 0 "register_operand" "")
16548 (neg (match_operand 1 "register_operand" "")))
16549 (clobber (reg:CC FLAGS_REG))]
16550 "! TARGET_PARTIAL_REG_STALL && reload_completed
16551 && (GET_MODE (operands[0]) == HImode
16552 || (GET_MODE (operands[0]) == QImode
16553 && (TARGET_PROMOTE_QImode
16554 || optimize_insn_for_size_p ())))"
16555 [(parallel [(set (match_dup 0)
16556 (neg:SI (match_dup 1)))
16557 (clobber (reg:CC FLAGS_REG))])]
16558 "operands[0] = gen_lowpart (SImode, operands[0]);
16559 operands[1] = gen_lowpart (SImode, operands[1]);")
16562 [(set (match_operand 0 "register_operand" "")
16563 (not (match_operand 1 "register_operand" "")))]
16564 "! TARGET_PARTIAL_REG_STALL && reload_completed
16565 && (GET_MODE (operands[0]) == HImode
16566 || (GET_MODE (operands[0]) == QImode
16567 && (TARGET_PROMOTE_QImode
16568 || optimize_insn_for_size_p ())))"
16569 [(set (match_dup 0)
16570 (not:SI (match_dup 1)))]
16571 "operands[0] = gen_lowpart (SImode, operands[0]);
16572 operands[1] = gen_lowpart (SImode, operands[1]);")
16575 [(set (match_operand 0 "register_operand" "")
16576 (if_then_else (match_operator 1 "ordered_comparison_operator"
16577 [(reg FLAGS_REG) (const_int 0)])
16578 (match_operand 2 "register_operand" "")
16579 (match_operand 3 "register_operand" "")))]
16580 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16581 && (GET_MODE (operands[0]) == HImode
16582 || (GET_MODE (operands[0]) == QImode
16583 && (TARGET_PROMOTE_QImode
16584 || optimize_insn_for_size_p ())))"
16585 [(set (match_dup 0)
16586 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16587 "operands[0] = gen_lowpart (SImode, operands[0]);
16588 operands[2] = gen_lowpart (SImode, operands[2]);
16589 operands[3] = gen_lowpart (SImode, operands[3]);")
16591 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16592 ;; transform a complex memory operation into two memory to register operations.
16594 ;; Don't push memory operands
16596 [(set (match_operand:SWI 0 "push_operand" "")
16597 (match_operand:SWI 1 "memory_operand" ""))
16598 (match_scratch:SWI 2 "<r>")]
16599 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16600 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16601 [(set (match_dup 2) (match_dup 1))
16602 (set (match_dup 0) (match_dup 2))])
16604 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16607 [(set (match_operand:SF 0 "push_operand" "")
16608 (match_operand:SF 1 "memory_operand" ""))
16609 (match_scratch:SF 2 "r")]
16610 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16611 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16612 [(set (match_dup 2) (match_dup 1))
16613 (set (match_dup 0) (match_dup 2))])
16615 ;; Don't move an immediate directly to memory when the instruction
16618 [(match_scratch:SWI124 1 "<r>")
16619 (set (match_operand:SWI124 0 "memory_operand" "")
16621 "optimize_insn_for_speed_p ()
16622 && !TARGET_USE_MOV0
16623 && TARGET_SPLIT_LONG_MOVES
16624 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16625 && peep2_regno_dead_p (0, FLAGS_REG)"
16626 [(parallel [(set (match_dup 2) (const_int 0))
16627 (clobber (reg:CC FLAGS_REG))])
16628 (set (match_dup 0) (match_dup 1))]
16629 "operands[2] = gen_lowpart (SImode, operands[1]);")
16632 [(match_scratch:SWI124 2 "<r>")
16633 (set (match_operand:SWI124 0 "memory_operand" "")
16634 (match_operand:SWI124 1 "immediate_operand" ""))]
16635 "optimize_insn_for_speed_p ()
16636 && TARGET_SPLIT_LONG_MOVES
16637 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16638 [(set (match_dup 2) (match_dup 1))
16639 (set (match_dup 0) (match_dup 2))])
16641 ;; Don't compare memory with zero, load and use a test instead.
16643 [(set (match_operand 0 "flags_reg_operand" "")
16644 (match_operator 1 "compare_operator"
16645 [(match_operand:SI 2 "memory_operand" "")
16647 (match_scratch:SI 3 "r")]
16648 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16649 [(set (match_dup 3) (match_dup 2))
16650 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16652 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16653 ;; Don't split NOTs with a displacement operand, because resulting XOR
16654 ;; will not be pairable anyway.
16656 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16657 ;; represented using a modRM byte. The XOR replacement is long decoded,
16658 ;; so this split helps here as well.
16660 ;; Note: Can't do this as a regular split because we can't get proper
16661 ;; lifetime information then.
16664 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16665 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16666 "optimize_insn_for_speed_p ()
16667 && ((TARGET_NOT_UNPAIRABLE
16668 && (!MEM_P (operands[0])
16669 || !memory_displacement_operand (operands[0], <MODE>mode)))
16670 || (TARGET_NOT_VECTORMODE
16671 && long_memory_operand (operands[0], <MODE>mode)))
16672 && peep2_regno_dead_p (0, FLAGS_REG)"
16673 [(parallel [(set (match_dup 0)
16674 (xor:SWI124 (match_dup 1) (const_int -1)))
16675 (clobber (reg:CC FLAGS_REG))])])
16677 ;; Non pairable "test imm, reg" instructions can be translated to
16678 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16679 ;; byte opcode instead of two, have a short form for byte operands),
16680 ;; so do it for other CPUs as well. Given that the value was dead,
16681 ;; this should not create any new dependencies. Pass on the sub-word
16682 ;; versions if we're concerned about partial register stalls.
16685 [(set (match_operand 0 "flags_reg_operand" "")
16686 (match_operator 1 "compare_operator"
16687 [(and:SI (match_operand:SI 2 "register_operand" "")
16688 (match_operand:SI 3 "immediate_operand" ""))
16690 "ix86_match_ccmode (insn, CCNOmode)
16691 && (true_regnum (operands[2]) != AX_REG
16692 || satisfies_constraint_K (operands[3]))
16693 && peep2_reg_dead_p (1, operands[2])"
16695 [(set (match_dup 0)
16696 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16699 (and:SI (match_dup 2) (match_dup 3)))])])
16701 ;; We don't need to handle HImode case, because it will be promoted to SImode
16702 ;; on ! TARGET_PARTIAL_REG_STALL
16705 [(set (match_operand 0 "flags_reg_operand" "")
16706 (match_operator 1 "compare_operator"
16707 [(and:QI (match_operand:QI 2 "register_operand" "")
16708 (match_operand:QI 3 "immediate_operand" ""))
16710 "! TARGET_PARTIAL_REG_STALL
16711 && ix86_match_ccmode (insn, CCNOmode)
16712 && true_regnum (operands[2]) != AX_REG
16713 && peep2_reg_dead_p (1, operands[2])"
16715 [(set (match_dup 0)
16716 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16719 (and:QI (match_dup 2) (match_dup 3)))])])
16722 [(set (match_operand 0 "flags_reg_operand" "")
16723 (match_operator 1 "compare_operator"
16726 (match_operand 2 "ext_register_operand" "")
16729 (match_operand 3 "const_int_operand" ""))
16731 "! TARGET_PARTIAL_REG_STALL
16732 && ix86_match_ccmode (insn, CCNOmode)
16733 && true_regnum (operands[2]) != AX_REG
16734 && peep2_reg_dead_p (1, operands[2])"
16735 [(parallel [(set (match_dup 0)
16744 (set (zero_extract:SI (match_dup 2)
16752 (match_dup 3)))])])
16754 ;; Don't do logical operations with memory inputs.
16756 [(match_scratch:SI 2 "r")
16757 (parallel [(set (match_operand:SI 0 "register_operand" "")
16758 (match_operator:SI 3 "arith_or_logical_operator"
16760 (match_operand:SI 1 "memory_operand" "")]))
16761 (clobber (reg:CC FLAGS_REG))])]
16762 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16763 [(set (match_dup 2) (match_dup 1))
16764 (parallel [(set (match_dup 0)
16765 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16766 (clobber (reg:CC FLAGS_REG))])])
16769 [(match_scratch:SI 2 "r")
16770 (parallel [(set (match_operand:SI 0 "register_operand" "")
16771 (match_operator:SI 3 "arith_or_logical_operator"
16772 [(match_operand:SI 1 "memory_operand" "")
16774 (clobber (reg:CC FLAGS_REG))])]
16775 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16776 [(set (match_dup 2) (match_dup 1))
16777 (parallel [(set (match_dup 0)
16778 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16779 (clobber (reg:CC FLAGS_REG))])])
16781 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16782 ;; refers to the destination of the load!
16785 [(set (match_operand:SI 0 "register_operand" "")
16786 (match_operand:SI 1 "register_operand" ""))
16787 (parallel [(set (match_dup 0)
16788 (match_operator:SI 3 "commutative_operator"
16790 (match_operand:SI 2 "memory_operand" "")]))
16791 (clobber (reg:CC FLAGS_REG))])]
16792 "REGNO (operands[0]) != REGNO (operands[1])
16793 && GENERAL_REGNO_P (REGNO (operands[0]))
16794 && GENERAL_REGNO_P (REGNO (operands[1]))"
16795 [(set (match_dup 0) (match_dup 4))
16796 (parallel [(set (match_dup 0)
16797 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16798 (clobber (reg:CC FLAGS_REG))])]
16799 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16802 [(set (match_operand 0 "register_operand" "")
16803 (match_operand 1 "register_operand" ""))
16805 (match_operator 3 "commutative_operator"
16807 (match_operand 2 "memory_operand" "")]))]
16808 "REGNO (operands[0]) != REGNO (operands[1])
16809 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16810 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16811 [(set (match_dup 0) (match_dup 2))
16813 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16815 ; Don't do logical operations with memory outputs
16817 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16818 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16819 ; the same decoder scheduling characteristics as the original.
16822 [(match_scratch:SI 2 "r")
16823 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16824 (match_operator:SI 3 "arith_or_logical_operator"
16826 (match_operand:SI 1 "nonmemory_operand" "")]))
16827 (clobber (reg:CC FLAGS_REG))])]
16828 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16829 /* Do not split stack checking probes. */
16830 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16831 [(set (match_dup 2) (match_dup 0))
16832 (parallel [(set (match_dup 2)
16833 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16834 (clobber (reg:CC FLAGS_REG))])
16835 (set (match_dup 0) (match_dup 2))])
16838 [(match_scratch:SI 2 "r")
16839 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16840 (match_operator:SI 3 "arith_or_logical_operator"
16841 [(match_operand:SI 1 "nonmemory_operand" "")
16843 (clobber (reg:CC FLAGS_REG))])]
16844 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16845 /* Do not split stack checking probes. */
16846 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16847 [(set (match_dup 2) (match_dup 0))
16848 (parallel [(set (match_dup 2)
16849 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16850 (clobber (reg:CC FLAGS_REG))])
16851 (set (match_dup 0) (match_dup 2))])
16853 ;; Attempt to always use XOR for zeroing registers.
16855 [(set (match_operand 0 "register_operand" "")
16856 (match_operand 1 "const0_operand" ""))]
16857 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16858 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16859 && GENERAL_REG_P (operands[0])
16860 && peep2_regno_dead_p (0, FLAGS_REG)"
16861 [(parallel [(set (match_dup 0) (const_int 0))
16862 (clobber (reg:CC FLAGS_REG))])]
16863 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16866 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16868 "(GET_MODE (operands[0]) == QImode
16869 || GET_MODE (operands[0]) == HImode)
16870 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16871 && peep2_regno_dead_p (0, FLAGS_REG)"
16872 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16873 (clobber (reg:CC FLAGS_REG))])])
16875 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16877 [(set (match_operand:SWI248 0 "register_operand" "")
16879 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16880 && peep2_regno_dead_p (0, FLAGS_REG)"
16881 [(parallel [(set (match_dup 0) (const_int -1))
16882 (clobber (reg:CC FLAGS_REG))])]
16884 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16885 operands[0] = gen_lowpart (SImode, operands[0]);
16888 ;; Attempt to convert simple lea to add/shift.
16889 ;; These can be created by move expanders.
16892 [(set (match_operand:SWI48 0 "register_operand" "")
16893 (plus:SWI48 (match_dup 0)
16894 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16895 "peep2_regno_dead_p (0, FLAGS_REG)"
16896 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16897 (clobber (reg:CC FLAGS_REG))])])
16900 [(set (match_operand:SI 0 "register_operand" "")
16901 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16902 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16904 && peep2_regno_dead_p (0, FLAGS_REG)
16905 && REGNO (operands[0]) == REGNO (operands[1])"
16906 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16907 (clobber (reg:CC FLAGS_REG))])]
16908 "operands[2] = gen_lowpart (SImode, operands[2]);")
16911 [(set (match_operand:SWI48 0 "register_operand" "")
16912 (mult:SWI48 (match_dup 0)
16913 (match_operand:SWI48 1 "const_int_operand" "")))]
16914 "exact_log2 (INTVAL (operands[1])) >= 0
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
16916 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16917 (clobber (reg:CC FLAGS_REG))])]
16918 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16921 [(set (match_operand:SI 0 "register_operand" "")
16922 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16923 (match_operand:DI 2 "const_int_operand" "")) 0))]
16925 && exact_log2 (INTVAL (operands[2])) >= 0
16926 && REGNO (operands[0]) == REGNO (operands[1])
16927 && peep2_regno_dead_p (0, FLAGS_REG)"
16928 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16929 (clobber (reg:CC FLAGS_REG))])]
16930 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16932 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16933 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16934 ;; On many CPUs it is also faster, since special hardware to avoid esp
16935 ;; dependencies is present.
16937 ;; While some of these conversions may be done using splitters, we use
16938 ;; peepholes in order to allow combine_stack_adjustments pass to see
16939 ;; nonobfuscated RTL.
16941 ;; Convert prologue esp subtractions to push.
16942 ;; We need register to push. In order to keep verify_flow_info happy we have
16944 ;; - use scratch and clobber it in order to avoid dependencies
16945 ;; - use already live register
16946 ;; We can't use the second way right now, since there is no reliable way how to
16947 ;; verify that given register is live. First choice will also most likely in
16948 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16949 ;; call clobbered registers are dead. We may want to use base pointer as an
16950 ;; alternative when no register is available later.
16953 [(match_scratch:P 1 "r")
16954 (parallel [(set (reg:P SP_REG)
16955 (plus:P (reg:P SP_REG)
16956 (match_operand:P 0 "const_int_operand" "")))
16957 (clobber (reg:CC FLAGS_REG))
16958 (clobber (mem:BLK (scratch)))])]
16959 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16960 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16961 [(clobber (match_dup 1))
16962 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16963 (clobber (mem:BLK (scratch)))])])
16966 [(match_scratch:P 1 "r")
16967 (parallel [(set (reg:P SP_REG)
16968 (plus:P (reg:P SP_REG)
16969 (match_operand:P 0 "const_int_operand" "")))
16970 (clobber (reg:CC FLAGS_REG))
16971 (clobber (mem:BLK (scratch)))])]
16972 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16973 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16974 [(clobber (match_dup 1))
16975 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16976 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16977 (clobber (mem:BLK (scratch)))])])
16979 ;; Convert esp subtractions to push.
16981 [(match_scratch:P 1 "r")
16982 (parallel [(set (reg:P SP_REG)
16983 (plus:P (reg:P SP_REG)
16984 (match_operand:P 0 "const_int_operand" "")))
16985 (clobber (reg:CC FLAGS_REG))])]
16986 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16987 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16988 [(clobber (match_dup 1))
16989 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16992 [(match_scratch:P 1 "r")
16993 (parallel [(set (reg:P SP_REG)
16994 (plus:P (reg:P SP_REG)
16995 (match_operand:P 0 "const_int_operand" "")))
16996 (clobber (reg:CC FLAGS_REG))])]
16997 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16998 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16999 [(clobber (match_dup 1))
17000 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17001 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17003 ;; Convert epilogue deallocator to pop.
17005 [(match_scratch:P 1 "r")
17006 (parallel [(set (reg:P SP_REG)
17007 (plus:P (reg:P SP_REG)
17008 (match_operand:P 0 "const_int_operand" "")))
17009 (clobber (reg:CC FLAGS_REG))
17010 (clobber (mem:BLK (scratch)))])]
17011 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17012 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17013 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17014 (clobber (mem:BLK (scratch)))])])
17016 ;; Two pops case is tricky, since pop causes dependency
17017 ;; on destination register. We use two registers if available.
17019 [(match_scratch:P 1 "r")
17020 (match_scratch:P 2 "r")
17021 (parallel [(set (reg:P SP_REG)
17022 (plus:P (reg:P SP_REG)
17023 (match_operand:P 0 "const_int_operand" "")))
17024 (clobber (reg:CC FLAGS_REG))
17025 (clobber (mem:BLK (scratch)))])]
17026 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17027 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17028 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17029 (clobber (mem:BLK (scratch)))])
17030 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17033 [(match_scratch:P 1 "r")
17034 (parallel [(set (reg:P SP_REG)
17035 (plus:P (reg:P SP_REG)
17036 (match_operand:P 0 "const_int_operand" "")))
17037 (clobber (reg:CC FLAGS_REG))
17038 (clobber (mem:BLK (scratch)))])]
17039 "optimize_insn_for_size_p ()
17040 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17041 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17042 (clobber (mem:BLK (scratch)))])
17043 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17045 ;; Convert esp additions to pop.
17047 [(match_scratch:P 1 "r")
17048 (parallel [(set (reg:P SP_REG)
17049 (plus:P (reg:P SP_REG)
17050 (match_operand:P 0 "const_int_operand" "")))
17051 (clobber (reg:CC FLAGS_REG))])]
17052 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17053 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17055 ;; Two pops case is tricky, since pop causes dependency
17056 ;; on destination register. We use two registers if available.
17058 [(match_scratch:P 1 "r")
17059 (match_scratch:P 2 "r")
17060 (parallel [(set (reg:P SP_REG)
17061 (plus:P (reg:P SP_REG)
17062 (match_operand:P 0 "const_int_operand" "")))
17063 (clobber (reg:CC FLAGS_REG))])]
17064 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17065 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17066 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17069 [(match_scratch:P 1 "r")
17070 (parallel [(set (reg:P SP_REG)
17071 (plus:P (reg:P SP_REG)
17072 (match_operand:P 0 "const_int_operand" "")))
17073 (clobber (reg:CC FLAGS_REG))])]
17074 "optimize_insn_for_size_p ()
17075 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17076 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17077 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17079 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17080 ;; required and register dies. Similarly for 128 to -128.
17082 [(set (match_operand 0 "flags_reg_operand" "")
17083 (match_operator 1 "compare_operator"
17084 [(match_operand 2 "register_operand" "")
17085 (match_operand 3 "const_int_operand" "")]))]
17086 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17087 && incdec_operand (operands[3], GET_MODE (operands[3])))
17088 || (!TARGET_FUSE_CMP_AND_BRANCH
17089 && INTVAL (operands[3]) == 128))
17090 && ix86_match_ccmode (insn, CCGCmode)
17091 && peep2_reg_dead_p (1, operands[2])"
17092 [(parallel [(set (match_dup 0)
17093 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17094 (clobber (match_dup 2))])])
17096 ;; Convert imul by three, five and nine into lea
17099 [(set (match_operand:SWI48 0 "register_operand" "")
17100 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17101 (match_operand:SWI48 2 "const_int_operand" "")))
17102 (clobber (reg:CC FLAGS_REG))])]
17103 "INTVAL (operands[2]) == 3
17104 || INTVAL (operands[2]) == 5
17105 || INTVAL (operands[2]) == 9"
17106 [(set (match_dup 0)
17107 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17109 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17113 [(set (match_operand:SWI48 0 "register_operand" "")
17114 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17115 (match_operand:SWI48 2 "const_int_operand" "")))
17116 (clobber (reg:CC FLAGS_REG))])]
17117 "optimize_insn_for_speed_p ()
17118 && (INTVAL (operands[2]) == 3
17119 || INTVAL (operands[2]) == 5
17120 || INTVAL (operands[2]) == 9)"
17121 [(set (match_dup 0) (match_dup 1))
17123 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17125 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17127 ;; imul $32bit_imm, mem, reg is vector decoded, while
17128 ;; imul $32bit_imm, reg, reg is direct decoded.
17130 [(match_scratch:SWI48 3 "r")
17131 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17132 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17133 (match_operand:SWI48 2 "immediate_operand" "")))
17134 (clobber (reg:CC FLAGS_REG))])]
17135 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17136 && !satisfies_constraint_K (operands[2])"
17137 [(set (match_dup 3) (match_dup 1))
17138 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17139 (clobber (reg:CC FLAGS_REG))])])
17142 [(match_scratch:SI 3 "r")
17143 (parallel [(set (match_operand:DI 0 "register_operand" "")
17145 (mult:SI (match_operand:SI 1 "memory_operand" "")
17146 (match_operand:SI 2 "immediate_operand" ""))))
17147 (clobber (reg:CC FLAGS_REG))])]
17149 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17150 && !satisfies_constraint_K (operands[2])"
17151 [(set (match_dup 3) (match_dup 1))
17152 (parallel [(set (match_dup 0)
17153 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17154 (clobber (reg:CC FLAGS_REG))])])
17156 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17157 ;; Convert it into imul reg, reg
17158 ;; It would be better to force assembler to encode instruction using long
17159 ;; immediate, but there is apparently no way to do so.
17161 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17163 (match_operand:SWI248 1 "nonimmediate_operand" "")
17164 (match_operand:SWI248 2 "const_int_operand" "")))
17165 (clobber (reg:CC FLAGS_REG))])
17166 (match_scratch:SWI248 3 "r")]
17167 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17168 && satisfies_constraint_K (operands[2])"
17169 [(set (match_dup 3) (match_dup 2))
17170 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17171 (clobber (reg:CC FLAGS_REG))])]
17173 if (!rtx_equal_p (operands[0], operands[1]))
17174 emit_move_insn (operands[0], operands[1]);
17177 ;; After splitting up read-modify operations, array accesses with memory
17178 ;; operands might end up in form:
17180 ;; movl 4(%esp), %edx
17182 ;; instead of pre-splitting:
17184 ;; addl 4(%esp), %eax
17186 ;; movl 4(%esp), %edx
17187 ;; leal (%edx,%eax,4), %eax
17190 [(match_scratch:P 5 "r")
17191 (parallel [(set (match_operand 0 "register_operand" "")
17192 (ashift (match_operand 1 "register_operand" "")
17193 (match_operand 2 "const_int_operand" "")))
17194 (clobber (reg:CC FLAGS_REG))])
17195 (parallel [(set (match_operand 3 "register_operand" "")
17196 (plus (match_dup 0)
17197 (match_operand 4 "x86_64_general_operand" "")))
17198 (clobber (reg:CC FLAGS_REG))])]
17199 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17200 /* Validate MODE for lea. */
17201 && ((!TARGET_PARTIAL_REG_STALL
17202 && (GET_MODE (operands[0]) == QImode
17203 || GET_MODE (operands[0]) == HImode))
17204 || GET_MODE (operands[0]) == SImode
17205 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17206 && (rtx_equal_p (operands[0], operands[3])
17207 || peep2_reg_dead_p (2, operands[0]))
17208 /* We reorder load and the shift. */
17209 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17210 [(set (match_dup 5) (match_dup 4))
17211 (set (match_dup 0) (match_dup 1))]
17213 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17214 int scale = 1 << INTVAL (operands[2]);
17215 rtx index = gen_lowpart (Pmode, operands[1]);
17216 rtx base = gen_lowpart (Pmode, operands[5]);
17217 rtx dest = gen_lowpart (mode, operands[3]);
17219 operands[1] = gen_rtx_PLUS (Pmode, base,
17220 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17221 operands[5] = base;
17224 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17225 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17227 operands[0] = dest;
17230 ;; Call-value patterns last so that the wildcard operand does not
17231 ;; disrupt insn-recog's switch tables.
17233 (define_insn "*call_value_pop_0"
17234 [(set (match_operand 0 "" "")
17235 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17236 (match_operand:SI 2 "" "")))
17237 (set (reg:SI SP_REG)
17238 (plus:SI (reg:SI SP_REG)
17239 (match_operand:SI 3 "immediate_operand" "")))]
17242 if (SIBLING_CALL_P (insn))
17245 return "call\t%P1";
17247 [(set_attr "type" "callv")])
17249 (define_insn "*call_value_pop_1"
17250 [(set (match_operand 0 "" "")
17251 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17252 (match_operand:SI 2 "" "")))
17253 (set (reg:SI SP_REG)
17254 (plus:SI (reg:SI SP_REG)
17255 (match_operand:SI 3 "immediate_operand" "i")))]
17256 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17258 if (constant_call_address_operand (operands[1], Pmode))
17259 return "call\t%P1";
17260 return "call\t%A1";
17262 [(set_attr "type" "callv")])
17264 (define_insn "*sibcall_value_pop_1"
17265 [(set (match_operand 0 "" "")
17266 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17267 (match_operand:SI 2 "" "")))
17268 (set (reg:SI SP_REG)
17269 (plus:SI (reg:SI SP_REG)
17270 (match_operand:SI 3 "immediate_operand" "i,i")))]
17271 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17275 [(set_attr "type" "callv")])
17277 (define_insn "*call_value_0"
17278 [(set (match_operand 0 "" "")
17279 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17280 (match_operand:SI 2 "" "")))]
17283 if (SIBLING_CALL_P (insn))
17286 return "call\t%P1";
17288 [(set_attr "type" "callv")])
17290 (define_insn "*call_value_0_rex64"
17291 [(set (match_operand 0 "" "")
17292 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17293 (match_operand:DI 2 "const_int_operand" "")))]
17296 if (SIBLING_CALL_P (insn))
17299 return "call\t%P1";
17301 [(set_attr "type" "callv")])
17303 (define_insn "*call_value_0_rex64_ms_sysv"
17304 [(set (match_operand 0 "" "")
17305 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17306 (match_operand:DI 2 "const_int_operand" "")))
17307 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17308 (clobber (reg:TI XMM6_REG))
17309 (clobber (reg:TI XMM7_REG))
17310 (clobber (reg:TI XMM8_REG))
17311 (clobber (reg:TI XMM9_REG))
17312 (clobber (reg:TI XMM10_REG))
17313 (clobber (reg:TI XMM11_REG))
17314 (clobber (reg:TI XMM12_REG))
17315 (clobber (reg:TI XMM13_REG))
17316 (clobber (reg:TI XMM14_REG))
17317 (clobber (reg:TI XMM15_REG))
17318 (clobber (reg:DI SI_REG))
17319 (clobber (reg:DI DI_REG))]
17320 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17322 if (SIBLING_CALL_P (insn))
17325 return "call\t%P1";
17327 [(set_attr "type" "callv")])
17329 (define_insn "*call_value_1"
17330 [(set (match_operand 0 "" "")
17331 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17332 (match_operand:SI 2 "" "")))]
17333 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17335 if (constant_call_address_operand (operands[1], Pmode))
17336 return "call\t%P1";
17337 return "call\t%A1";
17339 [(set_attr "type" "callv")])
17341 (define_insn "*sibcall_value_1"
17342 [(set (match_operand 0 "" "")
17343 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17344 (match_operand:SI 2 "" "")))]
17345 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17349 [(set_attr "type" "callv")])
17351 (define_insn "*call_value_1_rex64"
17352 [(set (match_operand 0 "" "")
17353 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17354 (match_operand:DI 2 "" "")))]
17355 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17356 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17358 if (constant_call_address_operand (operands[1], Pmode))
17359 return "call\t%P1";
17360 return "call\t%A1";
17362 [(set_attr "type" "callv")])
17364 (define_insn "*call_value_1_rex64_ms_sysv"
17365 [(set (match_operand 0 "" "")
17366 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17367 (match_operand:DI 2 "" "")))
17368 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17369 (clobber (reg:TI XMM6_REG))
17370 (clobber (reg:TI XMM7_REG))
17371 (clobber (reg:TI XMM8_REG))
17372 (clobber (reg:TI XMM9_REG))
17373 (clobber (reg:TI XMM10_REG))
17374 (clobber (reg:TI XMM11_REG))
17375 (clobber (reg:TI XMM12_REG))
17376 (clobber (reg:TI XMM13_REG))
17377 (clobber (reg:TI XMM14_REG))
17378 (clobber (reg:TI XMM15_REG))
17379 (clobber (reg:DI SI_REG))
17380 (clobber (reg:DI DI_REG))]
17381 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17383 if (constant_call_address_operand (operands[1], Pmode))
17384 return "call\t%P1";
17385 return "call\t%A1";
17387 [(set_attr "type" "callv")])
17389 (define_insn "*call_value_1_rex64_large"
17390 [(set (match_operand 0 "" "")
17391 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17392 (match_operand:DI 2 "" "")))]
17393 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17395 [(set_attr "type" "callv")])
17397 (define_insn "*sibcall_value_1_rex64"
17398 [(set (match_operand 0 "" "")
17399 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17400 (match_operand:DI 2 "" "")))]
17401 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17405 [(set_attr "type" "callv")])
17407 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17408 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17409 ;; caught for use by garbage collectors and the like. Using an insn that
17410 ;; maps to SIGILL makes it more likely the program will rightfully die.
17411 ;; Keeping with tradition, "6" is in honor of #UD.
17412 (define_insn "trap"
17413 [(trap_if (const_int 1) (const_int 6))]
17415 { return ASM_SHORT "0x0b0f"; }
17416 [(set_attr "length" "2")])
17418 (define_expand "prefetch"
17419 [(prefetch (match_operand 0 "address_operand" "")
17420 (match_operand:SI 1 "const_int_operand" "")
17421 (match_operand:SI 2 "const_int_operand" ""))]
17422 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17424 int rw = INTVAL (operands[1]);
17425 int locality = INTVAL (operands[2]);
17427 gcc_assert (rw == 0 || rw == 1);
17428 gcc_assert (locality >= 0 && locality <= 3);
17429 gcc_assert (GET_MODE (operands[0]) == Pmode
17430 || GET_MODE (operands[0]) == VOIDmode);
17432 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17433 supported by SSE counterpart or the SSE prefetch is not available
17434 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17436 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17437 operands[2] = GEN_INT (3);
17439 operands[1] = const0_rtx;
17442 (define_insn "*prefetch_sse_<mode>"
17443 [(prefetch (match_operand:P 0 "address_operand" "p")
17445 (match_operand:SI 1 "const_int_operand" ""))]
17446 "TARGET_PREFETCH_SSE"
17448 static const char * const patterns[4] = {
17449 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17452 int locality = INTVAL (operands[1]);
17453 gcc_assert (locality >= 0 && locality <= 3);
17455 return patterns[locality];
17457 [(set_attr "type" "sse")
17458 (set_attr "atom_sse_attr" "prefetch")
17459 (set (attr "length_address")
17460 (symbol_ref "memory_address_length (operands[0])"))
17461 (set_attr "memory" "none")])
17463 (define_insn "*prefetch_3dnow_<mode>"
17464 [(prefetch (match_operand:P 0 "address_operand" "p")
17465 (match_operand:SI 1 "const_int_operand" "n")
17469 if (INTVAL (operands[1]) == 0)
17470 return "prefetch\t%a0";
17472 return "prefetchw\t%a0";
17474 [(set_attr "type" "mmx")
17475 (set (attr "length_address")
17476 (symbol_ref "memory_address_length (operands[0])"))
17477 (set_attr "memory" "none")])
17479 (define_expand "stack_protect_set"
17480 [(match_operand 0 "memory_operand" "")
17481 (match_operand 1 "memory_operand" "")]
17484 rtx (*insn)(rtx, rtx);
17486 #ifdef TARGET_THREAD_SSP_OFFSET
17487 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17488 insn = (TARGET_64BIT
17489 ? gen_stack_tls_protect_set_di
17490 : gen_stack_tls_protect_set_si);
17492 insn = (TARGET_64BIT
17493 ? gen_stack_protect_set_di
17494 : gen_stack_protect_set_si);
17497 emit_insn (insn (operands[0], operands[1]));
17501 (define_insn "stack_protect_set_<mode>"
17502 [(set (match_operand:P 0 "memory_operand" "=m")
17503 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17504 (set (match_scratch:P 2 "=&r") (const_int 0))
17505 (clobber (reg:CC FLAGS_REG))]
17507 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17508 [(set_attr "type" "multi")])
17510 (define_insn "stack_tls_protect_set_<mode>"
17511 [(set (match_operand:P 0 "memory_operand" "=m")
17512 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17513 UNSPEC_SP_TLS_SET))
17514 (set (match_scratch:P 2 "=&r") (const_int 0))
17515 (clobber (reg:CC FLAGS_REG))]
17517 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17518 [(set_attr "type" "multi")])
17520 (define_expand "stack_protect_test"
17521 [(match_operand 0 "memory_operand" "")
17522 (match_operand 1 "memory_operand" "")
17523 (match_operand 2 "" "")]
17526 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17528 rtx (*insn)(rtx, rtx, rtx);
17530 #ifdef TARGET_THREAD_SSP_OFFSET
17531 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17532 insn = (TARGET_64BIT
17533 ? gen_stack_tls_protect_test_di
17534 : gen_stack_tls_protect_test_si);
17536 insn = (TARGET_64BIT
17537 ? gen_stack_protect_test_di
17538 : gen_stack_protect_test_si);
17541 emit_insn (insn (flags, operands[0], operands[1]));
17543 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17544 flags, const0_rtx, operands[2]));
17548 (define_insn "stack_protect_test_<mode>"
17549 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17550 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17551 (match_operand:P 2 "memory_operand" "m")]
17553 (clobber (match_scratch:P 3 "=&r"))]
17555 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17556 [(set_attr "type" "multi")])
17558 (define_insn "stack_tls_protect_test_<mode>"
17559 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17560 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17561 (match_operand:P 2 "const_int_operand" "i")]
17562 UNSPEC_SP_TLS_TEST))
17563 (clobber (match_scratch:P 3 "=r"))]
17565 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17566 [(set_attr "type" "multi")])
17568 (define_insn "sse4_2_crc32<mode>"
17569 [(set (match_operand:SI 0 "register_operand" "=r")
17571 [(match_operand:SI 1 "register_operand" "0")
17572 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17574 "TARGET_SSE4_2 || TARGET_CRC32"
17575 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17576 [(set_attr "type" "sselog1")
17577 (set_attr "prefix_rep" "1")
17578 (set_attr "prefix_extra" "1")
17579 (set (attr "prefix_data16")
17580 (if_then_else (match_operand:HI 2 "" "")
17582 (const_string "*")))
17583 (set (attr "prefix_rex")
17584 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17586 (const_string "*")))
17587 (set_attr "mode" "SI")])
17589 (define_insn "sse4_2_crc32di"
17590 [(set (match_operand:DI 0 "register_operand" "=r")
17592 [(match_operand:DI 1 "register_operand" "0")
17593 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17595 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17596 "crc32{q}\t{%2, %0|%0, %2}"
17597 [(set_attr "type" "sselog1")
17598 (set_attr "prefix_rep" "1")
17599 (set_attr "prefix_extra" "1")
17600 (set_attr "mode" "DI")])
17602 (define_expand "rdpmc"
17603 [(match_operand:DI 0 "register_operand" "")
17604 (match_operand:SI 1 "register_operand" "")]
17607 rtx reg = gen_reg_rtx (DImode);
17610 /* Force operand 1 into ECX. */
17611 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17612 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17613 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17618 rtvec vec = rtvec_alloc (2);
17619 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17620 rtx upper = gen_reg_rtx (DImode);
17621 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17622 gen_rtvec (1, const0_rtx),
17624 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17625 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17627 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17628 NULL, 1, OPTAB_DIRECT);
17629 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17633 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17634 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17638 (define_insn "*rdpmc"
17639 [(set (match_operand:DI 0 "register_operand" "=A")
17640 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17644 [(set_attr "type" "other")
17645 (set_attr "length" "2")])
17647 (define_insn "*rdpmc_rex64"
17648 [(set (match_operand:DI 0 "register_operand" "=a")
17649 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17651 (set (match_operand:DI 1 "register_operand" "=d")
17652 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17655 [(set_attr "type" "other")
17656 (set_attr "length" "2")])
17658 (define_expand "rdtsc"
17659 [(set (match_operand:DI 0 "register_operand" "")
17660 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17665 rtvec vec = rtvec_alloc (2);
17666 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17667 rtx upper = gen_reg_rtx (DImode);
17668 rtx lower = gen_reg_rtx (DImode);
17669 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17670 gen_rtvec (1, const0_rtx),
17672 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17673 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17675 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17676 NULL, 1, OPTAB_DIRECT);
17677 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17679 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17684 (define_insn "*rdtsc"
17685 [(set (match_operand:DI 0 "register_operand" "=A")
17686 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17689 [(set_attr "type" "other")
17690 (set_attr "length" "2")])
17692 (define_insn "*rdtsc_rex64"
17693 [(set (match_operand:DI 0 "register_operand" "=a")
17694 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17695 (set (match_operand:DI 1 "register_operand" "=d")
17696 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17699 [(set_attr "type" "other")
17700 (set_attr "length" "2")])
17702 (define_expand "rdtscp"
17703 [(match_operand:DI 0 "register_operand" "")
17704 (match_operand:SI 1 "memory_operand" "")]
17707 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17708 gen_rtvec (1, const0_rtx),
17710 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17711 gen_rtvec (1, const0_rtx),
17713 rtx reg = gen_reg_rtx (DImode);
17714 rtx tmp = gen_reg_rtx (SImode);
17718 rtvec vec = rtvec_alloc (3);
17719 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17720 rtx upper = gen_reg_rtx (DImode);
17721 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17722 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17723 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17725 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17726 NULL, 1, OPTAB_DIRECT);
17727 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17732 rtvec vec = rtvec_alloc (2);
17733 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17734 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17735 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17738 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17739 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17743 (define_insn "*rdtscp"
17744 [(set (match_operand:DI 0 "register_operand" "=A")
17745 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17746 (set (match_operand:SI 1 "register_operand" "=c")
17747 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17750 [(set_attr "type" "other")
17751 (set_attr "length" "3")])
17753 (define_insn "*rdtscp_rex64"
17754 [(set (match_operand:DI 0 "register_operand" "=a")
17755 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17756 (set (match_operand:DI 1 "register_operand" "=d")
17757 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17758 (set (match_operand:SI 2 "register_operand" "=c")
17759 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17762 [(set_attr "type" "other")
17763 (set_attr "length" "3")])
17765 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17767 ;; LWP instructions
17769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17771 (define_expand "lwp_llwpcb"
17772 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17773 UNSPECV_LLWP_INTRINSIC)]
17776 (define_insn "*lwp_llwpcb<mode>1"
17777 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17778 UNSPECV_LLWP_INTRINSIC)]
17781 [(set_attr "type" "lwp")
17782 (set_attr "mode" "<MODE>")
17783 (set_attr "length" "5")])
17785 (define_expand "lwp_slwpcb"
17786 [(set (match_operand 0 "register_operand" "=r")
17787 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17791 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17793 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17797 (define_insn "lwp_slwpcb<mode>"
17798 [(set (match_operand:P 0 "register_operand" "=r")
17799 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17802 [(set_attr "type" "lwp")
17803 (set_attr "mode" "<MODE>")
17804 (set_attr "length" "5")])
17806 (define_expand "lwp_lwpval<mode>3"
17807 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17808 (match_operand:SI 2 "nonimmediate_operand" "rm")
17809 (match_operand:SI 3 "const_int_operand" "i")]
17810 UNSPECV_LWPVAL_INTRINSIC)]
17812 "/* Avoid unused variable warning. */
17815 (define_insn "*lwp_lwpval<mode>3_1"
17816 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17817 (match_operand:SI 1 "nonimmediate_operand" "rm")
17818 (match_operand:SI 2 "const_int_operand" "i")]
17819 UNSPECV_LWPVAL_INTRINSIC)]
17821 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17822 [(set_attr "type" "lwp")
17823 (set_attr "mode" "<MODE>")
17824 (set (attr "length")
17825 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17827 (define_expand "lwp_lwpins<mode>3"
17828 [(set (reg:CCC FLAGS_REG)
17829 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17830 (match_operand:SI 2 "nonimmediate_operand" "rm")
17831 (match_operand:SI 3 "const_int_operand" "i")]
17832 UNSPECV_LWPINS_INTRINSIC))
17833 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17834 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17837 (define_insn "*lwp_lwpins<mode>3_1"
17838 [(set (reg:CCC FLAGS_REG)
17839 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17840 (match_operand:SI 1 "nonimmediate_operand" "rm")
17841 (match_operand:SI 2 "const_int_operand" "i")]
17842 UNSPECV_LWPINS_INTRINSIC))]
17844 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17845 [(set_attr "type" "lwp")
17846 (set_attr "mode" "<MODE>")
17847 (set (attr "length")
17848 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17850 (define_insn "rdfsbase<mode>"
17851 [(set (match_operand:SWI48 0 "register_operand" "=r")
17852 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17853 "TARGET_64BIT && TARGET_FSGSBASE"
17855 [(set_attr "type" "other")
17856 (set_attr "prefix_extra" "2")])
17858 (define_insn "rdgsbase<mode>"
17859 [(set (match_operand:SWI48 0 "register_operand" "=r")
17860 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17861 "TARGET_64BIT && TARGET_FSGSBASE"
17863 [(set_attr "type" "other")
17864 (set_attr "prefix_extra" "2")])
17866 (define_insn "wrfsbase<mode>"
17867 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17869 "TARGET_64BIT && TARGET_FSGSBASE"
17871 [(set_attr "type" "other")
17872 (set_attr "prefix_extra" "2")])
17874 (define_insn "wrgsbase<mode>"
17875 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17877 "TARGET_64BIT && TARGET_FSGSBASE"
17879 [(set_attr "type" "other")
17880 (set_attr "prefix_extra" "2")])
17882 (define_expand "rdrand<mode>"
17883 [(set (match_operand:SWI248 0 "register_operand" "=r")
17884 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17887 rtx retry_label, insn, ccc;
17889 retry_label = gen_label_rtx ();
17891 emit_label (retry_label);
17893 /* Generate rdrand. */
17894 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17896 /* Retry if the carry flag isn't valid. */
17897 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17898 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17899 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17900 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17901 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17902 JUMP_LABEL (insn) = retry_label;
17907 (define_insn "rdrand<mode>_1"
17908 [(set (match_operand:SWI248 0 "register_operand" "=r")
17909 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17912 [(set_attr "type" "other")
17913 (set_attr "prefix_extra" "1")])
17917 (include "sync.md")