1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2015 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
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 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
115 UNSPEC_INSN_FALSE_DEP
117 ;; For SSE/MMX support:
125 ;; Generic math support
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
130 ;; x87 Floating point
146 UNSPEC_FRNDINT_MASK_PM
150 ;; x87 Double output FP
184 ;; For AVX512F support
198 (define_c_enum "unspecv" [
201 UNSPECV_PROBE_STACK_RANGE
204 UNSPECV_SPLIT_STACK_RETURN
210 UNSPECV_LLWP_INTRINSIC
211 UNSPECV_SLWP_INTRINSIC
212 UNSPECV_LWPVAL_INTRINSIC
213 UNSPECV_LWPINS_INTRINSIC
235 ;; For atomic compound assignments.
241 ;; For RDRAND support
244 ;; For RDSEED support
258 ;; For PCOMMIT support
261 ;; For CLFLUSHOPT support
264 ;; For MONITORX and MWAITX support
270 ;; Constants to represent rounding modes in the ROUND instruction
279 ;; Constants to represent AVX512F embeded rounding
281 [(ROUND_NEAREST_INT 0)
289 ;; Constants to represent pcomtrue/pcomfalse variants
299 ;; Constants used in the XOP pperm instruction
301 [(PPERM_SRC 0x00) /* copy source */
302 (PPERM_INVERT 0x20) /* invert source */
303 (PPERM_REVERSE 0x40) /* bit reverse source */
304 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
305 (PPERM_ZERO 0x80) /* all 0's */
306 (PPERM_ONES 0xa0) /* all 1's */
307 (PPERM_SIGN 0xc0) /* propagate sign bit */
308 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
309 (PPERM_SRC1 0x00) /* use first source byte */
310 (PPERM_SRC2 0x10) /* use second source byte */
313 ;; Registers by name.
396 (FIRST_PSEUDO_REG 81)
399 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
402 ;; In C guard expressions, put expressions which may be compile-time
403 ;; constants first. This allows for better optimization. For
404 ;; example, write "TARGET_64BIT && reload_completed", not
405 ;; "reload_completed && TARGET_64BIT".
409 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
410 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
411 bdver4,btver2,znver1"
412 (const (symbol_ref "ix86_schedule")))
414 ;; A basic instruction type. Refinements due to arguments to be
415 ;; provided in other attributes.
418 alu,alu1,negnot,imov,imovx,lea,
419 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
420 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
421 push,pop,call,callv,leave,
423 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
424 fxch,fistp,fisttp,frndint,
425 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
426 ssemul,sseimul,ssediv,sselog,sselog1,
427 sseishft,sseishft1,ssecmp,ssecomi,
428 ssecvt,ssecvt1,sseicvt,sseins,
429 sseshuf,sseshuf1,ssemuladd,sse4arg,
431 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
432 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
433 (const_string "other"))
435 ;; Main data type used by the insn
437 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
439 (const_string "unknown"))
441 ;; The CPU unit operations uses.
442 (define_attr "unit" "integer,i387,sse,mmx,unknown"
443 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
444 fxch,fistp,fisttp,frndint")
445 (const_string "i387")
446 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
447 ssemul,sseimul,ssediv,sselog,sselog1,
448 sseishft,sseishft1,ssecmp,ssecomi,
449 ssecvt,ssecvt1,sseicvt,sseins,
450 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
452 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
454 (eq_attr "type" "other")
455 (const_string "unknown")]
456 (const_string "integer")))
458 ;; The minimum required alignment of vector mode memory operands of the SSE
459 ;; (non-VEX/EVEX) instruction in bits, if it is different from
460 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
461 ;; multiple alternatives, this should be conservative maximum of those minimum
462 ;; required alignments.
463 (define_attr "ssememalign" "" (const_int 0))
465 ;; The (bounding maximum) length of an instruction immediate.
466 (define_attr "length_immediate" ""
467 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
468 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
471 (eq_attr "unit" "i387,sse,mmx")
473 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
474 rotate,rotatex,rotate1,imul,icmp,push,pop")
475 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
476 (eq_attr "type" "imov,test")
477 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
478 (eq_attr "type" "call")
479 (if_then_else (match_operand 0 "constant_call_address_operand")
482 (eq_attr "type" "callv")
483 (if_then_else (match_operand 1 "constant_call_address_operand")
486 ;; We don't know the size before shorten_branches. Expect
487 ;; the instruction to fit for better scheduling.
488 (eq_attr "type" "ibr")
491 (symbol_ref "/* Update immediate_length and other attributes! */
492 gcc_unreachable (),1")))
494 ;; The (bounding maximum) length of an instruction address.
495 (define_attr "length_address" ""
496 (cond [(eq_attr "type" "str,other,multi,fxch")
498 (and (eq_attr "type" "call")
499 (match_operand 0 "constant_call_address_operand"))
501 (and (eq_attr "type" "callv")
502 (match_operand 1 "constant_call_address_operand"))
505 (symbol_ref "ix86_attr_length_address_default (insn)")))
507 ;; Set when length prefix is used.
508 (define_attr "prefix_data16" ""
509 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
511 (eq_attr "mode" "HI")
513 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
518 ;; Set when string REP prefix is used.
519 (define_attr "prefix_rep" ""
520 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
522 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
524 (and (eq_attr "type" "ibr,call,callv")
525 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
530 ;; Set when 0f opcode prefix is used.
531 (define_attr "prefix_0f" ""
533 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
534 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
535 (eq_attr "unit" "sse,mmx"))
539 ;; Set when REX opcode prefix is used.
540 (define_attr "prefix_rex" ""
541 (cond [(not (match_test "TARGET_64BIT"))
543 (and (eq_attr "mode" "DI")
544 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
545 (eq_attr "unit" "!mmx")))
547 (and (eq_attr "mode" "QI")
548 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
550 (match_test "x86_extended_reg_mentioned_p (insn)")
552 (and (eq_attr "type" "imovx")
553 (match_operand:QI 1 "ext_QIreg_operand"))
558 ;; There are also additional prefixes in 3DNOW, SSSE3.
559 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
560 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
561 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
562 (define_attr "prefix_extra" ""
563 (cond [(eq_attr "type" "ssemuladd,sse4arg")
565 (eq_attr "type" "sseiadd1,ssecvt1")
570 ;; Set when BND opcode prefix may be used.
571 (define_attr "maybe_prefix_bnd" "" (const_int 0))
573 ;; Prefix used: original, VEX or maybe VEX.
574 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
575 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
577 (eq_attr "mode" "XI,V16SF,V8DF")
578 (const_string "evex")
580 (const_string "orig")))
582 ;; VEX W bit is used.
583 (define_attr "prefix_vex_w" "" (const_int 0))
585 ;; The length of VEX prefix
586 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
587 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
588 ;; still prefix_0f 1, with prefix_extra 1.
589 (define_attr "length_vex" ""
590 (if_then_else (and (eq_attr "prefix_0f" "1")
591 (eq_attr "prefix_extra" "0"))
592 (if_then_else (eq_attr "prefix_vex_w" "1")
593 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
594 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
595 (if_then_else (eq_attr "prefix_vex_w" "1")
596 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
597 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
599 ;; 4-bytes evex prefix and 1 byte opcode.
600 (define_attr "length_evex" "" (const_int 5))
602 ;; Set when modrm byte is used.
603 (define_attr "modrm" ""
604 (cond [(eq_attr "type" "str,leave")
606 (eq_attr "unit" "i387")
608 (and (eq_attr "type" "incdec")
609 (and (not (match_test "TARGET_64BIT"))
610 (ior (match_operand:SI 1 "register_operand")
611 (match_operand:HI 1 "register_operand"))))
613 (and (eq_attr "type" "push")
614 (not (match_operand 1 "memory_operand")))
616 (and (eq_attr "type" "pop")
617 (not (match_operand 0 "memory_operand")))
619 (and (eq_attr "type" "imov")
620 (and (not (eq_attr "mode" "DI"))
621 (ior (and (match_operand 0 "register_operand")
622 (match_operand 1 "immediate_operand"))
623 (ior (and (match_operand 0 "ax_reg_operand")
624 (match_operand 1 "memory_displacement_only_operand"))
625 (and (match_operand 0 "memory_displacement_only_operand")
626 (match_operand 1 "ax_reg_operand"))))))
628 (and (eq_attr "type" "call")
629 (match_operand 0 "constant_call_address_operand"))
631 (and (eq_attr "type" "callv")
632 (match_operand 1 "constant_call_address_operand"))
634 (and (eq_attr "type" "alu,alu1,icmp,test")
635 (match_operand 0 "ax_reg_operand"))
636 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
640 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
641 (cond [(eq_attr "modrm" "0")
642 (const_string "none")
643 (eq_attr "type" "alu,imul,ishift")
644 (const_string "op02")
645 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
646 (const_string "op01")
647 (eq_attr "type" "incdec")
648 (const_string "incdec")
649 (eq_attr "type" "push,pop")
650 (const_string "pushpop")]
651 (const_string "unknown")))
653 ;; The (bounding maximum) length of an instruction in bytes.
654 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
655 ;; Later we may want to split them and compute proper length as for
657 (define_attr "length" ""
658 (cond [(eq_attr "type" "other,multi,fistp,frndint")
660 (eq_attr "type" "fcmp")
662 (eq_attr "unit" "i387")
664 (plus (attr "prefix_data16")
665 (attr "length_address")))
666 (ior (eq_attr "prefix" "evex")
667 (and (ior (eq_attr "prefix" "maybe_evex")
668 (eq_attr "prefix" "maybe_vex"))
669 (match_test "TARGET_AVX512F")))
670 (plus (attr "length_evex")
671 (plus (attr "length_immediate")
673 (attr "length_address"))))
674 (ior (eq_attr "prefix" "vex")
675 (and (ior (eq_attr "prefix" "maybe_vex")
676 (eq_attr "prefix" "maybe_evex"))
677 (match_test "TARGET_AVX")))
678 (plus (attr "length_vex")
679 (plus (attr "length_immediate")
681 (attr "length_address"))))]
682 (plus (plus (attr "modrm")
683 (plus (attr "prefix_0f")
684 (plus (attr "prefix_rex")
685 (plus (attr "prefix_extra")
687 (plus (attr "prefix_rep")
688 (plus (attr "prefix_data16")
689 (plus (attr "length_immediate")
690 (attr "length_address")))))))
692 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
693 ;; `store' if there is a simple memory reference therein, or `unknown'
694 ;; if the instruction is complex.
696 (define_attr "memory" "none,load,store,both,unknown"
697 (cond [(eq_attr "type" "other,multi,str,lwp")
698 (const_string "unknown")
699 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
700 (const_string "none")
701 (eq_attr "type" "fistp,leave")
702 (const_string "both")
703 (eq_attr "type" "frndint")
704 (const_string "load")
705 (eq_attr "type" "mpxld")
706 (const_string "load")
707 (eq_attr "type" "mpxst")
708 (const_string "store")
709 (eq_attr "type" "push")
710 (if_then_else (match_operand 1 "memory_operand")
711 (const_string "both")
712 (const_string "store"))
713 (eq_attr "type" "pop")
714 (if_then_else (match_operand 0 "memory_operand")
715 (const_string "both")
716 (const_string "load"))
717 (eq_attr "type" "setcc")
718 (if_then_else (match_operand 0 "memory_operand")
719 (const_string "store")
720 (const_string "none"))
721 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
722 (if_then_else (ior (match_operand 0 "memory_operand")
723 (match_operand 1 "memory_operand"))
724 (const_string "load")
725 (const_string "none"))
726 (eq_attr "type" "ibr")
727 (if_then_else (match_operand 0 "memory_operand")
728 (const_string "load")
729 (const_string "none"))
730 (eq_attr "type" "call")
731 (if_then_else (match_operand 0 "constant_call_address_operand")
732 (const_string "none")
733 (const_string "load"))
734 (eq_attr "type" "callv")
735 (if_then_else (match_operand 1 "constant_call_address_operand")
736 (const_string "none")
737 (const_string "load"))
738 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
739 (match_operand 1 "memory_operand"))
740 (const_string "both")
741 (and (match_operand 0 "memory_operand")
742 (match_operand 1 "memory_operand"))
743 (const_string "both")
744 (match_operand 0 "memory_operand")
745 (const_string "store")
746 (match_operand 1 "memory_operand")
747 (const_string "load")
749 "!alu1,negnot,ishift1,
750 imov,imovx,icmp,test,bitmanip,
752 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
753 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
754 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
755 (match_operand 2 "memory_operand"))
756 (const_string "load")
757 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
758 (match_operand 3 "memory_operand"))
759 (const_string "load")
761 (const_string "none")))
763 ;; Indicates if an instruction has both an immediate and a displacement.
765 (define_attr "imm_disp" "false,true,unknown"
766 (cond [(eq_attr "type" "other,multi")
767 (const_string "unknown")
768 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
769 (and (match_operand 0 "memory_displacement_operand")
770 (match_operand 1 "immediate_operand")))
771 (const_string "true")
772 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
773 (and (match_operand 0 "memory_displacement_operand")
774 (match_operand 2 "immediate_operand")))
775 (const_string "true")
777 (const_string "false")))
779 ;; Indicates if an FP operation has an integer source.
781 (define_attr "fp_int_src" "false,true"
782 (const_string "false"))
784 ;; Defines rounding mode of an FP operation.
786 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
787 (const_string "any"))
789 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
790 (define_attr "use_carry" "0,1" (const_string "0"))
792 ;; Define attribute to indicate unaligned ssemov insns
793 (define_attr "movu" "0,1" (const_string "0"))
795 ;; Used to control the "enabled" attribute on a per-instruction basis.
796 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
797 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
798 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
799 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
801 (const_string "base"))
803 (define_attr "enabled" ""
804 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
805 (eq_attr "isa" "x64_sse4")
806 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
807 (eq_attr "isa" "x64_sse4_noavx")
808 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
809 (eq_attr "isa" "x64_avx")
810 (symbol_ref "TARGET_64BIT && TARGET_AVX")
811 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
812 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
813 (eq_attr "isa" "sse2_noavx")
814 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
815 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
816 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
817 (eq_attr "isa" "sse4_noavx")
818 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
819 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
820 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
821 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
822 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
823 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
824 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
825 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
826 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
827 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
828 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
829 (eq_attr "isa" "fma_avx512f")
830 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
831 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
832 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
833 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
834 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
835 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
836 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
840 (define_attr "preferred_for_size" "" (const_int 1))
841 (define_attr "preferred_for_speed" "" (const_int 1))
843 ;; Describe a user's asm statement.
844 (define_asm_attributes
845 [(set_attr "length" "128")
846 (set_attr "type" "multi")])
848 (define_code_iterator plusminus [plus minus])
850 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
852 (define_code_iterator multdiv [mult div])
854 ;; Base name for define_insn
855 (define_code_attr plusminus_insn
856 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
857 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
859 ;; Base name for insn mnemonic.
860 (define_code_attr plusminus_mnemonic
861 [(plus "add") (ss_plus "adds") (us_plus "addus")
862 (minus "sub") (ss_minus "subs") (us_minus "subus")])
863 (define_code_attr multdiv_mnemonic
864 [(mult "mul") (div "div")])
866 ;; Mark commutative operators as such in constraints.
867 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
868 (minus "") (ss_minus "") (us_minus "")])
870 ;; Mapping of max and min
871 (define_code_iterator maxmin [smax smin umax umin])
873 ;; Mapping of signed max and min
874 (define_code_iterator smaxmin [smax smin])
876 ;; Mapping of unsigned max and min
877 (define_code_iterator umaxmin [umax umin])
879 ;; Base name for integer and FP insn mnemonic
880 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
881 (umax "maxu") (umin "minu")])
882 (define_code_attr maxmin_float [(smax "max") (smin "min")])
884 ;; Mapping of logic operators
885 (define_code_iterator any_logic [and ior xor])
886 (define_code_iterator any_or [ior xor])
887 (define_code_iterator fpint_logic [and xor])
889 ;; Base name for insn mnemonic.
890 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
892 ;; Mapping of logic-shift operators
893 (define_code_iterator any_lshift [ashift lshiftrt])
895 ;; Mapping of shift-right operators
896 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
898 ;; Mapping of all shift operators
899 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
901 ;; Base name for define_insn
902 (define_code_attr shift_insn
903 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
905 ;; Base name for insn mnemonic.
906 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
907 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
909 ;; Mask variant left right mnemonics
910 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
912 ;; Mapping of rotate operators
913 (define_code_iterator any_rotate [rotate rotatert])
915 ;; Base name for define_insn
916 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
918 ;; Base name for insn mnemonic.
919 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
921 ;; Mapping of abs neg operators
922 (define_code_iterator absneg [abs neg])
924 ;; Base name for x87 insn mnemonic.
925 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
927 ;; Used in signed and unsigned widening multiplications.
928 (define_code_iterator any_extend [sign_extend zero_extend])
930 ;; Prefix for insn menmonic.
931 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
933 ;; Prefix for define_insn
934 (define_code_attr u [(sign_extend "") (zero_extend "u")])
935 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
936 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
938 ;; Used in signed and unsigned truncations.
939 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
940 ;; Instruction suffix for truncations.
941 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
943 ;; Used in signed and unsigned fix.
944 (define_code_iterator any_fix [fix unsigned_fix])
945 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
947 ;; Used in signed and unsigned float.
948 (define_code_iterator any_float [float unsigned_float])
949 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
951 ;; All integer modes.
952 (define_mode_iterator SWI1248x [QI HI SI DI])
954 ;; All integer modes with AVX512BW/DQ.
955 (define_mode_iterator SWI1248_AVX512BWDQ
956 [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
958 ;; All integer modes without QImode.
959 (define_mode_iterator SWI248x [HI SI DI])
961 ;; All integer modes without QImode and HImode.
962 (define_mode_iterator SWI48x [SI DI])
964 ;; All integer modes without SImode and DImode.
965 (define_mode_iterator SWI12 [QI HI])
967 ;; All integer modes without DImode.
968 (define_mode_iterator SWI124 [QI HI SI])
970 ;; All integer modes without QImode and DImode.
971 (define_mode_iterator SWI24 [HI SI])
973 ;; Single word integer modes.
974 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
976 ;; Single word integer modes without QImode.
977 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
979 ;; Single word integer modes without QImode and HImode.
980 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
982 ;; All math-dependant single and double word integer modes.
983 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
984 (HI "TARGET_HIMODE_MATH")
985 SI DI (TI "TARGET_64BIT")])
987 ;; Math-dependant single word integer modes.
988 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
989 (HI "TARGET_HIMODE_MATH")
990 SI (DI "TARGET_64BIT")])
992 ;; Math-dependant integer modes without DImode.
993 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
994 (HI "TARGET_HIMODE_MATH")
997 ;; Math-dependant integer modes with DImode.
998 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
999 (HI "TARGET_HIMODE_MATH")
1000 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1002 ;; Math-dependant single word integer modes without QImode.
1003 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1004 SI (DI "TARGET_64BIT")])
1006 ;; Double word integer modes.
1007 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1008 (TI "TARGET_64BIT")])
1010 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1011 ;; compile time constant, it is faster to use <MODE_SIZE> than
1012 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1013 ;; command line options just use GET_MODE_SIZE macro.
1014 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1015 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1016 (V16QI "16") (V32QI "32") (V64QI "64")
1017 (V8HI "16") (V16HI "32") (V32HI "64")
1018 (V4SI "16") (V8SI "32") (V16SI "64")
1019 (V2DI "16") (V4DI "32") (V8DI "64")
1020 (V1TI "16") (V2TI "32") (V4TI "64")
1021 (V2DF "16") (V4DF "32") (V8DF "64")
1022 (V4SF "16") (V8SF "32") (V16SF "64")])
1024 ;; Double word integer modes as mode attribute.
1025 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1026 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1028 ;; Half mode for double word integer modes.
1029 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1030 (DI "TARGET_64BIT")])
1033 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1034 (BND64 "TARGET_LP64")])
1036 ;; Pointer mode corresponding to bound mode.
1037 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1040 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1043 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1045 (UNSPEC_BNDCN "cn")])
1047 ;; Instruction suffix for integer modes.
1048 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1050 ;; Instruction suffix for masks.
1051 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1053 ;; Pointer size prefix for integer modes (Intel asm dialect)
1054 (define_mode_attr iptrsize [(QI "BYTE")
1059 ;; Register class for integer modes.
1060 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1062 ;; Immediate operand constraint for integer modes.
1063 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1065 ;; General operand constraint for word modes.
1066 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1068 ;; Immediate operand constraint for double integer modes.
1069 (define_mode_attr di [(SI "nF") (DI "e")])
1071 ;; Immediate operand constraint for shifts.
1072 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1074 ;; General operand predicate for integer modes.
1075 (define_mode_attr general_operand
1076 [(QI "general_operand")
1077 (HI "general_operand")
1078 (SI "x86_64_general_operand")
1079 (DI "x86_64_general_operand")
1080 (TI "x86_64_general_operand")])
1082 ;; General sign extend operand predicate for integer modes,
1083 ;; which disallows VOIDmode operands and thus it is suitable
1084 ;; for use inside sign_extend.
1085 (define_mode_attr general_sext_operand
1086 [(QI "sext_operand")
1088 (SI "x86_64_sext_operand")
1089 (DI "x86_64_sext_operand")])
1091 ;; General sign/zero extend operand predicate for integer modes.
1092 (define_mode_attr general_szext_operand
1093 [(QI "general_operand")
1094 (HI "general_operand")
1095 (SI "x86_64_szext_general_operand")
1096 (DI "x86_64_szext_general_operand")])
1098 ;; Immediate operand predicate for integer modes.
1099 (define_mode_attr immediate_operand
1100 [(QI "immediate_operand")
1101 (HI "immediate_operand")
1102 (SI "x86_64_immediate_operand")
1103 (DI "x86_64_immediate_operand")])
1105 ;; Nonmemory operand predicate for integer modes.
1106 (define_mode_attr nonmemory_operand
1107 [(QI "nonmemory_operand")
1108 (HI "nonmemory_operand")
1109 (SI "x86_64_nonmemory_operand")
1110 (DI "x86_64_nonmemory_operand")])
1112 ;; Operand predicate for shifts.
1113 (define_mode_attr shift_operand
1114 [(QI "nonimmediate_operand")
1115 (HI "nonimmediate_operand")
1116 (SI "nonimmediate_operand")
1117 (DI "shiftdi_operand")
1118 (TI "register_operand")])
1120 ;; Operand predicate for shift argument.
1121 (define_mode_attr shift_immediate_operand
1122 [(QI "const_1_to_31_operand")
1123 (HI "const_1_to_31_operand")
1124 (SI "const_1_to_31_operand")
1125 (DI "const_1_to_63_operand")])
1127 ;; Input operand predicate for arithmetic left shifts.
1128 (define_mode_attr ashl_input_operand
1129 [(QI "nonimmediate_operand")
1130 (HI "nonimmediate_operand")
1131 (SI "nonimmediate_operand")
1132 (DI "ashldi_input_operand")
1133 (TI "reg_or_pm1_operand")])
1135 ;; SSE and x87 SFmode and DFmode floating point modes
1136 (define_mode_iterator MODEF [SF DF])
1138 ;; All x87 floating point modes
1139 (define_mode_iterator X87MODEF [SF DF XF])
1141 ;; SSE instruction suffix for various modes
1142 (define_mode_attr ssemodesuffix
1143 [(SF "ss") (DF "sd")
1144 (V16SF "ps") (V8DF "pd")
1145 (V8SF "ps") (V4DF "pd")
1146 (V4SF "ps") (V2DF "pd")
1147 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1148 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1149 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1151 ;; SSE vector suffix for floating point modes
1152 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1154 ;; SSE vector mode corresponding to a scalar mode
1155 (define_mode_attr ssevecmode
1156 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1157 (define_mode_attr ssevecmodelower
1158 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1160 ;; Instruction suffix for REX 64bit operators.
1161 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1163 ;; This mode iterator allows :P to be used for patterns that operate on
1164 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1165 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1167 ;; This mode iterator allows :W to be used for patterns that operate on
1168 ;; word_mode sized quantities.
1169 (define_mode_iterator W
1170 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1172 ;; This mode iterator allows :PTR to be used for patterns that operate on
1173 ;; ptr_mode sized quantities.
1174 (define_mode_iterator PTR
1175 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1177 ;; Scheduling descriptions
1179 (include "pentium.md")
1182 (include "athlon.md")
1183 (include "bdver1.md")
1184 (include "bdver3.md")
1185 (include "btver2.md")
1186 (include "znver1.md")
1187 (include "geode.md")
1190 (include "core2.md")
1191 (include "haswell.md")
1194 ;; Operand and operator predicates and constraints
1196 (include "predicates.md")
1197 (include "constraints.md")
1200 ;; Compare and branch/compare and store instructions.
1202 (define_expand "cbranch<mode>4"
1203 [(set (reg:CC FLAGS_REG)
1204 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1205 (match_operand:SDWIM 2 "<general_operand>")))
1206 (set (pc) (if_then_else
1207 (match_operator 0 "ordered_comparison_operator"
1208 [(reg:CC FLAGS_REG) (const_int 0)])
1209 (label_ref (match_operand 3))
1213 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1214 operands[1] = force_reg (<MODE>mode, operands[1]);
1215 ix86_expand_branch (GET_CODE (operands[0]),
1216 operands[1], operands[2], operands[3]);
1220 (define_expand "cstore<mode>4"
1221 [(set (reg:CC FLAGS_REG)
1222 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1223 (match_operand:SWIM 3 "<general_operand>")))
1224 (set (match_operand:QI 0 "register_operand")
1225 (match_operator 1 "ordered_comparison_operator"
1226 [(reg:CC FLAGS_REG) (const_int 0)]))]
1229 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1230 operands[2] = force_reg (<MODE>mode, operands[2]);
1231 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1232 operands[2], operands[3]);
1236 (define_expand "cmp<mode>_1"
1237 [(set (reg:CC FLAGS_REG)
1238 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1239 (match_operand:SWI48 1 "<general_operand>")))])
1241 (define_insn "*cmp<mode>_ccno_1"
1242 [(set (reg FLAGS_REG)
1243 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1244 (match_operand:SWI 1 "const0_operand")))]
1245 "ix86_match_ccmode (insn, CCNOmode)"
1247 test{<imodesuffix>}\t%0, %0
1248 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1249 [(set_attr "type" "test,icmp")
1250 (set_attr "length_immediate" "0,1")
1251 (set_attr "modrm_class" "op0,unknown")
1252 (set_attr "mode" "<MODE>")])
1254 (define_insn "*cmp<mode>_1"
1255 [(set (reg FLAGS_REG)
1256 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1257 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1258 "ix86_match_ccmode (insn, CCmode)"
1259 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1260 [(set_attr "type" "icmp")
1261 (set_attr "mode" "<MODE>")])
1263 (define_insn "*cmp<mode>_minus_1"
1264 [(set (reg FLAGS_REG)
1266 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1267 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1269 "ix86_match_ccmode (insn, CCGOCmode)"
1270 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1271 [(set_attr "type" "icmp")
1272 (set_attr "mode" "<MODE>")])
1274 (define_insn "*cmpqi_ext_1"
1275 [(set (reg FLAGS_REG)
1277 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1280 (match_operand 1 "ext_register_operand" "Q,Q")
1282 (const_int 8)) 0)))]
1283 "ix86_match_ccmode (insn, CCmode)"
1284 "cmp{b}\t{%h1, %0|%0, %h1}"
1285 [(set_attr "isa" "*,nox64")
1286 (set_attr "type" "icmp")
1287 (set_attr "mode" "QI")])
1289 (define_insn "*cmpqi_ext_2"
1290 [(set (reg FLAGS_REG)
1294 (match_operand 0 "ext_register_operand" "Q")
1297 (match_operand:QI 1 "const0_operand")))]
1298 "ix86_match_ccmode (insn, CCNOmode)"
1300 [(set_attr "type" "test")
1301 (set_attr "length_immediate" "0")
1302 (set_attr "mode" "QI")])
1304 (define_expand "cmpqi_ext_3"
1305 [(set (reg:CC FLAGS_REG)
1309 (match_operand 0 "ext_register_operand")
1312 (match_operand:QI 1 "const_int_operand")))])
1314 (define_insn "*cmpqi_ext_3"
1315 [(set (reg FLAGS_REG)
1319 (match_operand 0 "ext_register_operand" "Q,Q")
1322 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1323 "ix86_match_ccmode (insn, CCmode)"
1324 "cmp{b}\t{%1, %h0|%h0, %1}"
1325 [(set_attr "isa" "*,nox64")
1326 (set_attr "type" "icmp")
1327 (set_attr "modrm" "1")
1328 (set_attr "mode" "QI")])
1330 (define_insn "*cmpqi_ext_4"
1331 [(set (reg FLAGS_REG)
1335 (match_operand 0 "ext_register_operand" "Q")
1340 (match_operand 1 "ext_register_operand" "Q")
1342 (const_int 8)) 0)))]
1343 "ix86_match_ccmode (insn, CCmode)"
1344 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1345 [(set_attr "type" "icmp")
1346 (set_attr "mode" "QI")])
1348 ;; These implement float point compares.
1349 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1350 ;; which would allow mix and match FP modes on the compares. Which is what
1351 ;; the old patterns did, but with many more of them.
1353 (define_expand "cbranchxf4"
1354 [(set (reg:CC FLAGS_REG)
1355 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1356 (match_operand:XF 2 "nonmemory_operand")))
1357 (set (pc) (if_then_else
1358 (match_operator 0 "ix86_fp_comparison_operator"
1361 (label_ref (match_operand 3))
1365 ix86_expand_branch (GET_CODE (operands[0]),
1366 operands[1], operands[2], operands[3]);
1370 (define_expand "cstorexf4"
1371 [(set (reg:CC FLAGS_REG)
1372 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1373 (match_operand:XF 3 "nonmemory_operand")))
1374 (set (match_operand:QI 0 "register_operand")
1375 (match_operator 1 "ix86_fp_comparison_operator"
1380 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1381 operands[2], operands[3]);
1385 (define_expand "cbranch<mode>4"
1386 [(set (reg:CC FLAGS_REG)
1387 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1388 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1389 (set (pc) (if_then_else
1390 (match_operator 0 "ix86_fp_comparison_operator"
1393 (label_ref (match_operand 3))
1395 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1397 ix86_expand_branch (GET_CODE (operands[0]),
1398 operands[1], operands[2], operands[3]);
1402 (define_expand "cstore<mode>4"
1403 [(set (reg:CC FLAGS_REG)
1404 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1405 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1406 (set (match_operand:QI 0 "register_operand")
1407 (match_operator 1 "ix86_fp_comparison_operator"
1410 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1412 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1413 operands[2], operands[3]);
1417 (define_expand "cbranchcc4"
1418 [(set (pc) (if_then_else
1419 (match_operator 0 "comparison_operator"
1420 [(match_operand 1 "flags_reg_operand")
1421 (match_operand 2 "const0_operand")])
1422 (label_ref (match_operand 3))
1426 ix86_expand_branch (GET_CODE (operands[0]),
1427 operands[1], operands[2], operands[3]);
1431 (define_expand "cstorecc4"
1432 [(set (match_operand:QI 0 "register_operand")
1433 (match_operator 1 "comparison_operator"
1434 [(match_operand 2 "flags_reg_operand")
1435 (match_operand 3 "const0_operand")]))]
1438 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1439 operands[2], operands[3]);
1444 ;; FP compares, step 1:
1445 ;; Set the FP condition codes.
1447 ;; CCFPmode compare with exceptions
1448 ;; CCFPUmode compare with no exceptions
1450 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1451 ;; used to manage the reg stack popping would not be preserved.
1453 (define_insn "*cmp<mode>_0_i387"
1454 [(set (match_operand:HI 0 "register_operand" "=a")
1457 (match_operand:X87MODEF 1 "register_operand" "f")
1458 (match_operand:X87MODEF 2 "const0_operand"))]
1461 "* return output_fp_compare (insn, operands, false, false);"
1462 [(set_attr "type" "multi")
1463 (set_attr "unit" "i387")
1464 (set_attr "mode" "<MODE>")])
1466 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1467 [(set (reg:CCFP FLAGS_REG)
1469 (match_operand:X87MODEF 1 "register_operand" "f")
1470 (match_operand:X87MODEF 2 "const0_operand")))
1471 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1472 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1474 "&& reload_completed"
1477 [(compare:CCFP (match_dup 1)(match_dup 2))]
1479 (set (reg:CC FLAGS_REG)
1480 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1482 [(set_attr "type" "multi")
1483 (set_attr "unit" "i387")
1484 (set_attr "mode" "<MODE>")])
1486 (define_insn "*cmpxf_i387"
1487 [(set (match_operand:HI 0 "register_operand" "=a")
1490 (match_operand:XF 1 "register_operand" "f")
1491 (match_operand:XF 2 "register_operand" "f"))]
1494 "* return output_fp_compare (insn, operands, false, false);"
1495 [(set_attr "type" "multi")
1496 (set_attr "unit" "i387")
1497 (set_attr "mode" "XF")])
1499 (define_insn_and_split "*cmpxf_cc_i387"
1500 [(set (reg:CCFP FLAGS_REG)
1502 (match_operand:XF 1 "register_operand" "f")
1503 (match_operand:XF 2 "register_operand" "f")))
1504 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1505 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1507 "&& reload_completed"
1510 [(compare:CCFP (match_dup 1)(match_dup 2))]
1512 (set (reg:CC FLAGS_REG)
1513 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1515 [(set_attr "type" "multi")
1516 (set_attr "unit" "i387")
1517 (set_attr "mode" "XF")])
1519 (define_insn "*cmp<mode>_i387"
1520 [(set (match_operand:HI 0 "register_operand" "=a")
1523 (match_operand:MODEF 1 "register_operand" "f")
1524 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1527 "* return output_fp_compare (insn, operands, false, false);"
1528 [(set_attr "type" "multi")
1529 (set_attr "unit" "i387")
1530 (set_attr "mode" "<MODE>")])
1532 (define_insn_and_split "*cmp<mode>_cc_i387"
1533 [(set (reg:CCFP FLAGS_REG)
1535 (match_operand:MODEF 1 "register_operand" "f")
1536 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1537 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1538 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1540 "&& reload_completed"
1543 [(compare:CCFP (match_dup 1)(match_dup 2))]
1545 (set (reg:CC FLAGS_REG)
1546 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1548 [(set_attr "type" "multi")
1549 (set_attr "unit" "i387")
1550 (set_attr "mode" "<MODE>")])
1552 (define_insn "*cmpu<mode>_i387"
1553 [(set (match_operand:HI 0 "register_operand" "=a")
1556 (match_operand:X87MODEF 1 "register_operand" "f")
1557 (match_operand:X87MODEF 2 "register_operand" "f"))]
1560 "* return output_fp_compare (insn, operands, false, true);"
1561 [(set_attr "type" "multi")
1562 (set_attr "unit" "i387")
1563 (set_attr "mode" "<MODE>")])
1565 (define_insn_and_split "*cmpu<mode>_cc_i387"
1566 [(set (reg:CCFPU FLAGS_REG)
1568 (match_operand:X87MODEF 1 "register_operand" "f")
1569 (match_operand:X87MODEF 2 "register_operand" "f")))
1570 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1571 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1573 "&& reload_completed"
1576 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1578 (set (reg:CC FLAGS_REG)
1579 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1581 [(set_attr "type" "multi")
1582 (set_attr "unit" "i387")
1583 (set_attr "mode" "<MODE>")])
1585 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1586 [(set (match_operand:HI 0 "register_operand" "=a")
1589 (match_operand:X87MODEF 1 "register_operand" "f")
1590 (match_operator:X87MODEF 3 "float_operator"
1591 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1594 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1595 || optimize_function_for_size_p (cfun))"
1596 "* return output_fp_compare (insn, operands, false, false);"
1597 [(set_attr "type" "multi")
1598 (set_attr "unit" "i387")
1599 (set_attr "fp_int_src" "true")
1600 (set_attr "mode" "<SWI24:MODE>")])
1602 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1603 [(set (reg:CCFP FLAGS_REG)
1605 (match_operand:X87MODEF 1 "register_operand" "f")
1606 (match_operator:X87MODEF 3 "float_operator"
1607 [(match_operand:SWI24 2 "memory_operand" "m")])))
1608 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1609 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1610 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1611 || optimize_function_for_size_p (cfun))"
1613 "&& reload_completed"
1618 (match_op_dup 3 [(match_dup 2)]))]
1620 (set (reg:CC FLAGS_REG)
1621 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1623 [(set_attr "type" "multi")
1624 (set_attr "unit" "i387")
1625 (set_attr "fp_int_src" "true")
1626 (set_attr "mode" "<SWI24:MODE>")])
1628 ;; FP compares, step 2
1629 ;; Move the fpsw to ax.
1631 (define_insn "x86_fnstsw_1"
1632 [(set (match_operand:HI 0 "register_operand" "=a")
1633 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1636 [(set_attr "length" "2")
1637 (set_attr "mode" "SI")
1638 (set_attr "unit" "i387")])
1640 ;; FP compares, step 3
1641 ;; Get ax into flags, general case.
1643 (define_insn "x86_sahf_1"
1644 [(set (reg:CC FLAGS_REG)
1645 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1649 #ifndef HAVE_AS_IX86_SAHF
1651 return ASM_BYTE "0x9e";
1656 [(set_attr "length" "1")
1657 (set_attr "athlon_decode" "vector")
1658 (set_attr "amdfam10_decode" "direct")
1659 (set_attr "bdver1_decode" "direct")
1660 (set_attr "mode" "SI")])
1662 ;; Pentium Pro can do steps 1 through 3 in one go.
1663 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1664 ;; (these i387 instructions set flags directly)
1666 (define_mode_iterator FPCMP [CCFP CCFPU])
1667 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1669 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1670 [(set (reg:FPCMP FLAGS_REG)
1672 (match_operand:MODEF 0 "register_operand" "f,v")
1673 (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1674 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1675 "* return output_fp_compare (insn, operands, true,
1676 <FPCMP:MODE>mode == CCFPUmode);"
1677 [(set_attr "type" "fcmp,ssecomi")
1678 (set_attr "prefix" "orig,maybe_vex")
1679 (set_attr "mode" "<MODEF:MODE>")
1680 (set_attr "prefix_rep" "*,0")
1681 (set (attr "prefix_data16")
1682 (cond [(eq_attr "alternative" "0")
1684 (eq_attr "mode" "DF")
1687 (const_string "0")))
1688 (set_attr "athlon_decode" "vector")
1689 (set_attr "amdfam10_decode" "direct")
1690 (set_attr "bdver1_decode" "double")
1691 (set_attr "znver1_decode" "double")
1692 (set (attr "enabled")
1693 (cond [(eq_attr "alternative" "0")
1694 (symbol_ref "TARGET_MIX_SSE_I387")
1696 (symbol_ref "true")))])
1698 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1699 [(set (reg:FPCMP FLAGS_REG)
1701 (match_operand:X87MODEF 0 "register_operand" "f")
1702 (match_operand:X87MODEF 1 "register_operand" "f")))]
1703 "TARGET_80387 && TARGET_CMOVE
1704 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1705 "* return output_fp_compare (insn, operands, true,
1706 <FPCMP:MODE>mode == CCFPUmode);"
1707 [(set_attr "type" "fcmp")
1708 (set_attr "mode" "<X87MODEF:MODE>")
1709 (set_attr "athlon_decode" "vector")
1710 (set_attr "amdfam10_decode" "direct")
1711 (set_attr "bdver1_decode" "double")
1712 (set_attr "znver1_decode" "double")])
1714 ;; Push/pop instructions.
1716 (define_insn "*push<mode>2"
1717 [(set (match_operand:DWI 0 "push_operand" "=<")
1718 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1721 [(set_attr "type" "multi")
1722 (set_attr "mode" "<MODE>")])
1725 [(set (match_operand:TI 0 "push_operand")
1726 (match_operand:TI 1 "general_operand"))]
1727 "TARGET_64BIT && reload_completed
1728 && !SSE_REG_P (operands[1])"
1730 "ix86_split_long_move (operands); DONE;")
1732 (define_insn "*pushdi2_rex64"
1733 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1734 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1739 [(set_attr "type" "push,multi")
1740 (set_attr "mode" "DI")])
1742 ;; Convert impossible pushes of immediate to existing instructions.
1743 ;; First try to get scratch register and go through it. In case this
1744 ;; fails, push sign extended lower part first and then overwrite
1745 ;; upper part by 32bit move.
1747 [(match_scratch:DI 2 "r")
1748 (set (match_operand:DI 0 "push_operand")
1749 (match_operand:DI 1 "immediate_operand"))]
1750 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1751 && !x86_64_immediate_operand (operands[1], DImode)"
1752 [(set (match_dup 2) (match_dup 1))
1753 (set (match_dup 0) (match_dup 2))])
1755 ;; We need to define this as both peepholer and splitter for case
1756 ;; peephole2 pass is not run.
1757 ;; "&& 1" is needed to keep it from matching the previous pattern.
1759 [(set (match_operand:DI 0 "push_operand")
1760 (match_operand:DI 1 "immediate_operand"))]
1761 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1762 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1763 [(set (match_dup 0) (match_dup 1))
1764 (set (match_dup 2) (match_dup 3))]
1766 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1768 operands[1] = gen_lowpart (DImode, operands[2]);
1769 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1774 [(set (match_operand:DI 0 "push_operand")
1775 (match_operand:DI 1 "immediate_operand"))]
1776 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1777 ? epilogue_completed : reload_completed)
1778 && !symbolic_operand (operands[1], DImode)
1779 && !x86_64_immediate_operand (operands[1], DImode)"
1780 [(set (match_dup 0) (match_dup 1))
1781 (set (match_dup 2) (match_dup 3))]
1783 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1785 operands[1] = gen_lowpart (DImode, operands[2]);
1786 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1791 [(set (match_operand:DI 0 "push_operand")
1792 (match_operand:DI 1 "general_operand"))]
1793 "!TARGET_64BIT && reload_completed
1794 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1796 "ix86_split_long_move (operands); DONE;")
1798 (define_insn "*pushsi2"
1799 [(set (match_operand:SI 0 "push_operand" "=<")
1800 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1803 [(set_attr "type" "push")
1804 (set_attr "mode" "SI")])
1806 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1807 ;; "push a byte/word". But actually we use pushl, which has the effect
1808 ;; of rounding the amount pushed up to a word.
1810 ;; For TARGET_64BIT we always round up to 8 bytes.
1811 (define_insn "*push<mode>2_rex64"
1812 [(set (match_operand:SWI124 0 "push_operand" "=X")
1813 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1816 [(set_attr "type" "push")
1817 (set_attr "mode" "DI")])
1819 (define_insn "*push<mode>2"
1820 [(set (match_operand:SWI12 0 "push_operand" "=X")
1821 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1824 [(set_attr "type" "push")
1825 (set_attr "mode" "SI")])
1827 (define_insn "*push<mode>2_prologue"
1828 [(set (match_operand:W 0 "push_operand" "=<")
1829 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1830 (clobber (mem:BLK (scratch)))]
1832 "push{<imodesuffix>}\t%1"
1833 [(set_attr "type" "push")
1834 (set_attr "mode" "<MODE>")])
1836 (define_insn "*pop<mode>1"
1837 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1838 (match_operand:W 1 "pop_operand" ">"))]
1840 "pop{<imodesuffix>}\t%0"
1841 [(set_attr "type" "pop")
1842 (set_attr "mode" "<MODE>")])
1844 (define_insn "*pop<mode>1_epilogue"
1845 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1846 (match_operand:W 1 "pop_operand" ">"))
1847 (clobber (mem:BLK (scratch)))]
1849 "pop{<imodesuffix>}\t%0"
1850 [(set_attr "type" "pop")
1851 (set_attr "mode" "<MODE>")])
1853 (define_insn "*pushfl<mode>2"
1854 [(set (match_operand:W 0 "push_operand" "=<")
1855 (match_operand:W 1 "flags_reg_operand"))]
1857 "pushf{<imodesuffix>}"
1858 [(set_attr "type" "push")
1859 (set_attr "mode" "<MODE>")])
1861 (define_insn "*popfl<mode>1"
1862 [(set (match_operand:W 0 "flags_reg_operand")
1863 (match_operand:W 1 "pop_operand" ">"))]
1865 "popf{<imodesuffix>}"
1866 [(set_attr "type" "pop")
1867 (set_attr "mode" "<MODE>")])
1870 ;; Move instructions.
1872 (define_expand "movxi"
1873 [(set (match_operand:XI 0 "nonimmediate_operand")
1874 (match_operand:XI 1 "general_operand"))]
1876 "ix86_expand_move (XImode, operands); DONE;")
1878 ;; Reload patterns to support multi-word load/store
1879 ;; with non-offsetable address.
1880 (define_expand "reload_noff_store"
1881 [(parallel [(match_operand 0 "memory_operand" "=m")
1882 (match_operand 1 "register_operand" "r")
1883 (match_operand:DI 2 "register_operand" "=&r")])]
1886 rtx mem = operands[0];
1887 rtx addr = XEXP (mem, 0);
1889 emit_move_insn (operands[2], addr);
1890 mem = replace_equiv_address_nv (mem, operands[2]);
1892 emit_insn (gen_rtx_SET (mem, operands[1]));
1896 (define_expand "reload_noff_load"
1897 [(parallel [(match_operand 0 "register_operand" "=r")
1898 (match_operand 1 "memory_operand" "m")
1899 (match_operand:DI 2 "register_operand" "=r")])]
1902 rtx mem = operands[1];
1903 rtx addr = XEXP (mem, 0);
1905 emit_move_insn (operands[2], addr);
1906 mem = replace_equiv_address_nv (mem, operands[2]);
1908 emit_insn (gen_rtx_SET (operands[0], mem));
1912 (define_expand "movoi"
1913 [(set (match_operand:OI 0 "nonimmediate_operand")
1914 (match_operand:OI 1 "general_operand"))]
1916 "ix86_expand_move (OImode, operands); DONE;")
1918 (define_expand "movti"
1919 [(set (match_operand:TI 0 "nonimmediate_operand")
1920 (match_operand:TI 1 "nonimmediate_operand"))]
1921 "TARGET_64BIT || TARGET_SSE"
1924 ix86_expand_move (TImode, operands);
1926 ix86_expand_vector_move (TImode, operands);
1930 ;; This expands to what emit_move_complex would generate if we didn't
1931 ;; have a movti pattern. Having this avoids problems with reload on
1932 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1933 ;; to have around all the time.
1934 (define_expand "movcdi"
1935 [(set (match_operand:CDI 0 "nonimmediate_operand")
1936 (match_operand:CDI 1 "general_operand"))]
1939 if (push_operand (operands[0], CDImode))
1940 emit_move_complex_push (CDImode, operands[0], operands[1]);
1942 emit_move_complex_parts (operands[0], operands[1]);
1946 (define_expand "mov<mode>"
1947 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1948 (match_operand:SWI1248x 1 "general_operand"))]
1950 "ix86_expand_move (<MODE>mode, operands); DONE;")
1952 (define_insn "*mov<mode>_xor"
1953 [(set (match_operand:SWI48 0 "register_operand" "=r")
1954 (match_operand:SWI48 1 "const0_operand"))
1955 (clobber (reg:CC FLAGS_REG))]
1958 [(set_attr "type" "alu1")
1959 (set_attr "modrm_class" "op0")
1960 (set_attr "mode" "SI")
1961 (set_attr "length_immediate" "0")])
1963 (define_insn "*mov<mode>_or"
1964 [(set (match_operand:SWI48 0 "register_operand" "=r")
1965 (match_operand:SWI48 1 "const_int_operand"))
1966 (clobber (reg:CC FLAGS_REG))]
1968 && operands[1] == constm1_rtx"
1969 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1970 [(set_attr "type" "alu1")
1971 (set_attr "mode" "<MODE>")
1972 (set_attr "length_immediate" "1")])
1974 (define_insn "*movxi_internal_avx512f"
1975 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1976 (match_operand:XI 1 "vector_move_operand" "C ,vm,v"))]
1977 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1979 switch (which_alternative)
1982 return standard_sse_constant_opcode (insn, operands[1]);
1985 if (misaligned_operand (operands[0], XImode)
1986 || misaligned_operand (operands[1], XImode))
1987 return "vmovdqu32\t{%1, %0|%0, %1}";
1989 return "vmovdqa32\t{%1, %0|%0, %1}";
1994 [(set_attr "type" "sselog1,ssemov,ssemov")
1995 (set_attr "prefix" "evex")
1996 (set_attr "mode" "XI")])
1998 (define_insn "*movoi_internal_avx"
1999 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
2000 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
2001 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2003 switch (get_attr_type (insn))
2006 return standard_sse_constant_opcode (insn, operands[1]);
2009 if (misaligned_operand (operands[0], OImode)
2010 || misaligned_operand (operands[1], OImode))
2012 if (get_attr_mode (insn) == MODE_V8SF)
2013 return "vmovups\t{%1, %0|%0, %1}";
2014 else if (get_attr_mode (insn) == MODE_XI)
2015 return "vmovdqu32\t{%1, %0|%0, %1}";
2017 return "vmovdqu\t{%1, %0|%0, %1}";
2021 if (get_attr_mode (insn) == MODE_V8SF)
2022 return "vmovaps\t{%1, %0|%0, %1}";
2023 else if (get_attr_mode (insn) == MODE_XI)
2024 return "vmovdqa32\t{%1, %0|%0, %1}";
2026 return "vmovdqa\t{%1, %0|%0, %1}";
2033 [(set_attr "type" "sselog1,ssemov,ssemov")
2034 (set_attr "prefix" "vex")
2036 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2037 (match_operand 1 "ext_sse_reg_operand"))
2039 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2040 (const_string "V8SF")
2041 (and (eq_attr "alternative" "2")
2042 (match_test "TARGET_SSE_TYPELESS_STORES"))
2043 (const_string "V8SF")
2045 (const_string "OI")))])
2047 (define_insn "*movti_internal"
2048 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2049 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2050 "(TARGET_64BIT || TARGET_SSE)
2051 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2053 switch (get_attr_type (insn))
2059 return standard_sse_constant_opcode (insn, operands[1]);
2062 /* TDmode values are passed as TImode on the stack. Moving them
2063 to stack may result in unaligned memory access. */
2064 if (misaligned_operand (operands[0], TImode)
2065 || misaligned_operand (operands[1], TImode))
2067 if (get_attr_mode (insn) == MODE_V4SF)
2068 return "%vmovups\t{%1, %0|%0, %1}";
2069 else if (get_attr_mode (insn) == MODE_XI)
2070 return "vmovdqu32\t{%1, %0|%0, %1}";
2072 return "%vmovdqu\t{%1, %0|%0, %1}";
2076 if (get_attr_mode (insn) == MODE_V4SF)
2077 return "%vmovaps\t{%1, %0|%0, %1}";
2078 else if (get_attr_mode (insn) == MODE_XI)
2079 return "vmovdqa32\t{%1, %0|%0, %1}";
2081 return "%vmovdqa\t{%1, %0|%0, %1}";
2088 [(set_attr "isa" "x64,x64,*,*,*")
2089 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2090 (set (attr "prefix")
2091 (if_then_else (eq_attr "type" "sselog1,ssemov")
2092 (const_string "maybe_vex")
2093 (const_string "orig")))
2095 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2096 (match_operand 1 "ext_sse_reg_operand"))
2098 (eq_attr "alternative" "0,1")
2100 (ior (not (match_test "TARGET_SSE2"))
2101 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2102 (const_string "V4SF")
2103 (and (eq_attr "alternative" "4")
2104 (match_test "TARGET_SSE_TYPELESS_STORES"))
2105 (const_string "V4SF")
2106 (match_test "TARGET_AVX")
2108 (match_test "optimize_function_for_size_p (cfun)")
2109 (const_string "V4SF")
2111 (const_string "TI")))])
2114 [(set (match_operand:TI 0 "nonimmediate_operand")
2115 (match_operand:TI 1 "general_operand"))]
2117 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2119 "ix86_split_long_move (operands); DONE;")
2121 (define_insn "*movdi_internal"
2122 [(set (match_operand:DI 0 "nonimmediate_operand"
2123 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2124 (match_operand:DI 1 "general_operand"
2125 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2126 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2128 switch (get_attr_type (insn))
2131 return "kmovq\t{%1, %0|%0, %1}";
2137 return "pxor\t%0, %0";
2140 /* Handle broken assemblers that require movd instead of movq. */
2141 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2142 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2143 return "movd\t{%1, %0|%0, %1}";
2144 return "movq\t{%1, %0|%0, %1}";
2147 if (GENERAL_REG_P (operands[0]))
2148 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2150 return standard_sse_constant_opcode (insn, operands[1]);
2153 switch (get_attr_mode (insn))
2156 /* Handle broken assemblers that require movd instead of movq. */
2157 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2158 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2159 return "%vmovd\t{%1, %0|%0, %1}";
2160 return "%vmovq\t{%1, %0|%0, %1}";
2162 return "%vmovdqa\t{%1, %0|%0, %1}";
2164 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2167 gcc_assert (!TARGET_AVX);
2168 return "movlps\t{%1, %0|%0, %1}";
2170 return "%vmovaps\t{%1, %0|%0, %1}";
2177 if (SSE_REG_P (operands[0]))
2178 return "movq2dq\t{%1, %0|%0, %1}";
2180 return "movdq2q\t{%1, %0|%0, %1}";
2183 return "lea{q}\t{%E1, %0|%0, %E1}";
2186 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2187 if (get_attr_mode (insn) == MODE_SI)
2188 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2189 else if (which_alternative == 4)
2190 return "movabs{q}\t{%1, %0|%0, %1}";
2191 else if (ix86_use_lea_for_mov (insn, operands))
2192 return "lea{q}\t{%E1, %0|%0, %E1}";
2194 return "mov{q}\t{%1, %0|%0, %1}";
2201 (cond [(eq_attr "alternative" "0,1")
2202 (const_string "nox64")
2203 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2204 (const_string "x64")
2205 (eq_attr "alternative" "18")
2206 (const_string "x64_sse4")
2208 (const_string "*")))
2210 (cond [(eq_attr "alternative" "0,1")
2211 (const_string "multi")
2212 (eq_attr "alternative" "6")
2213 (const_string "mmx")
2214 (eq_attr "alternative" "7,8,9,10,11")
2215 (const_string "mmxmov")
2216 (eq_attr "alternative" "12,18")
2217 (const_string "sselog1")
2218 (eq_attr "alternative" "13,14,15,16,17,19")
2219 (const_string "ssemov")
2220 (eq_attr "alternative" "20,21")
2221 (const_string "ssecvt")
2222 (eq_attr "alternative" "22,23,24,25")
2223 (const_string "mskmov")
2224 (and (match_operand 0 "register_operand")
2225 (match_operand 1 "pic_32bit_operand"))
2226 (const_string "lea")
2228 (const_string "imov")))
2231 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2233 (const_string "*")))
2234 (set (attr "length_immediate")
2235 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2237 (eq_attr "alternative" "18")
2240 (const_string "*")))
2241 (set (attr "prefix_rex")
2242 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2244 (const_string "*")))
2245 (set (attr "prefix_extra")
2246 (if_then_else (eq_attr "alternative" "18")
2248 (const_string "*")))
2249 (set (attr "prefix")
2250 (if_then_else (eq_attr "type" "sselog1,ssemov")
2251 (const_string "maybe_vex")
2252 (const_string "orig")))
2253 (set (attr "prefix_data16")
2254 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2256 (const_string "*")))
2258 (cond [(eq_attr "alternative" "2")
2260 (eq_attr "alternative" "12,13")
2261 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2262 (match_operand 1 "ext_sse_reg_operand"))
2264 (ior (not (match_test "TARGET_SSE2"))
2265 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2266 (const_string "V4SF")
2267 (match_test "TARGET_AVX")
2269 (match_test "optimize_function_for_size_p (cfun)")
2270 (const_string "V4SF")
2272 (const_string "TI"))
2274 (and (eq_attr "alternative" "14,15,16")
2275 (not (match_test "TARGET_SSE2")))
2276 (const_string "V2SF")
2277 (eq_attr "alternative" "18")
2280 (const_string "DI")))
2281 (set (attr "enabled")
2282 (cond [(eq_attr "alternative" "15")
2284 (match_test "TARGET_STV && TARGET_SSE2")
2285 (symbol_ref "false")
2287 (eq_attr "alternative" "16")
2289 (match_test "TARGET_STV && TARGET_SSE2")
2291 (symbol_ref "false"))
2293 (const_string "*")))])
2296 [(set (match_operand:DI 0 "nonimmediate_operand")
2297 (match_operand:DI 1 "general_operand"))]
2298 "!TARGET_64BIT && reload_completed
2299 && !(MMX_REG_P (operands[0])
2300 || SSE_REG_P (operands[0])
2301 || MASK_REG_P (operands[0]))
2302 && !(MMX_REG_P (operands[1])
2303 || SSE_REG_P (operands[1])
2304 || MASK_REG_P (operands[1]))"
2306 "ix86_split_long_move (operands); DONE;")
2308 (define_insn "*movsi_internal"
2309 [(set (match_operand:SI 0 "nonimmediate_operand"
2310 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2311 (match_operand:SI 1 "general_operand"
2312 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2313 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2315 switch (get_attr_type (insn))
2318 if (GENERAL_REG_P (operands[0]))
2319 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2321 return standard_sse_constant_opcode (insn, operands[1]);
2324 return "kmovd\t{%1, %0|%0, %1}";
2327 switch (get_attr_mode (insn))
2330 return "%vmovd\t{%1, %0|%0, %1}";
2332 return "%vmovdqa\t{%1, %0|%0, %1}";
2334 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2337 return "%vmovaps\t{%1, %0|%0, %1}";
2340 gcc_assert (!TARGET_AVX);
2341 return "movss\t{%1, %0|%0, %1}";
2348 return "pxor\t%0, %0";
2351 switch (get_attr_mode (insn))
2354 return "movq\t{%1, %0|%0, %1}";
2356 return "movd\t{%1, %0|%0, %1}";
2363 return "lea{l}\t{%E1, %0|%0, %E1}";
2366 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2367 if (ix86_use_lea_for_mov (insn, operands))
2368 return "lea{l}\t{%E1, %0|%0, %E1}";
2370 return "mov{l}\t{%1, %0|%0, %1}";
2377 (if_then_else (eq_attr "alternative" "11")
2378 (const_string "sse4")
2379 (const_string "*")))
2381 (cond [(eq_attr "alternative" "2")
2382 (const_string "mmx")
2383 (eq_attr "alternative" "3,4,5")
2384 (const_string "mmxmov")
2385 (eq_attr "alternative" "6,11")
2386 (const_string "sselog1")
2387 (eq_attr "alternative" "7,8,9,10,12")
2388 (const_string "ssemov")
2389 (eq_attr "alternative" "13,14")
2390 (const_string "mskmov")
2391 (and (match_operand 0 "register_operand")
2392 (match_operand 1 "pic_32bit_operand"))
2393 (const_string "lea")
2395 (const_string "imov")))
2396 (set (attr "length_immediate")
2397 (if_then_else (eq_attr "alternative" "11")
2399 (const_string "*")))
2400 (set (attr "prefix_extra")
2401 (if_then_else (eq_attr "alternative" "11")
2403 (const_string "*")))
2404 (set (attr "prefix")
2405 (if_then_else (eq_attr "type" "sselog1,ssemov")
2406 (const_string "maybe_vex")
2407 (const_string "orig")))
2408 (set (attr "prefix_data16")
2409 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2411 (const_string "*")))
2413 (cond [(eq_attr "alternative" "2,3")
2415 (eq_attr "alternative" "6,7")
2416 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2417 (match_operand 1 "ext_sse_reg_operand"))
2419 (ior (not (match_test "TARGET_SSE2"))
2420 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2421 (const_string "V4SF")
2422 (match_test "TARGET_AVX")
2424 (match_test "optimize_function_for_size_p (cfun)")
2425 (const_string "V4SF")
2427 (const_string "TI"))
2429 (and (eq_attr "alternative" "8,9")
2430 (not (match_test "TARGET_SSE2")))
2432 (eq_attr "alternative" "11")
2435 (const_string "SI")))])
2437 (define_insn "kmovw"
2438 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2440 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2442 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2444 kmovw\t{%k1, %0|%0, %k1}
2445 kmovw\t{%1, %0|%0, %1}";
2446 [(set_attr "mode" "HI")
2447 (set_attr "type" "mskmov")
2448 (set_attr "prefix" "vex")])
2451 (define_insn "*movhi_internal"
2452 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2453 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2454 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456 switch (get_attr_type (insn))
2459 /* movzwl is faster than movw on p2 due to partial word stalls,
2460 though not as fast as an aligned movl. */
2461 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2464 switch (which_alternative)
2466 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2467 case 5: return "kmovw\t{%1, %0|%0, %1}";
2468 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2469 default: gcc_unreachable ();
2473 if (get_attr_mode (insn) == MODE_SI)
2474 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2476 return "mov{w}\t{%1, %0|%0, %1}";
2480 (cond [(eq_attr "alternative" "4,5,6")
2481 (const_string "mskmov")
2482 (match_test "optimize_function_for_size_p (cfun)")
2483 (const_string "imov")
2484 (and (eq_attr "alternative" "0")
2485 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2486 (not (match_test "TARGET_HIMODE_MATH"))))
2487 (const_string "imov")
2488 (and (eq_attr "alternative" "1,2")
2489 (match_operand:HI 1 "aligned_operand"))
2490 (const_string "imov")
2491 (and (match_test "TARGET_MOVX")
2492 (eq_attr "alternative" "0,2"))
2493 (const_string "imovx")
2495 (const_string "imov")))
2496 (set (attr "prefix")
2497 (if_then_else (eq_attr "alternative" "4,5,6")
2498 (const_string "vex")
2499 (const_string "orig")))
2501 (cond [(eq_attr "type" "imovx")
2503 (and (eq_attr "alternative" "1,2")
2504 (match_operand:HI 1 "aligned_operand"))
2506 (and (eq_attr "alternative" "0")
2507 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2508 (not (match_test "TARGET_HIMODE_MATH"))))
2511 (const_string "HI")))])
2513 ;; Situation is quite tricky about when to choose full sized (SImode) move
2514 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2515 ;; partial register dependency machines (such as AMD Athlon), where QImode
2516 ;; moves issue extra dependency and for partial register stalls machines
2517 ;; that don't use QImode patterns (and QImode move cause stall on the next
2520 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2521 ;; register stall machines with, where we use QImode instructions, since
2522 ;; partial register stall can be caused there. Then we use movzx.
2524 (define_insn "*movqi_internal"
2525 [(set (match_operand:QI 0 "nonimmediate_operand"
2526 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2527 (match_operand:QI 1 "general_operand"
2528 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2529 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2531 switch (get_attr_type (insn))
2534 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2535 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2538 switch (which_alternative)
2540 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2541 : "kmovw\t{%k1, %0|%0, %k1}";
2542 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2543 : "kmovw\t{%1, %0|%0, %1}";
2544 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2545 : "kmovw\t{%1, %k0|%k0, %1}";
2548 gcc_assert (TARGET_AVX512DQ);
2549 return "kmovb\t{%1, %0|%0, %1}";
2550 default: gcc_unreachable ();
2554 if (get_attr_mode (insn) == MODE_SI)
2555 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2557 return "mov{b}\t{%1, %0|%0, %1}";
2560 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2562 (cond [(eq_attr "alternative" "7,8,9,10,11")
2563 (const_string "mskmov")
2564 (and (eq_attr "alternative" "5")
2565 (not (match_operand:QI 1 "aligned_operand")))
2566 (const_string "imovx")
2567 (match_test "optimize_function_for_size_p (cfun)")
2568 (const_string "imov")
2569 (and (eq_attr "alternative" "3")
2570 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2571 (not (match_test "TARGET_QIMODE_MATH"))))
2572 (const_string "imov")
2573 (eq_attr "alternative" "3,5")
2574 (const_string "imovx")
2575 (and (match_test "TARGET_MOVX")
2576 (eq_attr "alternative" "2"))
2577 (const_string "imovx")
2579 (const_string "imov")))
2580 (set (attr "prefix")
2581 (if_then_else (eq_attr "alternative" "7,8,9")
2582 (const_string "vex")
2583 (const_string "orig")))
2585 (cond [(eq_attr "alternative" "3,4,5")
2587 (eq_attr "alternative" "6")
2589 (eq_attr "type" "imovx")
2591 (and (eq_attr "type" "imov")
2592 (and (eq_attr "alternative" "0,1")
2593 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2594 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2595 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2597 ;; Avoid partial register stalls when not using QImode arithmetic
2598 (and (eq_attr "type" "imov")
2599 (and (eq_attr "alternative" "0,1")
2600 (and (match_test "TARGET_PARTIAL_REG_STALL")
2601 (not (match_test "TARGET_QIMODE_MATH")))))
2604 (const_string "QI")))])
2606 ;; Stores and loads of ax to arbitrary constant address.
2607 ;; We fake an second form of instruction to force reload to load address
2608 ;; into register when rax is not available
2609 (define_insn "*movabs<mode>_1"
2610 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2611 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2612 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2614 /* Recover the full memory rtx. */
2615 operands[0] = SET_DEST (PATTERN (insn));
2616 switch (which_alternative)
2619 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2621 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2626 [(set_attr "type" "imov")
2627 (set_attr "modrm" "0,*")
2628 (set_attr "length_address" "8,0")
2629 (set_attr "length_immediate" "0,*")
2630 (set_attr "memory" "store")
2631 (set_attr "mode" "<MODE>")])
2633 (define_insn "*movabs<mode>_2"
2634 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2635 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2636 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2638 /* Recover the full memory rtx. */
2639 operands[1] = SET_SRC (PATTERN (insn));
2640 switch (which_alternative)
2643 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2645 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2650 [(set_attr "type" "imov")
2651 (set_attr "modrm" "0,*")
2652 (set_attr "length_address" "8,0")
2653 (set_attr "length_immediate" "0")
2654 (set_attr "memory" "load")
2655 (set_attr "mode" "<MODE>")])
2657 (define_insn "*swap<mode>"
2658 [(set (match_operand:SWI48 0 "register_operand" "+r")
2659 (match_operand:SWI48 1 "register_operand" "+r"))
2663 "xchg{<imodesuffix>}\t%1, %0"
2664 [(set_attr "type" "imov")
2665 (set_attr "mode" "<MODE>")
2666 (set_attr "pent_pair" "np")
2667 (set_attr "athlon_decode" "vector")
2668 (set_attr "amdfam10_decode" "double")
2669 (set_attr "bdver1_decode" "double")])
2671 (define_insn "*swap<mode>_1"
2672 [(set (match_operand:SWI12 0 "register_operand" "+r")
2673 (match_operand:SWI12 1 "register_operand" "+r"))
2676 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2678 [(set_attr "type" "imov")
2679 (set_attr "mode" "SI")
2680 (set_attr "pent_pair" "np")
2681 (set_attr "athlon_decode" "vector")
2682 (set_attr "amdfam10_decode" "double")
2683 (set_attr "bdver1_decode" "double")])
2685 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2686 ;; is disabled for AMDFAM10
2687 (define_insn "*swap<mode>_2"
2688 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2689 (match_operand:SWI12 1 "register_operand" "+<r>"))
2692 "TARGET_PARTIAL_REG_STALL"
2693 "xchg{<imodesuffix>}\t%1, %0"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "<MODE>")
2696 (set_attr "pent_pair" "np")
2697 (set_attr "athlon_decode" "vector")])
2699 (define_expand "movstrict<mode>"
2700 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2701 (match_operand:SWI12 1 "general_operand"))]
2704 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2706 if (SUBREG_P (operands[0])
2707 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2709 /* Don't generate memory->memory moves, go through a register */
2710 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2711 operands[1] = force_reg (<MODE>mode, operands[1]);
2714 (define_insn "*movstrict<mode>_1"
2715 [(set (strict_low_part
2716 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2717 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2718 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2719 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2720 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2721 [(set_attr "type" "imov")
2722 (set_attr "mode" "<MODE>")])
2724 (define_insn "*movstrict<mode>_xor"
2725 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2726 (match_operand:SWI12 1 "const0_operand"))
2727 (clobber (reg:CC FLAGS_REG))]
2729 "xor{<imodesuffix>}\t%0, %0"
2730 [(set_attr "type" "alu1")
2731 (set_attr "modrm_class" "op0")
2732 (set_attr "mode" "<MODE>")
2733 (set_attr "length_immediate" "0")])
2735 (define_expand "extv<mode>"
2736 [(set (match_operand:SWI24 0 "register_operand")
2737 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2738 (match_operand:SI 2 "const_int_operand")
2739 (match_operand:SI 3 "const_int_operand")))]
2742 /* Handle extractions from %ah et al. */
2743 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2746 if (! ext_register_operand (operands[1], VOIDmode))
2747 operands[1] = copy_to_reg (operands[1]);
2750 (define_insn "*extv<mode>"
2751 [(set (match_operand:SWI24 0 "register_operand" "=R")
2752 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2756 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2757 [(set_attr "type" "imovx")
2758 (set_attr "mode" "SI")])
2760 (define_insn "*extvqi"
2761 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2762 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2767 switch (get_attr_type (insn))
2770 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2772 return "mov{b}\t{%h1, %0|%0, %h1}";
2775 [(set_attr "isa" "*,*,nox64")
2777 (if_then_else (and (match_operand:QI 0 "register_operand")
2778 (ior (not (match_operand:QI 0 "QIreg_operand"))
2779 (match_test "TARGET_MOVX")))
2780 (const_string "imovx")
2781 (const_string "imov")))
2783 (if_then_else (eq_attr "type" "imovx")
2785 (const_string "QI")))])
2787 (define_expand "extzv<mode>"
2788 [(set (match_operand:SWI248 0 "register_operand")
2789 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2790 (match_operand:SI 2 "const_int_operand")
2791 (match_operand:SI 3 "const_int_operand")))]
2794 if (ix86_expand_pextr (operands))
2797 /* Handle extractions from %ah et al. */
2798 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2801 if (! ext_register_operand (operands[1], VOIDmode))
2802 operands[1] = copy_to_reg (operands[1]);
2805 (define_insn "*extzv<mode>"
2806 [(set (match_operand:SWI248 0 "register_operand" "=R")
2807 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2811 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2812 [(set_attr "type" "imovx")
2813 (set_attr "mode" "SI")])
2815 (define_insn "*extzvqi"
2816 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2818 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2823 switch (get_attr_type (insn))
2826 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2828 return "mov{b}\t{%h1, %0|%0, %h1}";
2831 [(set_attr "isa" "*,*,nox64")
2833 (if_then_else (and (match_operand:QI 0 "register_operand")
2834 (ior (not (match_operand:QI 0 "QIreg_operand"))
2835 (match_test "TARGET_MOVX")))
2836 (const_string "imovx")
2837 (const_string "imov")))
2839 (if_then_else (eq_attr "type" "imovx")
2841 (const_string "QI")))])
2843 (define_expand "insv<mode>"
2844 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2845 (match_operand:SI 1 "const_int_operand")
2846 (match_operand:SI 2 "const_int_operand"))
2847 (match_operand:SWI248 3 "register_operand"))]
2852 if (ix86_expand_pinsr (operands))
2855 /* Handle insertions to %ah et al. */
2856 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2861 if (!ext_register_operand (dst, VOIDmode))
2862 dst = copy_to_reg (dst);
2864 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2866 /* Fix up the destination if needed. */
2867 if (dst != operands[0])
2868 emit_move_insn (operands[0], dst);
2873 (define_insn "insv<mode>_1"
2874 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2877 (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2880 if (CONST_INT_P (operands[1]))
2881 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2882 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2884 [(set_attr "isa" "*,nox64")
2885 (set_attr "type" "imov")
2886 (set_attr "mode" "QI")])
2888 (define_insn "*insvqi"
2889 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2892 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2895 "mov{b}\t{%h1, %h0|%h0, %h1}"
2896 [(set_attr "type" "imov")
2897 (set_attr "mode" "QI")])
2899 ;; Floating point push instructions.
2901 (define_insn "*pushtf"
2902 [(set (match_operand:TF 0 "push_operand" "=<,<")
2903 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2904 "TARGET_64BIT || TARGET_SSE"
2906 /* This insn should be already split before reg-stack. */
2909 [(set_attr "isa" "*,x64")
2910 (set_attr "type" "multi")
2911 (set_attr "unit" "sse,*")
2912 (set_attr "mode" "TF,DI")])
2914 ;; %%% Kill this when call knows how to work this out.
2916 [(set (match_operand:TF 0 "push_operand")
2917 (match_operand:TF 1 "sse_reg_operand"))]
2918 "TARGET_SSE && reload_completed"
2919 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2920 (set (match_dup 0) (match_dup 1))]
2922 /* Preserve memory attributes. */
2923 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2926 (define_insn "*pushxf"
2927 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2928 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2931 /* This insn should be already split before reg-stack. */
2934 [(set_attr "type" "multi")
2935 (set_attr "unit" "i387,*,*,*")
2937 (cond [(eq_attr "alternative" "1,2,3")
2938 (if_then_else (match_test "TARGET_64BIT")
2940 (const_string "SI"))
2942 (const_string "XF")))
2943 (set (attr "preferred_for_size")
2944 (cond [(eq_attr "alternative" "1")
2945 (symbol_ref "false")]
2946 (symbol_ref "true")))])
2948 ;; %%% Kill this when call knows how to work this out.
2950 [(set (match_operand:XF 0 "push_operand")
2951 (match_operand:XF 1 "fp_register_operand"))]
2953 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2954 (set (match_dup 0) (match_dup 1))]
2956 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2957 /* Preserve memory attributes. */
2958 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2961 (define_insn "*pushdf"
2962 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2963 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2966 /* This insn should be already split before reg-stack. */
2969 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2970 (set_attr "type" "multi")
2971 (set_attr "unit" "i387,*,*,*,*,sse")
2972 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2973 (set (attr "preferred_for_size")
2974 (cond [(eq_attr "alternative" "1")
2975 (symbol_ref "false")]
2976 (symbol_ref "true")))
2977 (set (attr "preferred_for_speed")
2978 (cond [(eq_attr "alternative" "1")
2979 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2980 (symbol_ref "true")))])
2982 ;; %%% Kill this when call knows how to work this out.
2984 [(set (match_operand:DF 0 "push_operand")
2985 (match_operand:DF 1 "any_fp_register_operand"))]
2987 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2988 (set (match_dup 0) (match_dup 1))]
2990 /* Preserve memory attributes. */
2991 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2994 (define_insn "*pushsf_rex64"
2995 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2996 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2999 /* Anything else should be already split before reg-stack. */
3000 gcc_assert (which_alternative == 1);
3001 return "push{q}\t%q1";
3003 [(set_attr "type" "multi,push,multi")
3004 (set_attr "unit" "i387,*,*")
3005 (set_attr "mode" "SF,DI,SF")])
3007 (define_insn "*pushsf"
3008 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3009 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3012 /* Anything else should be already split before reg-stack. */
3013 gcc_assert (which_alternative == 1);
3014 return "push{l}\t%1";
3016 [(set_attr "type" "multi,push,multi")
3017 (set_attr "unit" "i387,*,*")
3018 (set_attr "mode" "SF,SI,SF")])
3020 ;; %%% Kill this when call knows how to work this out.
3022 [(set (match_operand:SF 0 "push_operand")
3023 (match_operand:SF 1 "any_fp_register_operand"))]
3025 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3026 (set (match_dup 0) (match_dup 1))]
3028 rtx op = XEXP (operands[0], 0);
3029 if (GET_CODE (op) == PRE_DEC)
3031 gcc_assert (!TARGET_64BIT);
3036 op = XEXP (XEXP (op, 1), 1);
3037 gcc_assert (CONST_INT_P (op));
3040 /* Preserve memory attributes. */
3041 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3045 [(set (match_operand:SF 0 "push_operand")
3046 (match_operand:SF 1 "memory_operand"))]
3048 [(set (match_dup 0) (match_dup 2))]
3050 operands[2] = find_constant_src (curr_insn);
3052 if (operands[2] == NULL_RTX)
3057 [(set (match_operand 0 "push_operand")
3058 (match_operand 1 "general_operand"))]
3060 && (GET_MODE (operands[0]) == TFmode
3061 || GET_MODE (operands[0]) == XFmode
3062 || GET_MODE (operands[0]) == DFmode)
3063 && !ANY_FP_REG_P (operands[1])"
3065 "ix86_split_long_move (operands); DONE;")
3067 ;; Floating point move instructions.
3069 (define_expand "movtf"
3070 [(set (match_operand:TF 0 "nonimmediate_operand")
3071 (match_operand:TF 1 "nonimmediate_operand"))]
3072 "TARGET_64BIT || TARGET_SSE"
3073 "ix86_expand_move (TFmode, operands); DONE;")
3075 (define_expand "mov<mode>"
3076 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3077 (match_operand:X87MODEF 1 "general_operand"))]
3079 "ix86_expand_move (<MODE>mode, operands); DONE;")
3081 (define_insn "*movtf_internal"
3082 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3083 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
3084 "(TARGET_64BIT || TARGET_SSE)
3085 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3086 && (!can_create_pseudo_p ()
3087 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3088 || !CONST_DOUBLE_P (operands[1])
3089 || (optimize_function_for_size_p (cfun)
3090 && standard_sse_constant_p (operands[1])
3091 && !memory_operand (operands[0], TFmode))
3092 || (!TARGET_MEMORY_MISMATCH_STALL
3093 && memory_operand (operands[0], TFmode)))"
3095 switch (get_attr_type (insn))
3098 return standard_sse_constant_opcode (insn, operands[1]);
3101 /* Handle misaligned load/store since we
3102 don't have movmisaligntf pattern. */
3103 if (misaligned_operand (operands[0], TFmode)
3104 || misaligned_operand (operands[1], TFmode))
3106 if (get_attr_mode (insn) == MODE_V4SF)
3107 return "%vmovups\t{%1, %0|%0, %1}";
3109 return "%vmovdqu\t{%1, %0|%0, %1}";
3113 if (get_attr_mode (insn) == MODE_V4SF)
3114 return "%vmovaps\t{%1, %0|%0, %1}";
3116 return "%vmovdqa\t{%1, %0|%0, %1}";
3126 [(set_attr "isa" "*,*,*,x64,x64")
3127 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3128 (set (attr "prefix")
3129 (if_then_else (eq_attr "type" "sselog1,ssemov")
3130 (const_string "maybe_vex")
3131 (const_string "orig")))
3133 (cond [(eq_attr "alternative" "3,4")
3135 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3136 (const_string "V4SF")
3137 (and (eq_attr "alternative" "2")
3138 (match_test "TARGET_SSE_TYPELESS_STORES"))
3139 (const_string "V4SF")
3140 (match_test "TARGET_AVX")
3142 (ior (not (match_test "TARGET_SSE2"))
3143 (match_test "optimize_function_for_size_p (cfun)"))
3144 (const_string "V4SF")
3146 (const_string "TI")))])
3149 [(set (match_operand:TF 0 "nonimmediate_operand")
3150 (match_operand:TF 1 "general_operand"))]
3152 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3154 "ix86_split_long_move (operands); DONE;")
3156 ;; Possible store forwarding (partial memory) stall
3157 ;; in alternatives 4, 6, 7 and 8.
3158 (define_insn "*movxf_internal"
3159 [(set (match_operand:XF 0 "nonimmediate_operand"
3160 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3161 (match_operand:XF 1 "general_operand"
3162 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3164 && (!can_create_pseudo_p ()
3165 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3166 || !CONST_DOUBLE_P (operands[1])
3167 || (optimize_function_for_size_p (cfun)
3168 && standard_80387_constant_p (operands[1]) > 0
3169 && !memory_operand (operands[0], XFmode))
3170 || (!TARGET_MEMORY_MISMATCH_STALL
3171 && memory_operand (operands[0], XFmode))
3172 || !TARGET_HARD_XF_REGS)"
3174 switch (get_attr_type (insn))
3177 if (which_alternative == 2)
3178 return standard_80387_constant_opcode (operands[1]);
3179 return output_387_reg_move (insn, operands);
3189 (cond [(eq_attr "alternative" "7")
3190 (const_string "nox64")
3191 (eq_attr "alternative" "8")
3192 (const_string "x64")
3194 (const_string "*")))
3196 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3197 (const_string "multi")
3199 (const_string "fmov")))
3201 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3202 (if_then_else (match_test "TARGET_64BIT")
3204 (const_string "SI"))
3206 (const_string "XF")))
3207 (set (attr "preferred_for_size")
3208 (cond [(eq_attr "alternative" "3,4")
3209 (symbol_ref "false")]
3210 (symbol_ref "true")))
3211 (set (attr "enabled")
3212 (cond [(eq_attr "alternative" "9,10")
3214 (match_test "TARGET_HARD_XF_REGS")
3215 (symbol_ref "false")
3217 (not (match_test "TARGET_HARD_XF_REGS"))
3218 (symbol_ref "false")
3220 (const_string "*")))])
3223 [(set (match_operand:XF 0 "nonimmediate_operand")
3224 (match_operand:XF 1 "general_operand"))]
3226 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3228 "ix86_split_long_move (operands); DONE;")
3230 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3231 (define_insn "*movdf_internal"
3232 [(set (match_operand:DF 0 "nonimmediate_operand"
3233 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r ,o ,r ,m")
3234 (match_operand:DF 1 "general_operand"
3235 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3236 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3237 && (!can_create_pseudo_p ()
3238 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3239 || !CONST_DOUBLE_P (operands[1])
3240 || (optimize_function_for_size_p (cfun)
3241 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3242 && standard_80387_constant_p (operands[1]) > 0)
3243 || (TARGET_SSE2 && TARGET_SSE_MATH
3244 && standard_sse_constant_p (operands[1])))
3245 && !memory_operand (operands[0], DFmode))
3246 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3247 && memory_operand (operands[0], DFmode))
3248 || !TARGET_HARD_DF_REGS)"
3250 switch (get_attr_type (insn))
3253 if (which_alternative == 2)
3254 return standard_80387_constant_opcode (operands[1]);
3255 return output_387_reg_move (insn, operands);
3261 if (get_attr_mode (insn) == MODE_SI)
3262 return "mov{l}\t{%1, %k0|%k0, %1}";
3263 else if (which_alternative == 11)
3264 return "movabs{q}\t{%1, %0|%0, %1}";
3266 return "mov{q}\t{%1, %0|%0, %1}";
3269 return standard_sse_constant_opcode (insn, operands[1]);
3272 switch (get_attr_mode (insn))
3275 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3276 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3277 return "%vmovsd\t{%1, %0|%0, %1}";
3280 return "%vmovaps\t{%1, %0|%0, %1}";
3282 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3284 return "%vmovapd\t{%1, %0|%0, %1}";
3287 gcc_assert (!TARGET_AVX);
3288 return "movlps\t{%1, %0|%0, %1}";
3290 gcc_assert (!TARGET_AVX);
3291 return "movlpd\t{%1, %0|%0, %1}";
3294 /* Handle broken assemblers that require movd instead of movq. */
3295 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3296 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3297 return "%vmovd\t{%1, %0|%0, %1}";
3298 return "%vmovq\t{%1, %0|%0, %1}";
3309 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3310 (const_string "nox64")
3311 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3312 (const_string "x64")
3313 (eq_attr "alternative" "12,13,14,15")
3314 (const_string "sse2")
3316 (const_string "*")))
3318 (cond [(eq_attr "alternative" "0,1,2")
3319 (const_string "fmov")
3320 (eq_attr "alternative" "3,4,5,6,7,22,23")
3321 (const_string "multi")
3322 (eq_attr "alternative" "8,9,10,11,24,25")
3323 (const_string "imov")
3324 (eq_attr "alternative" "12,16")
3325 (const_string "sselog1")
3327 (const_string "ssemov")))
3329 (if_then_else (eq_attr "alternative" "11")
3331 (const_string "*")))
3332 (set (attr "length_immediate")
3333 (if_then_else (eq_attr "alternative" "11")
3335 (const_string "*")))
3336 (set (attr "prefix")
3337 (if_then_else (eq_attr "type" "sselog1,ssemov")
3338 (const_string "maybe_vex")
3339 (const_string "orig")))
3340 (set (attr "prefix_data16")
3342 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3343 (eq_attr "mode" "V1DF"))
3345 (const_string "*")))
3347 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3349 (eq_attr "alternative" "8,9,11,20,21,24,25")
3352 /* xorps is one byte shorter for non-AVX targets. */
3353 (eq_attr "alternative" "12,16")
3354 (cond [(not (match_test "TARGET_SSE2"))
3355 (const_string "V4SF")
3356 (match_test "TARGET_AVX512F")
3358 (match_test "TARGET_AVX")
3359 (const_string "V2DF")
3360 (match_test "optimize_function_for_size_p (cfun)")
3361 (const_string "V4SF")
3362 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3365 (const_string "V2DF"))
3367 /* For architectures resolving dependencies on
3368 whole SSE registers use movapd to break dependency
3369 chains, otherwise use short move to avoid extra work. */
3371 /* movaps is one byte shorter for non-AVX targets. */
3372 (eq_attr "alternative" "13,17")
3373 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3374 (match_operand 1 "ext_sse_reg_operand"))
3375 (const_string "V8DF")
3376 (ior (not (match_test "TARGET_SSE2"))
3377 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3378 (const_string "V4SF")
3379 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3380 (const_string "V2DF")
3381 (match_test "TARGET_AVX")
3383 (match_test "optimize_function_for_size_p (cfun)")
3384 (const_string "V4SF")
3386 (const_string "DF"))
3388 /* For architectures resolving dependencies on register
3389 parts we may avoid extra work to zero out upper part
3391 (eq_attr "alternative" "14,18")
3392 (cond [(not (match_test "TARGET_SSE2"))
3393 (const_string "V2SF")
3394 (match_test "TARGET_AVX")
3396 (match_test "TARGET_SSE_SPLIT_REGS")
3397 (const_string "V1DF")
3399 (const_string "DF"))
3401 (and (eq_attr "alternative" "15,19")
3402 (not (match_test "TARGET_SSE2")))
3403 (const_string "V2SF")
3405 (const_string "DF")))
3406 (set (attr "preferred_for_size")
3407 (cond [(eq_attr "alternative" "3,4")
3408 (symbol_ref "false")]
3409 (symbol_ref "true")))
3410 (set (attr "preferred_for_speed")
3411 (cond [(eq_attr "alternative" "3,4")
3412 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3413 (symbol_ref "true")))
3414 (set (attr "enabled")
3415 (cond [(eq_attr "alternative" "22,23,24,25")
3417 (match_test "TARGET_HARD_DF_REGS")
3418 (symbol_ref "false")
3420 (not (match_test "TARGET_HARD_DF_REGS"))
3421 (symbol_ref "false")
3423 (const_string "*")))])
3426 [(set (match_operand:DF 0 "nonimmediate_operand")
3427 (match_operand:DF 1 "general_operand"))]
3428 "!TARGET_64BIT && reload_completed
3429 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3431 "ix86_split_long_move (operands); DONE;")
3433 (define_insn "*movsf_internal"
3434 [(set (match_operand:SF 0 "nonimmediate_operand"
3435 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3436 (match_operand:SF 1 "general_operand"
3437 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3438 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3439 && (!can_create_pseudo_p ()
3440 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3441 || !CONST_DOUBLE_P (operands[1])
3442 || (optimize_function_for_size_p (cfun)
3443 && ((!TARGET_SSE_MATH
3444 && standard_80387_constant_p (operands[1]) > 0)
3446 && standard_sse_constant_p (operands[1]))))
3447 || memory_operand (operands[0], SFmode)
3448 || !TARGET_HARD_SF_REGS)"
3450 switch (get_attr_type (insn))
3453 if (which_alternative == 2)
3454 return standard_80387_constant_opcode (operands[1]);
3455 return output_387_reg_move (insn, operands);
3458 return "mov{l}\t{%1, %0|%0, %1}";
3461 return standard_sse_constant_opcode (insn, operands[1]);
3464 switch (get_attr_mode (insn))
3467 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3468 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3469 return "%vmovss\t{%1, %0|%0, %1}";
3472 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3474 return "%vmovaps\t{%1, %0|%0, %1}";
3477 return "%vmovd\t{%1, %0|%0, %1}";
3484 switch (get_attr_mode (insn))
3487 return "movq\t{%1, %0|%0, %1}";
3489 return "movd\t{%1, %0|%0, %1}";
3500 (cond [(eq_attr "alternative" "0,1,2")
3501 (const_string "fmov")
3502 (eq_attr "alternative" "3,4,16,17")
3503 (const_string "imov")
3504 (eq_attr "alternative" "5")
3505 (const_string "sselog1")
3506 (eq_attr "alternative" "11,12,13,14,15")
3507 (const_string "mmxmov")
3509 (const_string "ssemov")))
3510 (set (attr "prefix")
3511 (if_then_else (eq_attr "type" "sselog1,ssemov")
3512 (const_string "maybe_vex")
3513 (const_string "orig")))
3514 (set (attr "prefix_data16")
3515 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3517 (const_string "*")))
3519 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3521 (eq_attr "alternative" "11")
3523 (eq_attr "alternative" "5")
3524 (cond [(not (match_test "TARGET_SSE2"))
3525 (const_string "V4SF")
3526 (match_test "TARGET_AVX512F")
3527 (const_string "V16SF")
3528 (match_test "TARGET_AVX")
3529 (const_string "V4SF")
3530 (match_test "optimize_function_for_size_p (cfun)")
3531 (const_string "V4SF")
3532 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3535 (const_string "V4SF"))
3537 /* For architectures resolving dependencies on
3538 whole SSE registers use APS move to break dependency
3539 chains, otherwise use short move to avoid extra work.
3541 Do the same for architectures resolving dependencies on
3542 the parts. While in DF mode it is better to always handle
3543 just register parts, the SF mode is different due to lack
3544 of instructions to load just part of the register. It is
3545 better to maintain the whole registers in single format
3546 to avoid problems on using packed logical operations. */
3547 (eq_attr "alternative" "6")
3548 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3549 (match_operand 1 "ext_sse_reg_operand"))
3550 (const_string "V16SF")
3551 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3552 (match_test "TARGET_SSE_SPLIT_REGS"))
3553 (const_string "V4SF")
3555 (const_string "SF"))
3557 (const_string "SF")))
3558 (set (attr "enabled")
3559 (cond [(eq_attr "alternative" "16,17")
3561 (match_test "TARGET_HARD_SF_REGS")
3562 (symbol_ref "false")
3564 (not (match_test "TARGET_HARD_SF_REGS"))
3565 (symbol_ref "false")
3567 (const_string "*")))])
3570 [(set (match_operand 0 "any_fp_register_operand")
3571 (match_operand 1 "memory_operand"))]
3573 && (GET_MODE (operands[0]) == TFmode
3574 || GET_MODE (operands[0]) == XFmode
3575 || GET_MODE (operands[0]) == DFmode
3576 || GET_MODE (operands[0]) == SFmode)"
3577 [(set (match_dup 0) (match_dup 2))]
3579 operands[2] = find_constant_src (curr_insn);
3581 if (operands[2] == NULL_RTX
3582 || (SSE_REGNO_P (REGNO (operands[0]))
3583 && !standard_sse_constant_p (operands[2]))
3584 || (STACK_REGNO_P (REGNO (operands[0]))
3585 && standard_80387_constant_p (operands[2]) < 1))
3590 [(set (match_operand 0 "any_fp_register_operand")
3591 (float_extend (match_operand 1 "memory_operand")))]
3593 && (GET_MODE (operands[0]) == TFmode
3594 || GET_MODE (operands[0]) == XFmode
3595 || GET_MODE (operands[0]) == DFmode)"
3596 [(set (match_dup 0) (match_dup 2))]
3598 operands[2] = find_constant_src (curr_insn);
3600 if (operands[2] == NULL_RTX
3601 || (SSE_REGNO_P (REGNO (operands[0]))
3602 && !standard_sse_constant_p (operands[2]))
3603 || (STACK_REGNO_P (REGNO (operands[0]))
3604 && standard_80387_constant_p (operands[2]) < 1))
3608 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3610 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3611 (match_operand:X87MODEF 1 "immediate_operand"))]
3613 && (standard_80387_constant_p (operands[1]) == 8
3614 || standard_80387_constant_p (operands[1]) == 9)"
3615 [(set (match_dup 0)(match_dup 1))
3617 (neg:X87MODEF (match_dup 0)))]
3619 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3620 operands[1] = CONST0_RTX (<MODE>mode);
3622 operands[1] = CONST1_RTX (<MODE>mode);
3625 (define_insn "swapxf"
3626 [(set (match_operand:XF 0 "register_operand" "+f")
3627 (match_operand:XF 1 "register_operand" "+f"))
3632 if (STACK_TOP_P (operands[0]))
3637 [(set_attr "type" "fxch")
3638 (set_attr "mode" "XF")])
3640 (define_insn "*swap<mode>"
3641 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3642 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3645 "TARGET_80387 || reload_completed"
3647 if (STACK_TOP_P (operands[0]))
3652 [(set_attr "type" "fxch")
3653 (set_attr "mode" "<MODE>")])
3655 ;; Zero extension instructions
3657 (define_expand "zero_extendsidi2"
3658 [(set (match_operand:DI 0 "nonimmediate_operand")
3659 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3661 (define_insn "*zero_extendsidi2"
3662 [(set (match_operand:DI 0 "nonimmediate_operand"
3663 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3665 (match_operand:SI 1 "x86_64_zext_operand"
3666 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3669 switch (get_attr_type (insn))
3672 if (ix86_use_lea_for_mov (insn, operands))
3673 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3675 return "mov{l}\t{%1, %k0|%k0, %1}";
3681 return "movd\t{%1, %0|%0, %1}";
3684 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3687 if (GENERAL_REG_P (operands[0]))
3688 return "%vmovd\t{%1, %k0|%k0, %1}";
3690 return "%vmovd\t{%1, %0|%0, %1}";
3697 (cond [(eq_attr "alternative" "0,1,2")
3698 (const_string "nox64")
3699 (eq_attr "alternative" "3,7")
3700 (const_string "x64")
3701 (eq_attr "alternative" "8")
3702 (const_string "x64_sse4")
3703 (eq_attr "alternative" "10")
3704 (const_string "sse2")
3706 (const_string "*")))
3708 (cond [(eq_attr "alternative" "0,1,2,4")
3709 (const_string "multi")
3710 (eq_attr "alternative" "5,6")
3711 (const_string "mmxmov")
3712 (eq_attr "alternative" "7,9,10")
3713 (const_string "ssemov")
3714 (eq_attr "alternative" "8")
3715 (const_string "sselog1")
3717 (const_string "imovx")))
3718 (set (attr "prefix_extra")
3719 (if_then_else (eq_attr "alternative" "8")
3721 (const_string "*")))
3722 (set (attr "length_immediate")
3723 (if_then_else (eq_attr "alternative" "8")
3725 (const_string "*")))
3726 (set (attr "prefix")
3727 (if_then_else (eq_attr "type" "ssemov,sselog1")
3728 (const_string "maybe_vex")
3729 (const_string "orig")))
3730 (set (attr "prefix_0f")
3731 (if_then_else (eq_attr "type" "imovx")
3733 (const_string "*")))
3735 (cond [(eq_attr "alternative" "5,6")
3737 (eq_attr "alternative" "7,8,9")
3740 (const_string "SI")))])
3743 [(set (match_operand:DI 0 "memory_operand")
3744 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3746 [(set (match_dup 4) (const_int 0))]
3747 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3750 [(set (match_operand:DI 0 "register_operand")
3751 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3752 "!TARGET_64BIT && reload_completed
3753 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3754 && true_regnum (operands[0]) == true_regnum (operands[1])"
3755 [(set (match_dup 4) (const_int 0))]
3756 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3759 [(set (match_operand:DI 0 "nonimmediate_operand")
3760 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3761 "!TARGET_64BIT && reload_completed
3762 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3763 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3764 [(set (match_dup 3) (match_dup 1))
3765 (set (match_dup 4) (const_int 0))]
3766 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3768 (define_insn "zero_extend<mode>di2"
3769 [(set (match_operand:DI 0 "register_operand" "=r")
3771 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3773 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3774 [(set_attr "type" "imovx")
3775 (set_attr "mode" "SI")])
3777 (define_expand "zero_extend<mode>si2"
3778 [(set (match_operand:SI 0 "register_operand")
3779 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3782 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3784 operands[1] = force_reg (<MODE>mode, operands[1]);
3785 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3790 (define_insn_and_split "zero_extend<mode>si2_and"
3791 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3793 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3794 (clobber (reg:CC FLAGS_REG))]
3795 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3797 "&& reload_completed"
3798 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3799 (clobber (reg:CC FLAGS_REG))])]
3801 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3803 ix86_expand_clear (operands[0]);
3805 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3806 emit_insn (gen_movstrict<mode>
3807 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3811 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3813 [(set_attr "type" "alu1")
3814 (set_attr "mode" "SI")])
3816 (define_insn "*zero_extend<mode>si2"
3817 [(set (match_operand:SI 0 "register_operand" "=r")
3819 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3820 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3821 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3825 (define_expand "zero_extendqihi2"
3826 [(set (match_operand:HI 0 "register_operand")
3827 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3830 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3832 operands[1] = force_reg (QImode, operands[1]);
3833 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3838 (define_insn_and_split "zero_extendqihi2_and"
3839 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3840 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3841 (clobber (reg:CC FLAGS_REG))]
3842 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3844 "&& reload_completed"
3845 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3846 (clobber (reg:CC FLAGS_REG))])]
3848 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3850 ix86_expand_clear (operands[0]);
3852 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3853 emit_insn (gen_movstrictqi
3854 (gen_lowpart (QImode, operands[0]), operands[1]));
3858 operands[0] = gen_lowpart (SImode, operands[0]);
3860 [(set_attr "type" "alu1")
3861 (set_attr "mode" "SI")])
3863 ; zero extend to SImode to avoid partial register stalls
3864 (define_insn "*zero_extendqihi2"
3865 [(set (match_operand:HI 0 "register_operand" "=r")
3866 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3867 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3868 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3872 (define_insn_and_split "*zext<mode>_doubleword"
3873 [(set (match_operand:DI 0 "register_operand" "=r")
3874 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3875 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3877 "&& reload_completed && GENERAL_REG_P (operands[0])"
3878 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3879 (set (match_dup 2) (const_int 0))]
3880 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3882 (define_insn_and_split "*zextsi_doubleword"
3883 [(set (match_operand:DI 0 "register_operand" "=r")
3884 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3885 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3887 "&& reload_completed && GENERAL_REG_P (operands[0])"
3888 [(set (match_dup 0) (match_dup 1))
3889 (set (match_dup 2) (const_int 0))]
3890 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3892 ;; Sign extension instructions
3894 (define_expand "extendsidi2"
3895 [(set (match_operand:DI 0 "register_operand")
3896 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3901 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3906 (define_insn "*extendsidi2_rex64"
3907 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3908 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3912 movs{lq|x}\t{%1, %0|%0, %1}"
3913 [(set_attr "type" "imovx")
3914 (set_attr "mode" "DI")
3915 (set_attr "prefix_0f" "0")
3916 (set_attr "modrm" "0,1")])
3918 (define_insn "extendsidi2_1"
3919 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3920 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3921 (clobber (reg:CC FLAGS_REG))
3922 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3926 ;; Split the memory case. If the source register doesn't die, it will stay
3927 ;; this way, if it does die, following peephole2s take care of it.
3929 [(set (match_operand:DI 0 "memory_operand")
3930 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3931 (clobber (reg:CC FLAGS_REG))
3932 (clobber (match_operand:SI 2 "register_operand"))]
3936 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3938 emit_move_insn (operands[3], operands[1]);
3940 /* Generate a cltd if possible and doing so it profitable. */
3941 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3942 && true_regnum (operands[1]) == AX_REG
3943 && true_regnum (operands[2]) == DX_REG)
3945 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3949 emit_move_insn (operands[2], operands[1]);
3950 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3952 emit_move_insn (operands[4], operands[2]);
3956 ;; Peepholes for the case where the source register does die, after
3957 ;; being split with the above splitter.
3959 [(set (match_operand:SI 0 "memory_operand")
3960 (match_operand:SI 1 "register_operand"))
3961 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3962 (parallel [(set (match_dup 2)
3963 (ashiftrt:SI (match_dup 2) (const_int 31)))
3964 (clobber (reg:CC FLAGS_REG))])
3965 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3966 "REGNO (operands[1]) != REGNO (operands[2])
3967 && peep2_reg_dead_p (2, operands[1])
3968 && peep2_reg_dead_p (4, operands[2])
3969 && !reg_mentioned_p (operands[2], operands[3])"
3970 [(set (match_dup 0) (match_dup 1))
3971 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3972 (clobber (reg:CC FLAGS_REG))])
3973 (set (match_dup 3) (match_dup 1))])
3976 [(set (match_operand:SI 0 "memory_operand")
3977 (match_operand:SI 1 "register_operand"))
3978 (parallel [(set (match_operand:SI 2 "register_operand")
3979 (ashiftrt:SI (match_dup 1) (const_int 31)))
3980 (clobber (reg:CC FLAGS_REG))])
3981 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3982 "/* cltd is shorter than sarl $31, %eax */
3983 !optimize_function_for_size_p (cfun)
3984 && true_regnum (operands[1]) == AX_REG
3985 && true_regnum (operands[2]) == DX_REG
3986 && peep2_reg_dead_p (2, operands[1])
3987 && peep2_reg_dead_p (3, operands[2])
3988 && !reg_mentioned_p (operands[2], operands[3])"
3989 [(set (match_dup 0) (match_dup 1))
3990 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3991 (clobber (reg:CC FLAGS_REG))])
3992 (set (match_dup 3) (match_dup 1))])
3994 ;; Extend to register case. Optimize case where source and destination
3995 ;; registers match and cases where we can use cltd.
3997 [(set (match_operand:DI 0 "register_operand")
3998 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3999 (clobber (reg:CC FLAGS_REG))
4000 (clobber (match_scratch:SI 2))]
4004 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4006 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4007 emit_move_insn (operands[3], operands[1]);
4009 /* Generate a cltd if possible and doing so it profitable. */
4010 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4011 && true_regnum (operands[3]) == AX_REG
4012 && true_regnum (operands[4]) == DX_REG)
4014 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4018 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4019 emit_move_insn (operands[4], operands[1]);
4021 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4025 (define_insn "extend<mode>di2"
4026 [(set (match_operand:DI 0 "register_operand" "=r")
4028 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4030 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4031 [(set_attr "type" "imovx")
4032 (set_attr "mode" "DI")])
4034 (define_insn "extendhisi2"
4035 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4036 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4039 switch (get_attr_prefix_0f (insn))
4042 return "{cwtl|cwde}";
4044 return "movs{wl|x}\t{%1, %0|%0, %1}";
4047 [(set_attr "type" "imovx")
4048 (set_attr "mode" "SI")
4049 (set (attr "prefix_0f")
4050 ;; movsx is short decodable while cwtl is vector decoded.
4051 (if_then_else (and (eq_attr "cpu" "!k6")
4052 (eq_attr "alternative" "0"))
4054 (const_string "1")))
4055 (set (attr "znver1_decode")
4056 (if_then_else (eq_attr "prefix_0f" "0")
4057 (const_string "double")
4058 (const_string "direct")))
4060 (if_then_else (eq_attr "prefix_0f" "0")
4062 (const_string "1")))])
4064 (define_insn "*extendhisi2_zext"
4065 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4068 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4071 switch (get_attr_prefix_0f (insn))
4074 return "{cwtl|cwde}";
4076 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4079 [(set_attr "type" "imovx")
4080 (set_attr "mode" "SI")
4081 (set (attr "prefix_0f")
4082 ;; movsx is short decodable while cwtl is vector decoded.
4083 (if_then_else (and (eq_attr "cpu" "!k6")
4084 (eq_attr "alternative" "0"))
4086 (const_string "1")))
4088 (if_then_else (eq_attr "prefix_0f" "0")
4090 (const_string "1")))])
4092 (define_insn "extendqisi2"
4093 [(set (match_operand:SI 0 "register_operand" "=r")
4094 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4096 "movs{bl|x}\t{%1, %0|%0, %1}"
4097 [(set_attr "type" "imovx")
4098 (set_attr "mode" "SI")])
4100 (define_insn "*extendqisi2_zext"
4101 [(set (match_operand:DI 0 "register_operand" "=r")
4103 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4105 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4106 [(set_attr "type" "imovx")
4107 (set_attr "mode" "SI")])
4109 (define_insn "extendqihi2"
4110 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4111 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4114 switch (get_attr_prefix_0f (insn))
4117 return "{cbtw|cbw}";
4119 return "movs{bw|x}\t{%1, %0|%0, %1}";
4122 [(set_attr "type" "imovx")
4123 (set_attr "mode" "HI")
4124 (set (attr "prefix_0f")
4125 ;; movsx is short decodable while cwtl is vector decoded.
4126 (if_then_else (and (eq_attr "cpu" "!k6")
4127 (eq_attr "alternative" "0"))
4129 (const_string "1")))
4131 (if_then_else (eq_attr "prefix_0f" "0")
4133 (const_string "1")))])
4135 ;; Conversions between float and double.
4137 ;; These are all no-ops in the model used for the 80387.
4138 ;; So just emit moves.
4140 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4142 [(set (match_operand:DF 0 "push_operand")
4143 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4145 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4146 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4149 [(set (match_operand:XF 0 "push_operand")
4150 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4152 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4153 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4154 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4156 (define_expand "extendsfdf2"
4157 [(set (match_operand:DF 0 "nonimmediate_operand")
4158 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4159 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4161 /* ??? Needed for compress_float_constant since all fp constants
4162 are TARGET_LEGITIMATE_CONSTANT_P. */
4163 if (CONST_DOUBLE_P (operands[1]))
4165 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4166 && standard_80387_constant_p (operands[1]) > 0)
4168 operands[1] = simplify_const_unary_operation
4169 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4170 emit_move_insn_1 (operands[0], operands[1]);
4173 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4177 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4179 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4181 We do the conversion post reload to avoid producing of 128bit spills
4182 that might lead to ICE on 32bit target. The sequence unlikely combine
4185 [(set (match_operand:DF 0 "register_operand")
4187 (match_operand:SF 1 "nonimmediate_operand")))]
4188 "TARGET_USE_VECTOR_FP_CONVERTS
4189 && optimize_insn_for_speed_p ()
4190 && reload_completed && SSE_REG_P (operands[0])
4191 && (!EXT_REX_SSE_REG_P (operands[0])
4192 || TARGET_AVX512VL)"
4197 (parallel [(const_int 0) (const_int 1)]))))]
4199 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4200 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4201 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4202 Try to avoid move when unpacking can be done in source. */
4203 if (REG_P (operands[1]))
4205 /* If it is unsafe to overwrite upper half of source, we need
4206 to move to destination and unpack there. */
4207 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4208 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4209 && true_regnum (operands[0]) != true_regnum (operands[1]))
4211 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4212 emit_move_insn (tmp, operands[1]);
4215 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4216 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4220 emit_insn (gen_vec_setv4sf_0 (operands[3],
4221 CONST0_RTX (V4SFmode), operands[1]));
4224 ;; It's more profitable to split and then extend in the same register.
4226 [(set (match_operand:DF 0 "register_operand")
4228 (match_operand:SF 1 "memory_operand")))]
4229 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4230 && optimize_insn_for_speed_p ()
4231 && SSE_REG_P (operands[0])"
4232 [(set (match_dup 2) (match_dup 1))
4233 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4234 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4236 (define_insn "*extendsfdf2_mixed"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4239 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4240 "TARGET_SSE2 && TARGET_SSE_MATH"
4242 switch (which_alternative)
4246 return output_387_reg_move (insn, operands);
4249 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4255 [(set_attr "type" "fmov,fmov,ssecvt")
4256 (set_attr "prefix" "orig,orig,maybe_vex")
4257 (set_attr "mode" "SF,XF,DF")
4258 (set (attr "enabled")
4259 (cond [(eq_attr "alternative" "0,1")
4260 (symbol_ref "TARGET_MIX_SSE_I387")
4262 (symbol_ref "true")))])
4264 (define_insn "*extendsfdf2_i387"
4265 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4266 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4268 "* return output_387_reg_move (insn, operands);"
4269 [(set_attr "type" "fmov")
4270 (set_attr "mode" "SF,XF")])
4272 (define_expand "extend<mode>xf2"
4273 [(set (match_operand:XF 0 "nonimmediate_operand")
4274 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4277 /* ??? Needed for compress_float_constant since all fp constants
4278 are TARGET_LEGITIMATE_CONSTANT_P. */
4279 if (CONST_DOUBLE_P (operands[1]))
4281 if (standard_80387_constant_p (operands[1]) > 0)
4283 operands[1] = simplify_const_unary_operation
4284 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4285 emit_move_insn_1 (operands[0], operands[1]);
4288 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4292 (define_insn "*extend<mode>xf2_i387"
4293 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4295 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4297 "* return output_387_reg_move (insn, operands);"
4298 [(set_attr "type" "fmov")
4299 (set_attr "mode" "<MODE>,XF")])
4301 ;; %%% This seems like bad news.
4302 ;; This cannot output into an f-reg because there is no way to be sure
4303 ;; of truncating in that case. Otherwise this is just like a simple move
4304 ;; insn. So we pretend we can output to a reg in order to get better
4305 ;; register preferencing, but we really use a stack slot.
4307 ;; Conversion from DFmode to SFmode.
4309 (define_expand "truncdfsf2"
4310 [(set (match_operand:SF 0 "nonimmediate_operand")
4312 (match_operand:DF 1 "nonimmediate_operand")))]
4313 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4315 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4317 else if (flag_unsafe_math_optimizations)
4321 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4322 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4327 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4329 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4331 We do the conversion post reload to avoid producing of 128bit spills
4332 that might lead to ICE on 32bit target. The sequence unlikely combine
4335 [(set (match_operand:SF 0 "register_operand")
4337 (match_operand:DF 1 "nonimmediate_operand")))]
4338 "TARGET_USE_VECTOR_FP_CONVERTS
4339 && optimize_insn_for_speed_p ()
4340 && reload_completed && SSE_REG_P (operands[0])
4341 && (!EXT_REX_SSE_REG_P (operands[0])
4342 || TARGET_AVX512VL)"
4345 (float_truncate:V2SF
4349 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4350 operands[3] = CONST0_RTX (V2SFmode);
4351 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4352 /* Use movsd for loading from memory, unpcklpd for registers.
4353 Try to avoid move when unpacking can be done in source, or SSE3
4354 movddup is available. */
4355 if (REG_P (operands[1]))
4358 && true_regnum (operands[0]) != true_regnum (operands[1])
4359 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4360 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4362 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4363 emit_move_insn (tmp, operands[1]);
4366 else if (!TARGET_SSE3)
4367 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4368 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4371 emit_insn (gen_sse2_loadlpd (operands[4],
4372 CONST0_RTX (V2DFmode), operands[1]));
4375 ;; It's more profitable to split and then extend in the same register.
4377 [(set (match_operand:SF 0 "register_operand")
4379 (match_operand:DF 1 "memory_operand")))]
4380 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4381 && optimize_insn_for_speed_p ()
4382 && SSE_REG_P (operands[0])"
4383 [(set (match_dup 2) (match_dup 1))
4384 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4385 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4387 (define_expand "truncdfsf2_with_temp"
4388 [(parallel [(set (match_operand:SF 0)
4389 (float_truncate:SF (match_operand:DF 1)))
4390 (clobber (match_operand:SF 2))])])
4392 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4393 ;; because nothing we do there is unsafe.
4394 (define_insn "*truncdfsf_fast_mixed"
4395 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4397 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4398 "TARGET_SSE2 && TARGET_SSE_MATH"
4400 switch (which_alternative)
4403 return output_387_reg_move (insn, operands);
4405 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4410 [(set_attr "type" "fmov,ssecvt")
4411 (set_attr "prefix" "orig,maybe_vex")
4412 (set_attr "mode" "SF")
4413 (set (attr "enabled")
4414 (cond [(eq_attr "alternative" "0")
4415 (symbol_ref "TARGET_MIX_SSE_I387
4416 && flag_unsafe_math_optimizations")
4418 (symbol_ref "true")))])
4420 (define_insn "*truncdfsf_fast_i387"
4421 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4423 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4424 "TARGET_80387 && flag_unsafe_math_optimizations"
4425 "* return output_387_reg_move (insn, operands);"
4426 [(set_attr "type" "fmov")
4427 (set_attr "mode" "SF")])
4429 (define_insn "*truncdfsf_mixed"
4430 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4432 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4433 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4434 "TARGET_MIX_SSE_I387"
4436 switch (which_alternative)
4439 return output_387_reg_move (insn, operands);
4441 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4447 [(set_attr "isa" "*,sse2,*,*,*")
4448 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4449 (set_attr "unit" "*,*,i387,i387,i387")
4450 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4451 (set_attr "mode" "SF")])
4453 (define_insn "*truncdfsf_i387"
4454 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4456 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4457 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4460 switch (which_alternative)
4463 return output_387_reg_move (insn, operands);
4469 [(set_attr "type" "fmov,multi,multi,multi")
4470 (set_attr "unit" "*,i387,i387,i387")
4471 (set_attr "mode" "SF")])
4473 (define_insn "*truncdfsf2_i387_1"
4474 [(set (match_operand:SF 0 "memory_operand" "=m")
4476 (match_operand:DF 1 "register_operand" "f")))]
4478 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4479 && !TARGET_MIX_SSE_I387"
4480 "* return output_387_reg_move (insn, operands);"
4481 [(set_attr "type" "fmov")
4482 (set_attr "mode" "SF")])
4485 [(set (match_operand:SF 0 "register_operand")
4487 (match_operand:DF 1 "fp_register_operand")))
4488 (clobber (match_operand 2))]
4490 [(set (match_dup 2) (match_dup 1))
4491 (set (match_dup 0) (match_dup 2))]
4492 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4494 ;; Conversion from XFmode to {SF,DF}mode
4496 (define_expand "truncxf<mode>2"
4497 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4498 (float_truncate:MODEF
4499 (match_operand:XF 1 "register_operand")))
4500 (clobber (match_dup 2))])]
4503 if (flag_unsafe_math_optimizations)
4505 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4506 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4507 if (reg != operands[0])
4508 emit_move_insn (operands[0], reg);
4512 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4515 (define_insn "*truncxfsf2_mixed"
4516 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4518 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4519 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4522 gcc_assert (!which_alternative);
4523 return output_387_reg_move (insn, operands);
4525 [(set_attr "type" "fmov,multi,multi,multi")
4526 (set_attr "unit" "*,i387,i387,i387")
4527 (set_attr "mode" "SF")])
4529 (define_insn "*truncxfdf2_mixed"
4530 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4532 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4533 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4536 gcc_assert (!which_alternative);
4537 return output_387_reg_move (insn, operands);
4539 [(set_attr "isa" "*,*,sse2,*")
4540 (set_attr "type" "fmov,multi,multi,multi")
4541 (set_attr "unit" "*,i387,i387,i387")
4542 (set_attr "mode" "DF")])
4544 (define_insn "truncxf<mode>2_i387_noop"
4545 [(set (match_operand:MODEF 0 "register_operand" "=f")
4546 (float_truncate:MODEF
4547 (match_operand:XF 1 "register_operand" "f")))]
4548 "TARGET_80387 && flag_unsafe_math_optimizations"
4549 "* return output_387_reg_move (insn, operands);"
4550 [(set_attr "type" "fmov")
4551 (set_attr "mode" "<MODE>")])
4553 (define_insn "*truncxf<mode>2_i387"
4554 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4555 (float_truncate:MODEF
4556 (match_operand:XF 1 "register_operand" "f")))]
4558 "* return output_387_reg_move (insn, operands);"
4559 [(set_attr "type" "fmov")
4560 (set_attr "mode" "<MODE>")])
4563 [(set (match_operand:MODEF 0 "register_operand")
4564 (float_truncate:MODEF
4565 (match_operand:XF 1 "register_operand")))
4566 (clobber (match_operand:MODEF 2 "memory_operand"))]
4567 "TARGET_80387 && reload_completed"
4568 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4569 (set (match_dup 0) (match_dup 2))])
4572 [(set (match_operand:MODEF 0 "memory_operand")
4573 (float_truncate:MODEF
4574 (match_operand:XF 1 "register_operand")))
4575 (clobber (match_operand:MODEF 2 "memory_operand"))]
4577 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4579 ;; Signed conversion to DImode.
4581 (define_expand "fix_truncxfdi2"
4582 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4583 (fix:DI (match_operand:XF 1 "register_operand")))
4584 (clobber (reg:CC FLAGS_REG))])]
4589 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4594 (define_expand "fix_trunc<mode>di2"
4595 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4596 (fix:DI (match_operand:MODEF 1 "register_operand")))
4597 (clobber (reg:CC FLAGS_REG))])]
4598 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4601 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4603 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4606 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4608 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4609 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4610 if (out != operands[0])
4611 emit_move_insn (operands[0], out);
4616 ;; Signed conversion to SImode.
4618 (define_expand "fix_truncxfsi2"
4619 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4620 (fix:SI (match_operand:XF 1 "register_operand")))
4621 (clobber (reg:CC FLAGS_REG))])]
4626 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4631 (define_expand "fix_trunc<mode>si2"
4632 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4633 (fix:SI (match_operand:MODEF 1 "register_operand")))
4634 (clobber (reg:CC FLAGS_REG))])]
4635 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4638 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4640 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4643 if (SSE_FLOAT_MODE_P (<MODE>mode))
4645 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4646 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4647 if (out != operands[0])
4648 emit_move_insn (operands[0], out);
4653 ;; Signed conversion to HImode.
4655 (define_expand "fix_trunc<mode>hi2"
4656 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4657 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4658 (clobber (reg:CC FLAGS_REG))])]
4660 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4664 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4669 ;; Unsigned conversion to SImode.
4671 (define_expand "fixuns_trunc<mode>si2"
4673 [(set (match_operand:SI 0 "register_operand")
4675 (match_operand:MODEF 1 "nonimmediate_operand")))
4677 (clobber (match_scratch:<ssevecmode> 3))
4678 (clobber (match_scratch:<ssevecmode> 4))])]
4679 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4681 machine_mode mode = <MODE>mode;
4682 machine_mode vecmode = <ssevecmode>mode;
4683 REAL_VALUE_TYPE TWO31r;
4686 if (optimize_insn_for_size_p ())
4689 real_ldexp (&TWO31r, &dconst1, 31);
4690 two31 = const_double_from_real_value (TWO31r, mode);
4691 two31 = ix86_build_const_vector (vecmode, true, two31);
4692 operands[2] = force_reg (vecmode, two31);
4695 (define_insn_and_split "*fixuns_trunc<mode>_1"
4696 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4698 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4699 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4700 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4701 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4702 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4703 && optimize_function_for_speed_p (cfun)"
4705 "&& reload_completed"
4708 ix86_split_convert_uns_si_sse (operands);
4712 ;; Unsigned conversion to HImode.
4713 ;; Without these patterns, we'll try the unsigned SI conversion which
4714 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4716 (define_expand "fixuns_trunc<mode>hi2"
4718 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4719 (set (match_operand:HI 0 "nonimmediate_operand")
4720 (subreg:HI (match_dup 2) 0))]
4721 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4722 "operands[2] = gen_reg_rtx (SImode);")
4724 ;; When SSE is available, it is always faster to use it!
4725 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4726 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4727 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4728 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4729 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4730 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4731 [(set_attr "type" "sseicvt")
4732 (set_attr "prefix" "maybe_vex")
4733 (set (attr "prefix_rex")
4735 (match_test "<SWI48:MODE>mode == DImode")
4737 (const_string "*")))
4738 (set_attr "mode" "<MODEF:MODE>")
4739 (set_attr "athlon_decode" "double,vector")
4740 (set_attr "amdfam10_decode" "double,double")
4741 (set_attr "bdver1_decode" "double,double")])
4743 ;; Avoid vector decoded forms of the instruction.
4745 [(match_scratch:MODEF 2 "x")
4746 (set (match_operand:SWI48 0 "register_operand")
4747 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4748 "TARGET_AVOID_VECTOR_DECODE
4749 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4750 && optimize_insn_for_speed_p ()"
4751 [(set (match_dup 2) (match_dup 1))
4752 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4754 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4755 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4756 (fix:SWI248x (match_operand 1 "register_operand")))]
4757 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4759 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4760 && (TARGET_64BIT || <MODE>mode != DImode))
4762 && can_create_pseudo_p ()"
4767 if (memory_operand (operands[0], VOIDmode))
4768 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4771 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4772 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4778 [(set_attr "type" "fisttp")
4779 (set_attr "mode" "<MODE>")])
4781 (define_insn "fix_trunc<mode>_i387_fisttp"
4782 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4783 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4784 (clobber (match_scratch:XF 2 "=&1f"))]
4785 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4788 && (TARGET_64BIT || <MODE>mode != DImode))
4789 && TARGET_SSE_MATH)"
4790 "* return output_fix_trunc (insn, operands, true);"
4791 [(set_attr "type" "fisttp")
4792 (set_attr "mode" "<MODE>")])
4794 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4795 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4796 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4797 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4798 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4799 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4801 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4802 && (TARGET_64BIT || <MODE>mode != DImode))
4803 && TARGET_SSE_MATH)"
4805 [(set_attr "type" "fisttp")
4806 (set_attr "mode" "<MODE>")])
4809 [(set (match_operand:SWI248x 0 "register_operand")
4810 (fix:SWI248x (match_operand 1 "register_operand")))
4811 (clobber (match_operand:SWI248x 2 "memory_operand"))
4812 (clobber (match_scratch 3))]
4814 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4815 (clobber (match_dup 3))])
4816 (set (match_dup 0) (match_dup 2))])
4819 [(set (match_operand:SWI248x 0 "memory_operand")
4820 (fix:SWI248x (match_operand 1 "register_operand")))
4821 (clobber (match_operand:SWI248x 2 "memory_operand"))
4822 (clobber (match_scratch 3))]
4824 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4825 (clobber (match_dup 3))])])
4827 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4828 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4829 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4830 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4831 ;; function in i386.c.
4832 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4833 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4834 (fix:SWI248x (match_operand 1 "register_operand")))
4835 (clobber (reg:CC FLAGS_REG))]
4836 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4839 && (TARGET_64BIT || <MODE>mode != DImode))
4840 && can_create_pseudo_p ()"
4845 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4847 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4848 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4849 if (memory_operand (operands[0], VOIDmode))
4850 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4851 operands[2], operands[3]));
4854 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4855 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4856 operands[2], operands[3],
4861 [(set_attr "type" "fistp")
4862 (set_attr "i387_cw" "trunc")
4863 (set_attr "mode" "<MODE>")])
4865 (define_insn "fix_truncdi_i387"
4866 [(set (match_operand:DI 0 "memory_operand" "=m")
4867 (fix:DI (match_operand 1 "register_operand" "f")))
4868 (use (match_operand:HI 2 "memory_operand" "m"))
4869 (use (match_operand:HI 3 "memory_operand" "m"))
4870 (clobber (match_scratch:XF 4 "=&1f"))]
4871 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4873 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4874 "* return output_fix_trunc (insn, operands, false);"
4875 [(set_attr "type" "fistp")
4876 (set_attr "i387_cw" "trunc")
4877 (set_attr "mode" "DI")])
4879 (define_insn "fix_truncdi_i387_with_temp"
4880 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4881 (fix:DI (match_operand 1 "register_operand" "f,f")))
4882 (use (match_operand:HI 2 "memory_operand" "m,m"))
4883 (use (match_operand:HI 3 "memory_operand" "m,m"))
4884 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4885 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4886 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4888 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4890 [(set_attr "type" "fistp")
4891 (set_attr "i387_cw" "trunc")
4892 (set_attr "mode" "DI")])
4895 [(set (match_operand:DI 0 "register_operand")
4896 (fix:DI (match_operand 1 "register_operand")))
4897 (use (match_operand:HI 2 "memory_operand"))
4898 (use (match_operand:HI 3 "memory_operand"))
4899 (clobber (match_operand:DI 4 "memory_operand"))
4900 (clobber (match_scratch 5))]
4902 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4905 (clobber (match_dup 5))])
4906 (set (match_dup 0) (match_dup 4))])
4909 [(set (match_operand:DI 0 "memory_operand")
4910 (fix:DI (match_operand 1 "register_operand")))
4911 (use (match_operand:HI 2 "memory_operand"))
4912 (use (match_operand:HI 3 "memory_operand"))
4913 (clobber (match_operand:DI 4 "memory_operand"))
4914 (clobber (match_scratch 5))]
4916 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4919 (clobber (match_dup 5))])])
4921 (define_insn "fix_trunc<mode>_i387"
4922 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4923 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4924 (use (match_operand:HI 2 "memory_operand" "m"))
4925 (use (match_operand:HI 3 "memory_operand" "m"))]
4926 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4928 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4929 "* return output_fix_trunc (insn, operands, false);"
4930 [(set_attr "type" "fistp")
4931 (set_attr "i387_cw" "trunc")
4932 (set_attr "mode" "<MODE>")])
4934 (define_insn "fix_trunc<mode>_i387_with_temp"
4935 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4936 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4937 (use (match_operand:HI 2 "memory_operand" "m,m"))
4938 (use (match_operand:HI 3 "memory_operand" "m,m"))
4939 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4942 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4944 [(set_attr "type" "fistp")
4945 (set_attr "i387_cw" "trunc")
4946 (set_attr "mode" "<MODE>")])
4949 [(set (match_operand:SWI24 0 "register_operand")
4950 (fix:SWI24 (match_operand 1 "register_operand")))
4951 (use (match_operand:HI 2 "memory_operand"))
4952 (use (match_operand:HI 3 "memory_operand"))
4953 (clobber (match_operand:SWI24 4 "memory_operand"))]
4955 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4957 (use (match_dup 3))])
4958 (set (match_dup 0) (match_dup 4))])
4961 [(set (match_operand:SWI24 0 "memory_operand")
4962 (fix:SWI24 (match_operand 1 "register_operand")))
4963 (use (match_operand:HI 2 "memory_operand"))
4964 (use (match_operand:HI 3 "memory_operand"))
4965 (clobber (match_operand:SWI24 4 "memory_operand"))]
4967 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4969 (use (match_dup 3))])])
4971 (define_insn "x86_fnstcw_1"
4972 [(set (match_operand:HI 0 "memory_operand" "=m")
4973 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4976 [(set (attr "length")
4977 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4978 (set_attr "mode" "HI")
4979 (set_attr "unit" "i387")
4980 (set_attr "bdver1_decode" "vector")])
4982 (define_insn "x86_fldcw_1"
4983 [(set (reg:HI FPCR_REG)
4984 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4987 [(set (attr "length")
4988 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4989 (set_attr "mode" "HI")
4990 (set_attr "unit" "i387")
4991 (set_attr "athlon_decode" "vector")
4992 (set_attr "amdfam10_decode" "vector")
4993 (set_attr "bdver1_decode" "vector")])
4995 ;; Conversion between fixed point and floating point.
4997 ;; Even though we only accept memory inputs, the backend _really_
4998 ;; wants to be able to do this between registers. Thankfully, LRA
4999 ;; will fix this up for us during register allocation.
5001 (define_insn "floathi<mode>2"
5002 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5003 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5006 || TARGET_MIX_SSE_I387)"
5008 [(set_attr "type" "fmov")
5009 (set_attr "mode" "<MODE>")
5010 (set_attr "znver1_decode" "double")
5011 (set_attr "fp_int_src" "true")])
5013 (define_insn "float<SWI48x:mode>xf2"
5014 [(set (match_operand:XF 0 "register_operand" "=f")
5015 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5018 [(set_attr "type" "fmov")
5019 (set_attr "mode" "XF")
5020 (set_attr "znver1_decode" "double")
5021 (set_attr "fp_int_src" "true")])
5023 (define_expand "float<SWI48:mode><MODEF:mode>2"
5024 [(set (match_operand:MODEF 0 "register_operand")
5025 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5026 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5028 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5029 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5031 rtx reg = gen_reg_rtx (XFmode);
5032 rtx (*insn)(rtx, rtx);
5034 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5036 if (<MODEF:MODE>mode == SFmode)
5037 insn = gen_truncxfsf2;
5038 else if (<MODEF:MODE>mode == DFmode)
5039 insn = gen_truncxfdf2;
5043 emit_insn (insn (operands[0], reg));
5048 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5049 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5051 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5052 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5055 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5056 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5057 [(set_attr "type" "fmov,sseicvt,sseicvt")
5058 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5059 (set_attr "mode" "<MODEF:MODE>")
5060 (set (attr "prefix_rex")
5062 (and (eq_attr "prefix" "maybe_vex")
5063 (match_test "<SWI48:MODE>mode == DImode"))
5065 (const_string "*")))
5066 (set_attr "unit" "i387,*,*")
5067 (set_attr "athlon_decode" "*,double,direct")
5068 (set_attr "amdfam10_decode" "*,vector,double")
5069 (set_attr "bdver1_decode" "*,double,direct")
5070 (set_attr "znver1_decode" "double,*,*")
5071 (set_attr "fp_int_src" "true")
5072 (set (attr "enabled")
5073 (cond [(eq_attr "alternative" "0")
5074 (symbol_ref "TARGET_MIX_SSE_I387
5075 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5078 (symbol_ref "true")))
5079 (set (attr "preferred_for_speed")
5080 (cond [(eq_attr "alternative" "1")
5081 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5082 (symbol_ref "true")))])
5084 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5085 [(set (match_operand:MODEF 0 "register_operand" "=f")
5086 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5087 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5089 [(set_attr "type" "fmov")
5090 (set_attr "mode" "<MODEF:MODE>")
5091 (set_attr "znver1_decode" "double")
5092 (set_attr "fp_int_src" "true")])
5094 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5095 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5096 ;; alternative in sse2_loadld.
5098 [(set (match_operand:MODEF 0 "register_operand")
5099 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5100 "TARGET_SSE2 && TARGET_SSE_MATH
5101 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5102 && reload_completed && SSE_REG_P (operands[0])
5103 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5104 && (!EXT_REX_SSE_REG_P (operands[0])
5105 || TARGET_AVX512VL)"
5108 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5110 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5112 emit_insn (gen_sse2_loadld (operands[4],
5113 CONST0_RTX (V4SImode), operands[1]));
5115 if (<ssevecmode>mode == V4SFmode)
5116 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5118 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5122 ;; Avoid partial SSE register dependency stalls
5124 [(set (match_operand:MODEF 0 "register_operand")
5125 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5126 "TARGET_SSE2 && TARGET_SSE_MATH
5127 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5128 && optimize_function_for_speed_p (cfun)
5129 && reload_completed && SSE_REG_P (operands[0])
5130 && (!EXT_REX_SSE_REG_P (operands[0])
5131 || TARGET_AVX512VL)"
5134 const machine_mode vmode = <MODEF:ssevecmode>mode;
5135 const machine_mode mode = <MODEF:MODE>mode;
5136 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5138 emit_move_insn (op0, CONST0_RTX (vmode));
5140 t = gen_rtx_FLOAT (mode, operands[1]);
5141 t = gen_rtx_VEC_DUPLICATE (vmode, t);
5142 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5143 emit_insn (gen_rtx_SET (op0, t));
5147 ;; Break partial reg stall for cvtsd2ss.
5150 [(set (match_operand:SF 0 "register_operand")
5152 (match_operand:DF 1 "nonimmediate_operand")))]
5153 "TARGET_SSE2 && TARGET_SSE_MATH
5154 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5155 && optimize_function_for_speed_p (cfun)
5156 && SSE_REG_P (operands[0])
5157 && (!SSE_REG_P (operands[1])
5158 || REGNO (operands[0]) != REGNO (operands[1]))
5159 && (!EXT_REX_SSE_REG_P (operands[0])
5160 || TARGET_AVX512VL)"
5164 (float_truncate:V2SF
5169 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5171 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5173 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5176 ;; Break partial reg stall for cvtss2sd.
5179 [(set (match_operand:DF 0 "register_operand")
5181 (match_operand:SF 1 "nonimmediate_operand")))]
5182 "TARGET_SSE2 && TARGET_SSE_MATH
5183 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5184 && optimize_function_for_speed_p (cfun)
5185 && SSE_REG_P (operands[0])
5186 && (!SSE_REG_P (operands[1])
5187 || REGNO (operands[0]) != REGNO (operands[1]))
5188 && (!EXT_REX_SSE_REG_P (operands[0])
5189 || TARGET_AVX512VL)"
5195 (parallel [(const_int 0) (const_int 1)])))
5199 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5201 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5203 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5206 ;; Avoid store forwarding (partial memory) stall penalty
5207 ;; by passing DImode value through XMM registers. */
5209 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5210 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5212 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5213 (clobber (match_scratch:V4SI 3 "=X,x"))
5214 (clobber (match_scratch:V4SI 4 "=X,x"))
5215 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5216 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5217 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5218 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5220 [(set_attr "type" "multi")
5221 (set_attr "mode" "<X87MODEF:MODE>")
5222 (set_attr "unit" "i387")
5223 (set_attr "fp_int_src" "true")])
5226 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5227 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5228 (clobber (match_scratch:V4SI 3))
5229 (clobber (match_scratch:V4SI 4))
5230 (clobber (match_operand:DI 2 "memory_operand"))]
5231 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5232 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5233 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5234 && reload_completed"
5235 [(set (match_dup 2) (match_dup 3))
5236 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5238 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5239 Assemble the 64-bit DImode value in an xmm register. */
5240 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5241 gen_lowpart (SImode, operands[1])));
5242 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5243 gen_highpart (SImode, operands[1])));
5244 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5247 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5251 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5252 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5253 (clobber (match_scratch:V4SI 3))
5254 (clobber (match_scratch:V4SI 4))
5255 (clobber (match_operand:DI 2 "memory_operand"))]
5256 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5257 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5258 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5259 && reload_completed"
5260 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5262 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5263 [(set (match_operand:MODEF 0 "register_operand")
5264 (unsigned_float:MODEF
5265 (match_operand:SWI12 1 "nonimmediate_operand")))]
5267 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5269 operands[1] = convert_to_mode (SImode, operands[1], 1);
5270 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5274 ;; Avoid store forwarding (partial memory) stall penalty by extending
5275 ;; SImode value to DImode through XMM register instead of pushing two
5276 ;; SImode values to stack. Also note that fild loads from memory only.
5278 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5280 (unsigned_float:X87MODEF
5281 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5282 (clobber (match_scratch:DI 3 "=x"))
5283 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5285 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5288 "&& reload_completed"
5289 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5290 (set (match_dup 2) (match_dup 3))
5292 (float:X87MODEF (match_dup 2)))]
5294 [(set_attr "type" "multi")
5295 (set_attr "mode" "<MODE>")])
5297 (define_expand "floatunssi<mode>2"
5299 [(set (match_operand:X87MODEF 0 "register_operand")
5300 (unsigned_float:X87MODEF
5301 (match_operand:SI 1 "nonimmediate_operand")))
5302 (clobber (match_scratch:DI 3))
5303 (clobber (match_dup 2))])]
5305 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5306 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5307 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5309 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5311 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5315 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5318 (define_expand "floatunsdisf2"
5319 [(use (match_operand:SF 0 "register_operand"))
5320 (use (match_operand:DI 1 "nonimmediate_operand"))]
5321 "TARGET_64BIT && TARGET_SSE_MATH"
5322 "x86_emit_floatuns (operands); DONE;")
5324 (define_expand "floatunsdidf2"
5325 [(use (match_operand:DF 0 "register_operand"))
5326 (use (match_operand:DI 1 "nonimmediate_operand"))]
5327 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5328 && TARGET_SSE2 && TARGET_SSE_MATH"
5331 x86_emit_floatuns (operands);
5333 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5337 ;; Load effective address instructions
5339 (define_insn_and_split "*lea<mode>"
5340 [(set (match_operand:SWI48 0 "register_operand" "=r")
5341 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5344 if (SImode_address_operand (operands[1], VOIDmode))
5346 gcc_assert (TARGET_64BIT);
5347 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5350 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5352 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5355 machine_mode mode = <MODE>mode;
5358 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5359 change operands[] array behind our back. */
5360 pat = PATTERN (curr_insn);
5362 operands[0] = SET_DEST (pat);
5363 operands[1] = SET_SRC (pat);
5365 /* Emit all operations in SImode for zero-extended addresses. */
5366 if (SImode_address_operand (operands[1], VOIDmode))
5369 ix86_split_lea_for_addr (curr_insn, operands, mode);
5371 /* Zero-extend return register to DImode for zero-extended addresses. */
5372 if (mode != <MODE>mode)
5373 emit_insn (gen_zero_extendsidi2
5374 (operands[0], gen_lowpart (mode, operands[0])));
5378 [(set_attr "type" "lea")
5381 (match_operand 1 "SImode_address_operand")
5383 (const_string "<MODE>")))])
5387 (define_expand "add<mode>3"
5388 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5389 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5390 (match_operand:SDWIM 2 "<general_operand>")))]
5392 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5394 (define_insn_and_split "*add<dwi>3_doubleword"
5395 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5397 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5398 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5399 (clobber (reg:CC FLAGS_REG))]
5400 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5403 [(parallel [(set (reg:CCC FLAGS_REG)
5405 (plus:DWIH (match_dup 1) (match_dup 2))
5408 (plus:DWIH (match_dup 1) (match_dup 2)))])
5409 (parallel [(set (match_dup 3)
5412 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5415 (clobber (reg:CC FLAGS_REG))])]
5416 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5418 (define_insn "*add<mode>_1"
5419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5421 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5422 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5423 (clobber (reg:CC FLAGS_REG))]
5424 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5426 switch (get_attr_type (insn))
5432 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5433 if (operands[2] == const1_rtx)
5434 return "inc{<imodesuffix>}\t%0";
5437 gcc_assert (operands[2] == constm1_rtx);
5438 return "dec{<imodesuffix>}\t%0";
5442 /* For most processors, ADD is faster than LEA. This alternative
5443 was added to use ADD as much as possible. */
5444 if (which_alternative == 2)
5445 std::swap (operands[1], operands[2]);
5447 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5448 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5449 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5451 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5455 (cond [(eq_attr "alternative" "3")
5456 (const_string "lea")
5457 (match_operand:SWI48 2 "incdec_operand")
5458 (const_string "incdec")
5460 (const_string "alu")))
5461 (set (attr "length_immediate")
5463 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5465 (const_string "*")))
5466 (set_attr "mode" "<MODE>")])
5468 ;; It may seem that nonimmediate operand is proper one for operand 1.
5469 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5470 ;; we take care in ix86_binary_operator_ok to not allow two memory
5471 ;; operands so proper swapping will be done in reload. This allow
5472 ;; patterns constructed from addsi_1 to match.
5474 (define_insn "addsi_1_zext"
5475 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5477 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5478 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5479 (clobber (reg:CC FLAGS_REG))]
5480 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5482 switch (get_attr_type (insn))
5488 if (operands[2] == const1_rtx)
5489 return "inc{l}\t%k0";
5492 gcc_assert (operands[2] == constm1_rtx);
5493 return "dec{l}\t%k0";
5497 /* For most processors, ADD is faster than LEA. This alternative
5498 was added to use ADD as much as possible. */
5499 if (which_alternative == 1)
5500 std::swap (operands[1], operands[2]);
5502 if (x86_maybe_negate_const_int (&operands[2], SImode))
5503 return "sub{l}\t{%2, %k0|%k0, %2}";
5505 return "add{l}\t{%2, %k0|%k0, %2}";
5509 (cond [(eq_attr "alternative" "2")
5510 (const_string "lea")
5511 (match_operand:SI 2 "incdec_operand")
5512 (const_string "incdec")
5514 (const_string "alu")))
5515 (set (attr "length_immediate")
5517 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5519 (const_string "*")))
5520 (set_attr "mode" "SI")])
5522 (define_insn "*addhi_1"
5523 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5524 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5525 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5526 (clobber (reg:CC FLAGS_REG))]
5527 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5529 switch (get_attr_type (insn))
5535 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5536 if (operands[2] == const1_rtx)
5537 return "inc{w}\t%0";
5540 gcc_assert (operands[2] == constm1_rtx);
5541 return "dec{w}\t%0";
5545 /* For most processors, ADD is faster than LEA. This alternative
5546 was added to use ADD as much as possible. */
5547 if (which_alternative == 2)
5548 std::swap (operands[1], operands[2]);
5550 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5551 if (x86_maybe_negate_const_int (&operands[2], HImode))
5552 return "sub{w}\t{%2, %0|%0, %2}";
5554 return "add{w}\t{%2, %0|%0, %2}";
5558 (cond [(eq_attr "alternative" "3")
5559 (const_string "lea")
5560 (match_operand:HI 2 "incdec_operand")
5561 (const_string "incdec")
5563 (const_string "alu")))
5564 (set (attr "length_immediate")
5566 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5568 (const_string "*")))
5569 (set_attr "mode" "HI,HI,HI,SI")])
5571 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5572 (define_insn "*addqi_1"
5573 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5574 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5575 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5576 (clobber (reg:CC FLAGS_REG))]
5577 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5579 bool widen = (which_alternative == 3 || which_alternative == 4);
5581 switch (get_attr_type (insn))
5587 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5588 if (operands[2] == const1_rtx)
5589 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5592 gcc_assert (operands[2] == constm1_rtx);
5593 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5597 /* For most processors, ADD is faster than LEA. These alternatives
5598 were added to use ADD as much as possible. */
5599 if (which_alternative == 2 || which_alternative == 4)
5600 std::swap (operands[1], operands[2]);
5602 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5603 if (x86_maybe_negate_const_int (&operands[2], QImode))
5606 return "sub{l}\t{%2, %k0|%k0, %2}";
5608 return "sub{b}\t{%2, %0|%0, %2}";
5611 return "add{l}\t{%k2, %k0|%k0, %k2}";
5613 return "add{b}\t{%2, %0|%0, %2}";
5617 (cond [(eq_attr "alternative" "5")
5618 (const_string "lea")
5619 (match_operand:QI 2 "incdec_operand")
5620 (const_string "incdec")
5622 (const_string "alu")))
5623 (set (attr "length_immediate")
5625 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5627 (const_string "*")))
5628 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5630 (define_insn "*addqi_1_slp"
5631 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5632 (plus:QI (match_dup 0)
5633 (match_operand:QI 1 "general_operand" "qn,qm")))
5634 (clobber (reg:CC FLAGS_REG))]
5635 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5636 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5638 switch (get_attr_type (insn))
5641 if (operands[1] == const1_rtx)
5642 return "inc{b}\t%0";
5645 gcc_assert (operands[1] == constm1_rtx);
5646 return "dec{b}\t%0";
5650 if (x86_maybe_negate_const_int (&operands[1], QImode))
5651 return "sub{b}\t{%1, %0|%0, %1}";
5653 return "add{b}\t{%1, %0|%0, %1}";
5657 (if_then_else (match_operand:QI 1 "incdec_operand")
5658 (const_string "incdec")
5659 (const_string "alu1")))
5660 (set (attr "memory")
5661 (if_then_else (match_operand 1 "memory_operand")
5662 (const_string "load")
5663 (const_string "none")))
5664 (set_attr "mode" "QI")])
5666 ;; Split non destructive adds if we cannot use lea.
5668 [(set (match_operand:SWI48 0 "register_operand")
5669 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5670 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5671 (clobber (reg:CC FLAGS_REG))]
5672 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5673 [(set (match_dup 0) (match_dup 1))
5674 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5675 (clobber (reg:CC FLAGS_REG))])])
5677 ;; Convert add to the lea pattern to avoid flags dependency.
5679 [(set (match_operand:SWI 0 "register_operand")
5680 (plus:SWI (match_operand:SWI 1 "register_operand")
5681 (match_operand:SWI 2 "<nonmemory_operand>")))
5682 (clobber (reg:CC FLAGS_REG))]
5683 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5686 machine_mode mode = <MODE>mode;
5689 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5692 operands[0] = gen_lowpart (mode, operands[0]);
5693 operands[1] = gen_lowpart (mode, operands[1]);
5694 operands[2] = gen_lowpart (mode, operands[2]);
5697 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5699 emit_insn (gen_rtx_SET (operands[0], pat));
5703 ;; Split non destructive adds if we cannot use lea.
5705 [(set (match_operand:DI 0 "register_operand")
5707 (plus:SI (match_operand:SI 1 "register_operand")
5708 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5709 (clobber (reg:CC FLAGS_REG))]
5711 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5712 [(set (match_dup 3) (match_dup 1))
5713 (parallel [(set (match_dup 0)
5714 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5715 (clobber (reg:CC FLAGS_REG))])]
5716 "operands[3] = gen_lowpart (SImode, operands[0]);")
5718 ;; Convert add to the lea pattern to avoid flags dependency.
5720 [(set (match_operand:DI 0 "register_operand")
5722 (plus:SI (match_operand:SI 1 "register_operand")
5723 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5724 (clobber (reg:CC FLAGS_REG))]
5725 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5727 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5729 (define_insn "*add<mode>_2"
5730 [(set (reg FLAGS_REG)
5733 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5734 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5736 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5737 (plus:SWI (match_dup 1) (match_dup 2)))]
5738 "ix86_match_ccmode (insn, CCGOCmode)
5739 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5741 switch (get_attr_type (insn))
5744 if (operands[2] == const1_rtx)
5745 return "inc{<imodesuffix>}\t%0";
5748 gcc_assert (operands[2] == constm1_rtx);
5749 return "dec{<imodesuffix>}\t%0";
5753 if (which_alternative == 2)
5754 std::swap (operands[1], operands[2]);
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5758 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5760 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5764 (if_then_else (match_operand:SWI 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" "<MODE>")])
5774 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5775 (define_insn "*addsi_2_zext"
5776 [(set (reg FLAGS_REG)
5778 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5779 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5781 (set (match_operand:DI 0 "register_operand" "=r,r")
5782 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5783 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5784 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5786 switch (get_attr_type (insn))
5789 if (operands[2] == const1_rtx)
5790 return "inc{l}\t%k0";
5793 gcc_assert (operands[2] == constm1_rtx);
5794 return "dec{l}\t%k0";
5798 if (which_alternative == 1)
5799 std::swap (operands[1], operands[2]);
5801 if (x86_maybe_negate_const_int (&operands[2], SImode))
5802 return "sub{l}\t{%2, %k0|%k0, %2}";
5804 return "add{l}\t{%2, %k0|%k0, %2}";
5808 (if_then_else (match_operand:SI 2 "incdec_operand")
5809 (const_string "incdec")
5810 (const_string "alu")))
5811 (set (attr "length_immediate")
5813 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5815 (const_string "*")))
5816 (set_attr "mode" "SI")])
5818 (define_insn "*add<mode>_3"
5819 [(set (reg FLAGS_REG)
5821 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5822 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5823 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5824 "ix86_match_ccmode (insn, CCZmode)
5825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5827 switch (get_attr_type (insn))
5830 if (operands[2] == const1_rtx)
5831 return "inc{<imodesuffix>}\t%0";
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{<imodesuffix>}\t%0";
5839 if (which_alternative == 1)
5840 std::swap (operands[1], operands[2]);
5842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5843 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5844 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5846 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5850 (if_then_else (match_operand:SWI 2 "incdec_operand")
5851 (const_string "incdec")
5852 (const_string "alu")))
5853 (set (attr "length_immediate")
5855 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5857 (const_string "*")))
5858 (set_attr "mode" "<MODE>")])
5860 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5861 (define_insn "*addsi_3_zext"
5862 [(set (reg FLAGS_REG)
5864 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5865 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5866 (set (match_operand:DI 0 "register_operand" "=r,r")
5867 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5869 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5871 switch (get_attr_type (insn))
5874 if (operands[2] == const1_rtx)
5875 return "inc{l}\t%k0";
5878 gcc_assert (operands[2] == constm1_rtx);
5879 return "dec{l}\t%k0";
5883 if (which_alternative == 1)
5884 std::swap (operands[1], operands[2]);
5886 if (x86_maybe_negate_const_int (&operands[2], SImode))
5887 return "sub{l}\t{%2, %k0|%k0, %2}";
5889 return "add{l}\t{%2, %k0|%k0, %2}";
5893 (if_then_else (match_operand:SI 2 "incdec_operand")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set (attr "length_immediate")
5898 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5900 (const_string "*")))
5901 (set_attr "mode" "SI")])
5903 ; For comparisons against 1, -1 and 128, we may generate better code
5904 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5905 ; is matched then. We can't accept general immediate, because for
5906 ; case of overflows, the result is messed up.
5907 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5908 ; only for comparisons not depending on it.
5910 (define_insn "*adddi_4"
5911 [(set (reg FLAGS_REG)
5913 (match_operand:DI 1 "nonimmediate_operand" "0")
5914 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5915 (clobber (match_scratch:DI 0 "=rm"))]
5917 && ix86_match_ccmode (insn, CCGCmode)"
5919 switch (get_attr_type (insn))
5922 if (operands[2] == constm1_rtx)
5923 return "inc{q}\t%0";
5926 gcc_assert (operands[2] == const1_rtx);
5927 return "dec{q}\t%0";
5931 if (x86_maybe_negate_const_int (&operands[2], DImode))
5932 return "add{q}\t{%2, %0|%0, %2}";
5934 return "sub{q}\t{%2, %0|%0, %2}";
5938 (if_then_else (match_operand:DI 2 "incdec_operand")
5939 (const_string "incdec")
5940 (const_string "alu")))
5941 (set (attr "length_immediate")
5943 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5945 (const_string "*")))
5946 (set_attr "mode" "DI")])
5948 ; For comparisons against 1, -1 and 128, we may generate better code
5949 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5950 ; is matched then. We can't accept general immediate, because for
5951 ; case of overflows, the result is messed up.
5952 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5953 ; only for comparisons not depending on it.
5955 (define_insn "*add<mode>_4"
5956 [(set (reg FLAGS_REG)
5958 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5959 (match_operand:SWI124 2 "const_int_operand" "n")))
5960 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5961 "ix86_match_ccmode (insn, CCGCmode)"
5963 switch (get_attr_type (insn))
5966 if (operands[2] == constm1_rtx)
5967 return "inc{<imodesuffix>}\t%0";
5970 gcc_assert (operands[2] == const1_rtx);
5971 return "dec{<imodesuffix>}\t%0";
5975 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5976 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5978 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5982 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5983 (const_string "incdec")
5984 (const_string "alu")))
5985 (set (attr "length_immediate")
5987 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5989 (const_string "*")))
5990 (set_attr "mode" "<MODE>")])
5992 (define_insn "*add<mode>_5"
5993 [(set (reg FLAGS_REG)
5996 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5997 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5999 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6000 "ix86_match_ccmode (insn, CCGOCmode)
6001 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6003 switch (get_attr_type (insn))
6006 if (operands[2] == const1_rtx)
6007 return "inc{<imodesuffix>}\t%0";
6010 gcc_assert (operands[2] == constm1_rtx);
6011 return "dec{<imodesuffix>}\t%0";
6015 if (which_alternative == 1)
6016 std::swap (operands[1], operands[2]);
6018 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6019 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6020 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6022 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6026 (if_then_else (match_operand:SWI 2 "incdec_operand")
6027 (const_string "incdec")
6028 (const_string "alu")))
6029 (set (attr "length_immediate")
6031 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6033 (const_string "*")))
6034 (set_attr "mode" "<MODE>")])
6036 (define_insn "addqi_ext_1"
6037 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6042 (match_operand 1 "ext_register_operand" "0,0")
6045 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6046 (clobber (reg:CC FLAGS_REG))]
6049 switch (get_attr_type (insn))
6052 if (operands[2] == const1_rtx)
6053 return "inc{b}\t%h0";
6056 gcc_assert (operands[2] == constm1_rtx);
6057 return "dec{b}\t%h0";
6061 return "add{b}\t{%2, %h0|%h0, %2}";
6064 [(set_attr "isa" "*,nox64")
6066 (if_then_else (match_operand:QI 2 "incdec_operand")
6067 (const_string "incdec")
6068 (const_string "alu")))
6069 (set_attr "modrm" "1")
6070 (set_attr "mode" "QI")])
6072 (define_insn "*addqi_ext_2"
6073 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6078 (match_operand 1 "ext_register_operand" "%0")
6082 (match_operand 2 "ext_register_operand" "Q")
6085 (clobber (reg:CC FLAGS_REG))]
6087 "add{b}\t{%h2, %h0|%h0, %h2}"
6088 [(set_attr "type" "alu")
6089 (set_attr "mode" "QI")])
6091 ;; Add with jump on overflow.
6092 (define_expand "addv<mode>4"
6093 [(parallel [(set (reg:CCO FLAGS_REG)
6096 (match_operand:SWI 1 "nonimmediate_operand"))
6099 (plus:SWI (match_dup 1)
6100 (match_operand:SWI 2
6101 "<general_operand>")))))
6102 (set (match_operand:SWI 0 "register_operand")
6103 (plus:SWI (match_dup 1) (match_dup 2)))])
6104 (set (pc) (if_then_else
6105 (eq (reg:CCO FLAGS_REG) (const_int 0))
6106 (label_ref (match_operand 3))
6110 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6111 if (CONST_INT_P (operands[2]))
6112 operands[4] = operands[2];
6114 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6117 (define_insn "*addv<mode>4"
6118 [(set (reg:CCO FLAGS_REG)
6121 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6123 (match_operand:SWI 2 "<general_sext_operand>"
6126 (plus:SWI (match_dup 1) (match_dup 2)))))
6127 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6128 (plus:SWI (match_dup 1) (match_dup 2)))]
6129 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6130 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6131 [(set_attr "type" "alu")
6132 (set_attr "mode" "<MODE>")])
6134 (define_insn "*addv<mode>4_1"
6135 [(set (reg:CCO FLAGS_REG)
6138 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6139 (match_operand:<DWI> 3 "const_int_operand" "i"))
6141 (plus:SWI (match_dup 1)
6142 (match_operand:SWI 2 "x86_64_immediate_operand"
6144 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6145 (plus:SWI (match_dup 1) (match_dup 2)))]
6146 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6147 && CONST_INT_P (operands[2])
6148 && INTVAL (operands[2]) == INTVAL (operands[3])"
6149 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6150 [(set_attr "type" "alu")
6151 (set_attr "mode" "<MODE>")
6152 (set (attr "length_immediate")
6153 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6155 (match_test "<MODE_SIZE> == 8")
6157 (const_string "<MODE_SIZE>")))])
6159 (define_expand "uaddv<mode>4"
6160 [(parallel [(set (reg:CCC FLAGS_REG)
6163 (match_operand:SWI 1 "nonimmediate_operand")
6164 (match_operand:SWI 2 "<general_operand>"))
6166 (set (match_operand:SWI 0 "register_operand")
6167 (plus:SWI (match_dup 1) (match_dup 2)))])
6168 (set (pc) (if_then_else
6169 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6170 (label_ref (match_operand 3))
6173 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6175 ;; The lea patterns for modes less than 32 bits need to be matched by
6176 ;; several insns converted to real lea by splitters.
6178 (define_insn_and_split "*lea_general_1"
6179 [(set (match_operand 0 "register_operand" "=r")
6180 (plus (plus (match_operand 1 "index_register_operand" "l")
6181 (match_operand 2 "register_operand" "r"))
6182 (match_operand 3 "immediate_operand" "i")))]
6183 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6184 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6185 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6186 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6187 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6188 || GET_MODE (operands[3]) == VOIDmode)"
6190 "&& reload_completed"
6193 machine_mode mode = SImode;
6196 operands[0] = gen_lowpart (mode, operands[0]);
6197 operands[1] = gen_lowpart (mode, operands[1]);
6198 operands[2] = gen_lowpart (mode, operands[2]);
6199 operands[3] = gen_lowpart (mode, operands[3]);
6201 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6204 emit_insn (gen_rtx_SET (operands[0], pat));
6207 [(set_attr "type" "lea")
6208 (set_attr "mode" "SI")])
6210 (define_insn_and_split "*lea_general_2"
6211 [(set (match_operand 0 "register_operand" "=r")
6212 (plus (mult (match_operand 1 "index_register_operand" "l")
6213 (match_operand 2 "const248_operand" "n"))
6214 (match_operand 3 "nonmemory_operand" "ri")))]
6215 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6217 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6218 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6219 || GET_MODE (operands[3]) == VOIDmode)"
6221 "&& reload_completed"
6224 machine_mode mode = SImode;
6227 operands[0] = gen_lowpart (mode, operands[0]);
6228 operands[1] = gen_lowpart (mode, operands[1]);
6229 operands[3] = gen_lowpart (mode, operands[3]);
6231 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6234 emit_insn (gen_rtx_SET (operands[0], pat));
6237 [(set_attr "type" "lea")
6238 (set_attr "mode" "SI")])
6240 (define_insn_and_split "*lea_general_3"
6241 [(set (match_operand 0 "register_operand" "=r")
6242 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6243 (match_operand 2 "const248_operand" "n"))
6244 (match_operand 3 "register_operand" "r"))
6245 (match_operand 4 "immediate_operand" "i")))]
6246 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6247 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6248 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6249 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6251 "&& reload_completed"
6254 machine_mode mode = SImode;
6257 operands[0] = gen_lowpart (mode, operands[0]);
6258 operands[1] = gen_lowpart (mode, operands[1]);
6259 operands[3] = gen_lowpart (mode, operands[3]);
6260 operands[4] = gen_lowpart (mode, operands[4]);
6262 pat = gen_rtx_PLUS (mode,
6264 gen_rtx_MULT (mode, operands[1],
6269 emit_insn (gen_rtx_SET (operands[0], pat));
6272 [(set_attr "type" "lea")
6273 (set_attr "mode" "SI")])
6275 (define_insn_and_split "*lea_general_4"
6276 [(set (match_operand 0 "register_operand" "=r")
6278 (match_operand 1 "index_register_operand" "l")
6279 (match_operand 2 "const_int_operand" "n"))
6280 (match_operand 3 "const_int_operand" "n")))]
6281 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6282 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6283 || GET_MODE (operands[0]) == SImode
6284 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6285 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6286 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6287 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6288 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6290 "&& reload_completed"
6293 machine_mode mode = GET_MODE (operands[0]);
6296 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6299 operands[0] = gen_lowpart (mode, operands[0]);
6300 operands[1] = gen_lowpart (mode, operands[1]);
6303 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6305 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6306 INTVAL (operands[3]));
6308 emit_insn (gen_rtx_SET (operands[0], pat));
6311 [(set_attr "type" "lea")
6313 (if_then_else (match_operand:DI 0)
6315 (const_string "SI")))])
6317 ;; Subtract instructions
6319 (define_expand "sub<mode>3"
6320 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6321 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6322 (match_operand:SDWIM 2 "<general_operand>")))]
6324 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6326 (define_insn_and_split "*sub<dwi>3_doubleword"
6327 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6329 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6330 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6331 (clobber (reg:CC FLAGS_REG))]
6332 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6335 [(parallel [(set (reg:CC FLAGS_REG)
6336 (compare:CC (match_dup 1) (match_dup 2)))
6338 (minus:DWIH (match_dup 1) (match_dup 2)))])
6339 (parallel [(set (match_dup 3)
6343 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6345 (clobber (reg:CC FLAGS_REG))])]
6346 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6348 (define_insn "*sub<mode>_1"
6349 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6351 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6352 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6353 (clobber (reg:CC FLAGS_REG))]
6354 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6355 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6356 [(set_attr "type" "alu")
6357 (set_attr "mode" "<MODE>")])
6359 (define_insn "*subsi_1_zext"
6360 [(set (match_operand:DI 0 "register_operand" "=r")
6362 (minus:SI (match_operand:SI 1 "register_operand" "0")
6363 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6364 (clobber (reg:CC FLAGS_REG))]
6365 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6366 "sub{l}\t{%2, %k0|%k0, %2}"
6367 [(set_attr "type" "alu")
6368 (set_attr "mode" "SI")])
6370 (define_insn "*subqi_1_slp"
6371 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6372 (minus:QI (match_dup 0)
6373 (match_operand:QI 1 "general_operand" "qn,qm")))
6374 (clobber (reg:CC FLAGS_REG))]
6375 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6376 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6377 "sub{b}\t{%1, %0|%0, %1}"
6378 [(set_attr "type" "alu1")
6379 (set_attr "mode" "QI")])
6381 (define_insn "*sub<mode>_2"
6382 [(set (reg FLAGS_REG)
6385 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6386 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6388 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6389 (minus:SWI (match_dup 1) (match_dup 2)))]
6390 "ix86_match_ccmode (insn, CCGOCmode)
6391 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6392 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6393 [(set_attr "type" "alu")
6394 (set_attr "mode" "<MODE>")])
6396 (define_insn "*subsi_2_zext"
6397 [(set (reg FLAGS_REG)
6399 (minus:SI (match_operand:SI 1 "register_operand" "0")
6400 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6402 (set (match_operand:DI 0 "register_operand" "=r")
6404 (minus:SI (match_dup 1)
6406 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6407 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6408 "sub{l}\t{%2, %k0|%k0, %2}"
6409 [(set_attr "type" "alu")
6410 (set_attr "mode" "SI")])
6412 ;; Subtract with jump on overflow.
6413 (define_expand "subv<mode>4"
6414 [(parallel [(set (reg:CCO FLAGS_REG)
6415 (eq:CCO (minus:<DWI>
6417 (match_operand:SWI 1 "nonimmediate_operand"))
6420 (minus:SWI (match_dup 1)
6421 (match_operand:SWI 2
6422 "<general_operand>")))))
6423 (set (match_operand:SWI 0 "register_operand")
6424 (minus:SWI (match_dup 1) (match_dup 2)))])
6425 (set (pc) (if_then_else
6426 (eq (reg:CCO FLAGS_REG) (const_int 0))
6427 (label_ref (match_operand 3))
6431 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6432 if (CONST_INT_P (operands[2]))
6433 operands[4] = operands[2];
6435 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6438 (define_insn "*subv<mode>4"
6439 [(set (reg:CCO FLAGS_REG)
6440 (eq:CCO (minus:<DWI>
6442 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6444 (match_operand:SWI 2 "<general_sext_operand>"
6447 (minus:SWI (match_dup 1) (match_dup 2)))))
6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (minus:SWI (match_dup 1) (match_dup 2)))]
6450 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6451 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6452 [(set_attr "type" "alu")
6453 (set_attr "mode" "<MODE>")])
6455 (define_insn "*subv<mode>4_1"
6456 [(set (reg:CCO FLAGS_REG)
6457 (eq:CCO (minus:<DWI>
6459 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6460 (match_operand:<DWI> 3 "const_int_operand" "i"))
6462 (minus:SWI (match_dup 1)
6463 (match_operand:SWI 2 "x86_64_immediate_operand"
6465 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6466 (minus:SWI (match_dup 1) (match_dup 2)))]
6467 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6468 && CONST_INT_P (operands[2])
6469 && INTVAL (operands[2]) == INTVAL (operands[3])"
6470 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6471 [(set_attr "type" "alu")
6472 (set_attr "mode" "<MODE>")
6473 (set (attr "length_immediate")
6474 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6476 (match_test "<MODE_SIZE> == 8")
6478 (const_string "<MODE_SIZE>")))])
6480 (define_expand "usubv<mode>4"
6481 [(parallel [(set (reg:CC FLAGS_REG)
6483 (match_operand:SWI 1 "nonimmediate_operand")
6484 (match_operand:SWI 2 "<general_operand>")))
6485 (set (match_operand:SWI 0 "register_operand")
6486 (minus:SWI (match_dup 1) (match_dup 2)))])
6487 (set (pc) (if_then_else
6488 (ltu (reg:CC FLAGS_REG) (const_int 0))
6489 (label_ref (match_operand 3))
6492 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6494 (define_insn "*sub<mode>_3"
6495 [(set (reg FLAGS_REG)
6496 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6497 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6499 (minus:SWI (match_dup 1) (match_dup 2)))]
6500 "ix86_match_ccmode (insn, CCmode)
6501 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6502 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6503 [(set_attr "type" "alu")
6504 (set_attr "mode" "<MODE>")])
6506 (define_insn "*subsi_3_zext"
6507 [(set (reg FLAGS_REG)
6508 (compare (match_operand:SI 1 "register_operand" "0")
6509 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6510 (set (match_operand:DI 0 "register_operand" "=r")
6512 (minus:SI (match_dup 1)
6514 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6515 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516 "sub{l}\t{%2, %1|%1, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "mode" "SI")])
6520 ;; Add with carry and subtract with borrow
6522 (define_insn "add<mode>3_carry"
6523 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6526 (match_operator:SWI 4 "ix86_carry_flag_operator"
6527 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6528 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6529 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6532 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "use_carry" "1")
6535 (set_attr "pent_pair" "pu")
6536 (set_attr "mode" "<MODE>")])
6538 (define_insn "*addsi3_carry_zext"
6539 [(set (match_operand:DI 0 "register_operand" "=r")
6542 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6543 [(reg FLAGS_REG) (const_int 0)])
6544 (match_operand:SI 1 "register_operand" "%0"))
6545 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6546 (clobber (reg:CC FLAGS_REG))]
6547 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6548 "adc{l}\t{%2, %k0|%k0, %2}"
6549 [(set_attr "type" "alu")
6550 (set_attr "use_carry" "1")
6551 (set_attr "pent_pair" "pu")
6552 (set_attr "mode" "SI")])
6554 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6556 (define_insn "addcarry<mode>"
6557 [(set (reg:CCC FLAGS_REG)
6561 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6562 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6563 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6564 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6566 (set (match_operand:SWI48 0 "register_operand" "=r")
6567 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6568 [(match_dup 3) (const_int 0)])
6571 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6572 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6573 [(set_attr "type" "alu")
6574 (set_attr "use_carry" "1")
6575 (set_attr "pent_pair" "pu")
6576 (set_attr "mode" "<MODE>")])
6578 (define_insn "sub<mode>3_carry"
6579 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6582 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6583 (match_operator:SWI 4 "ix86_carry_flag_operator"
6584 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6585 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6588 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6589 [(set_attr "type" "alu")
6590 (set_attr "use_carry" "1")
6591 (set_attr "pent_pair" "pu")
6592 (set_attr "mode" "<MODE>")])
6594 (define_insn "*subsi3_carry_zext"
6595 [(set (match_operand:DI 0 "register_operand" "=r")
6599 (match_operand:SI 1 "register_operand" "0")
6600 (match_operator:SI 3 "ix86_carry_flag_operator"
6601 [(reg FLAGS_REG) (const_int 0)]))
6602 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605 "sbb{l}\t{%2, %k0|%k0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "use_carry" "1")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "SI")])
6611 (define_insn "subborrow<mode>"
6612 [(set (reg:CCC FLAGS_REG)
6614 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6616 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6617 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6618 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6619 (set (match_operand:SWI48 0 "register_operand" "=r")
6620 (minus:SWI48 (minus:SWI48 (match_dup 1)
6622 [(match_dup 3) (const_int 0)]))
6624 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6625 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "use_carry" "1")
6628 (set_attr "pent_pair" "pu")
6629 (set_attr "mode" "<MODE>")])
6631 ;; Overflow setting add instructions
6633 (define_expand "addqi3_cconly_overflow"
6635 [(set (reg:CCC FLAGS_REG)
6638 (match_operand:QI 0 "nonimmediate_operand")
6639 (match_operand:QI 1 "general_operand"))
6641 (clobber (match_scratch:QI 2))])]
6642 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6644 (define_insn "*add<mode>3_cconly_overflow_1"
6645 [(set (reg:CCC FLAGS_REG)
6648 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6649 (match_operand:SWI 2 "<general_operand>" "<g>"))
6651 (clobber (match_scratch:SWI 0 "=<r>"))]
6652 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6653 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6654 [(set_attr "type" "alu")
6655 (set_attr "mode" "<MODE>")])
6657 (define_insn "*add<mode>3_cconly_overflow_2"
6658 [(set (reg:CCC FLAGS_REG)
6661 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6662 (match_operand:SWI 2 "<general_operand>" "<g>"))
6664 (clobber (match_scratch:SWI 0 "=<r>"))]
6665 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6666 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "<MODE>")])
6670 (define_insn "*add<mode>3_cc_overflow_1"
6671 [(set (reg:CCC FLAGS_REG)
6674 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6675 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6677 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6678 (plus:SWI (match_dup 1) (match_dup 2)))]
6679 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6680 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6681 [(set_attr "type" "alu")
6682 (set_attr "mode" "<MODE>")])
6684 (define_insn "*add<mode>3_cc_overflow_2"
6685 [(set (reg:CCC FLAGS_REG)
6688 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6689 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6691 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6692 (plus:SWI (match_dup 1) (match_dup 2)))]
6693 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6694 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "<MODE>")])
6698 (define_insn "*addsi3_zext_cc_overflow_1"
6699 [(set (reg:CCC FLAGS_REG)
6702 (match_operand:SI 1 "nonimmediate_operand" "%0")
6703 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6705 (set (match_operand:DI 0 "register_operand" "=r")
6706 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6707 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6708 "add{l}\t{%2, %k0|%k0, %2}"
6709 [(set_attr "type" "alu")
6710 (set_attr "mode" "SI")])
6712 (define_insn "*addsi3_zext_cc_overflow_2"
6713 [(set (reg:CCC FLAGS_REG)
6716 (match_operand:SI 1 "nonimmediate_operand" "%0")
6717 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6719 (set (match_operand:DI 0 "register_operand" "=r")
6720 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6721 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6722 "add{l}\t{%2, %k0|%k0, %2}"
6723 [(set_attr "type" "alu")
6724 (set_attr "mode" "SI")])
6726 ;; The patterns that match these are at the end of this file.
6728 (define_expand "<plusminus_insn>xf3"
6729 [(set (match_operand:XF 0 "register_operand")
6731 (match_operand:XF 1 "register_operand")
6732 (match_operand:XF 2 "register_operand")))]
6735 (define_expand "<plusminus_insn><mode>3"
6736 [(set (match_operand:MODEF 0 "register_operand")
6738 (match_operand:MODEF 1 "register_operand")
6739 (match_operand:MODEF 2 "nonimmediate_operand")))]
6740 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6741 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6743 ;; Multiply instructions
6745 (define_expand "mul<mode>3"
6746 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6748 (match_operand:SWIM248 1 "register_operand")
6749 (match_operand:SWIM248 2 "<general_operand>")))
6750 (clobber (reg:CC FLAGS_REG))])])
6752 (define_expand "mulqi3"
6753 [(parallel [(set (match_operand:QI 0 "register_operand")
6755 (match_operand:QI 1 "register_operand")
6756 (match_operand:QI 2 "nonimmediate_operand")))
6757 (clobber (reg:CC FLAGS_REG))])]
6758 "TARGET_QIMODE_MATH")
6761 ;; IMUL reg32/64, reg32/64, imm8 Direct
6762 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6763 ;; IMUL reg32/64, reg32/64, imm32 Direct
6764 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6765 ;; IMUL reg32/64, reg32/64 Direct
6766 ;; IMUL reg32/64, mem32/64 Direct
6768 ;; On BDVER1, all above IMULs use DirectPath
6771 ;; IMUL reg16, reg16, imm8 VectorPath
6772 ;; IMUL reg16, mem16, imm8 VectorPath
6773 ;; IMUL reg16, reg16, imm16 VectorPath
6774 ;; IMUL reg16, mem16, imm16 VectorPath
6775 ;; IMUL reg16, reg16 Direct
6776 ;; IMUL reg16, mem16 Direct
6778 ;; On BDVER1, all HI MULs use DoublePath
6780 (define_insn "*mul<mode>3_1"
6781 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6783 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6784 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6785 (clobber (reg:CC FLAGS_REG))]
6786 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6788 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6789 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6790 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "imul")
6792 (set_attr "prefix_0f" "0,0,1")
6793 (set (attr "athlon_decode")
6794 (cond [(eq_attr "cpu" "athlon")
6795 (const_string "vector")
6796 (eq_attr "alternative" "1")
6797 (const_string "vector")
6798 (and (eq_attr "alternative" "2")
6799 (ior (match_test "<MODE>mode == HImode")
6800 (match_operand 1 "memory_operand")))
6801 (const_string "vector")]
6802 (const_string "direct")))
6803 (set (attr "amdfam10_decode")
6804 (cond [(and (eq_attr "alternative" "0,1")
6805 (ior (match_test "<MODE>mode == HImode")
6806 (match_operand 1 "memory_operand")))
6807 (const_string "vector")]
6808 (const_string "direct")))
6809 (set (attr "bdver1_decode")
6811 (match_test "<MODE>mode == HImode")
6812 (const_string "double")
6813 (const_string "direct")))
6814 (set_attr "mode" "<MODE>")])
6816 (define_insn "*mulsi3_1_zext"
6817 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6819 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6820 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6821 (clobber (reg:CC FLAGS_REG))]
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6826 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6827 imul{l}\t{%2, %k0|%k0, %2}"
6828 [(set_attr "type" "imul")
6829 (set_attr "prefix_0f" "0,0,1")
6830 (set (attr "athlon_decode")
6831 (cond [(eq_attr "cpu" "athlon")
6832 (const_string "vector")
6833 (eq_attr "alternative" "1")
6834 (const_string "vector")
6835 (and (eq_attr "alternative" "2")
6836 (match_operand 1 "memory_operand"))
6837 (const_string "vector")]
6838 (const_string "direct")))
6839 (set (attr "amdfam10_decode")
6840 (cond [(and (eq_attr "alternative" "0,1")
6841 (match_operand 1 "memory_operand"))
6842 (const_string "vector")]
6843 (const_string "direct")))
6844 (set_attr "bdver1_decode" "direct")
6845 (set_attr "mode" "SI")])
6847 ;;On AMDFAM10 and BDVER1
6851 (define_insn "*mulqi3_1"
6852 [(set (match_operand:QI 0 "register_operand" "=a")
6853 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6854 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6855 (clobber (reg:CC FLAGS_REG))]
6857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6859 [(set_attr "type" "imul")
6860 (set_attr "length_immediate" "0")
6861 (set (attr "athlon_decode")
6862 (if_then_else (eq_attr "cpu" "athlon")
6863 (const_string "vector")
6864 (const_string "direct")))
6865 (set_attr "amdfam10_decode" "direct")
6866 (set_attr "bdver1_decode" "direct")
6867 (set_attr "mode" "QI")])
6869 ;; Multiply with jump on overflow.
6870 (define_expand "mulv<mode>4"
6871 [(parallel [(set (reg:CCO FLAGS_REG)
6874 (match_operand:SWI248 1 "register_operand"))
6877 (mult:SWI248 (match_dup 1)
6878 (match_operand:SWI248 2
6879 "<general_operand>")))))
6880 (set (match_operand:SWI248 0 "register_operand")
6881 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6882 (set (pc) (if_then_else
6883 (eq (reg:CCO FLAGS_REG) (const_int 0))
6884 (label_ref (match_operand 3))
6888 if (CONST_INT_P (operands[2]))
6889 operands[4] = operands[2];
6891 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6894 (define_insn "*mulv<mode>4"
6895 [(set (reg:CCO FLAGS_REG)
6898 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6900 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6902 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6903 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6904 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6905 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6907 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6908 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "imul")
6910 (set_attr "prefix_0f" "0,1")
6911 (set (attr "athlon_decode")
6912 (cond [(eq_attr "cpu" "athlon")
6913 (const_string "vector")
6914 (eq_attr "alternative" "0")
6915 (const_string "vector")
6916 (and (eq_attr "alternative" "1")
6917 (match_operand 1 "memory_operand"))
6918 (const_string "vector")]
6919 (const_string "direct")))
6920 (set (attr "amdfam10_decode")
6921 (cond [(and (eq_attr "alternative" "1")
6922 (match_operand 1 "memory_operand"))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "<MODE>")])
6928 (define_insn "*mulvhi4"
6929 [(set (reg:CCO FLAGS_REG)
6932 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6934 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6936 (mult:HI (match_dup 1) (match_dup 2)))))
6937 (set (match_operand:HI 0 "register_operand" "=r")
6938 (mult:HI (match_dup 1) (match_dup 2)))]
6939 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940 "imul{w}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "imul")
6942 (set_attr "prefix_0f" "1")
6943 (set_attr "athlon_decode" "vector")
6944 (set_attr "amdfam10_decode" "direct")
6945 (set_attr "bdver1_decode" "double")
6946 (set_attr "mode" "HI")])
6948 (define_insn "*mulv<mode>4_1"
6949 [(set (reg:CCO FLAGS_REG)
6952 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
6953 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6955 (mult:SWI248 (match_dup 1)
6956 (match_operand:SWI248 2
6957 "<immediate_operand>" "K,<i>")))))
6958 (set (match_operand:SWI248 0 "register_operand" "=r,r")
6959 (mult:SWI248 (match_dup 1) (match_dup 2)))]
6960 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6961 && CONST_INT_P (operands[2])
6962 && INTVAL (operands[2]) == INTVAL (operands[3])"
6963 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6964 [(set_attr "type" "imul")
6965 (set (attr "prefix_0f")
6967 (match_test "<MODE>mode == HImode")
6969 (const_string "*")))
6970 (set (attr "athlon_decode")
6971 (cond [(eq_attr "cpu" "athlon")
6972 (const_string "vector")
6973 (eq_attr "alternative" "1")
6974 (const_string "vector")]
6975 (const_string "direct")))
6976 (set (attr "amdfam10_decode")
6977 (cond [(ior (match_test "<MODE>mode == HImode")
6978 (match_operand 1 "memory_operand"))
6979 (const_string "vector")]
6980 (const_string "direct")))
6981 (set (attr "bdver1_decode")
6983 (match_test "<MODE>mode == HImode")
6984 (const_string "double")
6985 (const_string "direct")))
6986 (set_attr "mode" "<MODE>")
6987 (set (attr "length_immediate")
6988 (cond [(eq_attr "alternative" "0")
6990 (match_test "<MODE_SIZE> == 8")
6992 (const_string "<MODE_SIZE>")))])
6994 (define_expand "umulv<mode>4"
6995 [(parallel [(set (reg:CCO FLAGS_REG)
6998 (match_operand:SWI248 1
6999 "nonimmediate_operand"))
7001 (match_operand:SWI248 2
7002 "nonimmediate_operand")))
7004 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7005 (set (match_operand:SWI248 0 "register_operand")
7006 (mult:SWI248 (match_dup 1) (match_dup 2)))
7007 (clobber (match_scratch:SWI248 4))])
7008 (set (pc) (if_then_else
7009 (eq (reg:CCO FLAGS_REG) (const_int 0))
7010 (label_ref (match_operand 3))
7014 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7015 operands[1] = force_reg (<MODE>mode, operands[1]);
7018 (define_insn "*umulv<mode>4"
7019 [(set (reg:CCO FLAGS_REG)
7022 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7024 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7026 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7027 (set (match_operand:SWI248 0 "register_operand" "=a")
7028 (mult:SWI248 (match_dup 1) (match_dup 2)))
7029 (clobber (match_scratch:SWI248 3 "=d"))]
7030 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031 "mul{<imodesuffix>}\t%2"
7032 [(set_attr "type" "imul")
7033 (set_attr "length_immediate" "0")
7034 (set (attr "athlon_decode")
7035 (if_then_else (eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (const_string "double")))
7038 (set_attr "amdfam10_decode" "double")
7039 (set_attr "bdver1_decode" "direct")
7040 (set_attr "mode" "<MODE>")])
7042 (define_expand "<u>mulvqi4"
7043 [(parallel [(set (reg:CCO FLAGS_REG)
7046 (match_operand:QI 1 "nonimmediate_operand"))
7048 (match_operand:QI 2 "nonimmediate_operand")))
7050 (mult:QI (match_dup 1) (match_dup 2)))))
7051 (set (match_operand:QI 0 "register_operand")
7052 (mult:QI (match_dup 1) (match_dup 2)))])
7053 (set (pc) (if_then_else
7054 (eq (reg:CCO FLAGS_REG) (const_int 0))
7055 (label_ref (match_operand 3))
7057 "TARGET_QIMODE_MATH"
7059 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7060 operands[1] = force_reg (QImode, operands[1]);
7063 (define_insn "*<u>mulvqi4"
7064 [(set (reg:CCO FLAGS_REG)
7067 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7069 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7071 (mult:QI (match_dup 1) (match_dup 2)))))
7072 (set (match_operand:QI 0 "register_operand" "=a")
7073 (mult:QI (match_dup 1) (match_dup 2)))]
7075 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7076 "<sgnprefix>mul{b}\t%2"
7077 [(set_attr "type" "imul")
7078 (set_attr "length_immediate" "0")
7079 (set (attr "athlon_decode")
7080 (if_then_else (eq_attr "cpu" "athlon")
7081 (const_string "vector")
7082 (const_string "direct")))
7083 (set_attr "amdfam10_decode" "direct")
7084 (set_attr "bdver1_decode" "direct")
7085 (set_attr "mode" "QI")])
7087 (define_expand "<u>mul<mode><dwi>3"
7088 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7091 (match_operand:DWIH 1 "nonimmediate_operand"))
7093 (match_operand:DWIH 2 "register_operand"))))
7094 (clobber (reg:CC FLAGS_REG))])])
7096 (define_expand "<u>mulqihi3"
7097 [(parallel [(set (match_operand:HI 0 "register_operand")
7100 (match_operand:QI 1 "nonimmediate_operand"))
7102 (match_operand:QI 2 "register_operand"))))
7103 (clobber (reg:CC FLAGS_REG))])]
7104 "TARGET_QIMODE_MATH")
7106 (define_insn "*bmi2_umul<mode><dwi>3_1"
7107 [(set (match_operand:DWIH 0 "register_operand" "=r")
7109 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7110 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7111 (set (match_operand:DWIH 1 "register_operand" "=r")
7114 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7115 (zero_extend:<DWI> (match_dup 3)))
7116 (match_operand:QI 4 "const_int_operand" "n"))))]
7117 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7118 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7119 "mulx\t{%3, %0, %1|%1, %0, %3}"
7120 [(set_attr "type" "imulx")
7121 (set_attr "prefix" "vex")
7122 (set_attr "mode" "<MODE>")])
7124 (define_insn "*umul<mode><dwi>3_1"
7125 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7128 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7130 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7131 (clobber (reg:CC FLAGS_REG))]
7132 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7135 mul{<imodesuffix>}\t%2"
7136 [(set_attr "isa" "bmi2,*")
7137 (set_attr "type" "imulx,imul")
7138 (set_attr "length_immediate" "*,0")
7139 (set (attr "athlon_decode")
7140 (cond [(eq_attr "alternative" "1")
7141 (if_then_else (eq_attr "cpu" "athlon")
7142 (const_string "vector")
7143 (const_string "double"))]
7144 (const_string "*")))
7145 (set_attr "amdfam10_decode" "*,double")
7146 (set_attr "bdver1_decode" "*,direct")
7147 (set_attr "prefix" "vex,orig")
7148 (set_attr "mode" "<MODE>")])
7150 ;; Convert mul to the mulx pattern to avoid flags dependency.
7152 [(set (match_operand:<DWI> 0 "register_operand")
7155 (match_operand:DWIH 1 "register_operand"))
7157 (match_operand:DWIH 2 "nonimmediate_operand"))))
7158 (clobber (reg:CC FLAGS_REG))]
7159 "TARGET_BMI2 && reload_completed
7160 && true_regnum (operands[1]) == DX_REG"
7161 [(parallel [(set (match_dup 3)
7162 (mult:DWIH (match_dup 1) (match_dup 2)))
7166 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7167 (zero_extend:<DWI> (match_dup 2)))
7170 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7172 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7175 (define_insn "*mul<mode><dwi>3_1"
7176 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7179 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7181 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7182 (clobber (reg:CC FLAGS_REG))]
7183 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7184 "imul{<imodesuffix>}\t%2"
7185 [(set_attr "type" "imul")
7186 (set_attr "length_immediate" "0")
7187 (set (attr "athlon_decode")
7188 (if_then_else (eq_attr "cpu" "athlon")
7189 (const_string "vector")
7190 (const_string "double")))
7191 (set_attr "amdfam10_decode" "double")
7192 (set_attr "bdver1_decode" "direct")
7193 (set_attr "mode" "<MODE>")])
7195 (define_insn "*<u>mulqihi3_1"
7196 [(set (match_operand:HI 0 "register_operand" "=a")
7199 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7201 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7202 (clobber (reg:CC FLAGS_REG))]
7204 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7205 "<sgnprefix>mul{b}\t%2"
7206 [(set_attr "type" "imul")
7207 (set_attr "length_immediate" "0")
7208 (set (attr "athlon_decode")
7209 (if_then_else (eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (const_string "direct")))
7212 (set_attr "amdfam10_decode" "direct")
7213 (set_attr "bdver1_decode" "direct")
7214 (set_attr "mode" "QI")])
7216 (define_expand "<s>mul<mode>3_highpart"
7217 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7222 (match_operand:SWI48 1 "nonimmediate_operand"))
7224 (match_operand:SWI48 2 "register_operand")))
7226 (clobber (match_scratch:SWI48 3))
7227 (clobber (reg:CC FLAGS_REG))])]
7229 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7231 (define_insn "*<s>muldi3_highpart_1"
7232 [(set (match_operand:DI 0 "register_operand" "=d")
7237 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7239 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7241 (clobber (match_scratch:DI 3 "=1"))
7242 (clobber (reg:CC FLAGS_REG))]
7244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245 "<sgnprefix>mul{q}\t%2"
7246 [(set_attr "type" "imul")
7247 (set_attr "length_immediate" "0")
7248 (set (attr "athlon_decode")
7249 (if_then_else (eq_attr "cpu" "athlon")
7250 (const_string "vector")
7251 (const_string "double")))
7252 (set_attr "amdfam10_decode" "double")
7253 (set_attr "bdver1_decode" "direct")
7254 (set_attr "mode" "DI")])
7256 (define_insn "*<s>mulsi3_highpart_1"
7257 [(set (match_operand:SI 0 "register_operand" "=d")
7262 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7264 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7266 (clobber (match_scratch:SI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269 "<sgnprefix>mul{l}\t%2"
7270 [(set_attr "type" "imul")
7271 (set_attr "length_immediate" "0")
7272 (set (attr "athlon_decode")
7273 (if_then_else (eq_attr "cpu" "athlon")
7274 (const_string "vector")
7275 (const_string "double")))
7276 (set_attr "amdfam10_decode" "double")
7277 (set_attr "bdver1_decode" "direct")
7278 (set_attr "mode" "SI")])
7280 (define_insn "*<s>mulsi3_highpart_zext"
7281 [(set (match_operand:DI 0 "register_operand" "=d")
7282 (zero_extend:DI (truncate:SI
7284 (mult:DI (any_extend:DI
7285 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7287 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7289 (clobber (match_scratch:SI 3 "=1"))
7290 (clobber (reg:CC FLAGS_REG))]
7292 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7293 "<sgnprefix>mul{l}\t%2"
7294 [(set_attr "type" "imul")
7295 (set_attr "length_immediate" "0")
7296 (set (attr "athlon_decode")
7297 (if_then_else (eq_attr "cpu" "athlon")
7298 (const_string "vector")
7299 (const_string "double")))
7300 (set_attr "amdfam10_decode" "double")
7301 (set_attr "bdver1_decode" "direct")
7302 (set_attr "mode" "SI")])
7304 ;; The patterns that match these are at the end of this file.
7306 (define_expand "mulxf3"
7307 [(set (match_operand:XF 0 "register_operand")
7308 (mult:XF (match_operand:XF 1 "register_operand")
7309 (match_operand:XF 2 "register_operand")))]
7312 (define_expand "mul<mode>3"
7313 [(set (match_operand:MODEF 0 "register_operand")
7314 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7315 (match_operand:MODEF 2 "nonimmediate_operand")))]
7316 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7317 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7319 ;; Divide instructions
7321 ;; The patterns that match these are at the end of this file.
7323 (define_expand "divxf3"
7324 [(set (match_operand:XF 0 "register_operand")
7325 (div:XF (match_operand:XF 1 "register_operand")
7326 (match_operand:XF 2 "register_operand")))]
7329 (define_expand "divdf3"
7330 [(set (match_operand:DF 0 "register_operand")
7331 (div:DF (match_operand:DF 1 "register_operand")
7332 (match_operand:DF 2 "nonimmediate_operand")))]
7333 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7334 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7336 (define_expand "divsf3"
7337 [(set (match_operand:SF 0 "register_operand")
7338 (div:SF (match_operand:SF 1 "register_operand")
7339 (match_operand:SF 2 "nonimmediate_operand")))]
7340 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7345 && optimize_insn_for_speed_p ()
7346 && flag_finite_math_only && !flag_trapping_math
7347 && flag_unsafe_math_optimizations)
7349 ix86_emit_swdivsf (operands[0], operands[1],
7350 operands[2], SFmode);
7355 ;; Divmod instructions.
7357 (define_expand "divmod<mode>4"
7358 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7360 (match_operand:SWIM248 1 "register_operand")
7361 (match_operand:SWIM248 2 "nonimmediate_operand")))
7362 (set (match_operand:SWIM248 3 "register_operand")
7363 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7364 (clobber (reg:CC FLAGS_REG))])])
7366 ;; Split with 8bit unsigned divide:
7367 ;; if (dividend an divisor are in [0-255])
7368 ;; use 8bit unsigned integer divide
7370 ;; use original integer divide
7372 [(set (match_operand:SWI48 0 "register_operand")
7373 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7374 (match_operand:SWI48 3 "nonimmediate_operand")))
7375 (set (match_operand:SWI48 1 "register_operand")
7376 (mod:SWI48 (match_dup 2) (match_dup 3)))
7377 (clobber (reg:CC FLAGS_REG))]
7378 "TARGET_USE_8BIT_IDIV
7379 && TARGET_QIMODE_MATH
7380 && can_create_pseudo_p ()
7381 && !optimize_insn_for_size_p ()"
7383 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7385 (define_insn_and_split "divmod<mode>4_1"
7386 [(set (match_operand:SWI48 0 "register_operand" "=a")
7387 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7388 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7389 (set (match_operand:SWI48 1 "register_operand" "=&d")
7390 (mod:SWI48 (match_dup 2) (match_dup 3)))
7391 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7392 (clobber (reg:CC FLAGS_REG))]
7396 [(parallel [(set (match_dup 1)
7397 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7398 (clobber (reg:CC FLAGS_REG))])
7399 (parallel [(set (match_dup 0)
7400 (div:SWI48 (match_dup 2) (match_dup 3)))
7402 (mod:SWI48 (match_dup 2) (match_dup 3)))
7404 (clobber (reg:CC FLAGS_REG))])]
7406 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7408 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7409 operands[4] = operands[2];
7412 /* Avoid use of cltd in favor of a mov+shift. */
7413 emit_move_insn (operands[1], operands[2]);
7414 operands[4] = operands[1];
7417 [(set_attr "type" "multi")
7418 (set_attr "mode" "<MODE>")])
7420 (define_insn_and_split "*divmod<mode>4"
7421 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7422 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7423 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7424 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7425 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7426 (clobber (reg:CC FLAGS_REG))]
7430 [(parallel [(set (match_dup 1)
7431 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7432 (clobber (reg:CC FLAGS_REG))])
7433 (parallel [(set (match_dup 0)
7434 (div:SWIM248 (match_dup 2) (match_dup 3)))
7436 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7438 (clobber (reg:CC FLAGS_REG))])]
7440 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7442 if (<MODE>mode != HImode
7443 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7444 operands[4] = operands[2];
7447 /* Avoid use of cltd in favor of a mov+shift. */
7448 emit_move_insn (operands[1], operands[2]);
7449 operands[4] = operands[1];
7452 [(set_attr "type" "multi")
7453 (set_attr "mode" "<MODE>")])
7455 (define_insn "*divmod<mode>4_noext"
7456 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7457 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7458 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7459 (set (match_operand:SWIM248 1 "register_operand" "=d")
7460 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7461 (use (match_operand:SWIM248 4 "register_operand" "1"))
7462 (clobber (reg:CC FLAGS_REG))]
7464 "idiv{<imodesuffix>}\t%3"
7465 [(set_attr "type" "idiv")
7466 (set_attr "mode" "<MODE>")])
7468 (define_expand "divmodqi4"
7469 [(parallel [(set (match_operand:QI 0 "register_operand")
7471 (match_operand:QI 1 "register_operand")
7472 (match_operand:QI 2 "nonimmediate_operand")))
7473 (set (match_operand:QI 3 "register_operand")
7474 (mod:QI (match_dup 1) (match_dup 2)))
7475 (clobber (reg:CC FLAGS_REG))])]
7476 "TARGET_QIMODE_MATH"
7481 tmp0 = gen_reg_rtx (HImode);
7482 tmp1 = gen_reg_rtx (HImode);
7484 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7486 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7487 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7489 /* Extract remainder from AH. */
7490 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7491 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7493 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7494 set_unique_reg_note (insn, REG_EQUAL, mod);
7496 /* Extract quotient from AL. */
7497 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7499 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7500 set_unique_reg_note (insn, REG_EQUAL, div);
7505 ;; Divide AX by r/m8, with result stored in
7508 ;; Change div/mod to HImode and extend the second argument to HImode
7509 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7510 ;; combine may fail.
7511 (define_insn "divmodhiqi3"
7512 [(set (match_operand:HI 0 "register_operand" "=a")
7517 (mod:HI (match_operand:HI 1 "register_operand" "0")
7519 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7523 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7524 (clobber (reg:CC FLAGS_REG))]
7525 "TARGET_QIMODE_MATH"
7527 [(set_attr "type" "idiv")
7528 (set_attr "mode" "QI")])
7530 (define_expand "udivmod<mode>4"
7531 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7533 (match_operand:SWIM248 1 "register_operand")
7534 (match_operand:SWIM248 2 "nonimmediate_operand")))
7535 (set (match_operand:SWIM248 3 "register_operand")
7536 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7537 (clobber (reg:CC FLAGS_REG))])])
7539 ;; Split with 8bit unsigned divide:
7540 ;; if (dividend an divisor are in [0-255])
7541 ;; use 8bit unsigned integer divide
7543 ;; use original integer divide
7545 [(set (match_operand:SWI48 0 "register_operand")
7546 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7547 (match_operand:SWI48 3 "nonimmediate_operand")))
7548 (set (match_operand:SWI48 1 "register_operand")
7549 (umod:SWI48 (match_dup 2) (match_dup 3)))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "TARGET_USE_8BIT_IDIV
7552 && TARGET_QIMODE_MATH
7553 && can_create_pseudo_p ()
7554 && !optimize_insn_for_size_p ()"
7556 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7558 (define_insn_and_split "udivmod<mode>4_1"
7559 [(set (match_operand:SWI48 0 "register_operand" "=a")
7560 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7561 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7562 (set (match_operand:SWI48 1 "register_operand" "=&d")
7563 (umod:SWI48 (match_dup 2) (match_dup 3)))
7564 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7565 (clobber (reg:CC FLAGS_REG))]
7569 [(set (match_dup 1) (const_int 0))
7570 (parallel [(set (match_dup 0)
7571 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7573 (umod:SWI48 (match_dup 2) (match_dup 3)))
7575 (clobber (reg:CC FLAGS_REG))])]
7577 [(set_attr "type" "multi")
7578 (set_attr "mode" "<MODE>")])
7580 (define_insn_and_split "*udivmod<mode>4"
7581 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7582 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7583 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7584 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7585 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7586 (clobber (reg:CC FLAGS_REG))]
7590 [(set (match_dup 1) (const_int 0))
7591 (parallel [(set (match_dup 0)
7592 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7594 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7596 (clobber (reg:CC FLAGS_REG))])]
7598 [(set_attr "type" "multi")
7599 (set_attr "mode" "<MODE>")])
7601 ;; Optimize division or modulo by constant power of 2, if the constant
7602 ;; materializes only after expansion.
7603 (define_insn_and_split "*udivmod<mode>4_pow2"
7604 [(set (match_operand:SWI48 0 "register_operand" "=r")
7605 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7606 (match_operand:SWI48 3 "const_int_operand" "n")))
7607 (set (match_operand:SWI48 1 "register_operand" "=r")
7608 (umod:SWI48 (match_dup 2) (match_dup 3)))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7611 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7614 [(set (match_dup 1) (match_dup 2))
7615 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7616 (clobber (reg:CC FLAGS_REG))])
7617 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7618 (clobber (reg:CC FLAGS_REG))])]
7620 int v = exact_log2 (UINTVAL (operands[3]));
7621 operands[4] = GEN_INT (v);
7622 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7624 [(set_attr "type" "multi")
7625 (set_attr "mode" "<MODE>")])
7627 (define_insn "*udivmod<mode>4_noext"
7628 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7629 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7630 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7631 (set (match_operand:SWIM248 1 "register_operand" "=d")
7632 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7633 (use (match_operand:SWIM248 4 "register_operand" "1"))
7634 (clobber (reg:CC FLAGS_REG))]
7636 "div{<imodesuffix>}\t%3"
7637 [(set_attr "type" "idiv")
7638 (set_attr "mode" "<MODE>")])
7640 (define_expand "udivmodqi4"
7641 [(parallel [(set (match_operand:QI 0 "register_operand")
7643 (match_operand:QI 1 "register_operand")
7644 (match_operand:QI 2 "nonimmediate_operand")))
7645 (set (match_operand:QI 3 "register_operand")
7646 (umod:QI (match_dup 1) (match_dup 2)))
7647 (clobber (reg:CC FLAGS_REG))])]
7648 "TARGET_QIMODE_MATH"
7653 tmp0 = gen_reg_rtx (HImode);
7654 tmp1 = gen_reg_rtx (HImode);
7656 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7658 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7659 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7661 /* Extract remainder from AH. */
7662 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7663 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7664 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7666 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7667 set_unique_reg_note (insn, REG_EQUAL, mod);
7669 /* Extract quotient from AL. */
7670 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7672 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7673 set_unique_reg_note (insn, REG_EQUAL, div);
7678 (define_insn "udivmodhiqi3"
7679 [(set (match_operand:HI 0 "register_operand" "=a")
7684 (mod:HI (match_operand:HI 1 "register_operand" "0")
7686 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7690 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "TARGET_QIMODE_MATH"
7694 [(set_attr "type" "idiv")
7695 (set_attr "mode" "QI")])
7697 ;; We cannot use div/idiv for double division, because it causes
7698 ;; "division by zero" on the overflow and that's not what we expect
7699 ;; from truncate. Because true (non truncating) double division is
7700 ;; never generated, we can't create this insn anyway.
7703 ; [(set (match_operand:SI 0 "register_operand" "=a")
7705 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7707 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7708 ; (set (match_operand:SI 3 "register_operand" "=d")
7710 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7711 ; (clobber (reg:CC FLAGS_REG))]
7713 ; "div{l}\t{%2, %0|%0, %2}"
7714 ; [(set_attr "type" "idiv")])
7716 ;;- Logical AND instructions
7718 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7719 ;; Note that this excludes ah.
7721 (define_expand "testsi_ccno_1"
7722 [(set (reg:CCNO FLAGS_REG)
7724 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7725 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7728 (define_expand "testqi_ccz_1"
7729 [(set (reg:CCZ FLAGS_REG)
7730 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7731 (match_operand:QI 1 "nonmemory_operand"))
7734 (define_expand "testdi_ccno_1"
7735 [(set (reg:CCNO FLAGS_REG)
7737 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7738 (match_operand:DI 1 "x86_64_szext_general_operand"))
7740 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7742 (define_insn "*testdi_1"
7743 [(set (reg FLAGS_REG)
7746 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7747 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7749 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7750 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7752 test{l}\t{%k1, %k0|%k0, %k1}
7753 test{l}\t{%k1, %k0|%k0, %k1}
7754 test{q}\t{%1, %0|%0, %1}
7755 test{q}\t{%1, %0|%0, %1}
7756 test{q}\t{%1, %0|%0, %1}"
7757 [(set_attr "type" "test")
7758 (set_attr "modrm" "0,1,0,1,1")
7759 (set_attr "mode" "SI,SI,DI,DI,DI")])
7761 (define_insn "*testqi_1_maybe_si"
7762 [(set (reg FLAGS_REG)
7765 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7766 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7768 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7769 && ix86_match_ccmode (insn,
7770 CONST_INT_P (operands[1])
7771 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7773 if (which_alternative == 3)
7775 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7776 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7777 return "test{l}\t{%1, %k0|%k0, %1}";
7779 return "test{b}\t{%1, %0|%0, %1}";
7781 [(set_attr "type" "test")
7782 (set_attr "modrm" "0,1,1,1")
7783 (set_attr "mode" "QI,QI,QI,SI")
7784 (set_attr "pent_pair" "uv,np,uv,np")])
7786 (define_insn "*test<mode>_1"
7787 [(set (reg FLAGS_REG)
7790 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7791 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7793 "ix86_match_ccmode (insn, CCNOmode)
7794 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7795 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7796 [(set_attr "type" "test")
7797 (set_attr "modrm" "0,1,1")
7798 (set_attr "mode" "<MODE>")
7799 (set_attr "pent_pair" "uv,np,uv")])
7801 (define_expand "testqi_ext_ccno_0"
7802 [(set (reg:CCNO FLAGS_REG)
7806 (match_operand 0 "ext_register_operand")
7809 (match_operand 1 "const_int_operand"))
7812 (define_insn "*testqi_ext_0"
7813 [(set (reg FLAGS_REG)
7817 (match_operand 0 "ext_register_operand" "Q")
7820 (match_operand 1 "const_int_operand" "n"))
7822 "ix86_match_ccmode (insn, CCNOmode)"
7823 "test{b}\t{%1, %h0|%h0, %1}"
7824 [(set_attr "type" "test")
7825 (set_attr "mode" "QI")
7826 (set_attr "length_immediate" "1")
7827 (set_attr "modrm" "1")
7828 (set_attr "pent_pair" "np")])
7830 (define_insn "*testqi_ext_1"
7831 [(set (reg FLAGS_REG)
7835 (match_operand 0 "ext_register_operand" "Q,Q")
7839 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7841 "ix86_match_ccmode (insn, CCNOmode)"
7842 "test{b}\t{%1, %h0|%h0, %1}"
7843 [(set_attr "isa" "*,nox64")
7844 (set_attr "type" "test")
7845 (set_attr "mode" "QI")])
7847 (define_insn "*testqi_ext_2"
7848 [(set (reg FLAGS_REG)
7852 (match_operand 0 "ext_register_operand" "Q")
7856 (match_operand 1 "ext_register_operand" "Q")
7860 "ix86_match_ccmode (insn, CCNOmode)"
7861 "test{b}\t{%h1, %h0|%h0, %h1}"
7862 [(set_attr "type" "test")
7863 (set_attr "mode" "QI")])
7865 ;; Combine likes to form bit extractions for some tests. Humor it.
7866 (define_insn "*testqi_ext_3"
7867 [(set (reg FLAGS_REG)
7868 (compare (zero_extract:SWI48
7869 (match_operand 0 "nonimmediate_operand" "rm")
7870 (match_operand 1 "const_int_operand" "n")
7871 (match_operand 2 "const_int_operand" "n"))
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7875 || GET_MODE (operands[0]) == SImode
7876 || GET_MODE (operands[0]) == HImode
7877 || GET_MODE (operands[0]) == QImode)
7878 /* Ensure that resulting mask is zero or sign extended operand. */
7879 && INTVAL (operands[2]) >= 0
7880 && ((INTVAL (operands[1]) > 0
7881 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7882 || (<MODE>mode == DImode
7883 && INTVAL (operands[1]) > 32
7884 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7888 [(set (match_operand 0 "flags_reg_operand")
7889 (match_operator 1 "compare_operator"
7891 (match_operand 2 "nonimmediate_operand")
7892 (match_operand 3 "const_int_operand")
7893 (match_operand 4 "const_int_operand"))
7895 "ix86_match_ccmode (insn, CCNOmode)"
7896 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7898 rtx val = operands[2];
7899 HOST_WIDE_INT len = INTVAL (operands[3]);
7900 HOST_WIDE_INT pos = INTVAL (operands[4]);
7902 machine_mode mode, submode;
7904 mode = GET_MODE (val);
7907 /* ??? Combine likes to put non-volatile mem extractions in QImode
7908 no matter the size of the test. So find a mode that works. */
7909 if (! MEM_VOLATILE_P (val))
7911 mode = smallest_mode_for_size (pos + len, MODE_INT);
7912 val = adjust_address (val, mode, 0);
7915 else if (SUBREG_P (val)
7916 && (submode = GET_MODE (SUBREG_REG (val)),
7917 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7918 && pos + len <= GET_MODE_BITSIZE (submode)
7919 && GET_MODE_CLASS (submode) == MODE_INT)
7921 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7923 val = SUBREG_REG (val);
7925 else if (mode == HImode && pos + len <= 8)
7927 /* Small HImode tests can be converted to QImode. */
7929 val = gen_lowpart (QImode, val);
7932 if (len == HOST_BITS_PER_WIDE_INT)
7935 mask = ((HOST_WIDE_INT)1 << len) - 1;
7938 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7941 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7942 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7943 ;; this is relatively important trick.
7944 ;; Do the conversion only post-reload to avoid limiting of the register class
7947 [(set (match_operand 0 "flags_reg_operand")
7948 (match_operator 1 "compare_operator"
7949 [(and (match_operand 2 "QIreg_operand")
7950 (match_operand 3 "const_int_operand"))
7953 && GET_MODE (operands[2]) != QImode
7954 && ((ix86_match_ccmode (insn, CCZmode)
7955 && !(INTVAL (operands[3]) & ~(255 << 8)))
7956 || (ix86_match_ccmode (insn, CCNOmode)
7957 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7960 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7964 operands[2] = gen_lowpart (SImode, operands[2]);
7965 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7969 [(set (match_operand 0 "flags_reg_operand")
7970 (match_operator 1 "compare_operator"
7971 [(and (match_operand 2 "nonimmediate_operand")
7972 (match_operand 3 "const_int_operand"))
7975 && GET_MODE (operands[2]) != QImode
7976 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7977 && ((ix86_match_ccmode (insn, CCZmode)
7978 && !(INTVAL (operands[3]) & ~255))
7979 || (ix86_match_ccmode (insn, CCNOmode)
7980 && !(INTVAL (operands[3]) & ~127)))"
7982 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7985 operands[2] = gen_lowpart (QImode, operands[2]);
7986 operands[3] = gen_lowpart (QImode, operands[3]);
7990 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7991 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7992 (match_operand:SWI1248x 2 "mask_reg_operand")))
7993 (clobber (reg:CC FLAGS_REG))]
7994 "TARGET_AVX512F && reload_completed"
7996 (any_logic:SWI1248x (match_dup 1)
7999 (define_mode_iterator SWI1248_AVX512BW
8000 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8002 (define_insn "*k<logic><mode>"
8003 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8004 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8005 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8008 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8009 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8011 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8013 [(set_attr "mode" "<MODE>")
8014 (set_attr "type" "msklog")
8015 (set_attr "prefix" "vex")])
8017 ;; %%% This used to optimize known byte-wide and operations to memory,
8018 ;; and sometimes to QImode registers. If this is considered useful,
8019 ;; it should be done with splitters.
8021 (define_expand "and<mode>3"
8022 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8023 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8024 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8027 machine_mode mode = <MODE>mode;
8028 rtx (*insn) (rtx, rtx);
8030 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8032 HOST_WIDE_INT ival = INTVAL (operands[2]);
8034 if (ival == (HOST_WIDE_INT) 0xffffffff)
8036 else if (ival == 0xffff)
8038 else if (ival == 0xff)
8042 if (mode == <MODE>mode)
8044 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8048 if (<MODE>mode == DImode)
8049 insn = (mode == SImode)
8050 ? gen_zero_extendsidi2
8052 ? gen_zero_extendhidi2
8053 : gen_zero_extendqidi2;
8054 else if (<MODE>mode == SImode)
8055 insn = (mode == HImode)
8056 ? gen_zero_extendhisi2
8057 : gen_zero_extendqisi2;
8058 else if (<MODE>mode == HImode)
8059 insn = gen_zero_extendqihi2;
8063 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8067 (define_insn "*anddi_1"
8068 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8070 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8071 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8072 (clobber (reg:CC FLAGS_REG))]
8073 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8075 switch (get_attr_type (insn))
8081 return "kandq\t{%2, %1, %0|%0, %1, %2}";
8084 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8085 if (get_attr_mode (insn) == MODE_SI)
8086 return "and{l}\t{%k2, %k0|%k0, %k2}";
8088 return "and{q}\t{%2, %0|%0, %2}";
8091 [(set_attr "type" "alu,alu,alu,imovx,msklog")
8092 (set_attr "length_immediate" "*,*,*,0,0")
8093 (set (attr "prefix_rex")
8095 (and (eq_attr "type" "imovx")
8096 (and (match_test "INTVAL (operands[2]) == 0xff")
8097 (match_operand 1 "ext_QIreg_operand")))
8099 (const_string "*")))
8100 (set_attr "mode" "SI,DI,DI,SI,DI")])
8102 (define_insn_and_split "*anddi3_doubleword"
8103 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8105 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8106 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8107 (clobber (reg:CC FLAGS_REG))]
8108 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (AND, DImode, operands)"
8110 "&& reload_completed"
8111 [(parallel [(set (match_dup 0)
8112 (and:SI (match_dup 1) (match_dup 2)))
8113 (clobber (reg:CC FLAGS_REG))])
8114 (parallel [(set (match_dup 3)
8115 (and:SI (match_dup 4) (match_dup 5)))
8116 (clobber (reg:CC FLAGS_REG))])]
8117 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8119 (define_insn "*andsi_1"
8120 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8121 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8122 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8123 (clobber (reg:CC FLAGS_REG))]
8124 "ix86_binary_operator_ok (AND, SImode, operands)"
8126 switch (get_attr_type (insn))
8132 return "kandd\t{%2, %1, %0|%0, %1, %2}";
8135 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8136 return "and{l}\t{%2, %0|%0, %2}";
8139 [(set_attr "type" "alu,alu,imovx,msklog")
8140 (set (attr "prefix_rex")
8142 (and (eq_attr "type" "imovx")
8143 (and (match_test "INTVAL (operands[2]) == 0xff")
8144 (match_operand 1 "ext_QIreg_operand")))
8146 (const_string "*")))
8147 (set_attr "length_immediate" "*,*,0,0")
8148 (set_attr "mode" "SI")])
8150 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8151 (define_insn "*andsi_1_zext"
8152 [(set (match_operand:DI 0 "register_operand" "=r")
8154 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8155 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8156 (clobber (reg:CC FLAGS_REG))]
8157 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8158 "and{l}\t{%2, %k0|%k0, %2}"
8159 [(set_attr "type" "alu")
8160 (set_attr "mode" "SI")])
8162 (define_insn "*andhi_1"
8163 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8164 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8165 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "ix86_binary_operator_ok (AND, HImode, operands)"
8169 switch (get_attr_type (insn))
8175 return "kandw\t{%2, %1, %0|%0, %1, %2}";
8178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8179 return "and{w}\t{%2, %0|%0, %2}";
8182 [(set_attr "type" "alu,alu,imovx,msklog")
8183 (set_attr "length_immediate" "*,*,0,*")
8184 (set (attr "prefix_rex")
8186 (and (eq_attr "type" "imovx")
8187 (match_operand 1 "ext_QIreg_operand"))
8189 (const_string "*")))
8190 (set_attr "mode" "HI,HI,SI,HI")])
8192 ;; %%% Potential partial reg stall on alternative 2. What to do?
8193 (define_insn "*andqi_1"
8194 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8195 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8196 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "ix86_binary_operator_ok (AND, QImode, operands)"
8200 switch (which_alternative)
8204 return "and{b}\t{%2, %0|%0, %2}";
8206 return "and{l}\t{%k2, %k0|%k0, %k2}";
8208 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8209 : "kandw\t{%2, %1, %0|%0, %1, %2}";
8214 [(set_attr "type" "alu,alu,alu,msklog")
8215 (set_attr "mode" "QI,QI,SI,HI")])
8217 (define_insn "*andqi_1_slp"
8218 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8219 (and:QI (match_dup 0)
8220 (match_operand:QI 1 "general_operand" "qn,qmn")))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8223 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8224 "and{b}\t{%1, %0|%0, %1}"
8225 [(set_attr "type" "alu1")
8226 (set_attr "mode" "QI")])
8228 (define_insn "kandn<mode>"
8229 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8232 (match_operand:SWI12 1 "register_operand" "r,0,k"))
8233 (match_operand:SWI12 2 "register_operand" "r,r,k")))
8234 (clobber (reg:CC FLAGS_REG))]
8237 switch (which_alternative)
8240 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8244 if (TARGET_AVX512DQ && <MODE>mode == QImode)
8245 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8247 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8252 [(set_attr "isa" "bmi,*,avx512f")
8253 (set_attr "type" "bitmanip,*,msklog")
8254 (set_attr "prefix" "*,*,vex")
8255 (set_attr "btver2_decode" "direct,*,*")
8256 (set_attr "mode" "<MODE>")])
8259 [(set (match_operand:SWI12 0 "general_reg_operand")
8263 (match_operand:SWI12 1 "general_reg_operand")))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8267 (not:HI (match_dup 0)))
8268 (parallel [(set (match_dup 0)
8269 (and:HI (match_dup 0)
8271 (clobber (reg:CC FLAGS_REG))])])
8273 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8275 [(set (match_operand:DI 0 "register_operand")
8276 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8277 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8278 (clobber (reg:CC FLAGS_REG))]
8280 [(parallel [(set (match_dup 0)
8281 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8282 (clobber (reg:CC FLAGS_REG))])]
8283 "operands[2] = gen_lowpart (SImode, operands[2]);")
8286 [(set (match_operand:SWI248 0 "register_operand")
8287 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8288 (match_operand:SWI248 2 "const_int_operand")))
8289 (clobber (reg:CC FLAGS_REG))]
8291 && true_regnum (operands[0]) != true_regnum (operands[1])"
8294 HOST_WIDE_INT ival = INTVAL (operands[2]);
8296 rtx (*insn) (rtx, rtx);
8298 if (ival == (HOST_WIDE_INT) 0xffffffff)
8300 else if (ival == 0xffff)
8304 gcc_assert (ival == 0xff);
8308 if (<MODE>mode == DImode)
8309 insn = (mode == SImode)
8310 ? gen_zero_extendsidi2
8312 ? gen_zero_extendhidi2
8313 : gen_zero_extendqidi2;
8316 if (<MODE>mode != SImode)
8317 /* Zero extend to SImode to avoid partial register stalls. */
8318 operands[0] = gen_lowpart (SImode, operands[0]);
8320 insn = (mode == HImode)
8321 ? gen_zero_extendhisi2
8322 : gen_zero_extendqisi2;
8324 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8329 [(set (match_operand:SWI48 0 "register_operand")
8330 (and:SWI48 (match_dup 0)
8331 (const_int -65536)))
8332 (clobber (reg:CC FLAGS_REG))]
8333 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8334 || optimize_function_for_size_p (cfun)"
8335 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8336 "operands[1] = gen_lowpart (HImode, operands[0]);")
8339 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8340 (and:SWI248 (match_dup 0)
8342 (clobber (reg:CC FLAGS_REG))]
8343 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8344 && reload_completed"
8345 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8346 "operands[1] = gen_lowpart (QImode, operands[0]);")
8349 [(set (match_operand:SWI248 0 "QIreg_operand")
8350 (and:SWI248 (match_dup 0)
8351 (const_int -65281)))
8352 (clobber (reg:CC FLAGS_REG))]
8353 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354 && reload_completed"
8355 [(parallel [(set (zero_extract:SI (match_dup 0)
8359 (zero_extract:SI (match_dup 0)
8362 (zero_extract:SI (match_dup 0)
8365 (clobber (reg:CC FLAGS_REG))])]
8366 "operands[0] = gen_lowpart (SImode, operands[0]);")
8368 (define_insn "*anddi_2"
8369 [(set (reg FLAGS_REG)
8372 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8373 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8375 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8376 (and:DI (match_dup 1) (match_dup 2)))]
8378 && ix86_match_ccmode
8380 /* If we are going to emit andl instead of andq, and the operands[2]
8381 constant might have the SImode sign bit set, make sure the sign
8382 flag isn't tested, because the instruction will set the sign flag
8383 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8384 conservatively assume it might have bit 31 set. */
8385 (satisfies_constraint_Z (operands[2])
8386 && (!CONST_INT_P (operands[2])
8387 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8388 ? CCZmode : CCNOmode)
8389 && ix86_binary_operator_ok (AND, DImode, operands)"
8391 and{l}\t{%k2, %k0|%k0, %k2}
8392 and{q}\t{%2, %0|%0, %2}
8393 and{q}\t{%2, %0|%0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "mode" "SI,DI,DI")])
8397 (define_insn "*andqi_2_maybe_si"
8398 [(set (reg FLAGS_REG)
8400 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8401 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8403 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8404 (and:QI (match_dup 1) (match_dup 2)))]
8405 "ix86_binary_operator_ok (AND, QImode, operands)
8406 && ix86_match_ccmode (insn,
8407 CONST_INT_P (operands[2])
8408 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8410 if (which_alternative == 2)
8412 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8413 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8414 return "and{l}\t{%2, %k0|%k0, %2}";
8416 return "and{b}\t{%2, %0|%0, %2}";
8418 [(set_attr "type" "alu")
8419 (set_attr "mode" "QI,QI,SI")])
8421 (define_insn "*and<mode>_2"
8422 [(set (reg FLAGS_REG)
8423 (compare (and:SWI124
8424 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8425 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8427 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8428 (and:SWI124 (match_dup 1) (match_dup 2)))]
8429 "ix86_match_ccmode (insn, CCNOmode)
8430 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8431 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "mode" "<MODE>")])
8435 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8436 (define_insn "*andsi_2_zext"
8437 [(set (reg FLAGS_REG)
8439 (match_operand:SI 1 "nonimmediate_operand" "%0")
8440 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8442 (set (match_operand:DI 0 "register_operand" "=r")
8443 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8444 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8445 && ix86_binary_operator_ok (AND, SImode, operands)"
8446 "and{l}\t{%2, %k0|%k0, %2}"
8447 [(set_attr "type" "alu")
8448 (set_attr "mode" "SI")])
8450 (define_insn "*andqi_2_slp"
8451 [(set (reg FLAGS_REG)
8453 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8454 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8456 (set (strict_low_part (match_dup 0))
8457 (and:QI (match_dup 0) (match_dup 1)))]
8458 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8459 && ix86_match_ccmode (insn, CCNOmode)
8460 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8461 "and{b}\t{%1, %0|%0, %1}"
8462 [(set_attr "type" "alu1")
8463 (set_attr "mode" "QI")])
8465 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8466 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8467 ;; for a QImode operand, which of course failed.
8468 (define_insn "andqi_ext_0"
8469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8474 (match_operand 1 "ext_register_operand" "0")
8477 (match_operand 2 "const_int_operand" "n")))
8478 (clobber (reg:CC FLAGS_REG))]
8480 "and{b}\t{%2, %h0|%h0, %2}"
8481 [(set_attr "type" "alu")
8482 (set_attr "length_immediate" "1")
8483 (set_attr "modrm" "1")
8484 (set_attr "mode" "QI")])
8486 ;; Generated by peephole translating test to and. This shows up
8487 ;; often in fp comparisons.
8488 (define_insn "*andqi_ext_0_cc"
8489 [(set (reg FLAGS_REG)
8493 (match_operand 1 "ext_register_operand" "0")
8496 (match_operand 2 "const_int_operand" "n"))
8498 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8507 "ix86_match_ccmode (insn, CCNOmode)"
8508 "and{b}\t{%2, %h0|%h0, %2}"
8509 [(set_attr "type" "alu")
8510 (set_attr "length_immediate" "1")
8511 (set_attr "modrm" "1")
8512 (set_attr "mode" "QI")])
8514 (define_insn "*andqi_ext_1"
8515 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8520 (match_operand 1 "ext_register_operand" "0,0")
8524 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8525 (clobber (reg:CC FLAGS_REG))]
8527 "and{b}\t{%2, %h0|%h0, %2}"
8528 [(set_attr "isa" "*,nox64")
8529 (set_attr "type" "alu")
8530 (set_attr "length_immediate" "0")
8531 (set_attr "mode" "QI")])
8533 (define_insn "*andqi_ext_2"
8534 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8539 (match_operand 1 "ext_register_operand" "%0")
8543 (match_operand 2 "ext_register_operand" "Q")
8546 (clobber (reg:CC FLAGS_REG))]
8548 "and{b}\t{%h2, %h0|%h0, %h2}"
8549 [(set_attr "type" "alu")
8550 (set_attr "length_immediate" "0")
8551 (set_attr "mode" "QI")])
8553 ;; Convert wide AND instructions with immediate operand to shorter QImode
8554 ;; equivalents when possible.
8555 ;; Don't do the splitting with memory operands, since it introduces risk
8556 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8557 ;; for size, but that can (should?) be handled by generic code instead.
8559 [(set (match_operand 0 "QIreg_operand")
8560 (and (match_operand 1 "register_operand")
8561 (match_operand 2 "const_int_operand")))
8562 (clobber (reg:CC FLAGS_REG))]
8564 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8565 && !(~INTVAL (operands[2]) & ~(255 << 8))
8566 && GET_MODE (operands[0]) != QImode"
8567 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8568 (and:SI (zero_extract:SI (match_dup 1)
8569 (const_int 8) (const_int 8))
8571 (clobber (reg:CC FLAGS_REG))])]
8573 operands[0] = gen_lowpart (SImode, operands[0]);
8574 operands[1] = gen_lowpart (SImode, operands[1]);
8575 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8578 ;; Since AND can be encoded with sign extended immediate, this is only
8579 ;; profitable when 7th bit is not set.
8581 [(set (match_operand 0 "any_QIreg_operand")
8582 (and (match_operand 1 "general_operand")
8583 (match_operand 2 "const_int_operand")))
8584 (clobber (reg:CC FLAGS_REG))]
8586 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8587 && !(~INTVAL (operands[2]) & ~255)
8588 && !(INTVAL (operands[2]) & 128)
8589 && GET_MODE (operands[0]) != QImode"
8590 [(parallel [(set (strict_low_part (match_dup 0))
8591 (and:QI (match_dup 1)
8593 (clobber (reg:CC FLAGS_REG))])]
8595 operands[0] = gen_lowpart (QImode, operands[0]);
8596 operands[1] = gen_lowpart (QImode, operands[1]);
8597 operands[2] = gen_lowpart (QImode, operands[2]);
8600 ;; Logical inclusive and exclusive OR instructions
8602 ;; %%% This used to optimize known byte-wide and operations to memory.
8603 ;; If this is considered useful, it should be done with splitters.
8605 (define_expand "<code><mode>3"
8606 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8607 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8608 (match_operand:SWIM1248x 2 "<general_operand>")))]
8610 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8612 (define_insn "*<code><mode>_1"
8613 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8615 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8616 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8620 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8621 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8622 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8623 [(set_attr "type" "alu,alu,msklog")
8624 (set_attr "mode" "<MODE>")])
8626 (define_insn_and_split "*<code>di3_doubleword"
8627 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8629 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8630 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8631 (clobber (reg:CC FLAGS_REG))]
8632 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8634 "&& reload_completed"
8635 [(parallel [(set (match_dup 0)
8636 (any_or:SI (match_dup 1) (match_dup 2)))
8637 (clobber (reg:CC FLAGS_REG))])
8638 (parallel [(set (match_dup 3)
8639 (any_or:SI (match_dup 4) (match_dup 5)))
8640 (clobber (reg:CC FLAGS_REG))])]
8641 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8643 (define_insn "*<code>hi_1"
8644 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8646 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8647 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8648 (clobber (reg:CC FLAGS_REG))]
8649 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8651 <logic>{w}\t{%2, %0|%0, %2}
8652 <logic>{w}\t{%2, %0|%0, %2}
8653 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8654 [(set_attr "type" "alu,alu,msklog")
8655 (set_attr "mode" "HI")])
8657 ;; %%% Potential partial reg stall on alternative 2. What to do?
8658 (define_insn "*<code>qi_1"
8659 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8660 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8661 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8662 (clobber (reg:CC FLAGS_REG))]
8663 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8665 <logic>{b}\t{%2, %0|%0, %2}
8666 <logic>{b}\t{%2, %0|%0, %2}
8667 <logic>{l}\t{%k2, %k0|%k0, %k2}
8668 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8669 [(set_attr "type" "alu,alu,alu,msklog")
8670 (set_attr "mode" "QI,QI,SI,HI")])
8672 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8673 (define_insn "*<code>si_1_zext"
8674 [(set (match_operand:DI 0 "register_operand" "=r")
8676 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8678 (clobber (reg:CC FLAGS_REG))]
8679 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8680 "<logic>{l}\t{%2, %k0|%k0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "mode" "SI")])
8684 (define_insn "*<code>si_1_zext_imm"
8685 [(set (match_operand:DI 0 "register_operand" "=r")
8687 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8691 "<logic>{l}\t{%2, %k0|%k0, %2}"
8692 [(set_attr "type" "alu")
8693 (set_attr "mode" "SI")])
8695 (define_insn "*<code>qi_1_slp"
8696 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8697 (any_or:QI (match_dup 0)
8698 (match_operand:QI 1 "general_operand" "qmn,qn")))
8699 (clobber (reg:CC FLAGS_REG))]
8700 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8701 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8702 "<logic>{b}\t{%1, %0|%0, %1}"
8703 [(set_attr "type" "alu1")
8704 (set_attr "mode" "QI")])
8706 (define_insn "*<code><mode>_2"
8707 [(set (reg FLAGS_REG)
8708 (compare (any_or:SWI
8709 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8710 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8713 (any_or:SWI (match_dup 1) (match_dup 2)))]
8714 "ix86_match_ccmode (insn, CCNOmode)
8715 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8716 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8717 [(set_attr "type" "alu")
8718 (set_attr "mode" "<MODE>")])
8720 (define_insn "kxnor<mode>"
8721 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8724 (match_operand:SWI12 1 "register_operand" "0,k")
8725 (match_operand:SWI12 2 "register_operand" "r,k"))))
8726 (clobber (reg:CC FLAGS_REG))]
8729 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8730 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8731 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8733 [(set_attr "type" "*,msklog")
8734 (set_attr "prefix" "*,vex")
8735 (set_attr "mode" "<MODE>")])
8737 (define_insn "kxnor<mode>"
8738 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8741 (match_operand:SWI48x 1 "register_operand" "0,k")
8742 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8743 (clobber (reg:CC FLAGS_REG))]
8747 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8748 [(set_attr "type" "*,msklog")
8749 (set_attr "prefix" "*,vex")
8750 (set_attr "mode" "<MODE>")])
8753 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8757 (match_operand:SWI1248x 1 "general_reg_operand"))))
8758 (clobber (reg:CC FLAGS_REG))]
8759 "TARGET_AVX512F && reload_completed"
8760 [(parallel [(set (match_dup 0)
8761 (xor:SWI1248x (match_dup 0)
8763 (clobber (reg:CC FLAGS_REG))])
8765 (not:SWI1248x (match_dup 0)))])
8767 ;;There are kortrest[bdq] but no intrinsics for them.
8768 ;;We probably don't need to implement them.
8769 (define_insn "kortestzhi"
8770 [(set (reg:CCZ FLAGS_REG)
8773 (match_operand:HI 0 "register_operand" "k")
8774 (match_operand:HI 1 "register_operand" "k"))
8776 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8777 "kortestw\t{%1, %0|%0, %1}"
8778 [(set_attr "mode" "HI")
8779 (set_attr "type" "msklog")
8780 (set_attr "prefix" "vex")])
8782 (define_insn "kortestchi"
8783 [(set (reg:CCC FLAGS_REG)
8786 (match_operand:HI 0 "register_operand" "k")
8787 (match_operand:HI 1 "register_operand" "k"))
8789 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8790 "kortestw\t{%1, %0|%0, %1}"
8791 [(set_attr "mode" "HI")
8792 (set_attr "type" "msklog")
8793 (set_attr "prefix" "vex")])
8795 (define_insn "kunpckhi"
8796 [(set (match_operand:HI 0 "register_operand" "=k")
8799 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8801 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8803 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8804 [(set_attr "mode" "HI")
8805 (set_attr "type" "msklog")
8806 (set_attr "prefix" "vex")])
8808 (define_insn "kunpcksi"
8809 [(set (match_operand:SI 0 "register_operand" "=k")
8812 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8814 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8816 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8817 [(set_attr "mode" "SI")])
8819 (define_insn "kunpckdi"
8820 [(set (match_operand:DI 0 "register_operand" "=k")
8823 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8825 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8827 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8828 [(set_attr "mode" "DI")])
8830 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8831 ;; ??? Special case for immediate operand is missing - it is tricky.
8832 (define_insn "*<code>si_2_zext"
8833 [(set (reg FLAGS_REG)
8834 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8835 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8837 (set (match_operand:DI 0 "register_operand" "=r")
8838 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8839 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8840 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8841 "<logic>{l}\t{%2, %k0|%k0, %2}"
8842 [(set_attr "type" "alu")
8843 (set_attr "mode" "SI")])
8845 (define_insn "*<code>si_2_zext_imm"
8846 [(set (reg FLAGS_REG)
8848 (match_operand:SI 1 "nonimmediate_operand" "%0")
8849 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8851 (set (match_operand:DI 0 "register_operand" "=r")
8852 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8853 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8854 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8855 "<logic>{l}\t{%2, %k0|%k0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "SI")])
8859 (define_insn "*<code>qi_2_slp"
8860 [(set (reg FLAGS_REG)
8861 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8862 (match_operand:QI 1 "general_operand" "qmn,qn"))
8864 (set (strict_low_part (match_dup 0))
8865 (any_or:QI (match_dup 0) (match_dup 1)))]
8866 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8867 && ix86_match_ccmode (insn, CCNOmode)
8868 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8869 "<logic>{b}\t{%1, %0|%0, %1}"
8870 [(set_attr "type" "alu1")
8871 (set_attr "mode" "QI")])
8873 (define_insn "*<code><mode>_3"
8874 [(set (reg FLAGS_REG)
8875 (compare (any_or:SWI
8876 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8877 (match_operand:SWI 2 "<general_operand>" "<g>"))
8879 (clobber (match_scratch:SWI 0 "=<r>"))]
8880 "ix86_match_ccmode (insn, CCNOmode)
8881 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8882 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8883 [(set_attr "type" "alu")
8884 (set_attr "mode" "<MODE>")])
8886 (define_insn "*<code>qi_ext_0"
8887 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8892 (match_operand 1 "ext_register_operand" "0")
8895 (match_operand 2 "const_int_operand" "n")))
8896 (clobber (reg:CC FLAGS_REG))]
8897 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8898 "<logic>{b}\t{%2, %h0|%h0, %2}"
8899 [(set_attr "type" "alu")
8900 (set_attr "length_immediate" "1")
8901 (set_attr "modrm" "1")
8902 (set_attr "mode" "QI")])
8904 (define_insn "*<code>qi_ext_1"
8905 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8910 (match_operand 1 "ext_register_operand" "0,0")
8914 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8915 (clobber (reg:CC FLAGS_REG))]
8916 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8917 "<logic>{b}\t{%2, %h0|%h0, %2}"
8918 [(set_attr "isa" "*,nox64")
8919 (set_attr "type" "alu")
8920 (set_attr "length_immediate" "0")
8921 (set_attr "mode" "QI")])
8923 (define_insn "*<code>qi_ext_2"
8924 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8928 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8931 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8934 (clobber (reg:CC FLAGS_REG))]
8935 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8936 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8937 [(set_attr "type" "alu")
8938 (set_attr "length_immediate" "0")
8939 (set_attr "mode" "QI")])
8942 [(set (match_operand 0 "QIreg_operand")
8943 (any_or (match_operand 1 "register_operand")
8944 (match_operand 2 "const_int_operand")))
8945 (clobber (reg:CC FLAGS_REG))]
8947 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8948 && !(INTVAL (operands[2]) & ~(255 << 8))
8949 && GET_MODE (operands[0]) != QImode"
8950 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8951 (any_or:SI (zero_extract:SI (match_dup 1)
8952 (const_int 8) (const_int 8))
8954 (clobber (reg:CC FLAGS_REG))])]
8956 operands[0] = gen_lowpart (SImode, operands[0]);
8957 operands[1] = gen_lowpart (SImode, operands[1]);
8958 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8961 ;; Since OR can be encoded with sign extended immediate, this is only
8962 ;; profitable when 7th bit is set.
8964 [(set (match_operand 0 "any_QIreg_operand")
8965 (any_or (match_operand 1 "general_operand")
8966 (match_operand 2 "const_int_operand")))
8967 (clobber (reg:CC FLAGS_REG))]
8969 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8970 && !(INTVAL (operands[2]) & ~255)
8971 && (INTVAL (operands[2]) & 128)
8972 && GET_MODE (operands[0]) != QImode"
8973 [(parallel [(set (strict_low_part (match_dup 0))
8974 (any_or:QI (match_dup 1)
8976 (clobber (reg:CC FLAGS_REG))])]
8978 operands[0] = gen_lowpart (QImode, operands[0]);
8979 operands[1] = gen_lowpart (QImode, operands[1]);
8980 operands[2] = gen_lowpart (QImode, operands[2]);
8983 (define_expand "xorqi_cc_ext_1"
8985 (set (reg:CCNO FLAGS_REG)
8989 (match_operand 1 "ext_register_operand")
8992 (match_operand:QI 2 "const_int_operand"))
8994 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9004 (define_insn "*xorqi_cc_ext_1"
9005 [(set (reg FLAGS_REG)
9009 (match_operand 1 "ext_register_operand" "0,0")
9012 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9014 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9023 "ix86_match_ccmode (insn, CCNOmode)"
9024 "xor{b}\t{%2, %h0|%h0, %2}"
9025 [(set_attr "isa" "*,nox64")
9026 (set_attr "type" "alu")
9027 (set_attr "modrm" "1")
9028 (set_attr "mode" "QI")])
9030 ;; Negation instructions
9032 (define_expand "neg<mode>2"
9033 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9034 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9036 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9038 (define_insn_and_split "*neg<dwi>2_doubleword"
9039 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9040 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9046 [(set (reg:CCZ FLAGS_REG)
9047 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9048 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9051 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9054 (clobber (reg:CC FLAGS_REG))])
9057 (neg:DWIH (match_dup 2)))
9058 (clobber (reg:CC FLAGS_REG))])]
9059 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9061 (define_insn "*neg<mode>2_1"
9062 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9063 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9064 (clobber (reg:CC FLAGS_REG))]
9065 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9066 "neg{<imodesuffix>}\t%0"
9067 [(set_attr "type" "negnot")
9068 (set_attr "mode" "<MODE>")])
9070 ;; Combine is quite creative about this pattern.
9071 (define_insn "*negsi2_1_zext"
9072 [(set (match_operand:DI 0 "register_operand" "=r")
9074 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9077 (clobber (reg:CC FLAGS_REG))]
9078 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9080 [(set_attr "type" "negnot")
9081 (set_attr "mode" "SI")])
9083 ;; The problem with neg is that it does not perform (compare x 0),
9084 ;; it really performs (compare 0 x), which leaves us with the zero
9085 ;; flag being the only useful item.
9087 (define_insn "*neg<mode>2_cmpz"
9088 [(set (reg:CCZ FLAGS_REG)
9090 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9092 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9093 (neg:SWI (match_dup 1)))]
9094 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9095 "neg{<imodesuffix>}\t%0"
9096 [(set_attr "type" "negnot")
9097 (set_attr "mode" "<MODE>")])
9099 (define_insn "*negsi2_cmpz_zext"
9100 [(set (reg:CCZ FLAGS_REG)
9104 (match_operand:DI 1 "register_operand" "0")
9108 (set (match_operand:DI 0 "register_operand" "=r")
9109 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9112 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9114 [(set_attr "type" "negnot")
9115 (set_attr "mode" "SI")])
9117 ;; Negate with jump on overflow.
9118 (define_expand "negv<mode>3"
9119 [(parallel [(set (reg:CCO FLAGS_REG)
9120 (ne:CCO (match_operand:SWI 1 "register_operand")
9122 (set (match_operand:SWI 0 "register_operand")
9123 (neg:SWI (match_dup 1)))])
9124 (set (pc) (if_then_else
9125 (eq (reg:CCO FLAGS_REG) (const_int 0))
9126 (label_ref (match_operand 2))
9131 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9135 (define_insn "*negv<mode>3"
9136 [(set (reg:CCO FLAGS_REG)
9137 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9138 (match_operand:SWI 2 "const_int_operand")))
9139 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9140 (neg:SWI (match_dup 1)))]
9141 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9142 && mode_signbit_p (<MODE>mode, operands[2])"
9143 "neg{<imodesuffix>}\t%0"
9144 [(set_attr "type" "negnot")
9145 (set_attr "mode" "<MODE>")])
9147 ;; Changing of sign for FP values is doable using integer unit too.
9149 (define_expand "<code><mode>2"
9150 [(set (match_operand:X87MODEF 0 "register_operand")
9151 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9152 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9153 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9155 (define_insn "*absneg<mode>2_mixed"
9156 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9157 (match_operator:MODEF 3 "absneg_operator"
9158 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9159 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9163 [(set (attr "enabled")
9164 (cond [(eq_attr "alternative" "2")
9165 (symbol_ref "TARGET_MIX_SSE_I387")
9167 (symbol_ref "true")))])
9169 (define_insn "*absneg<mode>2_i387"
9170 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9171 (match_operator:X87MODEF 3 "absneg_operator"
9172 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9173 (use (match_operand 2))
9174 (clobber (reg:CC FLAGS_REG))]
9175 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9178 (define_expand "<code>tf2"
9179 [(set (match_operand:TF 0 "register_operand")
9180 (absneg:TF (match_operand:TF 1 "register_operand")))]
9182 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9184 (define_insn "*absnegtf2_sse"
9185 [(set (match_operand:TF 0 "register_operand" "=x,x")
9186 (match_operator:TF 3 "absneg_operator"
9187 [(match_operand:TF 1 "register_operand" "0,x")]))
9188 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9189 (clobber (reg:CC FLAGS_REG))]
9193 ;; Splitters for fp abs and neg.
9196 [(set (match_operand 0 "fp_register_operand")
9197 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9198 (use (match_operand 2))
9199 (clobber (reg:CC FLAGS_REG))]
9201 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9204 [(set (match_operand 0 "register_operand")
9205 (match_operator 3 "absneg_operator"
9206 [(match_operand 1 "register_operand")]))
9207 (use (match_operand 2 "nonimmediate_operand"))
9208 (clobber (reg:CC FLAGS_REG))]
9209 "reload_completed && SSE_REG_P (operands[0])"
9210 [(set (match_dup 0) (match_dup 3))]
9212 machine_mode mode = GET_MODE (operands[0]);
9213 machine_mode vmode = GET_MODE (operands[2]);
9216 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9217 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9218 if (operands_match_p (operands[0], operands[2]))
9219 std::swap (operands[1], operands[2]);
9220 if (GET_CODE (operands[3]) == ABS)
9221 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9223 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9228 [(set (match_operand:SF 0 "register_operand")
9229 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9230 (use (match_operand:V4SF 2))
9231 (clobber (reg:CC FLAGS_REG))]
9233 [(parallel [(set (match_dup 0) (match_dup 1))
9234 (clobber (reg:CC FLAGS_REG))])]
9237 operands[0] = gen_lowpart (SImode, operands[0]);
9238 if (GET_CODE (operands[1]) == ABS)
9240 tmp = gen_int_mode (0x7fffffff, SImode);
9241 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9245 tmp = gen_int_mode (0x80000000, SImode);
9246 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9252 [(set (match_operand:DF 0 "register_operand")
9253 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9254 (use (match_operand 2))
9255 (clobber (reg:CC FLAGS_REG))]
9257 [(parallel [(set (match_dup 0) (match_dup 1))
9258 (clobber (reg:CC FLAGS_REG))])]
9263 tmp = gen_lowpart (DImode, operands[0]);
9264 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9267 if (GET_CODE (operands[1]) == ABS)
9270 tmp = gen_rtx_NOT (DImode, tmp);
9274 operands[0] = gen_highpart (SImode, operands[0]);
9275 if (GET_CODE (operands[1]) == ABS)
9277 tmp = gen_int_mode (0x7fffffff, SImode);
9278 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9282 tmp = gen_int_mode (0x80000000, SImode);
9283 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9290 [(set (match_operand:XF 0 "register_operand")
9291 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9292 (use (match_operand 2))
9293 (clobber (reg:CC FLAGS_REG))]
9295 [(parallel [(set (match_dup 0) (match_dup 1))
9296 (clobber (reg:CC FLAGS_REG))])]
9299 operands[0] = gen_rtx_REG (SImode,
9300 true_regnum (operands[0])
9301 + (TARGET_64BIT ? 1 : 2));
9302 if (GET_CODE (operands[1]) == ABS)
9304 tmp = GEN_INT (0x7fff);
9305 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9309 tmp = GEN_INT (0x8000);
9310 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9315 ;; Conditionalize these after reload. If they match before reload, we
9316 ;; lose the clobber and ability to use integer instructions.
9318 (define_insn "*<code><mode>2_1"
9319 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9320 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9322 && (reload_completed
9323 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9324 "f<absneg_mnemonic>"
9325 [(set_attr "type" "fsgn")
9326 (set_attr "mode" "<MODE>")])
9328 (define_insn "*<code>extendsfdf2"
9329 [(set (match_operand:DF 0 "register_operand" "=f")
9330 (absneg:DF (float_extend:DF
9331 (match_operand:SF 1 "register_operand" "0"))))]
9332 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9333 "f<absneg_mnemonic>"
9334 [(set_attr "type" "fsgn")
9335 (set_attr "mode" "DF")])
9337 (define_insn "*<code>extendsfxf2"
9338 [(set (match_operand:XF 0 "register_operand" "=f")
9339 (absneg:XF (float_extend:XF
9340 (match_operand:SF 1 "register_operand" "0"))))]
9342 "f<absneg_mnemonic>"
9343 [(set_attr "type" "fsgn")
9344 (set_attr "mode" "XF")])
9346 (define_insn "*<code>extenddfxf2"
9347 [(set (match_operand:XF 0 "register_operand" "=f")
9348 (absneg:XF (float_extend:XF
9349 (match_operand:DF 1 "register_operand" "0"))))]
9351 "f<absneg_mnemonic>"
9352 [(set_attr "type" "fsgn")
9353 (set_attr "mode" "XF")])
9355 ;; Copysign instructions
9357 (define_mode_iterator CSGNMODE [SF DF TF])
9358 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9360 (define_expand "copysign<mode>3"
9361 [(match_operand:CSGNMODE 0 "register_operand")
9362 (match_operand:CSGNMODE 1 "nonmemory_operand")
9363 (match_operand:CSGNMODE 2 "register_operand")]
9364 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9365 || (TARGET_SSE && (<MODE>mode == TFmode))"
9366 "ix86_expand_copysign (operands); DONE;")
9368 (define_insn_and_split "copysign<mode>3_const"
9369 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9371 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9372 (match_operand:CSGNMODE 2 "register_operand" "0")
9373 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9375 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9376 || (TARGET_SSE && (<MODE>mode == TFmode))"
9378 "&& reload_completed"
9380 "ix86_split_copysign_const (operands); DONE;")
9382 (define_insn "copysign<mode>3_var"
9383 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9385 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9386 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9387 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9388 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9390 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9391 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9392 || (TARGET_SSE && (<MODE>mode == TFmode))"
9396 [(set (match_operand:CSGNMODE 0 "register_operand")
9398 [(match_operand:CSGNMODE 2 "register_operand")
9399 (match_operand:CSGNMODE 3 "register_operand")
9400 (match_operand:<CSGNVMODE> 4)
9401 (match_operand:<CSGNVMODE> 5)]
9403 (clobber (match_scratch:<CSGNVMODE> 1))]
9404 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9405 || (TARGET_SSE && (<MODE>mode == TFmode)))
9406 && reload_completed"
9408 "ix86_split_copysign_var (operands); DONE;")
9410 ;; One complement instructions
9412 (define_expand "one_cmpl<mode>2"
9413 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9414 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9416 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9418 (define_insn "*one_cmpl<mode>2_1"
9419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9420 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9421 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9423 not{<imodesuffix>}\t%0
9424 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9425 [(set_attr "isa" "*,avx512bw")
9426 (set_attr "type" "negnot,msklog")
9427 (set_attr "prefix" "*,vex")
9428 (set_attr "mode" "<MODE>")])
9430 (define_insn "*one_cmplhi2_1"
9431 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9432 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9433 "ix86_unary_operator_ok (NOT, HImode, operands)"
9436 knotw\t{%1, %0|%0, %1}"
9437 [(set_attr "isa" "*,avx512f")
9438 (set_attr "type" "negnot,msklog")
9439 (set_attr "prefix" "*,vex")
9440 (set_attr "mode" "HI")])
9442 ;; %%% Potential partial reg stall on alternative 1. What to do?
9443 (define_insn "*one_cmplqi2_1"
9444 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9445 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9446 "ix86_unary_operator_ok (NOT, QImode, operands)"
9448 switch (which_alternative)
9451 return "not{b}\t%0";
9453 return "not{l}\t%k0";
9455 if (TARGET_AVX512DQ)
9456 return "knotb\t{%1, %0|%0, %1}";
9457 return "knotw\t{%1, %0|%0, %1}";
9462 [(set_attr "isa" "*,*,avx512f")
9463 (set_attr "type" "negnot,negnot,msklog")
9464 (set_attr "prefix" "*,*,vex")
9465 (set_attr "mode" "QI,SI,QI")])
9467 ;; ??? Currently never generated - xor is used instead.
9468 (define_insn "*one_cmplsi2_1_zext"
9469 [(set (match_operand:DI 0 "register_operand" "=r")
9471 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9472 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9474 [(set_attr "type" "negnot")
9475 (set_attr "mode" "SI")])
9477 (define_insn "*one_cmpl<mode>2_2"
9478 [(set (reg FLAGS_REG)
9479 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9481 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9482 (not:SWI (match_dup 1)))]
9483 "ix86_match_ccmode (insn, CCNOmode)
9484 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9486 [(set_attr "type" "alu1")
9487 (set_attr "mode" "<MODE>")])
9490 [(set (match_operand 0 "flags_reg_operand")
9491 (match_operator 2 "compare_operator"
9492 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9494 (set (match_operand:SWI 1 "nonimmediate_operand")
9495 (not:SWI (match_dup 3)))]
9496 "ix86_match_ccmode (insn, CCNOmode)"
9497 [(parallel [(set (match_dup 0)
9498 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9501 (xor:SWI (match_dup 3) (const_int -1)))])])
9503 ;; ??? Currently never generated - xor is used instead.
9504 (define_insn "*one_cmplsi2_2_zext"
9505 [(set (reg FLAGS_REG)
9506 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9508 (set (match_operand:DI 0 "register_operand" "=r")
9509 (zero_extend:DI (not:SI (match_dup 1))))]
9510 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9511 && ix86_unary_operator_ok (NOT, SImode, operands)"
9513 [(set_attr "type" "alu1")
9514 (set_attr "mode" "SI")])
9517 [(set (match_operand 0 "flags_reg_operand")
9518 (match_operator 2 "compare_operator"
9519 [(not:SI (match_operand:SI 3 "register_operand"))
9521 (set (match_operand:DI 1 "register_operand")
9522 (zero_extend:DI (not:SI (match_dup 3))))]
9523 "ix86_match_ccmode (insn, CCNOmode)"
9524 [(parallel [(set (match_dup 0)
9525 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9528 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9530 ;; Shift instructions
9532 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9533 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9534 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9535 ;; from the assembler input.
9537 ;; This instruction shifts the target reg/mem as usual, but instead of
9538 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9539 ;; is a left shift double, bits are taken from the high order bits of
9540 ;; reg, else if the insn is a shift right double, bits are taken from the
9541 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9542 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9544 ;; Since sh[lr]d does not change the `reg' operand, that is done
9545 ;; separately, making all shifts emit pairs of shift double and normal
9546 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9547 ;; support a 63 bit shift, each shift where the count is in a reg expands
9548 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9550 ;; If the shift count is a constant, we need never emit more than one
9551 ;; shift pair, instead using moves and sign extension for counts greater
9554 (define_insn "*<mshift><mode>3"
9555 [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9556 (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9557 (match_operand:QI 2 "immediate_operand" "i")))]
9559 "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9560 [(set_attr "type" "msklog")
9561 (set_attr "prefix" "vex")])
9563 (define_expand "ashl<mode>3"
9564 [(set (match_operand:SDWIM 0 "<shift_operand>")
9565 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9566 (match_operand:QI 2 "nonmemory_operand")))]
9568 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9570 (define_insn "*ashl<mode>3_doubleword"
9571 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9572 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9573 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9574 (clobber (reg:CC FLAGS_REG))]
9577 [(set_attr "type" "multi")])
9580 [(set (match_operand:DWI 0 "register_operand")
9581 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9582 (match_operand:QI 2 "nonmemory_operand")))
9583 (clobber (reg:CC FLAGS_REG))]
9584 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9586 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9588 ;; By default we don't ask for a scratch register, because when DWImode
9589 ;; values are manipulated, registers are already at a premium. But if
9590 ;; we have one handy, we won't turn it away.
9593 [(match_scratch:DWIH 3 "r")
9594 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9596 (match_operand:<DWI> 1 "nonmemory_operand")
9597 (match_operand:QI 2 "nonmemory_operand")))
9598 (clobber (reg:CC FLAGS_REG))])
9602 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9604 (define_insn "x86_64_shld"
9605 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9606 (ior:DI (ashift:DI (match_dup 0)
9607 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9608 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9609 (minus:QI (const_int 64) (match_dup 2)))))
9610 (clobber (reg:CC FLAGS_REG))]
9612 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9613 [(set_attr "type" "ishift")
9614 (set_attr "prefix_0f" "1")
9615 (set_attr "mode" "DI")
9616 (set_attr "athlon_decode" "vector")
9617 (set_attr "amdfam10_decode" "vector")
9618 (set_attr "bdver1_decode" "vector")])
9620 (define_insn "x86_shld"
9621 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9622 (ior:SI (ashift:SI (match_dup 0)
9623 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9624 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9625 (minus:QI (const_int 32) (match_dup 2)))))
9626 (clobber (reg:CC FLAGS_REG))]
9628 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9629 [(set_attr "type" "ishift")
9630 (set_attr "prefix_0f" "1")
9631 (set_attr "mode" "SI")
9632 (set_attr "pent_pair" "np")
9633 (set_attr "athlon_decode" "vector")
9634 (set_attr "amdfam10_decode" "vector")
9635 (set_attr "bdver1_decode" "vector")])
9637 (define_expand "x86_shift<mode>_adj_1"
9638 [(set (reg:CCZ FLAGS_REG)
9639 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9642 (set (match_operand:SWI48 0 "register_operand")
9643 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9644 (match_operand:SWI48 1 "register_operand")
9647 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9648 (match_operand:SWI48 3 "register_operand")
9651 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9653 (define_expand "x86_shift<mode>_adj_2"
9654 [(use (match_operand:SWI48 0 "register_operand"))
9655 (use (match_operand:SWI48 1 "register_operand"))
9656 (use (match_operand:QI 2 "register_operand"))]
9659 rtx_code_label *label = gen_label_rtx ();
9662 emit_insn (gen_testqi_ccz_1 (operands[2],
9663 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9665 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9666 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9667 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9668 gen_rtx_LABEL_REF (VOIDmode, label),
9670 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9671 JUMP_LABEL (tmp) = label;
9673 emit_move_insn (operands[0], operands[1]);
9674 ix86_expand_clear (operands[1]);
9677 LABEL_NUSES (label) = 1;
9682 ;; Avoid useless masking of count operand.
9683 (define_insn "*ashl<mode>3_mask"
9684 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9686 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9689 (match_operand:SI 2 "register_operand" "c")
9690 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9691 (clobber (reg:CC FLAGS_REG))]
9692 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9693 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9694 == GET_MODE_BITSIZE (<MODE>mode)-1"
9696 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9698 [(set_attr "type" "ishift")
9699 (set_attr "mode" "<MODE>")])
9701 (define_insn "*bmi2_ashl<mode>3_1"
9702 [(set (match_operand:SWI48 0 "register_operand" "=r")
9703 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9704 (match_operand:SWI48 2 "register_operand" "r")))]
9706 "shlx\t{%2, %1, %0|%0, %1, %2}"
9707 [(set_attr "type" "ishiftx")
9708 (set_attr "mode" "<MODE>")])
9710 (define_insn "*ashl<mode>3_1"
9711 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9712 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9713 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9717 switch (get_attr_type (insn))
9724 gcc_assert (operands[2] == const1_rtx);
9725 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9726 return "add{<imodesuffix>}\t%0, %0";
9729 if (operands[2] == const1_rtx
9730 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731 return "sal{<imodesuffix>}\t%0";
9733 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9736 [(set_attr "isa" "*,*,bmi2")
9738 (cond [(eq_attr "alternative" "1")
9739 (const_string "lea")
9740 (eq_attr "alternative" "2")
9741 (const_string "ishiftx")
9742 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9743 (match_operand 0 "register_operand"))
9744 (match_operand 2 "const1_operand"))
9745 (const_string "alu")
9747 (const_string "ishift")))
9748 (set (attr "length_immediate")
9750 (ior (eq_attr "type" "alu")
9751 (and (eq_attr "type" "ishift")
9752 (and (match_operand 2 "const1_operand")
9753 (ior (match_test "TARGET_SHIFT1")
9754 (match_test "optimize_function_for_size_p (cfun)")))))
9756 (const_string "*")))
9757 (set_attr "mode" "<MODE>")])
9759 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9761 [(set (match_operand:SWI48 0 "register_operand")
9762 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9763 (match_operand:QI 2 "register_operand")))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "TARGET_BMI2 && reload_completed"
9767 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9768 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9770 (define_insn "*bmi2_ashlsi3_1_zext"
9771 [(set (match_operand:DI 0 "register_operand" "=r")
9773 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9774 (match_operand:SI 2 "register_operand" "r"))))]
9775 "TARGET_64BIT && TARGET_BMI2"
9776 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9777 [(set_attr "type" "ishiftx")
9778 (set_attr "mode" "SI")])
9780 (define_insn "*ashlsi3_1_zext"
9781 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9783 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9784 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9785 (clobber (reg:CC FLAGS_REG))]
9786 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9788 switch (get_attr_type (insn))
9795 gcc_assert (operands[2] == const1_rtx);
9796 return "add{l}\t%k0, %k0";
9799 if (operands[2] == const1_rtx
9800 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9801 return "sal{l}\t%k0";
9803 return "sal{l}\t{%2, %k0|%k0, %2}";
9806 [(set_attr "isa" "*,*,bmi2")
9808 (cond [(eq_attr "alternative" "1")
9809 (const_string "lea")
9810 (eq_attr "alternative" "2")
9811 (const_string "ishiftx")
9812 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9813 (match_operand 2 "const1_operand"))
9814 (const_string "alu")
9816 (const_string "ishift")))
9817 (set (attr "length_immediate")
9819 (ior (eq_attr "type" "alu")
9820 (and (eq_attr "type" "ishift")
9821 (and (match_operand 2 "const1_operand")
9822 (ior (match_test "TARGET_SHIFT1")
9823 (match_test "optimize_function_for_size_p (cfun)")))))
9825 (const_string "*")))
9826 (set_attr "mode" "SI")])
9828 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9830 [(set (match_operand:DI 0 "register_operand")
9832 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9833 (match_operand:QI 2 "register_operand"))))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9837 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9838 "operands[2] = gen_lowpart (SImode, operands[2]);")
9840 (define_insn "*ashlhi3_1"
9841 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9842 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9843 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9844 (clobber (reg:CC FLAGS_REG))]
9845 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9847 switch (get_attr_type (insn))
9853 gcc_assert (operands[2] == const1_rtx);
9854 return "add{w}\t%0, %0";
9857 if (operands[2] == const1_rtx
9858 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9859 return "sal{w}\t%0";
9861 return "sal{w}\t{%2, %0|%0, %2}";
9865 (cond [(eq_attr "alternative" "1")
9866 (const_string "lea")
9867 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9868 (match_operand 0 "register_operand"))
9869 (match_operand 2 "const1_operand"))
9870 (const_string "alu")
9872 (const_string "ishift")))
9873 (set (attr "length_immediate")
9875 (ior (eq_attr "type" "alu")
9876 (and (eq_attr "type" "ishift")
9877 (and (match_operand 2 "const1_operand")
9878 (ior (match_test "TARGET_SHIFT1")
9879 (match_test "optimize_function_for_size_p (cfun)")))))
9881 (const_string "*")))
9882 (set_attr "mode" "HI,SI")])
9884 ;; %%% Potential partial reg stall on alternative 1. What to do?
9885 (define_insn "*ashlqi3_1"
9886 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9887 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9888 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9889 (clobber (reg:CC FLAGS_REG))]
9890 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9892 switch (get_attr_type (insn))
9898 gcc_assert (operands[2] == const1_rtx);
9899 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9900 return "add{l}\t%k0, %k0";
9902 return "add{b}\t%0, %0";
9905 if (operands[2] == const1_rtx
9906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9908 if (get_attr_mode (insn) == MODE_SI)
9909 return "sal{l}\t%k0";
9911 return "sal{b}\t%0";
9915 if (get_attr_mode (insn) == MODE_SI)
9916 return "sal{l}\t{%2, %k0|%k0, %2}";
9918 return "sal{b}\t{%2, %0|%0, %2}";
9923 (cond [(eq_attr "alternative" "2")
9924 (const_string "lea")
9925 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9926 (match_operand 0 "register_operand"))
9927 (match_operand 2 "const1_operand"))
9928 (const_string "alu")
9930 (const_string "ishift")))
9931 (set (attr "length_immediate")
9933 (ior (eq_attr "type" "alu")
9934 (and (eq_attr "type" "ishift")
9935 (and (match_operand 2 "const1_operand")
9936 (ior (match_test "TARGET_SHIFT1")
9937 (match_test "optimize_function_for_size_p (cfun)")))))
9939 (const_string "*")))
9940 (set_attr "mode" "QI,SI,SI")])
9942 (define_insn "*ashlqi3_1_slp"
9943 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9944 (ashift:QI (match_dup 0)
9945 (match_operand:QI 1 "nonmemory_operand" "cI")))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "(optimize_function_for_size_p (cfun)
9948 || !TARGET_PARTIAL_FLAG_REG_STALL
9949 || (operands[1] == const1_rtx
9951 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9953 switch (get_attr_type (insn))
9956 gcc_assert (operands[1] == const1_rtx);
9957 return "add{b}\t%0, %0";
9960 if (operands[1] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962 return "sal{b}\t%0";
9964 return "sal{b}\t{%1, %0|%0, %1}";
9968 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9969 (match_operand 0 "register_operand"))
9970 (match_operand 1 "const1_operand"))
9971 (const_string "alu")
9973 (const_string "ishift1")))
9974 (set (attr "length_immediate")
9976 (ior (eq_attr "type" "alu")
9977 (and (eq_attr "type" "ishift1")
9978 (and (match_operand 1 "const1_operand")
9979 (ior (match_test "TARGET_SHIFT1")
9980 (match_test "optimize_function_for_size_p (cfun)")))))
9982 (const_string "*")))
9983 (set_attr "mode" "QI")])
9985 ;; Convert ashift to the lea pattern to avoid flags dependency.
9987 [(set (match_operand 0 "register_operand")
9988 (ashift (match_operand 1 "index_register_operand")
9989 (match_operand:QI 2 "const_int_operand")))
9990 (clobber (reg:CC FLAGS_REG))]
9991 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9993 && true_regnum (operands[0]) != true_regnum (operands[1])"
9996 machine_mode mode = GET_MODE (operands[0]);
9999 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
10002 operands[0] = gen_lowpart (mode, operands[0]);
10003 operands[1] = gen_lowpart (mode, operands[1]);
10006 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
10008 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
10010 emit_insn (gen_rtx_SET (operands[0], pat));
10014 ;; Convert ashift to the lea pattern to avoid flags dependency.
10016 [(set (match_operand:DI 0 "register_operand")
10018 (ashift:SI (match_operand:SI 1 "index_register_operand")
10019 (match_operand:QI 2 "const_int_operand"))))
10020 (clobber (reg:CC FLAGS_REG))]
10021 "TARGET_64BIT && reload_completed
10022 && true_regnum (operands[0]) != true_regnum (operands[1])"
10023 [(set (match_dup 0)
10024 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10026 operands[1] = gen_lowpart (SImode, operands[1]);
10027 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
10030 ;; This pattern can't accept a variable shift count, since shifts by
10031 ;; zero don't affect the flags. We assume that shifts by constant
10032 ;; zero are optimized away.
10033 (define_insn "*ashl<mode>3_cmp"
10034 [(set (reg FLAGS_REG)
10036 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10037 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10039 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10040 (ashift:SWI (match_dup 1) (match_dup 2)))]
10041 "(optimize_function_for_size_p (cfun)
10042 || !TARGET_PARTIAL_FLAG_REG_STALL
10043 || (operands[2] == const1_rtx
10045 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10046 && ix86_match_ccmode (insn, CCGOCmode)
10047 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10049 switch (get_attr_type (insn))
10052 gcc_assert (operands[2] == const1_rtx);
10053 return "add{<imodesuffix>}\t%0, %0";
10056 if (operands[2] == const1_rtx
10057 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10058 return "sal{<imodesuffix>}\t%0";
10060 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10063 [(set (attr "type")
10064 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10065 (match_operand 0 "register_operand"))
10066 (match_operand 2 "const1_operand"))
10067 (const_string "alu")
10069 (const_string "ishift")))
10070 (set (attr "length_immediate")
10072 (ior (eq_attr "type" "alu")
10073 (and (eq_attr "type" "ishift")
10074 (and (match_operand 2 "const1_operand")
10075 (ior (match_test "TARGET_SHIFT1")
10076 (match_test "optimize_function_for_size_p (cfun)")))))
10078 (const_string "*")))
10079 (set_attr "mode" "<MODE>")])
10081 (define_insn "*ashlsi3_cmp_zext"
10082 [(set (reg FLAGS_REG)
10084 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10085 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10087 (set (match_operand:DI 0 "register_operand" "=r")
10088 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10090 && (optimize_function_for_size_p (cfun)
10091 || !TARGET_PARTIAL_FLAG_REG_STALL
10092 || (operands[2] == const1_rtx
10094 || TARGET_DOUBLE_WITH_ADD)))
10095 && ix86_match_ccmode (insn, CCGOCmode)
10096 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10098 switch (get_attr_type (insn))
10101 gcc_assert (operands[2] == const1_rtx);
10102 return "add{l}\t%k0, %k0";
10105 if (operands[2] == const1_rtx
10106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10107 return "sal{l}\t%k0";
10109 return "sal{l}\t{%2, %k0|%k0, %2}";
10112 [(set (attr "type")
10113 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10114 (match_operand 2 "const1_operand"))
10115 (const_string "alu")
10117 (const_string "ishift")))
10118 (set (attr "length_immediate")
10120 (ior (eq_attr "type" "alu")
10121 (and (eq_attr "type" "ishift")
10122 (and (match_operand 2 "const1_operand")
10123 (ior (match_test "TARGET_SHIFT1")
10124 (match_test "optimize_function_for_size_p (cfun)")))))
10126 (const_string "*")))
10127 (set_attr "mode" "SI")])
10129 (define_insn "*ashl<mode>3_cconly"
10130 [(set (reg FLAGS_REG)
10132 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10133 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10135 (clobber (match_scratch:SWI 0 "=<r>"))]
10136 "(optimize_function_for_size_p (cfun)
10137 || !TARGET_PARTIAL_FLAG_REG_STALL
10138 || (operands[2] == const1_rtx
10140 || TARGET_DOUBLE_WITH_ADD)))
10141 && ix86_match_ccmode (insn, CCGOCmode)"
10143 switch (get_attr_type (insn))
10146 gcc_assert (operands[2] == const1_rtx);
10147 return "add{<imodesuffix>}\t%0, %0";
10150 if (operands[2] == const1_rtx
10151 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10152 return "sal{<imodesuffix>}\t%0";
10154 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10157 [(set (attr "type")
10158 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10159 (match_operand 0 "register_operand"))
10160 (match_operand 2 "const1_operand"))
10161 (const_string "alu")
10163 (const_string "ishift")))
10164 (set (attr "length_immediate")
10166 (ior (eq_attr "type" "alu")
10167 (and (eq_attr "type" "ishift")
10168 (and (match_operand 2 "const1_operand")
10169 (ior (match_test "TARGET_SHIFT1")
10170 (match_test "optimize_function_for_size_p (cfun)")))))
10172 (const_string "*")))
10173 (set_attr "mode" "<MODE>")])
10175 ;; See comment above `ashl<mode>3' about how this works.
10177 (define_expand "<shift_insn><mode>3"
10178 [(set (match_operand:SDWIM 0 "<shift_operand>")
10179 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10180 (match_operand:QI 2 "nonmemory_operand")))]
10182 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10184 ;; Avoid useless masking of count operand.
10185 (define_insn "*<shift_insn><mode>3_mask"
10186 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10188 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10191 (match_operand:SI 2 "register_operand" "c")
10192 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10193 (clobber (reg:CC FLAGS_REG))]
10194 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10195 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10196 == GET_MODE_BITSIZE (<MODE>mode)-1"
10198 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10200 [(set_attr "type" "ishift")
10201 (set_attr "mode" "<MODE>")])
10203 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10204 [(set (match_operand:DWI 0 "register_operand" "=r")
10205 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10206 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10207 (clobber (reg:CC FLAGS_REG))]
10210 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10212 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10213 [(set_attr "type" "multi")])
10215 ;; By default we don't ask for a scratch register, because when DWImode
10216 ;; values are manipulated, registers are already at a premium. But if
10217 ;; we have one handy, we won't turn it away.
10220 [(match_scratch:DWIH 3 "r")
10221 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10223 (match_operand:<DWI> 1 "register_operand")
10224 (match_operand:QI 2 "nonmemory_operand")))
10225 (clobber (reg:CC FLAGS_REG))])
10229 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10231 (define_insn "x86_64_shrd"
10232 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10233 (ior:DI (lshiftrt:DI (match_dup 0)
10234 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10235 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10236 (minus:QI (const_int 64) (match_dup 2)))))
10237 (clobber (reg:CC FLAGS_REG))]
10239 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10240 [(set_attr "type" "ishift")
10241 (set_attr "prefix_0f" "1")
10242 (set_attr "mode" "DI")
10243 (set_attr "athlon_decode" "vector")
10244 (set_attr "amdfam10_decode" "vector")
10245 (set_attr "bdver1_decode" "vector")])
10247 (define_insn "x86_shrd"
10248 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10249 (ior:SI (lshiftrt:SI (match_dup 0)
10250 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10251 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10252 (minus:QI (const_int 32) (match_dup 2)))))
10253 (clobber (reg:CC FLAGS_REG))]
10255 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10256 [(set_attr "type" "ishift")
10257 (set_attr "prefix_0f" "1")
10258 (set_attr "mode" "SI")
10259 (set_attr "pent_pair" "np")
10260 (set_attr "athlon_decode" "vector")
10261 (set_attr "amdfam10_decode" "vector")
10262 (set_attr "bdver1_decode" "vector")])
10264 (define_insn "ashrdi3_cvt"
10265 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10266 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10267 (match_operand:QI 2 "const_int_operand")))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "TARGET_64BIT && INTVAL (operands[2]) == 63
10270 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10271 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10274 sar{q}\t{%2, %0|%0, %2}"
10275 [(set_attr "type" "imovx,ishift")
10276 (set_attr "prefix_0f" "0,*")
10277 (set_attr "length_immediate" "0,*")
10278 (set_attr "modrm" "0,1")
10279 (set_attr "mode" "DI")])
10281 (define_insn "ashrsi3_cvt"
10282 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10283 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10284 (match_operand:QI 2 "const_int_operand")))
10285 (clobber (reg:CC FLAGS_REG))]
10286 "INTVAL (operands[2]) == 31
10287 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10288 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10291 sar{l}\t{%2, %0|%0, %2}"
10292 [(set_attr "type" "imovx,ishift")
10293 (set_attr "prefix_0f" "0,*")
10294 (set_attr "length_immediate" "0,*")
10295 (set_attr "modrm" "0,1")
10296 (set_attr "mode" "SI")])
10298 (define_insn "*ashrsi3_cvt_zext"
10299 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10301 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10302 (match_operand:QI 2 "const_int_operand"))))
10303 (clobber (reg:CC FLAGS_REG))]
10304 "TARGET_64BIT && INTVAL (operands[2]) == 31
10305 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10306 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10309 sar{l}\t{%2, %k0|%k0, %2}"
10310 [(set_attr "type" "imovx,ishift")
10311 (set_attr "prefix_0f" "0,*")
10312 (set_attr "length_immediate" "0,*")
10313 (set_attr "modrm" "0,1")
10314 (set_attr "mode" "SI")])
10316 (define_expand "x86_shift<mode>_adj_3"
10317 [(use (match_operand:SWI48 0 "register_operand"))
10318 (use (match_operand:SWI48 1 "register_operand"))
10319 (use (match_operand:QI 2 "register_operand"))]
10322 rtx_code_label *label = gen_label_rtx ();
10325 emit_insn (gen_testqi_ccz_1 (operands[2],
10326 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10328 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10329 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10330 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10331 gen_rtx_LABEL_REF (VOIDmode, label),
10333 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10334 JUMP_LABEL (tmp) = label;
10336 emit_move_insn (operands[0], operands[1]);
10337 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10338 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10339 emit_label (label);
10340 LABEL_NUSES (label) = 1;
10345 (define_insn "*bmi2_<shift_insn><mode>3_1"
10346 [(set (match_operand:SWI48 0 "register_operand" "=r")
10347 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10348 (match_operand:SWI48 2 "register_operand" "r")))]
10350 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10351 [(set_attr "type" "ishiftx")
10352 (set_attr "mode" "<MODE>")])
10354 (define_insn "*<shift_insn><mode>3_1"
10355 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10357 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10358 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10359 (clobber (reg:CC FLAGS_REG))]
10360 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10362 switch (get_attr_type (insn))
10368 if (operands[2] == const1_rtx
10369 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10370 return "<shift>{<imodesuffix>}\t%0";
10372 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10375 [(set_attr "isa" "*,bmi2")
10376 (set_attr "type" "ishift,ishiftx")
10377 (set (attr "length_immediate")
10379 (and (match_operand 2 "const1_operand")
10380 (ior (match_test "TARGET_SHIFT1")
10381 (match_test "optimize_function_for_size_p (cfun)")))
10383 (const_string "*")))
10384 (set_attr "mode" "<MODE>")])
10386 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10388 [(set (match_operand:SWI48 0 "register_operand")
10389 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10390 (match_operand:QI 2 "register_operand")))
10391 (clobber (reg:CC FLAGS_REG))]
10392 "TARGET_BMI2 && reload_completed"
10393 [(set (match_dup 0)
10394 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10395 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10397 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10398 [(set (match_operand:DI 0 "register_operand" "=r")
10400 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10401 (match_operand:SI 2 "register_operand" "r"))))]
10402 "TARGET_64BIT && TARGET_BMI2"
10403 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10404 [(set_attr "type" "ishiftx")
10405 (set_attr "mode" "SI")])
10407 (define_insn "*<shift_insn>si3_1_zext"
10408 [(set (match_operand:DI 0 "register_operand" "=r,r")
10410 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10411 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10415 switch (get_attr_type (insn))
10421 if (operands[2] == const1_rtx
10422 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10423 return "<shift>{l}\t%k0";
10425 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10428 [(set_attr "isa" "*,bmi2")
10429 (set_attr "type" "ishift,ishiftx")
10430 (set (attr "length_immediate")
10432 (and (match_operand 2 "const1_operand")
10433 (ior (match_test "TARGET_SHIFT1")
10434 (match_test "optimize_function_for_size_p (cfun)")))
10436 (const_string "*")))
10437 (set_attr "mode" "SI")])
10439 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10441 [(set (match_operand:DI 0 "register_operand")
10443 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10444 (match_operand:QI 2 "register_operand"))))
10445 (clobber (reg:CC FLAGS_REG))]
10446 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10447 [(set (match_dup 0)
10448 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10449 "operands[2] = gen_lowpart (SImode, operands[2]);")
10451 (define_insn "*<shift_insn><mode>3_1"
10452 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10454 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10455 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10456 (clobber (reg:CC FLAGS_REG))]
10457 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10459 if (operands[2] == const1_rtx
10460 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10461 return "<shift>{<imodesuffix>}\t%0";
10463 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10465 [(set_attr "type" "ishift")
10466 (set (attr "length_immediate")
10468 (and (match_operand 2 "const1_operand")
10469 (ior (match_test "TARGET_SHIFT1")
10470 (match_test "optimize_function_for_size_p (cfun)")))
10472 (const_string "*")))
10473 (set_attr "mode" "<MODE>")])
10475 (define_insn "*<shift_insn>qi3_1_slp"
10476 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10477 (any_shiftrt:QI (match_dup 0)
10478 (match_operand:QI 1 "nonmemory_operand" "cI")))
10479 (clobber (reg:CC FLAGS_REG))]
10480 "(optimize_function_for_size_p (cfun)
10481 || !TARGET_PARTIAL_REG_STALL
10482 || (operands[1] == const1_rtx
10483 && TARGET_SHIFT1))"
10485 if (operands[1] == const1_rtx
10486 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10487 return "<shift>{b}\t%0";
10489 return "<shift>{b}\t{%1, %0|%0, %1}";
10491 [(set_attr "type" "ishift1")
10492 (set (attr "length_immediate")
10494 (and (match_operand 1 "const1_operand")
10495 (ior (match_test "TARGET_SHIFT1")
10496 (match_test "optimize_function_for_size_p (cfun)")))
10498 (const_string "*")))
10499 (set_attr "mode" "QI")])
10501 ;; This pattern can't accept a variable shift count, since shifts by
10502 ;; zero don't affect the flags. We assume that shifts by constant
10503 ;; zero are optimized away.
10504 (define_insn "*<shift_insn><mode>3_cmp"
10505 [(set (reg FLAGS_REG)
10508 (match_operand:SWI 1 "nonimmediate_operand" "0")
10509 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10511 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10512 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10513 "(optimize_function_for_size_p (cfun)
10514 || !TARGET_PARTIAL_FLAG_REG_STALL
10515 || (operands[2] == const1_rtx
10517 && ix86_match_ccmode (insn, CCGOCmode)
10518 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10520 if (operands[2] == const1_rtx
10521 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10522 return "<shift>{<imodesuffix>}\t%0";
10524 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10526 [(set_attr "type" "ishift")
10527 (set (attr "length_immediate")
10529 (and (match_operand 2 "const1_operand")
10530 (ior (match_test "TARGET_SHIFT1")
10531 (match_test "optimize_function_for_size_p (cfun)")))
10533 (const_string "*")))
10534 (set_attr "mode" "<MODE>")])
10536 (define_insn "*<shift_insn>si3_cmp_zext"
10537 [(set (reg FLAGS_REG)
10539 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10540 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10542 (set (match_operand:DI 0 "register_operand" "=r")
10543 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10545 && (optimize_function_for_size_p (cfun)
10546 || !TARGET_PARTIAL_FLAG_REG_STALL
10547 || (operands[2] == const1_rtx
10549 && ix86_match_ccmode (insn, CCGOCmode)
10550 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10552 if (operands[2] == const1_rtx
10553 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10554 return "<shift>{l}\t%k0";
10556 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10558 [(set_attr "type" "ishift")
10559 (set (attr "length_immediate")
10561 (and (match_operand 2 "const1_operand")
10562 (ior (match_test "TARGET_SHIFT1")
10563 (match_test "optimize_function_for_size_p (cfun)")))
10565 (const_string "*")))
10566 (set_attr "mode" "SI")])
10568 (define_insn "*<shift_insn><mode>3_cconly"
10569 [(set (reg FLAGS_REG)
10572 (match_operand:SWI 1 "register_operand" "0")
10573 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10575 (clobber (match_scratch:SWI 0 "=<r>"))]
10576 "(optimize_function_for_size_p (cfun)
10577 || !TARGET_PARTIAL_FLAG_REG_STALL
10578 || (operands[2] == const1_rtx
10580 && ix86_match_ccmode (insn, CCGOCmode)"
10582 if (operands[2] == const1_rtx
10583 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10584 return "<shift>{<imodesuffix>}\t%0";
10586 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10588 [(set_attr "type" "ishift")
10589 (set (attr "length_immediate")
10591 (and (match_operand 2 "const1_operand")
10592 (ior (match_test "TARGET_SHIFT1")
10593 (match_test "optimize_function_for_size_p (cfun)")))
10595 (const_string "*")))
10596 (set_attr "mode" "<MODE>")])
10598 ;; Rotate instructions
10600 (define_expand "<rotate_insn>ti3"
10601 [(set (match_operand:TI 0 "register_operand")
10602 (any_rotate:TI (match_operand:TI 1 "register_operand")
10603 (match_operand:QI 2 "nonmemory_operand")))]
10606 if (const_1_to_63_operand (operands[2], VOIDmode))
10607 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10608 (operands[0], operands[1], operands[2]));
10615 (define_expand "<rotate_insn>di3"
10616 [(set (match_operand:DI 0 "shiftdi_operand")
10617 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10618 (match_operand:QI 2 "nonmemory_operand")))]
10622 ix86_expand_binary_operator (<CODE>, DImode, operands);
10623 else if (const_1_to_31_operand (operands[2], VOIDmode))
10624 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10625 (operands[0], operands[1], operands[2]));
10632 (define_expand "<rotate_insn><mode>3"
10633 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10634 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10635 (match_operand:QI 2 "nonmemory_operand")))]
10637 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10639 ;; Avoid useless masking of count operand.
10640 (define_insn "*<rotate_insn><mode>3_mask"
10641 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10643 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10646 (match_operand:SI 2 "register_operand" "c")
10647 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10648 (clobber (reg:CC FLAGS_REG))]
10649 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10650 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10651 == GET_MODE_BITSIZE (<MODE>mode)-1"
10653 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10655 [(set_attr "type" "rotate")
10656 (set_attr "mode" "<MODE>")])
10658 ;; Implement rotation using two double-precision
10659 ;; shift instructions and a scratch register.
10661 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10662 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10663 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10664 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10665 (clobber (reg:CC FLAGS_REG))
10666 (clobber (match_scratch:DWIH 3 "=&r"))]
10670 [(set (match_dup 3) (match_dup 4))
10672 [(set (match_dup 4)
10673 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10674 (lshiftrt:DWIH (match_dup 5)
10675 (minus:QI (match_dup 6) (match_dup 2)))))
10676 (clobber (reg:CC FLAGS_REG))])
10678 [(set (match_dup 5)
10679 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10680 (lshiftrt:DWIH (match_dup 3)
10681 (minus:QI (match_dup 6) (match_dup 2)))))
10682 (clobber (reg:CC FLAGS_REG))])]
10684 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10686 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10689 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10690 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10691 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10692 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10693 (clobber (reg:CC FLAGS_REG))
10694 (clobber (match_scratch:DWIH 3 "=&r"))]
10698 [(set (match_dup 3) (match_dup 4))
10700 [(set (match_dup 4)
10701 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10702 (ashift:DWIH (match_dup 5)
10703 (minus:QI (match_dup 6) (match_dup 2)))))
10704 (clobber (reg:CC FLAGS_REG))])
10706 [(set (match_dup 5)
10707 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10708 (ashift:DWIH (match_dup 3)
10709 (minus:QI (match_dup 6) (match_dup 2)))))
10710 (clobber (reg:CC FLAGS_REG))])]
10712 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10714 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10717 (define_insn "*bmi2_rorx<mode>3_1"
10718 [(set (match_operand:SWI48 0 "register_operand" "=r")
10719 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10720 (match_operand:QI 2 "immediate_operand" "<S>")))]
10722 "rorx\t{%2, %1, %0|%0, %1, %2}"
10723 [(set_attr "type" "rotatex")
10724 (set_attr "mode" "<MODE>")])
10726 (define_insn "*<rotate_insn><mode>3_1"
10727 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10729 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10730 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10731 (clobber (reg:CC FLAGS_REG))]
10732 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10734 switch (get_attr_type (insn))
10740 if (operands[2] == const1_rtx
10741 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742 return "<rotate>{<imodesuffix>}\t%0";
10744 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10747 [(set_attr "isa" "*,bmi2")
10748 (set_attr "type" "rotate,rotatex")
10749 (set (attr "length_immediate")
10751 (and (eq_attr "type" "rotate")
10752 (and (match_operand 2 "const1_operand")
10753 (ior (match_test "TARGET_SHIFT1")
10754 (match_test "optimize_function_for_size_p (cfun)"))))
10756 (const_string "*")))
10757 (set_attr "mode" "<MODE>")])
10759 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10761 [(set (match_operand:SWI48 0 "register_operand")
10762 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10763 (match_operand:QI 2 "immediate_operand")))
10764 (clobber (reg:CC FLAGS_REG))]
10765 "TARGET_BMI2 && reload_completed"
10766 [(set (match_dup 0)
10767 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10770 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10774 [(set (match_operand:SWI48 0 "register_operand")
10775 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10776 (match_operand:QI 2 "immediate_operand")))
10777 (clobber (reg:CC FLAGS_REG))]
10778 "TARGET_BMI2 && reload_completed"
10779 [(set (match_dup 0)
10780 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10782 (define_insn "*bmi2_rorxsi3_1_zext"
10783 [(set (match_operand:DI 0 "register_operand" "=r")
10785 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10786 (match_operand:QI 2 "immediate_operand" "I"))))]
10787 "TARGET_64BIT && TARGET_BMI2"
10788 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10789 [(set_attr "type" "rotatex")
10790 (set_attr "mode" "SI")])
10792 (define_insn "*<rotate_insn>si3_1_zext"
10793 [(set (match_operand:DI 0 "register_operand" "=r,r")
10795 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10796 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10797 (clobber (reg:CC FLAGS_REG))]
10798 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10800 switch (get_attr_type (insn))
10806 if (operands[2] == const1_rtx
10807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10808 return "<rotate>{l}\t%k0";
10810 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10813 [(set_attr "isa" "*,bmi2")
10814 (set_attr "type" "rotate,rotatex")
10815 (set (attr "length_immediate")
10817 (and (eq_attr "type" "rotate")
10818 (and (match_operand 2 "const1_operand")
10819 (ior (match_test "TARGET_SHIFT1")
10820 (match_test "optimize_function_for_size_p (cfun)"))))
10822 (const_string "*")))
10823 (set_attr "mode" "SI")])
10825 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10827 [(set (match_operand:DI 0 "register_operand")
10829 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10830 (match_operand:QI 2 "immediate_operand"))))
10831 (clobber (reg:CC FLAGS_REG))]
10832 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10833 [(set (match_dup 0)
10834 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10837 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10841 [(set (match_operand:DI 0 "register_operand")
10843 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10844 (match_operand:QI 2 "immediate_operand"))))
10845 (clobber (reg:CC FLAGS_REG))]
10846 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10847 [(set (match_dup 0)
10848 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10850 (define_insn "*<rotate_insn><mode>3_1"
10851 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10852 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10853 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10854 (clobber (reg:CC FLAGS_REG))]
10855 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10857 if (operands[2] == const1_rtx
10858 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10859 return "<rotate>{<imodesuffix>}\t%0";
10861 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10863 [(set_attr "type" "rotate")
10864 (set (attr "length_immediate")
10866 (and (match_operand 2 "const1_operand")
10867 (ior (match_test "TARGET_SHIFT1")
10868 (match_test "optimize_function_for_size_p (cfun)")))
10870 (const_string "*")))
10871 (set_attr "mode" "<MODE>")])
10873 (define_insn "*<rotate_insn>qi3_1_slp"
10874 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10875 (any_rotate:QI (match_dup 0)
10876 (match_operand:QI 1 "nonmemory_operand" "cI")))
10877 (clobber (reg:CC FLAGS_REG))]
10878 "(optimize_function_for_size_p (cfun)
10879 || !TARGET_PARTIAL_REG_STALL
10880 || (operands[1] == const1_rtx
10881 && TARGET_SHIFT1))"
10883 if (operands[1] == const1_rtx
10884 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10885 return "<rotate>{b}\t%0";
10887 return "<rotate>{b}\t{%1, %0|%0, %1}";
10889 [(set_attr "type" "rotate1")
10890 (set (attr "length_immediate")
10892 (and (match_operand 1 "const1_operand")
10893 (ior (match_test "TARGET_SHIFT1")
10894 (match_test "optimize_function_for_size_p (cfun)")))
10896 (const_string "*")))
10897 (set_attr "mode" "QI")])
10900 [(set (match_operand:HI 0 "register_operand")
10901 (any_rotate:HI (match_dup 0) (const_int 8)))
10902 (clobber (reg:CC FLAGS_REG))]
10904 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10905 [(parallel [(set (strict_low_part (match_dup 0))
10906 (bswap:HI (match_dup 0)))
10907 (clobber (reg:CC FLAGS_REG))])])
10909 ;; Bit set / bit test instructions
10911 ;; %%% bts, btr, btc, bt.
10912 ;; In general these instructions are *slow* when applied to memory,
10913 ;; since they enforce atomic operation. When applied to registers,
10914 ;; it depends on the cpu implementation. They're never faster than
10915 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10916 ;; no point. But in 64-bit, we can't hold the relevant immediates
10917 ;; within the instruction itself, so operating on bits in the high
10918 ;; 32-bits of a register becomes easier.
10920 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10921 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10922 ;; negdf respectively, so they can never be disabled entirely.
10924 (define_insn "*btsq"
10925 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10927 (match_operand 1 "const_0_to_63_operand" "J"))
10929 (clobber (reg:CC FLAGS_REG))]
10930 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10931 "bts{q}\t{%1, %0|%0, %1}"
10932 [(set_attr "type" "alu1")
10933 (set_attr "prefix_0f" "1")
10934 (set_attr "znver1_decode" "double")
10935 (set_attr "mode" "DI")])
10937 (define_insn "*btrq"
10938 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10940 (match_operand 1 "const_0_to_63_operand" "J"))
10942 (clobber (reg:CC FLAGS_REG))]
10943 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10944 "btr{q}\t{%1, %0|%0, %1}"
10945 [(set_attr "type" "alu1")
10946 (set_attr "prefix_0f" "1")
10947 (set_attr "znver1_decode" "double")
10948 (set_attr "mode" "DI")])
10950 (define_insn "*btcq"
10951 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10953 (match_operand 1 "const_0_to_63_operand" "J"))
10954 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10955 (clobber (reg:CC FLAGS_REG))]
10956 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10957 "btc{q}\t{%1, %0|%0, %1}"
10958 [(set_attr "type" "alu1")
10959 (set_attr "prefix_0f" "1")
10960 (set_attr "znver1_decode" "double")
10961 (set_attr "mode" "DI")])
10963 ;; Allow Nocona to avoid these instructions if a register is available.
10966 [(match_scratch:DI 2 "r")
10967 (parallel [(set (zero_extract:DI
10968 (match_operand:DI 0 "register_operand")
10970 (match_operand 1 "const_0_to_63_operand"))
10972 (clobber (reg:CC FLAGS_REG))])]
10973 "TARGET_64BIT && !TARGET_USE_BT"
10976 int i = INTVAL (operands[1]);
10978 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10982 emit_move_insn (operands[2], op1);
10986 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10991 [(match_scratch:DI 2 "r")
10992 (parallel [(set (zero_extract:DI
10993 (match_operand:DI 0 "register_operand")
10995 (match_operand 1 "const_0_to_63_operand"))
10997 (clobber (reg:CC FLAGS_REG))])]
10998 "TARGET_64BIT && !TARGET_USE_BT"
11001 int i = INTVAL (operands[1]);
11003 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11007 emit_move_insn (operands[2], op1);
11011 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
11016 [(match_scratch:DI 2 "r")
11017 (parallel [(set (zero_extract:DI
11018 (match_operand:DI 0 "register_operand")
11020 (match_operand 1 "const_0_to_63_operand"))
11021 (not:DI (zero_extract:DI
11022 (match_dup 0) (const_int 1) (match_dup 1))))
11023 (clobber (reg:CC FLAGS_REG))])]
11024 "TARGET_64BIT && !TARGET_USE_BT"
11027 int i = INTVAL (operands[1]);
11029 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11033 emit_move_insn (operands[2], op1);
11037 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
11041 (define_insn "*bt<mode>"
11042 [(set (reg:CCC FLAGS_REG)
11044 (zero_extract:SWI48
11045 (match_operand:SWI48 0 "register_operand" "r")
11047 (match_operand:SI 1 "nonmemory_operand" "rN"))
11051 switch (get_attr_mode (insn))
11054 return "bt{l}\t{%1, %k0|%k0, %1}";
11057 return "bt{q}\t{%q1, %0|%0, %q1}";
11060 gcc_unreachable ();
11063 [(set_attr "type" "alu1")
11064 (set_attr "prefix_0f" "1")
11067 (and (match_test "CONST_INT_P (operands[1])")
11068 (match_test "INTVAL (operands[1]) < 32"))
11069 (const_string "SI")
11070 (const_string "<MODE>")))])
11072 (define_insn_and_split "*jcc_bt<mode>"
11074 (if_then_else (match_operator 0 "bt_comparison_operator"
11075 [(zero_extract:SWI48
11076 (match_operand:SWI48 1 "register_operand")
11078 (match_operand:SI 2 "nonmemory_operand"))
11080 (label_ref (match_operand 3))
11082 (clobber (reg:CC FLAGS_REG))]
11083 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11084 && (CONST_INT_P (operands[2])
11085 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11086 && INTVAL (operands[2])
11087 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11088 : register_operand (operands[2], SImode))
11089 && can_create_pseudo_p ()"
11092 [(set (reg:CCC FLAGS_REG)
11094 (zero_extract:SWI48
11100 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11101 (label_ref (match_dup 3))
11104 operands[0] = shallow_copy_rtx (operands[0]);
11105 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11108 (define_insn_and_split "*jcc_bt<mode>_1"
11110 (if_then_else (match_operator 0 "bt_comparison_operator"
11111 [(zero_extract:SWI48
11112 (match_operand:SWI48 1 "register_operand")
11115 (match_operand:QI 2 "register_operand")))
11117 (label_ref (match_operand 3))
11119 (clobber (reg:CC FLAGS_REG))]
11120 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11121 && can_create_pseudo_p ()"
11124 [(set (reg:CCC FLAGS_REG)
11126 (zero_extract:SWI48
11132 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11133 (label_ref (match_dup 3))
11136 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11137 operands[0] = shallow_copy_rtx (operands[0]);
11138 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11141 ;; Avoid useless masking of bit offset operand.
11142 (define_insn_and_split "*jcc_bt<mode>_mask"
11144 (if_then_else (match_operator 0 "bt_comparison_operator"
11145 [(zero_extract:SWI48
11146 (match_operand:SWI48 1 "register_operand")
11149 (match_operand:SI 2 "register_operand")
11150 (match_operand 3 "const_int_operand")))])
11151 (label_ref (match_operand 4))
11153 (clobber (reg:CC FLAGS_REG))]
11154 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11155 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11156 == GET_MODE_BITSIZE (<MODE>mode)-1
11157 && can_create_pseudo_p ()"
11160 [(set (reg:CCC FLAGS_REG)
11162 (zero_extract:SWI48
11168 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11169 (label_ref (match_dup 4))
11172 operands[0] = shallow_copy_rtx (operands[0]);
11173 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11176 ;; Store-flag instructions.
11178 ;; For all sCOND expanders, also expand the compare or test insn that
11179 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11181 (define_insn_and_split "*setcc_di_1"
11182 [(set (match_operand:DI 0 "register_operand" "=q")
11183 (match_operator:DI 1 "ix86_comparison_operator"
11184 [(reg FLAGS_REG) (const_int 0)]))]
11185 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11187 "&& reload_completed"
11188 [(set (match_dup 2) (match_dup 1))
11189 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11191 operands[1] = shallow_copy_rtx (operands[1]);
11192 PUT_MODE (operands[1], QImode);
11193 operands[2] = gen_lowpart (QImode, operands[0]);
11196 (define_insn_and_split "*setcc_si_1_and"
11197 [(set (match_operand:SI 0 "register_operand" "=q")
11198 (match_operator:SI 1 "ix86_comparison_operator"
11199 [(reg FLAGS_REG) (const_int 0)]))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "!TARGET_PARTIAL_REG_STALL
11202 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11204 "&& reload_completed"
11205 [(set (match_dup 2) (match_dup 1))
11206 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11207 (clobber (reg:CC FLAGS_REG))])]
11209 operands[1] = shallow_copy_rtx (operands[1]);
11210 PUT_MODE (operands[1], QImode);
11211 operands[2] = gen_lowpart (QImode, operands[0]);
11214 (define_insn_and_split "*setcc_si_1_movzbl"
11215 [(set (match_operand:SI 0 "register_operand" "=q")
11216 (match_operator:SI 1 "ix86_comparison_operator"
11217 [(reg FLAGS_REG) (const_int 0)]))]
11218 "!TARGET_PARTIAL_REG_STALL
11219 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11221 "&& reload_completed"
11222 [(set (match_dup 2) (match_dup 1))
11223 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11225 operands[1] = shallow_copy_rtx (operands[1]);
11226 PUT_MODE (operands[1], QImode);
11227 operands[2] = gen_lowpart (QImode, operands[0]);
11230 (define_insn "*setcc_qi"
11231 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11232 (match_operator:QI 1 "ix86_comparison_operator"
11233 [(reg FLAGS_REG) (const_int 0)]))]
11236 [(set_attr "type" "setcc")
11237 (set_attr "mode" "QI")])
11239 (define_insn "*setcc_qi_slp"
11240 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11241 (match_operator:QI 1 "ix86_comparison_operator"
11242 [(reg FLAGS_REG) (const_int 0)]))]
11245 [(set_attr "type" "setcc")
11246 (set_attr "mode" "QI")])
11248 ;; In general it is not safe to assume too much about CCmode registers,
11249 ;; so simplify-rtx stops when it sees a second one. Under certain
11250 ;; conditions this is safe on x86, so help combine not create
11257 [(set (match_operand:QI 0 "nonimmediate_operand")
11258 (ne:QI (match_operator 1 "ix86_comparison_operator"
11259 [(reg FLAGS_REG) (const_int 0)])
11262 [(set (match_dup 0) (match_dup 1))]
11264 operands[1] = shallow_copy_rtx (operands[1]);
11265 PUT_MODE (operands[1], QImode);
11269 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11270 (ne:QI (match_operator 1 "ix86_comparison_operator"
11271 [(reg FLAGS_REG) (const_int 0)])
11274 [(set (match_dup 0) (match_dup 1))]
11276 operands[1] = shallow_copy_rtx (operands[1]);
11277 PUT_MODE (operands[1], QImode);
11281 [(set (match_operand:QI 0 "nonimmediate_operand")
11282 (eq:QI (match_operator 1 "ix86_comparison_operator"
11283 [(reg FLAGS_REG) (const_int 0)])
11286 [(set (match_dup 0) (match_dup 1))]
11288 operands[1] = shallow_copy_rtx (operands[1]);
11289 PUT_MODE (operands[1], QImode);
11290 PUT_CODE (operands[1],
11291 ix86_reverse_condition (GET_CODE (operands[1]),
11292 GET_MODE (XEXP (operands[1], 0))));
11294 /* Make sure that (a) the CCmode we have for the flags is strong
11295 enough for the reversed compare or (b) we have a valid FP compare. */
11296 if (! ix86_comparison_operator (operands[1], VOIDmode))
11301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11302 (eq:QI (match_operator 1 "ix86_comparison_operator"
11303 [(reg FLAGS_REG) (const_int 0)])
11306 [(set (match_dup 0) (match_dup 1))]
11308 operands[1] = shallow_copy_rtx (operands[1]);
11309 PUT_MODE (operands[1], QImode);
11310 PUT_CODE (operands[1],
11311 ix86_reverse_condition (GET_CODE (operands[1]),
11312 GET_MODE (XEXP (operands[1], 0))));
11314 /* Make sure that (a) the CCmode we have for the flags is strong
11315 enough for the reversed compare or (b) we have a valid FP compare. */
11316 if (! ix86_comparison_operator (operands[1], VOIDmode))
11320 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11321 ;; subsequent logical operations are used to imitate conditional moves.
11322 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11325 (define_insn "setcc_<mode>_sse"
11326 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11327 (match_operator:MODEF 3 "sse_comparison_operator"
11328 [(match_operand:MODEF 1 "register_operand" "0,x")
11329 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11330 "SSE_FLOAT_MODE_P (<MODE>mode)"
11332 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11333 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11334 [(set_attr "isa" "noavx,avx")
11335 (set_attr "type" "ssecmp")
11336 (set_attr "length_immediate" "1")
11337 (set_attr "prefix" "orig,vex")
11338 (set_attr "mode" "<MODE>")])
11340 ;; Basic conditional jump instructions.
11341 ;; We ignore the overflow flag for signed branch instructions.
11343 (define_insn "*jcc_1"
11345 (if_then_else (match_operator 1 "ix86_comparison_operator"
11346 [(reg FLAGS_REG) (const_int 0)])
11347 (label_ref (match_operand 0))
11351 [(set_attr "type" "ibr")
11352 (set_attr "modrm" "0")
11353 (set (attr "length")
11355 (and (ge (minus (match_dup 0) (pc))
11357 (lt (minus (match_dup 0) (pc))
11361 (set_attr "maybe_prefix_bnd" "1")])
11363 (define_insn "*jcc_2"
11365 (if_then_else (match_operator 1 "ix86_comparison_operator"
11366 [(reg FLAGS_REG) (const_int 0)])
11368 (label_ref (match_operand 0))))]
11371 [(set_attr "type" "ibr")
11372 (set_attr "modrm" "0")
11373 (set (attr "length")
11375 (and (ge (minus (match_dup 0) (pc))
11377 (lt (minus (match_dup 0) (pc))
11381 (set_attr "maybe_prefix_bnd" "1")])
11383 ;; In general it is not safe to assume too much about CCmode registers,
11384 ;; so simplify-rtx stops when it sees a second one. Under certain
11385 ;; conditions this is safe on x86, so help combine not create
11393 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)])
11396 (label_ref (match_operand 1))
11400 (if_then_else (match_dup 0)
11401 (label_ref (match_dup 1))
11404 operands[0] = shallow_copy_rtx (operands[0]);
11405 PUT_MODE (operands[0], VOIDmode);
11410 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11411 [(reg FLAGS_REG) (const_int 0)])
11413 (label_ref (match_operand 1))
11417 (if_then_else (match_dup 0)
11418 (label_ref (match_dup 1))
11421 operands[0] = shallow_copy_rtx (operands[0]);
11422 PUT_MODE (operands[0], VOIDmode);
11423 PUT_CODE (operands[0],
11424 ix86_reverse_condition (GET_CODE (operands[0]),
11425 GET_MODE (XEXP (operands[0], 0))));
11427 /* Make sure that (a) the CCmode we have for the flags is strong
11428 enough for the reversed compare or (b) we have a valid FP compare. */
11429 if (! ix86_comparison_operator (operands[0], VOIDmode))
11433 ;; Define combination compare-and-branch fp compare instructions to help
11436 (define_insn "*jcc<mode>_0_i387"
11438 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11439 [(match_operand:X87MODEF 1 "register_operand" "f")
11440 (match_operand:X87MODEF 2 "const0_operand")])
11441 (label_ref (match_operand 3))
11443 (clobber (reg:CCFP FPSR_REG))
11444 (clobber (reg:CCFP FLAGS_REG))
11445 (clobber (match_scratch:HI 4 "=a"))]
11446 "TARGET_80387 && !TARGET_CMOVE"
11449 (define_insn "*jcc<mode>_0_r_i387"
11451 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11452 [(match_operand:X87MODEF 1 "register_operand" "f")
11453 (match_operand:X87MODEF 2 "const0_operand")])
11455 (label_ref (match_operand 3))))
11456 (clobber (reg:CCFP FPSR_REG))
11457 (clobber (reg:CCFP FLAGS_REG))
11458 (clobber (match_scratch:HI 4 "=a"))]
11459 "TARGET_80387 && !TARGET_CMOVE"
11462 (define_insn "*jccxf_i387"
11464 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11465 [(match_operand:XF 1 "register_operand" "f")
11466 (match_operand:XF 2 "register_operand" "f")])
11467 (label_ref (match_operand 3))
11469 (clobber (reg:CCFP FPSR_REG))
11470 (clobber (reg:CCFP FLAGS_REG))
11471 (clobber (match_scratch:HI 4 "=a"))]
11472 "TARGET_80387 && !TARGET_CMOVE"
11475 (define_insn "*jccxf_r_i387"
11477 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11478 [(match_operand:XF 1 "register_operand" "f")
11479 (match_operand:XF 2 "register_operand" "f")])
11481 (label_ref (match_operand 3))))
11482 (clobber (reg:CCFP FPSR_REG))
11483 (clobber (reg:CCFP FLAGS_REG))
11484 (clobber (match_scratch:HI 4 "=a"))]
11485 "TARGET_80387 && !TARGET_CMOVE"
11488 (define_insn "*jcc<mode>_i387"
11490 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11491 [(match_operand:MODEF 1 "register_operand" "f")
11492 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11493 (label_ref (match_operand 3))
11495 (clobber (reg:CCFP FPSR_REG))
11496 (clobber (reg:CCFP FLAGS_REG))
11497 (clobber (match_scratch:HI 4 "=a"))]
11498 "TARGET_80387 && !TARGET_CMOVE"
11501 (define_insn "*jcc<mode>_r_i387"
11503 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11504 [(match_operand:MODEF 1 "register_operand" "f")
11505 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11507 (label_ref (match_operand 3))))
11508 (clobber (reg:CCFP FPSR_REG))
11509 (clobber (reg:CCFP FLAGS_REG))
11510 (clobber (match_scratch:HI 4 "=a"))]
11511 "TARGET_80387 && !TARGET_CMOVE"
11514 (define_insn "*jccu<mode>_i387"
11516 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11517 [(match_operand:X87MODEF 1 "register_operand" "f")
11518 (match_operand:X87MODEF 2 "register_operand" "f")])
11519 (label_ref (match_operand 3))
11521 (clobber (reg:CCFP FPSR_REG))
11522 (clobber (reg:CCFP FLAGS_REG))
11523 (clobber (match_scratch:HI 4 "=a"))]
11524 "TARGET_80387 && !TARGET_CMOVE"
11527 (define_insn "*jccu<mode>_r_i387"
11529 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11530 [(match_operand:X87MODEF 1 "register_operand" "f")
11531 (match_operand:X87MODEF 2 "register_operand" "f")])
11533 (label_ref (match_operand 3))))
11534 (clobber (reg:CCFP FPSR_REG))
11535 (clobber (reg:CCFP FLAGS_REG))
11536 (clobber (match_scratch:HI 4 "=a"))]
11537 "TARGET_80387 && !TARGET_CMOVE"
11542 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11543 [(match_operand:X87MODEF 1 "register_operand")
11544 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11546 (match_operand 4)))
11547 (clobber (reg:CCFP FPSR_REG))
11548 (clobber (reg:CCFP FLAGS_REG))]
11549 "TARGET_80387 && !TARGET_CMOVE
11550 && reload_completed"
11553 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11554 operands[3], operands[4], NULL_RTX);
11560 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11561 [(match_operand:X87MODEF 1 "register_operand")
11562 (match_operand:X87MODEF 2 "general_operand")])
11564 (match_operand 4)))
11565 (clobber (reg:CCFP FPSR_REG))
11566 (clobber (reg:CCFP FLAGS_REG))
11567 (clobber (match_scratch:HI 5))]
11568 "TARGET_80387 && !TARGET_CMOVE
11569 && reload_completed"
11572 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11573 operands[3], operands[4], operands[5]);
11577 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11578 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11579 ;; with a precedence over other operators and is always put in the first
11580 ;; place. Swap condition and operands to match ficom instruction.
11582 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11585 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11586 [(match_operator:X87MODEF 1 "float_operator"
11587 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11588 (match_operand:X87MODEF 3 "register_operand" "f")])
11589 (label_ref (match_operand 4))
11591 (clobber (reg:CCFP FPSR_REG))
11592 (clobber (reg:CCFP FLAGS_REG))
11593 (clobber (match_scratch:HI 5 "=a"))]
11594 "TARGET_80387 && !TARGET_CMOVE
11595 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11596 || optimize_function_for_size_p (cfun))"
11599 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11602 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11603 [(match_operator:X87MODEF 1 "float_operator"
11604 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11605 (match_operand:X87MODEF 3 "register_operand" "f")])
11607 (label_ref (match_operand 4))))
11608 (clobber (reg:CCFP FPSR_REG))
11609 (clobber (reg:CCFP FLAGS_REG))
11610 (clobber (match_scratch:HI 5 "=a"))]
11611 "TARGET_80387 && !TARGET_CMOVE
11612 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11613 || optimize_function_for_size_p (cfun))"
11619 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11620 [(match_operator:X87MODEF 1 "float_operator"
11621 [(match_operand:SWI24 2 "memory_operand")])
11622 (match_operand:X87MODEF 3 "register_operand")])
11624 (match_operand 5)))
11625 (clobber (reg:CCFP FPSR_REG))
11626 (clobber (reg:CCFP FLAGS_REG))
11627 (clobber (match_scratch:HI 6))]
11628 "TARGET_80387 && !TARGET_CMOVE
11629 && reload_completed"
11632 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11633 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11634 operands[4], operands[5], operands[6]);
11638 ;; Unconditional and other jump instructions
11640 (define_insn "jump"
11642 (label_ref (match_operand 0)))]
11645 [(set_attr "type" "ibr")
11646 (set_attr "modrm" "0")
11647 (set (attr "length")
11649 (and (ge (minus (match_dup 0) (pc))
11651 (lt (minus (match_dup 0) (pc))
11655 (set_attr "maybe_prefix_bnd" "1")])
11657 (define_expand "indirect_jump"
11658 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11662 operands[0] = convert_memory_address (word_mode, operands[0]);
11665 (define_insn "*indirect_jump"
11666 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11669 [(set_attr "type" "ibr")
11670 (set_attr "length_immediate" "0")
11671 (set_attr "maybe_prefix_bnd" "1")])
11673 (define_expand "tablejump"
11674 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11675 (use (label_ref (match_operand 1)))])]
11678 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11679 relative. Convert the relative address to an absolute address. */
11683 enum rtx_code code;
11685 /* We can't use @GOTOFF for text labels on VxWorks;
11686 see gotoff_operand. */
11687 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11691 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11693 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11697 op1 = pic_offset_table_rtx;
11702 op0 = pic_offset_table_rtx;
11706 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11711 operands[0] = convert_memory_address (word_mode, operands[0]);
11714 (define_insn "*tablejump_1"
11715 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11716 (use (label_ref (match_operand 1)))]
11719 [(set_attr "type" "ibr")
11720 (set_attr "length_immediate" "0")
11721 (set_attr "maybe_prefix_bnd" "1")])
11723 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11726 [(set (reg FLAGS_REG) (match_operand 0))
11727 (set (match_operand:QI 1 "register_operand")
11728 (match_operator:QI 2 "ix86_comparison_operator"
11729 [(reg FLAGS_REG) (const_int 0)]))
11730 (set (match_operand 3 "any_QIreg_operand")
11731 (zero_extend (match_dup 1)))]
11732 "(peep2_reg_dead_p (3, operands[1])
11733 || operands_match_p (operands[1], operands[3]))
11734 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11735 [(set (match_dup 4) (match_dup 0))
11736 (set (strict_low_part (match_dup 5))
11739 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11740 operands[5] = gen_lowpart (QImode, operands[3]);
11741 ix86_expand_clear (operands[3]);
11745 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11746 (match_operand 4)])
11747 (set (match_operand:QI 1 "register_operand")
11748 (match_operator:QI 2 "ix86_comparison_operator"
11749 [(reg FLAGS_REG) (const_int 0)]))
11750 (set (match_operand 3 "any_QIreg_operand")
11751 (zero_extend (match_dup 1)))]
11752 "(peep2_reg_dead_p (3, operands[1])
11753 || operands_match_p (operands[1], operands[3]))
11754 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11755 && ! (GET_CODE (operands[4]) == CLOBBER
11756 && reg_mentioned_p (operands[3], operands[4]))"
11757 [(parallel [(set (match_dup 5) (match_dup 0))
11759 (set (strict_low_part (match_dup 6))
11762 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11763 operands[6] = gen_lowpart (QImode, operands[3]);
11764 ix86_expand_clear (operands[3]);
11767 ;; Similar, but match zero extend with andsi3.
11770 [(set (reg FLAGS_REG) (match_operand 0))
11771 (set (match_operand:QI 1 "register_operand")
11772 (match_operator:QI 2 "ix86_comparison_operator"
11773 [(reg FLAGS_REG) (const_int 0)]))
11774 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11775 (and:SI (match_dup 3) (const_int 255)))
11776 (clobber (reg:CC FLAGS_REG))])]
11777 "REGNO (operands[1]) == REGNO (operands[3])
11778 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11779 [(set (match_dup 4) (match_dup 0))
11780 (set (strict_low_part (match_dup 5))
11783 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11784 operands[5] = gen_lowpart (QImode, operands[3]);
11785 ix86_expand_clear (operands[3]);
11789 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11790 (match_operand 4)])
11791 (set (match_operand:QI 1 "register_operand")
11792 (match_operator:QI 2 "ix86_comparison_operator"
11793 [(reg FLAGS_REG) (const_int 0)]))
11794 (parallel [(set (match_operand 3 "any_QIreg_operand")
11795 (zero_extend (match_dup 1)))
11796 (clobber (reg:CC FLAGS_REG))])]
11797 "(peep2_reg_dead_p (3, operands[1])
11798 || operands_match_p (operands[1], operands[3]))
11799 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11800 && ! (GET_CODE (operands[4]) == CLOBBER
11801 && reg_mentioned_p (operands[3], operands[4]))"
11802 [(parallel [(set (match_dup 5) (match_dup 0))
11804 (set (strict_low_part (match_dup 6))
11807 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11808 operands[6] = gen_lowpart (QImode, operands[3]);
11809 ix86_expand_clear (operands[3]);
11812 ;; Call instructions.
11814 ;; The predicates normally associated with named expanders are not properly
11815 ;; checked for calls. This is a bug in the generic code, but it isn't that
11816 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11818 ;; P6 processors will jump to the address after the decrement when %esp
11819 ;; is used as a call operand, so they will execute return address as a code.
11820 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11822 ;; Register constraint for call instruction.
11823 (define_mode_attr c [(SI "l") (DI "r")])
11825 ;; Call subroutine returning no value.
11827 (define_expand "call"
11828 [(call (match_operand:QI 0)
11830 (use (match_operand 2))]
11833 ix86_expand_call (NULL, operands[0], operands[1],
11834 operands[2], NULL, false);
11838 (define_expand "sibcall"
11839 [(call (match_operand:QI 0)
11841 (use (match_operand 2))]
11844 ix86_expand_call (NULL, operands[0], operands[1],
11845 operands[2], NULL, true);
11849 (define_insn "*call"
11850 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11851 (match_operand 1))]
11852 "!SIBLING_CALL_P (insn)"
11853 "* return ix86_output_call_insn (insn, operands[0]);"
11854 [(set_attr "type" "call")])
11856 ;; This covers both call and sibcall since only GOT slot is allowed.
11857 (define_insn "*call_got_x32"
11858 [(call (mem:QI (zero_extend:DI
11859 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11860 (match_operand 1))]
11862 "* return ix86_output_call_insn (insn, operands[0]);"
11863 [(set_attr "type" "call")])
11865 (define_insn "*sibcall"
11866 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11867 (match_operand 1))]
11868 "SIBLING_CALL_P (insn)"
11869 "* return ix86_output_call_insn (insn, operands[0]);"
11870 [(set_attr "type" "call")])
11872 (define_insn "*sibcall_memory"
11873 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11875 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11877 "* return ix86_output_call_insn (insn, operands[0]);"
11878 [(set_attr "type" "call")])
11881 [(set (match_operand:W 0 "register_operand")
11882 (match_operand:W 1 "memory_operand"))
11883 (call (mem:QI (match_dup 0))
11884 (match_operand 3))]
11885 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11886 && !reg_mentioned_p (operands[0],
11887 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11888 [(parallel [(call (mem:QI (match_dup 1))
11890 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11893 [(set (match_operand:W 0 "register_operand")
11894 (match_operand:W 1 "memory_operand"))
11895 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11896 (call (mem:QI (match_dup 0))
11897 (match_operand 3))]
11898 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11899 && !reg_mentioned_p (operands[0],
11900 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11901 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11902 (parallel [(call (mem:QI (match_dup 1))
11904 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11906 (define_expand "call_pop"
11907 [(parallel [(call (match_operand:QI 0)
11908 (match_operand:SI 1))
11909 (set (reg:SI SP_REG)
11910 (plus:SI (reg:SI SP_REG)
11911 (match_operand:SI 3)))])]
11914 ix86_expand_call (NULL, operands[0], operands[1],
11915 operands[2], operands[3], false);
11919 (define_insn "*call_pop"
11920 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11922 (set (reg:SI SP_REG)
11923 (plus:SI (reg:SI SP_REG)
11924 (match_operand:SI 2 "immediate_operand" "i")))]
11925 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11926 "* return ix86_output_call_insn (insn, operands[0]);"
11927 [(set_attr "type" "call")])
11929 (define_insn "*sibcall_pop"
11930 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11932 (set (reg:SI SP_REG)
11933 (plus:SI (reg:SI SP_REG)
11934 (match_operand:SI 2 "immediate_operand" "i")))]
11935 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11936 "* return ix86_output_call_insn (insn, operands[0]);"
11937 [(set_attr "type" "call")])
11939 (define_insn "*sibcall_pop_memory"
11940 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11942 (set (reg:SI SP_REG)
11943 (plus:SI (reg:SI SP_REG)
11944 (match_operand:SI 2 "immediate_operand" "i")))
11945 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11947 "* return ix86_output_call_insn (insn, operands[0]);"
11948 [(set_attr "type" "call")])
11951 [(set (match_operand:SI 0 "register_operand")
11952 (match_operand:SI 1 "memory_operand"))
11953 (parallel [(call (mem:QI (match_dup 0))
11955 (set (reg:SI SP_REG)
11956 (plus:SI (reg:SI SP_REG)
11957 (match_operand:SI 4 "immediate_operand")))])]
11958 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11959 && !reg_mentioned_p (operands[0],
11960 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11961 [(parallel [(call (mem:QI (match_dup 1))
11963 (set (reg:SI SP_REG)
11964 (plus:SI (reg:SI SP_REG)
11966 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11969 [(set (match_operand:SI 0 "register_operand")
11970 (match_operand:SI 1 "memory_operand"))
11971 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11972 (parallel [(call (mem:QI (match_dup 0))
11974 (set (reg:SI SP_REG)
11975 (plus:SI (reg:SI SP_REG)
11976 (match_operand:SI 4 "immediate_operand")))])]
11977 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11978 && !reg_mentioned_p (operands[0],
11979 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11980 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11981 (parallel [(call (mem:QI (match_dup 1))
11983 (set (reg:SI SP_REG)
11984 (plus:SI (reg:SI SP_REG)
11986 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11988 ;; Combining simple memory jump instruction
11991 [(set (match_operand:W 0 "register_operand")
11992 (match_operand:W 1 "memory_operand"))
11993 (set (pc) (match_dup 0))]
11994 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11995 [(set (pc) (match_dup 1))])
11997 ;; Call subroutine, returning value in operand 0
11999 (define_expand "call_value"
12000 [(set (match_operand 0)
12001 (call (match_operand:QI 1)
12002 (match_operand 2)))
12003 (use (match_operand 3))]
12006 ix86_expand_call (operands[0], operands[1], operands[2],
12007 operands[3], NULL, false);
12011 (define_expand "sibcall_value"
12012 [(set (match_operand 0)
12013 (call (match_operand:QI 1)
12014 (match_operand 2)))
12015 (use (match_operand 3))]
12018 ix86_expand_call (operands[0], operands[1], operands[2],
12019 operands[3], NULL, true);
12023 (define_insn "*call_value"
12024 [(set (match_operand 0)
12025 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12026 (match_operand 2)))]
12027 "!SIBLING_CALL_P (insn)"
12028 "* return ix86_output_call_insn (insn, operands[1]);"
12029 [(set_attr "type" "callv")])
12031 ;; This covers both call and sibcall since only GOT slot is allowed.
12032 (define_insn "*call_value_got_x32"
12033 [(set (match_operand 0)
12036 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12037 (match_operand 2)))]
12039 "* return ix86_output_call_insn (insn, operands[1]);"
12040 [(set_attr "type" "callv")])
12042 (define_insn "*sibcall_value"
12043 [(set (match_operand 0)
12044 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12045 (match_operand 2)))]
12046 "SIBLING_CALL_P (insn)"
12047 "* return ix86_output_call_insn (insn, operands[1]);"
12048 [(set_attr "type" "callv")])
12050 (define_insn "*sibcall_value_memory"
12051 [(set (match_operand 0)
12052 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12053 (match_operand 2)))
12054 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12056 "* return ix86_output_call_insn (insn, operands[1]);"
12057 [(set_attr "type" "callv")])
12060 [(set (match_operand:W 0 "register_operand")
12061 (match_operand:W 1 "memory_operand"))
12062 (set (match_operand 2)
12063 (call (mem:QI (match_dup 0))
12064 (match_operand 3)))]
12065 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12066 && !reg_mentioned_p (operands[0],
12067 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12068 [(parallel [(set (match_dup 2)
12069 (call (mem:QI (match_dup 1))
12071 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12074 [(set (match_operand:W 0 "register_operand")
12075 (match_operand:W 1 "memory_operand"))
12076 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12077 (set (match_operand 2)
12078 (call (mem:QI (match_dup 0))
12079 (match_operand 3)))]
12080 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12081 && !reg_mentioned_p (operands[0],
12082 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12083 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12084 (parallel [(set (match_dup 2)
12085 (call (mem:QI (match_dup 1))
12087 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12089 (define_expand "call_value_pop"
12090 [(parallel [(set (match_operand 0)
12091 (call (match_operand:QI 1)
12092 (match_operand:SI 2)))
12093 (set (reg:SI SP_REG)
12094 (plus:SI (reg:SI SP_REG)
12095 (match_operand:SI 4)))])]
12098 ix86_expand_call (operands[0], operands[1], operands[2],
12099 operands[3], operands[4], false);
12103 (define_insn "*call_value_pop"
12104 [(set (match_operand 0)
12105 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12106 (match_operand 2)))
12107 (set (reg:SI SP_REG)
12108 (plus:SI (reg:SI SP_REG)
12109 (match_operand:SI 3 "immediate_operand" "i")))]
12110 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12111 "* return ix86_output_call_insn (insn, operands[1]);"
12112 [(set_attr "type" "callv")])
12114 (define_insn "*sibcall_value_pop"
12115 [(set (match_operand 0)
12116 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12117 (match_operand 2)))
12118 (set (reg:SI SP_REG)
12119 (plus:SI (reg:SI SP_REG)
12120 (match_operand:SI 3 "immediate_operand" "i")))]
12121 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12122 "* return ix86_output_call_insn (insn, operands[1]);"
12123 [(set_attr "type" "callv")])
12125 (define_insn "*sibcall_value_pop_memory"
12126 [(set (match_operand 0)
12127 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12128 (match_operand 2)))
12129 (set (reg:SI SP_REG)
12130 (plus:SI (reg:SI SP_REG)
12131 (match_operand:SI 3 "immediate_operand" "i")))
12132 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12134 "* return ix86_output_call_insn (insn, operands[1]);"
12135 [(set_attr "type" "callv")])
12138 [(set (match_operand:SI 0 "register_operand")
12139 (match_operand:SI 1 "memory_operand"))
12140 (parallel [(set (match_operand 2)
12141 (call (mem:QI (match_dup 0))
12142 (match_operand 3)))
12143 (set (reg:SI SP_REG)
12144 (plus:SI (reg:SI SP_REG)
12145 (match_operand:SI 4 "immediate_operand")))])]
12146 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12147 && !reg_mentioned_p (operands[0],
12148 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12149 [(parallel [(set (match_dup 2)
12150 (call (mem:QI (match_dup 1))
12152 (set (reg:SI SP_REG)
12153 (plus:SI (reg:SI SP_REG)
12155 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12158 [(set (match_operand:SI 0 "register_operand")
12159 (match_operand:SI 1 "memory_operand"))
12160 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12161 (parallel [(set (match_operand 2)
12162 (call (mem:QI (match_dup 0))
12163 (match_operand 3)))
12164 (set (reg:SI SP_REG)
12165 (plus:SI (reg:SI SP_REG)
12166 (match_operand:SI 4 "immediate_operand")))])]
12167 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12168 && !reg_mentioned_p (operands[0],
12169 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12170 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12171 (parallel [(set (match_dup 2)
12172 (call (mem:QI (match_dup 1))
12174 (set (reg:SI SP_REG)
12175 (plus:SI (reg:SI SP_REG)
12177 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12179 ;; Call subroutine returning any type.
12181 (define_expand "untyped_call"
12182 [(parallel [(call (match_operand 0)
12185 (match_operand 2)])]
12190 /* In order to give reg-stack an easier job in validating two
12191 coprocessor registers as containing a possible return value,
12192 simply pretend the untyped call returns a complex long double
12195 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12196 and should have the default ABI. */
12198 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12199 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12200 operands[0], const0_rtx,
12201 GEN_INT ((TARGET_64BIT
12202 ? (ix86_abi == SYSV_ABI
12203 ? X86_64_SSE_REGPARM_MAX
12204 : X86_64_MS_SSE_REGPARM_MAX)
12205 : X86_32_SSE_REGPARM_MAX)
12209 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12211 rtx set = XVECEXP (operands[2], 0, i);
12212 emit_move_insn (SET_DEST (set), SET_SRC (set));
12215 /* The optimizer does not know that the call sets the function value
12216 registers we stored in the result block. We avoid problems by
12217 claiming that all hard registers are used and clobbered at this
12219 emit_insn (gen_blockage ());
12224 ;; Prologue and epilogue instructions
12226 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12227 ;; all of memory. This blocks insns from being moved across this point.
12229 (define_insn "blockage"
12230 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12233 [(set_attr "length" "0")])
12235 ;; Do not schedule instructions accessing memory across this point.
12237 (define_expand "memory_blockage"
12238 [(set (match_dup 0)
12239 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12242 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12243 MEM_VOLATILE_P (operands[0]) = 1;
12246 (define_insn "*memory_blockage"
12247 [(set (match_operand:BLK 0)
12248 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12251 [(set_attr "length" "0")])
12253 ;; As USE insns aren't meaningful after reload, this is used instead
12254 ;; to prevent deleting instructions setting registers for PIC code
12255 (define_insn "prologue_use"
12256 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12259 [(set_attr "length" "0")])
12261 ;; Insn emitted into the body of a function to return from a function.
12262 ;; This is only done if the function's epilogue is known to be simple.
12263 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12265 (define_expand "return"
12267 "ix86_can_use_return_insn_p ()"
12269 if (crtl->args.pops_args)
12271 rtx popc = GEN_INT (crtl->args.pops_args);
12272 emit_jump_insn (gen_simple_return_pop_internal (popc));
12277 ;; We need to disable this for TARGET_SEH, as otherwise
12278 ;; shrink-wrapped prologue gets enabled too. This might exceed
12279 ;; the maximum size of prologue in unwind information.
12280 ;; Also disallow shrink-wrapping if using stack slot to pass the
12281 ;; static chain pointer - the first instruction has to be pushl %esi
12282 ;; and it can't be moved around, as we use alternate entry points
12285 (define_expand "simple_return"
12287 "!TARGET_SEH && !ix86_static_chain_on_stack"
12289 if (crtl->args.pops_args)
12291 rtx popc = GEN_INT (crtl->args.pops_args);
12292 emit_jump_insn (gen_simple_return_pop_internal (popc));
12297 (define_insn "simple_return_internal"
12301 [(set_attr "length" "1")
12302 (set_attr "atom_unit" "jeu")
12303 (set_attr "length_immediate" "0")
12304 (set_attr "modrm" "0")
12305 (set_attr "maybe_prefix_bnd" "1")])
12307 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12308 ;; instruction Athlon and K8 have.
12310 (define_insn "simple_return_internal_long"
12312 (unspec [(const_int 0)] UNSPEC_REP)]
12315 if (ix86_bnd_prefixed_insn_p (insn))
12318 return "rep%; ret";
12320 [(set_attr "length" "2")
12321 (set_attr "atom_unit" "jeu")
12322 (set_attr "length_immediate" "0")
12323 (set_attr "prefix_rep" "1")
12324 (set_attr "modrm" "0")])
12326 (define_insn "simple_return_pop_internal"
12328 (use (match_operand:SI 0 "const_int_operand"))]
12331 [(set_attr "length" "3")
12332 (set_attr "atom_unit" "jeu")
12333 (set_attr "length_immediate" "2")
12334 (set_attr "modrm" "0")
12335 (set_attr "maybe_prefix_bnd" "1")])
12337 (define_insn "simple_return_indirect_internal"
12339 (use (match_operand:SI 0 "register_operand" "r"))]
12342 [(set_attr "type" "ibr")
12343 (set_attr "length_immediate" "0")
12344 (set_attr "maybe_prefix_bnd" "1")])
12350 [(set_attr "length" "1")
12351 (set_attr "length_immediate" "0")
12352 (set_attr "modrm" "0")])
12354 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12355 (define_insn "nops"
12356 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12360 int num = INTVAL (operands[0]);
12362 gcc_assert (IN_RANGE (num, 1, 8));
12365 fputs ("\tnop\n", asm_out_file);
12369 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12370 (set_attr "length_immediate" "0")
12371 (set_attr "modrm" "0")])
12373 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12374 ;; branch prediction penalty for the third jump in a 16-byte
12378 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12381 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12382 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12384 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12385 The align insn is used to avoid 3 jump instructions in the row to improve
12386 branch prediction and the benefits hardly outweigh the cost of extra 8
12387 nops on the average inserted by full alignment pseudo operation. */
12391 [(set_attr "length" "16")])
12393 (define_expand "prologue"
12396 "ix86_expand_prologue (); DONE;")
12398 (define_insn "set_got"
12399 [(set (match_operand:SI 0 "register_operand" "=r")
12400 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12401 (clobber (reg:CC FLAGS_REG))]
12403 "* return output_set_got (operands[0], NULL_RTX);"
12404 [(set_attr "type" "multi")
12405 (set_attr "length" "12")])
12407 (define_insn "set_got_labelled"
12408 [(set (match_operand:SI 0 "register_operand" "=r")
12409 (unspec:SI [(label_ref (match_operand 1))]
12411 (clobber (reg:CC FLAGS_REG))]
12413 "* return output_set_got (operands[0], operands[1]);"
12414 [(set_attr "type" "multi")
12415 (set_attr "length" "12")])
12417 (define_insn "set_got_rex64"
12418 [(set (match_operand:DI 0 "register_operand" "=r")
12419 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12421 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12422 [(set_attr "type" "lea")
12423 (set_attr "length_address" "4")
12424 (set_attr "mode" "DI")])
12426 (define_insn "set_rip_rex64"
12427 [(set (match_operand:DI 0 "register_operand" "=r")
12428 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12430 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12431 [(set_attr "type" "lea")
12432 (set_attr "length_address" "4")
12433 (set_attr "mode" "DI")])
12435 (define_insn "set_got_offset_rex64"
12436 [(set (match_operand:DI 0 "register_operand" "=r")
12438 [(label_ref (match_operand 1))]
12439 UNSPEC_SET_GOT_OFFSET))]
12441 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12442 [(set_attr "type" "imov")
12443 (set_attr "length_immediate" "0")
12444 (set_attr "length_address" "8")
12445 (set_attr "mode" "DI")])
12447 (define_expand "epilogue"
12450 "ix86_expand_epilogue (1); DONE;")
12452 (define_expand "sibcall_epilogue"
12455 "ix86_expand_epilogue (0); DONE;")
12457 (define_expand "eh_return"
12458 [(use (match_operand 0 "register_operand"))]
12461 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12463 /* Tricky bit: we write the address of the handler to which we will
12464 be returning into someone else's stack frame, one word below the
12465 stack address we wish to restore. */
12466 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12467 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12468 tmp = gen_rtx_MEM (Pmode, tmp);
12469 emit_move_insn (tmp, ra);
12471 emit_jump_insn (gen_eh_return_internal ());
12476 (define_insn_and_split "eh_return_internal"
12480 "epilogue_completed"
12482 "ix86_expand_epilogue (2); DONE;")
12484 (define_insn "leave"
12485 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12486 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12487 (clobber (mem:BLK (scratch)))]
12490 [(set_attr "type" "leave")])
12492 (define_insn "leave_rex64"
12493 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12494 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12495 (clobber (mem:BLK (scratch)))]
12498 [(set_attr "type" "leave")])
12500 ;; Handle -fsplit-stack.
12502 (define_expand "split_stack_prologue"
12506 ix86_expand_split_stack_prologue ();
12510 ;; In order to support the call/return predictor, we use a return
12511 ;; instruction which the middle-end doesn't see.
12512 (define_insn "split_stack_return"
12513 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12514 UNSPECV_SPLIT_STACK_RETURN)]
12517 if (operands[0] == const0_rtx)
12522 [(set_attr "atom_unit" "jeu")
12523 (set_attr "modrm" "0")
12524 (set (attr "length")
12525 (if_then_else (match_operand:SI 0 "const0_operand")
12528 (set (attr "length_immediate")
12529 (if_then_else (match_operand:SI 0 "const0_operand")
12533 ;; If there are operand 0 bytes available on the stack, jump to
12536 (define_expand "split_stack_space_check"
12537 [(set (pc) (if_then_else
12538 (ltu (minus (reg SP_REG)
12539 (match_operand 0 "register_operand"))
12540 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12541 (label_ref (match_operand 1))
12545 rtx reg, size, limit;
12547 reg = gen_reg_rtx (Pmode);
12548 size = force_reg (Pmode, operands[0]);
12549 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12550 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12551 UNSPEC_STACK_CHECK);
12552 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12553 ix86_expand_branch (GEU, reg, limit, operands[1]);
12558 ;; Bit manipulation instructions.
12560 (define_expand "ffs<mode>2"
12561 [(set (match_dup 2) (const_int -1))
12562 (parallel [(set (match_dup 3) (match_dup 4))
12563 (set (match_operand:SWI48 0 "register_operand")
12565 (match_operand:SWI48 1 "nonimmediate_operand")))])
12566 (set (match_dup 0) (if_then_else:SWI48
12567 (eq (match_dup 3) (const_int 0))
12570 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12571 (clobber (reg:CC FLAGS_REG))])]
12574 machine_mode flags_mode;
12576 if (<MODE>mode == SImode && !TARGET_CMOVE)
12578 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12583 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12585 operands[2] = gen_reg_rtx (<MODE>mode);
12586 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12587 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12590 (define_insn_and_split "ffssi2_no_cmove"
12591 [(set (match_operand:SI 0 "register_operand" "=r")
12592 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12593 (clobber (match_scratch:SI 2 "=&q"))
12594 (clobber (reg:CC FLAGS_REG))]
12597 "&& reload_completed"
12598 [(parallel [(set (match_dup 4) (match_dup 5))
12599 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12600 (set (strict_low_part (match_dup 3))
12601 (eq:QI (match_dup 4) (const_int 0)))
12602 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12603 (clobber (reg:CC FLAGS_REG))])
12604 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12605 (clobber (reg:CC FLAGS_REG))])
12606 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12607 (clobber (reg:CC FLAGS_REG))])]
12609 machine_mode flags_mode
12610 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12612 operands[3] = gen_lowpart (QImode, operands[2]);
12613 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12614 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12616 ix86_expand_clear (operands[2]);
12619 (define_insn "*tzcnt<mode>_1"
12620 [(set (reg:CCC FLAGS_REG)
12621 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12623 (set (match_operand:SWI48 0 "register_operand" "=r")
12624 (ctz:SWI48 (match_dup 1)))]
12625 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12626 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12627 [(set_attr "type" "alu1")
12628 (set_attr "prefix_0f" "1")
12629 (set_attr "prefix_rep" "1")
12630 (set_attr "btver2_decode" "double")
12631 (set_attr "mode" "<MODE>")])
12633 (define_insn "*bsf<mode>_1"
12634 [(set (reg:CCZ FLAGS_REG)
12635 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12637 (set (match_operand:SWI48 0 "register_operand" "=r")
12638 (ctz:SWI48 (match_dup 1)))]
12640 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12641 [(set_attr "type" "alu1")
12642 (set_attr "prefix_0f" "1")
12643 (set_attr "btver2_decode" "double")
12644 (set_attr "znver1_decode" "vector")
12645 (set_attr "mode" "<MODE>")])
12647 (define_expand "ctz<mode>2"
12649 [(set (match_operand:SWI248 0 "register_operand")
12651 (match_operand:SWI248 1 "nonimmediate_operand")))
12652 (clobber (reg:CC FLAGS_REG))])])
12654 ; False dependency happens when destination is only updated by tzcnt,
12655 ; lzcnt or popcnt. There is no false dependency when destination is
12656 ; also used in source.
12657 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12658 [(set (match_operand:SWI48 0 "register_operand" "=r")
12660 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12661 (clobber (reg:CC FLAGS_REG))]
12662 "(TARGET_BMI || TARGET_GENERIC)
12663 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12665 "&& reload_completed"
12667 [(set (match_dup 0)
12668 (ctz:SWI48 (match_dup 1)))
12669 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12670 (clobber (reg:CC FLAGS_REG))])]
12672 if (!reg_mentioned_p (operands[0], operands[1]))
12673 ix86_expand_clear (operands[0]);
12676 (define_insn "*ctz<mode>2_falsedep"
12677 [(set (match_operand:SWI48 0 "register_operand" "=r")
12679 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12680 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12681 UNSPEC_INSN_FALSE_DEP)
12682 (clobber (reg:CC FLAGS_REG))]
12686 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12687 else if (TARGET_GENERIC)
12688 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12689 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12691 gcc_unreachable ();
12693 [(set_attr "type" "alu1")
12694 (set_attr "prefix_0f" "1")
12695 (set_attr "prefix_rep" "1")
12696 (set_attr "mode" "<MODE>")])
12698 (define_insn "*ctz<mode>2"
12699 [(set (match_operand:SWI248 0 "register_operand" "=r")
12700 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12701 (clobber (reg:CC FLAGS_REG))]
12705 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12706 else if (optimize_function_for_size_p (cfun))
12708 else if (TARGET_GENERIC)
12709 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12710 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12712 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12714 [(set_attr "type" "alu1")
12715 (set_attr "prefix_0f" "1")
12716 (set (attr "prefix_rep")
12718 (ior (match_test "TARGET_BMI")
12719 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12720 (match_test "TARGET_GENERIC")))
12722 (const_string "0")))
12723 (set_attr "mode" "<MODE>")])
12725 (define_expand "clz<mode>2"
12727 [(set (match_operand:SWI248 0 "register_operand")
12730 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12731 (clobber (reg:CC FLAGS_REG))])
12733 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12734 (clobber (reg:CC FLAGS_REG))])]
12739 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12742 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12745 (define_expand "clz<mode>2_lzcnt"
12747 [(set (match_operand:SWI248 0 "register_operand")
12749 (match_operand:SWI248 1 "nonimmediate_operand")))
12750 (clobber (reg:CC FLAGS_REG))])]
12753 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12754 [(set (match_operand:SWI48 0 "register_operand" "=r")
12756 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12757 (clobber (reg:CC FLAGS_REG))]
12759 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12761 "&& reload_completed"
12763 [(set (match_dup 0)
12764 (clz:SWI48 (match_dup 1)))
12765 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12766 (clobber (reg:CC FLAGS_REG))])]
12768 if (!reg_mentioned_p (operands[0], operands[1]))
12769 ix86_expand_clear (operands[0]);
12772 (define_insn "*clz<mode>2_lzcnt_falsedep"
12773 [(set (match_operand:SWI48 0 "register_operand" "=r")
12775 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12776 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12777 UNSPEC_INSN_FALSE_DEP)
12778 (clobber (reg:CC FLAGS_REG))]
12780 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12781 [(set_attr "prefix_rep" "1")
12782 (set_attr "type" "bitmanip")
12783 (set_attr "mode" "<MODE>")])
12785 (define_insn "*clz<mode>2_lzcnt"
12786 [(set (match_operand:SWI248 0 "register_operand" "=r")
12787 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12788 (clobber (reg:CC FLAGS_REG))]
12790 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12791 [(set_attr "prefix_rep" "1")
12792 (set_attr "type" "bitmanip")
12793 (set_attr "mode" "<MODE>")])
12795 ;; BMI instructions.
12796 (define_insn "*bmi_andn_<mode>"
12797 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12799 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12800 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12801 (clobber (reg:CC FLAGS_REG))]
12803 "andn\t{%2, %1, %0|%0, %1, %2}"
12804 [(set_attr "type" "bitmanip")
12805 (set_attr "btver2_decode" "direct, double")
12806 (set_attr "mode" "<MODE>")])
12808 (define_insn "*bmi_andn_<mode>_ccno"
12809 [(set (reg FLAGS_REG)
12812 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12813 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12815 (clobber (match_scratch:SWI48 0 "=r,r"))]
12816 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12817 "andn\t{%2, %1, %0|%0, %1, %2}"
12818 [(set_attr "type" "bitmanip")
12819 (set_attr "btver2_decode" "direct, double")
12820 (set_attr "mode" "<MODE>")])
12822 (define_insn "bmi_bextr_<mode>"
12823 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12824 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12825 (match_operand:SWI48 2 "register_operand" "r,r")]
12827 (clobber (reg:CC FLAGS_REG))]
12829 "bextr\t{%2, %1, %0|%0, %1, %2}"
12830 [(set_attr "type" "bitmanip")
12831 (set_attr "btver2_decode" "direct, double")
12832 (set_attr "mode" "<MODE>")])
12834 (define_insn "*bmi_bextr_<mode>_ccz"
12835 [(set (reg:CCZ FLAGS_REG)
12837 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12838 (match_operand:SWI48 2 "register_operand" "r,r")]
12841 (clobber (match_scratch:SWI48 0 "=r,r"))]
12843 "bextr\t{%2, %1, %0|%0, %1, %2}"
12844 [(set_attr "type" "bitmanip")
12845 (set_attr "btver2_decode" "direct, double")
12846 (set_attr "mode" "<MODE>")])
12848 (define_insn "*bmi_blsi_<mode>"
12849 [(set (match_operand:SWI48 0 "register_operand" "=r")
12852 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12854 (clobber (reg:CC FLAGS_REG))]
12856 "blsi\t{%1, %0|%0, %1}"
12857 [(set_attr "type" "bitmanip")
12858 (set_attr "btver2_decode" "double")
12859 (set_attr "mode" "<MODE>")])
12861 (define_insn "*bmi_blsmsk_<mode>"
12862 [(set (match_operand:SWI48 0 "register_operand" "=r")
12865 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12868 (clobber (reg:CC FLAGS_REG))]
12870 "blsmsk\t{%1, %0|%0, %1}"
12871 [(set_attr "type" "bitmanip")
12872 (set_attr "btver2_decode" "double")
12873 (set_attr "mode" "<MODE>")])
12875 (define_insn "*bmi_blsr_<mode>"
12876 [(set (match_operand:SWI48 0 "register_operand" "=r")
12879 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12882 (clobber (reg:CC FLAGS_REG))]
12884 "blsr\t{%1, %0|%0, %1}"
12885 [(set_attr "type" "bitmanip")
12886 (set_attr "btver2_decode" "double")
12887 (set_attr "mode" "<MODE>")])
12889 ;; BMI2 instructions.
12890 (define_expand "bmi2_bzhi_<mode>3"
12892 [(set (match_operand:SWI48 0 "register_operand")
12893 (zero_extract:SWI48
12894 (match_operand:SWI48 1 "nonimmediate_operand")
12896 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12900 (clobber (reg:CC FLAGS_REG))])]
12902 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12904 (define_insn "*bmi2_bzhi_<mode>3"
12905 [(set (match_operand:SWI48 0 "register_operand" "=r")
12906 (zero_extract:SWI48
12907 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12909 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12911 (match_operand:SWI48 3 "const_int_operand" "n"))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12915 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12916 [(set_attr "type" "bitmanip")
12917 (set_attr "prefix" "vex")
12918 (set_attr "mode" "<MODE>")])
12920 (define_mode_attr k [(SI "k") (DI "q")])
12922 (define_insn "*bmi2_bzhi_<mode>3_1"
12923 [(set (match_operand:SWI48 0 "register_operand" "=r")
12924 (zero_extract:SWI48
12925 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12927 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12928 (match_operand:SWI48 3 "const_int_operand" "n"))
12930 (clobber (reg:CC FLAGS_REG))]
12931 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12932 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12933 [(set_attr "type" "bitmanip")
12934 (set_attr "prefix" "vex")
12935 (set_attr "mode" "<MODE>")])
12937 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12938 [(set (reg:CCZ FLAGS_REG)
12940 (zero_extract:SWI48
12941 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12943 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12944 (match_operand:SWI48 3 "const_int_operand" "n"))
12947 (clobber (match_scratch:SWI48 0 "=r"))]
12948 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12949 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12950 [(set_attr "type" "bitmanip")
12951 (set_attr "prefix" "vex")
12952 (set_attr "mode" "<MODE>")])
12954 (define_insn "bmi2_pdep_<mode>3"
12955 [(set (match_operand:SWI48 0 "register_operand" "=r")
12956 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12957 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12960 "pdep\t{%2, %1, %0|%0, %1, %2}"
12961 [(set_attr "type" "bitmanip")
12962 (set_attr "prefix" "vex")
12963 (set_attr "mode" "<MODE>")])
12965 (define_insn "bmi2_pext_<mode>3"
12966 [(set (match_operand:SWI48 0 "register_operand" "=r")
12967 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12968 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12971 "pext\t{%2, %1, %0|%0, %1, %2}"
12972 [(set_attr "type" "bitmanip")
12973 (set_attr "prefix" "vex")
12974 (set_attr "mode" "<MODE>")])
12976 ;; TBM instructions.
12977 (define_insn "tbm_bextri_<mode>"
12978 [(set (match_operand:SWI48 0 "register_operand" "=r")
12979 (zero_extract:SWI48
12980 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12981 (match_operand 2 "const_0_to_255_operand" "N")
12982 (match_operand 3 "const_0_to_255_operand" "N")))
12983 (clobber (reg:CC FLAGS_REG))]
12986 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12987 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12989 [(set_attr "type" "bitmanip")
12990 (set_attr "mode" "<MODE>")])
12992 (define_insn "*tbm_blcfill_<mode>"
12993 [(set (match_operand:SWI48 0 "register_operand" "=r")
12996 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12999 (clobber (reg:CC FLAGS_REG))]
13001 "blcfill\t{%1, %0|%0, %1}"
13002 [(set_attr "type" "bitmanip")
13003 (set_attr "mode" "<MODE>")])
13005 (define_insn "*tbm_blci_<mode>"
13006 [(set (match_operand:SWI48 0 "register_operand" "=r")
13010 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13013 (clobber (reg:CC FLAGS_REG))]
13015 "blci\t{%1, %0|%0, %1}"
13016 [(set_attr "type" "bitmanip")
13017 (set_attr "mode" "<MODE>")])
13019 (define_insn "*tbm_blcic_<mode>"
13020 [(set (match_operand:SWI48 0 "register_operand" "=r")
13023 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13027 (clobber (reg:CC FLAGS_REG))]
13029 "blcic\t{%1, %0|%0, %1}"
13030 [(set_attr "type" "bitmanip")
13031 (set_attr "mode" "<MODE>")])
13033 (define_insn "*tbm_blcmsk_<mode>"
13034 [(set (match_operand:SWI48 0 "register_operand" "=r")
13037 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13040 (clobber (reg:CC FLAGS_REG))]
13042 "blcmsk\t{%1, %0|%0, %1}"
13043 [(set_attr "type" "bitmanip")
13044 (set_attr "mode" "<MODE>")])
13046 (define_insn "*tbm_blcs_<mode>"
13047 [(set (match_operand:SWI48 0 "register_operand" "=r")
13050 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13053 (clobber (reg:CC FLAGS_REG))]
13055 "blcs\t{%1, %0|%0, %1}"
13056 [(set_attr "type" "bitmanip")
13057 (set_attr "mode" "<MODE>")])
13059 (define_insn "*tbm_blsfill_<mode>"
13060 [(set (match_operand:SWI48 0 "register_operand" "=r")
13063 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13066 (clobber (reg:CC FLAGS_REG))]
13068 "blsfill\t{%1, %0|%0, %1}"
13069 [(set_attr "type" "bitmanip")
13070 (set_attr "mode" "<MODE>")])
13072 (define_insn "*tbm_blsic_<mode>"
13073 [(set (match_operand:SWI48 0 "register_operand" "=r")
13076 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13080 (clobber (reg:CC FLAGS_REG))]
13082 "blsic\t{%1, %0|%0, %1}"
13083 [(set_attr "type" "bitmanip")
13084 (set_attr "mode" "<MODE>")])
13086 (define_insn "*tbm_t1mskc_<mode>"
13087 [(set (match_operand:SWI48 0 "register_operand" "=r")
13090 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13094 (clobber (reg:CC FLAGS_REG))]
13096 "t1mskc\t{%1, %0|%0, %1}"
13097 [(set_attr "type" "bitmanip")
13098 (set_attr "mode" "<MODE>")])
13100 (define_insn "*tbm_tzmsk_<mode>"
13101 [(set (match_operand:SWI48 0 "register_operand" "=r")
13104 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13108 (clobber (reg:CC FLAGS_REG))]
13110 "tzmsk\t{%1, %0|%0, %1}"
13111 [(set_attr "type" "bitmanip")
13112 (set_attr "mode" "<MODE>")])
13114 (define_insn "bsr_rex64"
13115 [(set (match_operand:DI 0 "register_operand" "=r")
13116 (minus:DI (const_int 63)
13117 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13118 (clobber (reg:CC FLAGS_REG))]
13120 "bsr{q}\t{%1, %0|%0, %1}"
13121 [(set_attr "type" "alu1")
13122 (set_attr "prefix_0f" "1")
13123 (set_attr "znver1_decode" "vector")
13124 (set_attr "mode" "DI")])
13127 [(set (match_operand:SI 0 "register_operand" "=r")
13128 (minus:SI (const_int 31)
13129 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13130 (clobber (reg:CC FLAGS_REG))]
13132 "bsr{l}\t{%1, %0|%0, %1}"
13133 [(set_attr "type" "alu1")
13134 (set_attr "prefix_0f" "1")
13135 (set_attr "znver1_decode" "vector")
13136 (set_attr "mode" "SI")])
13138 (define_insn "*bsrhi"
13139 [(set (match_operand:HI 0 "register_operand" "=r")
13140 (minus:HI (const_int 15)
13141 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13142 (clobber (reg:CC FLAGS_REG))]
13144 "bsr{w}\t{%1, %0|%0, %1}"
13145 [(set_attr "type" "alu1")
13146 (set_attr "prefix_0f" "1")
13147 (set_attr "znver1_decode" "vector")
13148 (set_attr "mode" "HI")])
13150 (define_expand "popcount<mode>2"
13152 [(set (match_operand:SWI248 0 "register_operand")
13154 (match_operand:SWI248 1 "nonimmediate_operand")))
13155 (clobber (reg:CC FLAGS_REG))])]
13158 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13159 [(set (match_operand:SWI48 0 "register_operand" "=r")
13161 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13162 (clobber (reg:CC FLAGS_REG))]
13164 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13166 "&& reload_completed"
13168 [(set (match_dup 0)
13169 (popcount:SWI48 (match_dup 1)))
13170 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13171 (clobber (reg:CC FLAGS_REG))])]
13173 if (!reg_mentioned_p (operands[0], operands[1]))
13174 ix86_expand_clear (operands[0]);
13177 (define_insn "*popcount<mode>2_falsedep"
13178 [(set (match_operand:SWI48 0 "register_operand" "=r")
13180 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13181 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13182 UNSPEC_INSN_FALSE_DEP)
13183 (clobber (reg:CC FLAGS_REG))]
13187 return "popcnt\t{%1, %0|%0, %1}";
13189 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13192 [(set_attr "prefix_rep" "1")
13193 (set_attr "type" "bitmanip")
13194 (set_attr "mode" "<MODE>")])
13196 (define_insn "*popcount<mode>2"
13197 [(set (match_operand:SWI248 0 "register_operand" "=r")
13199 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13200 (clobber (reg:CC FLAGS_REG))]
13204 return "popcnt\t{%1, %0|%0, %1}";
13206 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13209 [(set_attr "prefix_rep" "1")
13210 (set_attr "type" "bitmanip")
13211 (set_attr "mode" "<MODE>")])
13213 (define_expand "bswapdi2"
13214 [(set (match_operand:DI 0 "register_operand")
13215 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13219 operands[1] = force_reg (DImode, operands[1]);
13222 (define_expand "bswapsi2"
13223 [(set (match_operand:SI 0 "register_operand")
13224 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13229 else if (TARGET_BSWAP)
13230 operands[1] = force_reg (SImode, operands[1]);
13233 rtx x = operands[0];
13235 emit_move_insn (x, operands[1]);
13236 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13237 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13238 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13243 (define_insn "*bswap<mode>2_movbe"
13244 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13245 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13247 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13250 movbe\t{%1, %0|%0, %1}
13251 movbe\t{%1, %0|%0, %1}"
13252 [(set_attr "type" "bitmanip,imov,imov")
13253 (set_attr "modrm" "0,1,1")
13254 (set_attr "prefix_0f" "*,1,1")
13255 (set_attr "prefix_extra" "*,1,1")
13256 (set_attr "mode" "<MODE>")])
13258 (define_insn "*bswap<mode>2"
13259 [(set (match_operand:SWI48 0 "register_operand" "=r")
13260 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13263 [(set_attr "type" "bitmanip")
13264 (set_attr "modrm" "0")
13265 (set_attr "mode" "<MODE>")])
13267 (define_insn "*bswaphi_lowpart_1"
13268 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13269 (bswap:HI (match_dup 0)))
13270 (clobber (reg:CC FLAGS_REG))]
13271 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13273 xchg{b}\t{%h0, %b0|%b0, %h0}
13274 rol{w}\t{$8, %0|%0, 8}"
13275 [(set_attr "length" "2,4")
13276 (set_attr "mode" "QI,HI")])
13278 (define_insn "bswaphi_lowpart"
13279 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13280 (bswap:HI (match_dup 0)))
13281 (clobber (reg:CC FLAGS_REG))]
13283 "rol{w}\t{$8, %0|%0, 8}"
13284 [(set_attr "length" "4")
13285 (set_attr "mode" "HI")])
13287 (define_expand "paritydi2"
13288 [(set (match_operand:DI 0 "register_operand")
13289 (parity:DI (match_operand:DI 1 "register_operand")))]
13292 rtx scratch = gen_reg_rtx (QImode);
13295 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13296 NULL_RTX, operands[1]));
13298 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13299 gen_rtx_REG (CCmode, FLAGS_REG),
13301 emit_insn (gen_rtx_SET (scratch, cond));
13304 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13307 rtx tmp = gen_reg_rtx (SImode);
13309 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13310 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13315 (define_expand "paritysi2"
13316 [(set (match_operand:SI 0 "register_operand")
13317 (parity:SI (match_operand:SI 1 "register_operand")))]
13320 rtx scratch = gen_reg_rtx (QImode);
13323 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13325 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13326 gen_rtx_REG (CCmode, FLAGS_REG),
13328 emit_insn (gen_rtx_SET (scratch, cond));
13330 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13334 (define_insn_and_split "paritydi2_cmp"
13335 [(set (reg:CC FLAGS_REG)
13336 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13338 (clobber (match_scratch:DI 0 "=r"))
13339 (clobber (match_scratch:SI 1 "=&r"))
13340 (clobber (match_scratch:HI 2 "=Q"))]
13343 "&& reload_completed"
13345 [(set (match_dup 1)
13346 (xor:SI (match_dup 1) (match_dup 4)))
13347 (clobber (reg:CC FLAGS_REG))])
13349 [(set (reg:CC FLAGS_REG)
13350 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13351 (clobber (match_dup 1))
13352 (clobber (match_dup 2))])]
13354 operands[4] = gen_lowpart (SImode, operands[3]);
13358 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13359 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13362 operands[1] = gen_highpart (SImode, operands[3]);
13365 (define_insn_and_split "paritysi2_cmp"
13366 [(set (reg:CC FLAGS_REG)
13367 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13369 (clobber (match_scratch:SI 0 "=r"))
13370 (clobber (match_scratch:HI 1 "=&Q"))]
13373 "&& reload_completed"
13375 [(set (match_dup 1)
13376 (xor:HI (match_dup 1) (match_dup 3)))
13377 (clobber (reg:CC FLAGS_REG))])
13379 [(set (reg:CC FLAGS_REG)
13380 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13381 (clobber (match_dup 1))])]
13383 operands[3] = gen_lowpart (HImode, operands[2]);
13385 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13386 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13389 (define_insn "*parityhi2_cmp"
13390 [(set (reg:CC FLAGS_REG)
13391 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13393 (clobber (match_scratch:HI 0 "=Q"))]
13395 "xor{b}\t{%h0, %b0|%b0, %h0}"
13396 [(set_attr "length" "2")
13397 (set_attr "mode" "HI")])
13400 ;; Thread-local storage patterns for ELF.
13402 ;; Note that these code sequences must appear exactly as shown
13403 ;; in order to allow linker relaxation.
13405 (define_insn "*tls_global_dynamic_32_gnu"
13406 [(set (match_operand:SI 0 "register_operand" "=a")
13408 [(match_operand:SI 1 "register_operand" "b")
13409 (match_operand 2 "tls_symbolic_operand")
13410 (match_operand 3 "constant_call_address_operand" "Bz")
13413 (clobber (match_scratch:SI 4 "=d"))
13414 (clobber (match_scratch:SI 5 "=c"))
13415 (clobber (reg:CC FLAGS_REG))]
13416 "!TARGET_64BIT && TARGET_GNU_TLS"
13419 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13420 if (TARGET_SUN_TLS)
13421 #ifdef HAVE_AS_IX86_TLSGDPLT
13422 return "call\t%a2@tlsgdplt";
13424 return "call\t%p3@plt";
13426 return "call\t%P3";
13428 [(set_attr "type" "multi")
13429 (set_attr "length" "12")])
13431 (define_expand "tls_global_dynamic_32"
13433 [(set (match_operand:SI 0 "register_operand")
13434 (unspec:SI [(match_operand:SI 2 "register_operand")
13435 (match_operand 1 "tls_symbolic_operand")
13436 (match_operand 3 "constant_call_address_operand")
13439 (clobber (match_scratch:SI 4))
13440 (clobber (match_scratch:SI 5))
13441 (clobber (reg:CC FLAGS_REG))])]
13443 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13445 (define_insn "*tls_global_dynamic_64_<mode>"
13446 [(set (match_operand:P 0 "register_operand" "=a")
13448 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13449 (match_operand 3)))
13450 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13456 fputs (ASM_BYTE "0x66\n", asm_out_file);
13458 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13459 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13460 fputs ("\trex64\n", asm_out_file);
13461 if (TARGET_SUN_TLS)
13462 return "call\t%p2@plt";
13463 return "call\t%P2";
13465 [(set_attr "type" "multi")
13466 (set (attr "length")
13467 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13469 (define_insn "*tls_global_dynamic_64_largepic"
13470 [(set (match_operand:DI 0 "register_operand" "=a")
13472 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13473 (match_operand:DI 3 "immediate_operand" "i")))
13474 (match_operand 4)))
13475 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13478 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13479 && GET_CODE (operands[3]) == CONST
13480 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13481 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13484 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13485 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13486 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13487 return "call\t{*%%rax|rax}";
13489 [(set_attr "type" "multi")
13490 (set_attr "length" "22")])
13492 (define_expand "tls_global_dynamic_64_<mode>"
13494 [(set (match_operand:P 0 "register_operand")
13496 (mem:QI (match_operand 2))
13498 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13502 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13504 (define_insn "*tls_local_dynamic_base_32_gnu"
13505 [(set (match_operand:SI 0 "register_operand" "=a")
13507 [(match_operand:SI 1 "register_operand" "b")
13508 (match_operand 2 "constant_call_address_operand" "Bz")
13510 UNSPEC_TLS_LD_BASE))
13511 (clobber (match_scratch:SI 3 "=d"))
13512 (clobber (match_scratch:SI 4 "=c"))
13513 (clobber (reg:CC FLAGS_REG))]
13514 "!TARGET_64BIT && TARGET_GNU_TLS"
13517 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13518 if (TARGET_SUN_TLS)
13520 if (HAVE_AS_IX86_TLSLDMPLT)
13521 return "call\t%&@tlsldmplt";
13523 return "call\t%p2@plt";
13525 return "call\t%P2";
13527 [(set_attr "type" "multi")
13528 (set_attr "length" "11")])
13530 (define_expand "tls_local_dynamic_base_32"
13532 [(set (match_operand:SI 0 "register_operand")
13534 [(match_operand:SI 1 "register_operand")
13535 (match_operand 2 "constant_call_address_operand")
13537 UNSPEC_TLS_LD_BASE))
13538 (clobber (match_scratch:SI 3))
13539 (clobber (match_scratch:SI 4))
13540 (clobber (reg:CC FLAGS_REG))])]
13542 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13544 (define_insn "*tls_local_dynamic_base_64_<mode>"
13545 [(set (match_operand:P 0 "register_operand" "=a")
13547 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13548 (match_operand 2)))
13549 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13553 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13554 if (TARGET_SUN_TLS)
13555 return "call\t%p1@plt";
13556 return "call\t%P1";
13558 [(set_attr "type" "multi")
13559 (set_attr "length" "12")])
13561 (define_insn "*tls_local_dynamic_base_64_largepic"
13562 [(set (match_operand:DI 0 "register_operand" "=a")
13564 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13565 (match_operand:DI 2 "immediate_operand" "i")))
13566 (match_operand 3)))
13567 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13568 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13569 && GET_CODE (operands[2]) == CONST
13570 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13571 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13574 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13575 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13576 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13577 return "call\t{*%%rax|rax}";
13579 [(set_attr "type" "multi")
13580 (set_attr "length" "22")])
13582 (define_expand "tls_local_dynamic_base_64_<mode>"
13584 [(set (match_operand:P 0 "register_operand")
13586 (mem:QI (match_operand 1))
13588 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13590 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13592 ;; Local dynamic of a single variable is a lose. Show combine how
13593 ;; to convert that back to global dynamic.
13595 (define_insn_and_split "*tls_local_dynamic_32_once"
13596 [(set (match_operand:SI 0 "register_operand" "=a")
13598 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13599 (match_operand 2 "constant_call_address_operand" "Bz")
13601 UNSPEC_TLS_LD_BASE)
13602 (const:SI (unspec:SI
13603 [(match_operand 3 "tls_symbolic_operand")]
13605 (clobber (match_scratch:SI 4 "=d"))
13606 (clobber (match_scratch:SI 5 "=c"))
13607 (clobber (reg:CC FLAGS_REG))]
13612 [(set (match_dup 0)
13613 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13616 (clobber (match_dup 4))
13617 (clobber (match_dup 5))
13618 (clobber (reg:CC FLAGS_REG))])])
13620 ;; Segment register for the thread base ptr load
13621 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13623 ;; Load and add the thread base pointer from %<tp_seg>:0.
13624 (define_insn "*load_tp_x32"
13625 [(set (match_operand:SI 0 "register_operand" "=r")
13626 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13628 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13629 [(set_attr "type" "imov")
13630 (set_attr "modrm" "0")
13631 (set_attr "length" "7")
13632 (set_attr "memory" "load")
13633 (set_attr "imm_disp" "false")])
13635 (define_insn "*load_tp_x32_zext"
13636 [(set (match_operand:DI 0 "register_operand" "=r")
13637 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13639 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13640 [(set_attr "type" "imov")
13641 (set_attr "modrm" "0")
13642 (set_attr "length" "7")
13643 (set_attr "memory" "load")
13644 (set_attr "imm_disp" "false")])
13646 (define_insn "*load_tp_<mode>"
13647 [(set (match_operand:P 0 "register_operand" "=r")
13648 (unspec:P [(const_int 0)] UNSPEC_TP))]
13650 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13651 [(set_attr "type" "imov")
13652 (set_attr "modrm" "0")
13653 (set_attr "length" "7")
13654 (set_attr "memory" "load")
13655 (set_attr "imm_disp" "false")])
13657 (define_insn "*add_tp_x32"
13658 [(set (match_operand:SI 0 "register_operand" "=r")
13659 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13660 (match_operand:SI 1 "register_operand" "0")))
13661 (clobber (reg:CC FLAGS_REG))]
13663 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13664 [(set_attr "type" "alu")
13665 (set_attr "modrm" "0")
13666 (set_attr "length" "7")
13667 (set_attr "memory" "load")
13668 (set_attr "imm_disp" "false")])
13670 (define_insn "*add_tp_x32_zext"
13671 [(set (match_operand:DI 0 "register_operand" "=r")
13673 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13674 (match_operand:SI 1 "register_operand" "0"))))
13675 (clobber (reg:CC FLAGS_REG))]
13677 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13678 [(set_attr "type" "alu")
13679 (set_attr "modrm" "0")
13680 (set_attr "length" "7")
13681 (set_attr "memory" "load")
13682 (set_attr "imm_disp" "false")])
13684 (define_insn "*add_tp_<mode>"
13685 [(set (match_operand:P 0 "register_operand" "=r")
13686 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13687 (match_operand:P 1 "register_operand" "0")))
13688 (clobber (reg:CC FLAGS_REG))]
13690 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13691 [(set_attr "type" "alu")
13692 (set_attr "modrm" "0")
13693 (set_attr "length" "7")
13694 (set_attr "memory" "load")
13695 (set_attr "imm_disp" "false")])
13697 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13698 ;; %rax as destination of the initial executable code sequence.
13699 (define_insn "tls_initial_exec_64_sun"
13700 [(set (match_operand:DI 0 "register_operand" "=a")
13702 [(match_operand 1 "tls_symbolic_operand")]
13703 UNSPEC_TLS_IE_SUN))
13704 (clobber (reg:CC FLAGS_REG))]
13705 "TARGET_64BIT && TARGET_SUN_TLS"
13708 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13709 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13711 [(set_attr "type" "multi")])
13713 ;; GNU2 TLS patterns can be split.
13715 (define_expand "tls_dynamic_gnu2_32"
13716 [(set (match_dup 3)
13717 (plus:SI (match_operand:SI 2 "register_operand")
13719 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13722 [(set (match_operand:SI 0 "register_operand")
13723 (unspec:SI [(match_dup 1) (match_dup 3)
13724 (match_dup 2) (reg:SI SP_REG)]
13726 (clobber (reg:CC FLAGS_REG))])]
13727 "!TARGET_64BIT && TARGET_GNU2_TLS"
13729 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13730 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13733 (define_insn "*tls_dynamic_gnu2_lea_32"
13734 [(set (match_operand:SI 0 "register_operand" "=r")
13735 (plus:SI (match_operand:SI 1 "register_operand" "b")
13737 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13738 UNSPEC_TLSDESC))))]
13739 "!TARGET_64BIT && TARGET_GNU2_TLS"
13740 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13741 [(set_attr "type" "lea")
13742 (set_attr "mode" "SI")
13743 (set_attr "length" "6")
13744 (set_attr "length_address" "4")])
13746 (define_insn "*tls_dynamic_gnu2_call_32"
13747 [(set (match_operand:SI 0 "register_operand" "=a")
13748 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13749 (match_operand:SI 2 "register_operand" "0")
13750 ;; we have to make sure %ebx still points to the GOT
13751 (match_operand:SI 3 "register_operand" "b")
13754 (clobber (reg:CC FLAGS_REG))]
13755 "!TARGET_64BIT && TARGET_GNU2_TLS"
13756 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13757 [(set_attr "type" "call")
13758 (set_attr "length" "2")
13759 (set_attr "length_address" "0")])
13761 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13762 [(set (match_operand:SI 0 "register_operand" "=&a")
13764 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13765 (match_operand:SI 4)
13766 (match_operand:SI 2 "register_operand" "b")
13769 (const:SI (unspec:SI
13770 [(match_operand 1 "tls_symbolic_operand")]
13772 (clobber (reg:CC FLAGS_REG))]
13773 "!TARGET_64BIT && TARGET_GNU2_TLS"
13776 [(set (match_dup 0) (match_dup 5))]
13778 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13779 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13782 (define_expand "tls_dynamic_gnu2_64"
13783 [(set (match_dup 2)
13784 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13787 [(set (match_operand:DI 0 "register_operand")
13788 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13790 (clobber (reg:CC FLAGS_REG))])]
13791 "TARGET_64BIT && TARGET_GNU2_TLS"
13793 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13794 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13797 (define_insn "*tls_dynamic_gnu2_lea_64"
13798 [(set (match_operand:DI 0 "register_operand" "=r")
13799 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13801 "TARGET_64BIT && TARGET_GNU2_TLS"
13802 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13803 [(set_attr "type" "lea")
13804 (set_attr "mode" "DI")
13805 (set_attr "length" "7")
13806 (set_attr "length_address" "4")])
13808 (define_insn "*tls_dynamic_gnu2_call_64"
13809 [(set (match_operand:DI 0 "register_operand" "=a")
13810 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13811 (match_operand:DI 2 "register_operand" "0")
13814 (clobber (reg:CC FLAGS_REG))]
13815 "TARGET_64BIT && TARGET_GNU2_TLS"
13816 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13817 [(set_attr "type" "call")
13818 (set_attr "length" "2")
13819 (set_attr "length_address" "0")])
13821 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13822 [(set (match_operand:DI 0 "register_operand" "=&a")
13824 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13825 (match_operand:DI 3)
13828 (const:DI (unspec:DI
13829 [(match_operand 1 "tls_symbolic_operand")]
13831 (clobber (reg:CC FLAGS_REG))]
13832 "TARGET_64BIT && TARGET_GNU2_TLS"
13835 [(set (match_dup 0) (match_dup 4))]
13837 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13838 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13841 ;; These patterns match the binary 387 instructions for addM3, subM3,
13842 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13843 ;; SFmode. The first is the normal insn, the second the same insn but
13844 ;; with one operand a conversion, and the third the same insn but with
13845 ;; the other operand a conversion. The conversion may be SFmode or
13846 ;; SImode if the target mode DFmode, but only SImode if the target mode
13849 ;; Gcc is slightly more smart about handling normal two address instructions
13850 ;; so use special patterns for add and mull.
13852 (define_insn "*fop_<mode>_comm_mixed"
13853 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13854 (match_operator:MODEF 3 "binary_fp_operator"
13855 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13856 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13857 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13858 && COMMUTATIVE_ARITH_P (operands[3])
13859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13860 "* return output_387_binary_op (insn, operands);"
13861 [(set (attr "type")
13862 (if_then_else (eq_attr "alternative" "1,2")
13863 (if_then_else (match_operand:MODEF 3 "mult_operator")
13864 (const_string "ssemul")
13865 (const_string "sseadd"))
13866 (if_then_else (match_operand:MODEF 3 "mult_operator")
13867 (const_string "fmul")
13868 (const_string "fop"))))
13869 (set_attr "isa" "*,noavx,avx")
13870 (set_attr "prefix" "orig,orig,vex")
13871 (set_attr "mode" "<MODE>")
13872 (set (attr "enabled")
13873 (cond [(eq_attr "alternative" "0")
13874 (symbol_ref "TARGET_MIX_SSE_I387")
13876 (const_string "*")))])
13878 (define_insn "*fop_<mode>_comm_i387"
13879 [(set (match_operand:MODEF 0 "register_operand" "=f")
13880 (match_operator:MODEF 3 "binary_fp_operator"
13881 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13882 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13883 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13884 && COMMUTATIVE_ARITH_P (operands[3])
13885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13886 "* return output_387_binary_op (insn, operands);"
13887 [(set (attr "type")
13888 (if_then_else (match_operand:MODEF 3 "mult_operator")
13889 (const_string "fmul")
13890 (const_string "fop")))
13891 (set_attr "mode" "<MODE>")])
13893 (define_insn "*rcpsf2_sse"
13894 [(set (match_operand:SF 0 "register_operand" "=x")
13895 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13898 "%vrcpss\t{%1, %d0|%d0, %1}"
13899 [(set_attr "type" "sse")
13900 (set_attr "atom_sse_attr" "rcp")
13901 (set_attr "btver2_sse_attr" "rcp")
13902 (set_attr "prefix" "maybe_vex")
13903 (set_attr "mode" "SF")])
13905 (define_insn "*fop_<mode>_1_mixed"
13906 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13907 (match_operator:MODEF 3 "binary_fp_operator"
13908 [(match_operand:MODEF 1
13909 "register_mixssei387nonimm_operand" "0,fm,0,v")
13910 (match_operand:MODEF 2
13911 "nonimmediate_operand" "fm,0,xm,vm")]))]
13912 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13913 && !COMMUTATIVE_ARITH_P (operands[3])
13914 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13915 "* return output_387_binary_op (insn, operands);"
13916 [(set (attr "type")
13917 (cond [(and (eq_attr "alternative" "2,3")
13918 (match_operand:MODEF 3 "mult_operator"))
13919 (const_string "ssemul")
13920 (and (eq_attr "alternative" "2,3")
13921 (match_operand:MODEF 3 "div_operator"))
13922 (const_string "ssediv")
13923 (eq_attr "alternative" "2,3")
13924 (const_string "sseadd")
13925 (match_operand:MODEF 3 "mult_operator")
13926 (const_string "fmul")
13927 (match_operand:MODEF 3 "div_operator")
13928 (const_string "fdiv")
13930 (const_string "fop")))
13931 (set_attr "isa" "*,*,noavx,avx")
13932 (set_attr "prefix" "orig,orig,orig,vex")
13933 (set_attr "mode" "<MODE>")
13934 (set (attr "enabled")
13935 (cond [(eq_attr "alternative" "0,1")
13936 (symbol_ref "TARGET_MIX_SSE_I387")
13938 (const_string "*")))])
13940 ;; This pattern is not fully shadowed by the pattern above.
13941 (define_insn "*fop_<mode>_1_i387"
13942 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13943 (match_operator:MODEF 3 "binary_fp_operator"
13944 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13945 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13946 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13947 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13948 && !COMMUTATIVE_ARITH_P (operands[3])
13949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13950 "* return output_387_binary_op (insn, operands);"
13951 [(set (attr "type")
13952 (cond [(match_operand:MODEF 3 "mult_operator")
13953 (const_string "fmul")
13954 (match_operand:MODEF 3 "div_operator")
13955 (const_string "fdiv")
13957 (const_string "fop")))
13958 (set_attr "mode" "<MODE>")])
13960 ;; ??? Add SSE splitters for these!
13961 (define_insn "*fop_<MODEF:mode>_2_i387"
13962 [(set (match_operand:MODEF 0 "register_operand" "=f")
13963 (match_operator:MODEF 3 "binary_fp_operator"
13965 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13966 (match_operand:MODEF 2 "register_operand" "0")]))]
13967 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13968 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13969 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13970 || optimize_function_for_size_p (cfun))"
13971 { return output_387_binary_op (insn, operands); }
13972 [(set (attr "type")
13973 (cond [(match_operand:MODEF 3 "mult_operator")
13974 (const_string "fmul")
13975 (match_operand:MODEF 3 "div_operator")
13976 (const_string "fdiv")
13978 (const_string "fop")))
13979 (set_attr "fp_int_src" "true")
13980 (set_attr "mode" "<SWI24:MODE>")])
13982 (define_insn "*fop_<MODEF:mode>_3_i387"
13983 [(set (match_operand:MODEF 0 "register_operand" "=f")
13984 (match_operator:MODEF 3 "binary_fp_operator"
13985 [(match_operand:MODEF 1 "register_operand" "0")
13987 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13988 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13989 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13990 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13991 || optimize_function_for_size_p (cfun))"
13992 { return output_387_binary_op (insn, operands); }
13993 [(set (attr "type")
13994 (cond [(match_operand:MODEF 3 "mult_operator")
13995 (const_string "fmul")
13996 (match_operand:MODEF 3 "div_operator")
13997 (const_string "fdiv")
13999 (const_string "fop")))
14000 (set_attr "fp_int_src" "true")
14001 (set_attr "mode" "<MODE>")])
14003 (define_insn "*fop_df_4_i387"
14004 [(set (match_operand:DF 0 "register_operand" "=f,f")
14005 (match_operator:DF 3 "binary_fp_operator"
14007 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14008 (match_operand:DF 2 "register_operand" "0,f")]))]
14009 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14010 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14011 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14012 "* return output_387_binary_op (insn, operands);"
14013 [(set (attr "type")
14014 (cond [(match_operand:DF 3 "mult_operator")
14015 (const_string "fmul")
14016 (match_operand:DF 3 "div_operator")
14017 (const_string "fdiv")
14019 (const_string "fop")))
14020 (set_attr "mode" "SF")])
14022 (define_insn "*fop_df_5_i387"
14023 [(set (match_operand:DF 0 "register_operand" "=f,f")
14024 (match_operator:DF 3 "binary_fp_operator"
14025 [(match_operand:DF 1 "register_operand" "0,f")
14027 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14028 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14029 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14030 "* return output_387_binary_op (insn, operands);"
14031 [(set (attr "type")
14032 (cond [(match_operand:DF 3 "mult_operator")
14033 (const_string "fmul")
14034 (match_operand:DF 3 "div_operator")
14035 (const_string "fdiv")
14037 (const_string "fop")))
14038 (set_attr "mode" "SF")])
14040 (define_insn "*fop_df_6_i387"
14041 [(set (match_operand:DF 0 "register_operand" "=f,f")
14042 (match_operator:DF 3 "binary_fp_operator"
14044 (match_operand:SF 1 "register_operand" "0,f"))
14046 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14047 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14048 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14049 "* return output_387_binary_op (insn, operands);"
14050 [(set (attr "type")
14051 (cond [(match_operand:DF 3 "mult_operator")
14052 (const_string "fmul")
14053 (match_operand:DF 3 "div_operator")
14054 (const_string "fdiv")
14056 (const_string "fop")))
14057 (set_attr "mode" "SF")])
14059 (define_insn "*fop_xf_comm_i387"
14060 [(set (match_operand:XF 0 "register_operand" "=f")
14061 (match_operator:XF 3 "binary_fp_operator"
14062 [(match_operand:XF 1 "register_operand" "%0")
14063 (match_operand:XF 2 "register_operand" "f")]))]
14065 && COMMUTATIVE_ARITH_P (operands[3])"
14066 "* return output_387_binary_op (insn, operands);"
14067 [(set (attr "type")
14068 (if_then_else (match_operand:XF 3 "mult_operator")
14069 (const_string "fmul")
14070 (const_string "fop")))
14071 (set_attr "mode" "XF")])
14073 (define_insn "*fop_xf_1_i387"
14074 [(set (match_operand:XF 0 "register_operand" "=f,f")
14075 (match_operator:XF 3 "binary_fp_operator"
14076 [(match_operand:XF 1 "register_operand" "0,f")
14077 (match_operand:XF 2 "register_operand" "f,0")]))]
14079 && !COMMUTATIVE_ARITH_P (operands[3])"
14080 "* return output_387_binary_op (insn, operands);"
14081 [(set (attr "type")
14082 (cond [(match_operand:XF 3 "mult_operator")
14083 (const_string "fmul")
14084 (match_operand:XF 3 "div_operator")
14085 (const_string "fdiv")
14087 (const_string "fop")))
14088 (set_attr "mode" "XF")])
14090 (define_insn "*fop_xf_2_i387"
14091 [(set (match_operand:XF 0 "register_operand" "=f")
14092 (match_operator:XF 3 "binary_fp_operator"
14094 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14095 (match_operand:XF 2 "register_operand" "0")]))]
14097 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14098 { return output_387_binary_op (insn, operands); }
14099 [(set (attr "type")
14100 (cond [(match_operand:XF 3 "mult_operator")
14101 (const_string "fmul")
14102 (match_operand:XF 3 "div_operator")
14103 (const_string "fdiv")
14105 (const_string "fop")))
14106 (set_attr "fp_int_src" "true")
14107 (set_attr "mode" "<MODE>")])
14109 (define_insn "*fop_xf_3_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f")
14111 (match_operator:XF 3 "binary_fp_operator"
14112 [(match_operand:XF 1 "register_operand" "0")
14114 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14116 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14117 { return output_387_binary_op (insn, operands); }
14118 [(set (attr "type")
14119 (cond [(match_operand:XF 3 "mult_operator")
14120 (const_string "fmul")
14121 (match_operand:XF 3 "div_operator")
14122 (const_string "fdiv")
14124 (const_string "fop")))
14125 (set_attr "fp_int_src" "true")
14126 (set_attr "mode" "<MODE>")])
14128 (define_insn "*fop_xf_4_i387"
14129 [(set (match_operand:XF 0 "register_operand" "=f,f")
14130 (match_operator:XF 3 "binary_fp_operator"
14132 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14133 (match_operand:XF 2 "register_operand" "0,f")]))]
14135 "* return output_387_binary_op (insn, operands);"
14136 [(set (attr "type")
14137 (cond [(match_operand:XF 3 "mult_operator")
14138 (const_string "fmul")
14139 (match_operand:XF 3 "div_operator")
14140 (const_string "fdiv")
14142 (const_string "fop")))
14143 (set_attr "mode" "<MODE>")])
14145 (define_insn "*fop_xf_5_i387"
14146 [(set (match_operand:XF 0 "register_operand" "=f,f")
14147 (match_operator:XF 3 "binary_fp_operator"
14148 [(match_operand:XF 1 "register_operand" "0,f")
14150 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14152 "* return output_387_binary_op (insn, operands);"
14153 [(set (attr "type")
14154 (cond [(match_operand:XF 3 "mult_operator")
14155 (const_string "fmul")
14156 (match_operand:XF 3 "div_operator")
14157 (const_string "fdiv")
14159 (const_string "fop")))
14160 (set_attr "mode" "<MODE>")])
14162 (define_insn "*fop_xf_6_i387"
14163 [(set (match_operand:XF 0 "register_operand" "=f,f")
14164 (match_operator:XF 3 "binary_fp_operator"
14166 (match_operand:MODEF 1 "register_operand" "0,f"))
14168 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14170 "* return output_387_binary_op (insn, operands);"
14171 [(set (attr "type")
14172 (cond [(match_operand:XF 3 "mult_operator")
14173 (const_string "fmul")
14174 (match_operand:XF 3 "div_operator")
14175 (const_string "fdiv")
14177 (const_string "fop")))
14178 (set_attr "mode" "<MODE>")])
14180 ;; FPU special functions.
14182 ;; This pattern implements a no-op XFmode truncation for
14183 ;; all fancy i386 XFmode math functions.
14185 (define_insn "truncxf<mode>2_i387_noop_unspec"
14186 [(set (match_operand:MODEF 0 "register_operand" "=f")
14187 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14188 UNSPEC_TRUNC_NOOP))]
14189 "TARGET_USE_FANCY_MATH_387"
14190 "* return output_387_reg_move (insn, operands);"
14191 [(set_attr "type" "fmov")
14192 (set_attr "mode" "<MODE>")])
14194 (define_insn "sqrtxf2"
14195 [(set (match_operand:XF 0 "register_operand" "=f")
14196 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14197 "TARGET_USE_FANCY_MATH_387"
14199 [(set_attr "type" "fpspc")
14200 (set_attr "mode" "XF")
14201 (set_attr "athlon_decode" "direct")
14202 (set_attr "amdfam10_decode" "direct")
14203 (set_attr "bdver1_decode" "direct")])
14205 (define_insn "sqrt_extend<mode>xf2_i387"
14206 [(set (match_operand:XF 0 "register_operand" "=f")
14209 (match_operand:MODEF 1 "register_operand" "0"))))]
14210 "TARGET_USE_FANCY_MATH_387"
14212 [(set_attr "type" "fpspc")
14213 (set_attr "mode" "XF")
14214 (set_attr "athlon_decode" "direct")
14215 (set_attr "amdfam10_decode" "direct")
14216 (set_attr "bdver1_decode" "direct")])
14218 (define_insn "*rsqrtsf2_sse"
14219 [(set (match_operand:SF 0 "register_operand" "=x")
14220 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14223 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14224 [(set_attr "type" "sse")
14225 (set_attr "atom_sse_attr" "rcp")
14226 (set_attr "btver2_sse_attr" "rcp")
14227 (set_attr "prefix" "maybe_vex")
14228 (set_attr "mode" "SF")])
14230 (define_expand "rsqrtsf2"
14231 [(set (match_operand:SF 0 "register_operand")
14232 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14236 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14240 (define_insn "*sqrt<mode>2_sse"
14241 [(set (match_operand:MODEF 0 "register_operand" "=v")
14243 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14244 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14245 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14246 [(set_attr "type" "sse")
14247 (set_attr "atom_sse_attr" "sqrt")
14248 (set_attr "btver2_sse_attr" "sqrt")
14249 (set_attr "prefix" "maybe_vex")
14250 (set_attr "mode" "<MODE>")
14251 (set_attr "athlon_decode" "*")
14252 (set_attr "amdfam10_decode" "*")
14253 (set_attr "bdver1_decode" "*")])
14255 (define_expand "sqrt<mode>2"
14256 [(set (match_operand:MODEF 0 "register_operand")
14258 (match_operand:MODEF 1 "nonimmediate_operand")))]
14259 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14260 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14262 if (<MODE>mode == SFmode
14264 && TARGET_RECIP_SQRT
14265 && !optimize_function_for_size_p (cfun)
14266 && flag_finite_math_only && !flag_trapping_math
14267 && flag_unsafe_math_optimizations)
14269 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14273 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14275 rtx op0 = gen_reg_rtx (XFmode);
14276 rtx op1 = force_reg (<MODE>mode, operands[1]);
14278 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14279 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14284 (define_insn "fpremxf4_i387"
14285 [(set (match_operand:XF 0 "register_operand" "=f")
14286 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14287 (match_operand:XF 3 "register_operand" "1")]
14289 (set (match_operand:XF 1 "register_operand" "=u")
14290 (unspec:XF [(match_dup 2) (match_dup 3)]
14292 (set (reg:CCFP FPSR_REG)
14293 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14295 "TARGET_USE_FANCY_MATH_387
14296 && flag_finite_math_only"
14298 [(set_attr "type" "fpspc")
14299 (set_attr "znver1_decode" "vector")
14300 (set_attr "mode" "XF")])
14302 (define_expand "fmodxf3"
14303 [(use (match_operand:XF 0 "register_operand"))
14304 (use (match_operand:XF 1 "general_operand"))
14305 (use (match_operand:XF 2 "general_operand"))]
14306 "TARGET_USE_FANCY_MATH_387
14307 && flag_finite_math_only"
14309 rtx_code_label *label = gen_label_rtx ();
14311 rtx op1 = gen_reg_rtx (XFmode);
14312 rtx op2 = gen_reg_rtx (XFmode);
14314 emit_move_insn (op2, operands[2]);
14315 emit_move_insn (op1, operands[1]);
14317 emit_label (label);
14318 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14319 ix86_emit_fp_unordered_jump (label);
14320 LABEL_NUSES (label) = 1;
14322 emit_move_insn (operands[0], op1);
14326 (define_expand "fmod<mode>3"
14327 [(use (match_operand:MODEF 0 "register_operand"))
14328 (use (match_operand:MODEF 1 "general_operand"))
14329 (use (match_operand:MODEF 2 "general_operand"))]
14330 "TARGET_USE_FANCY_MATH_387
14331 && flag_finite_math_only"
14333 rtx (*gen_truncxf) (rtx, rtx);
14335 rtx_code_label *label = gen_label_rtx ();
14337 rtx op1 = gen_reg_rtx (XFmode);
14338 rtx op2 = gen_reg_rtx (XFmode);
14340 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14343 emit_label (label);
14344 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14345 ix86_emit_fp_unordered_jump (label);
14346 LABEL_NUSES (label) = 1;
14348 /* Truncate the result properly for strict SSE math. */
14349 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14350 && !TARGET_MIX_SSE_I387)
14351 gen_truncxf = gen_truncxf<mode>2;
14353 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14355 emit_insn (gen_truncxf (operands[0], op1));
14359 (define_insn "fprem1xf4_i387"
14360 [(set (match_operand:XF 0 "register_operand" "=f")
14361 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14362 (match_operand:XF 3 "register_operand" "1")]
14364 (set (match_operand:XF 1 "register_operand" "=u")
14365 (unspec:XF [(match_dup 2) (match_dup 3)]
14367 (set (reg:CCFP FPSR_REG)
14368 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14370 "TARGET_USE_FANCY_MATH_387
14371 && flag_finite_math_only"
14373 [(set_attr "type" "fpspc")
14374 (set_attr "znver1_decode" "vector")
14375 (set_attr "mode" "XF")])
14377 (define_expand "remainderxf3"
14378 [(use (match_operand:XF 0 "register_operand"))
14379 (use (match_operand:XF 1 "general_operand"))
14380 (use (match_operand:XF 2 "general_operand"))]
14381 "TARGET_USE_FANCY_MATH_387
14382 && flag_finite_math_only"
14384 rtx_code_label *label = gen_label_rtx ();
14386 rtx op1 = gen_reg_rtx (XFmode);
14387 rtx op2 = gen_reg_rtx (XFmode);
14389 emit_move_insn (op2, operands[2]);
14390 emit_move_insn (op1, operands[1]);
14392 emit_label (label);
14393 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14394 ix86_emit_fp_unordered_jump (label);
14395 LABEL_NUSES (label) = 1;
14397 emit_move_insn (operands[0], op1);
14401 (define_expand "remainder<mode>3"
14402 [(use (match_operand:MODEF 0 "register_operand"))
14403 (use (match_operand:MODEF 1 "general_operand"))
14404 (use (match_operand:MODEF 2 "general_operand"))]
14405 "TARGET_USE_FANCY_MATH_387
14406 && flag_finite_math_only"
14408 rtx (*gen_truncxf) (rtx, rtx);
14410 rtx_code_label *label = gen_label_rtx ();
14412 rtx op1 = gen_reg_rtx (XFmode);
14413 rtx op2 = gen_reg_rtx (XFmode);
14415 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14416 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14418 emit_label (label);
14420 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14421 ix86_emit_fp_unordered_jump (label);
14422 LABEL_NUSES (label) = 1;
14424 /* Truncate the result properly for strict SSE math. */
14425 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14426 && !TARGET_MIX_SSE_I387)
14427 gen_truncxf = gen_truncxf<mode>2;
14429 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14431 emit_insn (gen_truncxf (operands[0], op1));
14435 (define_int_iterator SINCOS
14439 (define_int_attr sincos
14440 [(UNSPEC_SIN "sin")
14441 (UNSPEC_COS "cos")])
14443 (define_insn "*<sincos>xf2_i387"
14444 [(set (match_operand:XF 0 "register_operand" "=f")
14445 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14447 "TARGET_USE_FANCY_MATH_387
14448 && flag_unsafe_math_optimizations"
14450 [(set_attr "type" "fpspc")
14451 (set_attr "znver1_decode" "vector")
14452 (set_attr "mode" "XF")])
14454 (define_insn "*<sincos>_extend<mode>xf2_i387"
14455 [(set (match_operand:XF 0 "register_operand" "=f")
14456 (unspec:XF [(float_extend:XF
14457 (match_operand:MODEF 1 "register_operand" "0"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14461 || TARGET_MIX_SSE_I387)
14462 && flag_unsafe_math_optimizations"
14464 [(set_attr "type" "fpspc")
14465 (set_attr "znver1_decode" "vector")
14466 (set_attr "mode" "XF")])
14468 ;; When sincos pattern is defined, sin and cos builtin functions will be
14469 ;; expanded to sincos pattern with one of its outputs left unused.
14470 ;; CSE pass will figure out if two sincos patterns can be combined,
14471 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14472 ;; depending on the unused output.
14474 (define_insn "sincosxf3"
14475 [(set (match_operand:XF 0 "register_operand" "=f")
14476 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14477 UNSPEC_SINCOS_COS))
14478 (set (match_operand:XF 1 "register_operand" "=u")
14479 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && flag_unsafe_math_optimizations"
14483 [(set_attr "type" "fpspc")
14484 (set_attr "znver1_decode" "vector")
14485 (set_attr "mode" "XF")])
14488 [(set (match_operand:XF 0 "register_operand")
14489 (unspec:XF [(match_operand:XF 2 "register_operand")]
14490 UNSPEC_SINCOS_COS))
14491 (set (match_operand:XF 1 "register_operand")
14492 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14493 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14494 && can_create_pseudo_p ()"
14495 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14498 [(set (match_operand:XF 0 "register_operand")
14499 (unspec:XF [(match_operand:XF 2 "register_operand")]
14500 UNSPEC_SINCOS_COS))
14501 (set (match_operand:XF 1 "register_operand")
14502 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14503 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14504 && can_create_pseudo_p ()"
14505 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14507 (define_insn "sincos_extend<mode>xf3_i387"
14508 [(set (match_operand:XF 0 "register_operand" "=f")
14509 (unspec:XF [(float_extend:XF
14510 (match_operand:MODEF 2 "register_operand" "0"))]
14511 UNSPEC_SINCOS_COS))
14512 (set (match_operand:XF 1 "register_operand" "=u")
14513 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14514 "TARGET_USE_FANCY_MATH_387
14515 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14516 || TARGET_MIX_SSE_I387)
14517 && flag_unsafe_math_optimizations"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "znver1_decode" "vector")
14521 (set_attr "mode" "XF")])
14524 [(set (match_operand:XF 0 "register_operand")
14525 (unspec:XF [(float_extend:XF
14526 (match_operand:MODEF 2 "register_operand"))]
14527 UNSPEC_SINCOS_COS))
14528 (set (match_operand:XF 1 "register_operand")
14529 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14530 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14531 && can_create_pseudo_p ()"
14532 [(set (match_dup 1)
14533 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14536 [(set (match_operand:XF 0 "register_operand")
14537 (unspec:XF [(float_extend:XF
14538 (match_operand:MODEF 2 "register_operand"))]
14539 UNSPEC_SINCOS_COS))
14540 (set (match_operand:XF 1 "register_operand")
14541 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14542 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14543 && can_create_pseudo_p ()"
14544 [(set (match_dup 0)
14545 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14547 (define_expand "sincos<mode>3"
14548 [(use (match_operand:MODEF 0 "register_operand"))
14549 (use (match_operand:MODEF 1 "register_operand"))
14550 (use (match_operand:MODEF 2 "register_operand"))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553 || TARGET_MIX_SSE_I387)
14554 && flag_unsafe_math_optimizations"
14556 rtx op0 = gen_reg_rtx (XFmode);
14557 rtx op1 = gen_reg_rtx (XFmode);
14559 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14560 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14561 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14565 (define_insn "fptanxf4_i387"
14566 [(set (match_operand:XF 0 "register_operand" "=f")
14567 (match_operand:XF 3 "const_double_operand" "F"))
14568 (set (match_operand:XF 1 "register_operand" "=u")
14569 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations
14573 && standard_80387_constant_p (operands[3]) == 2"
14575 [(set_attr "type" "fpspc")
14576 (set_attr "znver1_decode" "vector")
14577 (set_attr "mode" "XF")])
14579 (define_insn "fptan_extend<mode>xf4_i387"
14580 [(set (match_operand:MODEF 0 "register_operand" "=f")
14581 (match_operand:MODEF 3 "const_double_operand" "F"))
14582 (set (match_operand:XF 1 "register_operand" "=u")
14583 (unspec:XF [(float_extend:XF
14584 (match_operand:MODEF 2 "register_operand" "0"))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations
14590 && standard_80387_constant_p (operands[3]) == 2"
14592 [(set_attr "type" "fpspc")
14593 (set_attr "znver1_decode" "vector")
14594 (set_attr "mode" "XF")])
14596 (define_expand "tanxf2"
14597 [(use (match_operand:XF 0 "register_operand"))
14598 (use (match_operand:XF 1 "register_operand"))]
14599 "TARGET_USE_FANCY_MATH_387
14600 && flag_unsafe_math_optimizations"
14602 rtx one = gen_reg_rtx (XFmode);
14603 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14605 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14609 (define_expand "tan<mode>2"
14610 [(use (match_operand:MODEF 0 "register_operand"))
14611 (use (match_operand:MODEF 1 "register_operand"))]
14612 "TARGET_USE_FANCY_MATH_387
14613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14614 || TARGET_MIX_SSE_I387)
14615 && flag_unsafe_math_optimizations"
14617 rtx op0 = gen_reg_rtx (XFmode);
14619 rtx one = gen_reg_rtx (<MODE>mode);
14620 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14622 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14623 operands[1], op2));
14624 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14628 (define_insn "*fpatanxf3_i387"
14629 [(set (match_operand:XF 0 "register_operand" "=f")
14630 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14631 (match_operand:XF 2 "register_operand" "u")]
14633 (clobber (match_scratch:XF 3 "=2"))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && flag_unsafe_math_optimizations"
14637 [(set_attr "type" "fpspc")
14638 (set_attr "znver1_decode" "vector")
14639 (set_attr "mode" "XF")])
14641 (define_insn "fpatan_extend<mode>xf3_i387"
14642 [(set (match_operand:XF 0 "register_operand" "=f")
14643 (unspec:XF [(float_extend:XF
14644 (match_operand:MODEF 1 "register_operand" "0"))
14646 (match_operand:MODEF 2 "register_operand" "u"))]
14648 (clobber (match_scratch:XF 3 "=2"))]
14649 "TARGET_USE_FANCY_MATH_387
14650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14651 || TARGET_MIX_SSE_I387)
14652 && flag_unsafe_math_optimizations"
14654 [(set_attr "type" "fpspc")
14655 (set_attr "znver1_decode" "vector")
14656 (set_attr "mode" "XF")])
14658 (define_expand "atan2xf3"
14659 [(parallel [(set (match_operand:XF 0 "register_operand")
14660 (unspec:XF [(match_operand:XF 2 "register_operand")
14661 (match_operand:XF 1 "register_operand")]
14663 (clobber (match_scratch:XF 3))])]
14664 "TARGET_USE_FANCY_MATH_387
14665 && flag_unsafe_math_optimizations")
14667 (define_expand "atan2<mode>3"
14668 [(use (match_operand:MODEF 0 "register_operand"))
14669 (use (match_operand:MODEF 1 "register_operand"))
14670 (use (match_operand:MODEF 2 "register_operand"))]
14671 "TARGET_USE_FANCY_MATH_387
14672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14673 || TARGET_MIX_SSE_I387)
14674 && flag_unsafe_math_optimizations"
14676 rtx op0 = gen_reg_rtx (XFmode);
14678 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14679 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14683 (define_expand "atanxf2"
14684 [(parallel [(set (match_operand:XF 0 "register_operand")
14685 (unspec:XF [(match_dup 2)
14686 (match_operand:XF 1 "register_operand")]
14688 (clobber (match_scratch:XF 3))])]
14689 "TARGET_USE_FANCY_MATH_387
14690 && flag_unsafe_math_optimizations"
14692 operands[2] = gen_reg_rtx (XFmode);
14693 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14696 (define_expand "atan<mode>2"
14697 [(use (match_operand:MODEF 0 "register_operand"))
14698 (use (match_operand:MODEF 1 "register_operand"))]
14699 "TARGET_USE_FANCY_MATH_387
14700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14701 || TARGET_MIX_SSE_I387)
14702 && flag_unsafe_math_optimizations"
14704 rtx op0 = gen_reg_rtx (XFmode);
14706 rtx op2 = gen_reg_rtx (<MODE>mode);
14707 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14709 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14710 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14714 (define_expand "asinxf2"
14715 [(set (match_dup 2)
14716 (mult:XF (match_operand:XF 1 "register_operand")
14718 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14719 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14720 (parallel [(set (match_operand:XF 0 "register_operand")
14721 (unspec:XF [(match_dup 5) (match_dup 1)]
14723 (clobber (match_scratch:XF 6))])]
14724 "TARGET_USE_FANCY_MATH_387
14725 && flag_unsafe_math_optimizations"
14729 if (optimize_insn_for_size_p ())
14732 for (i = 2; i < 6; i++)
14733 operands[i] = gen_reg_rtx (XFmode);
14735 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14738 (define_expand "asin<mode>2"
14739 [(use (match_operand:MODEF 0 "register_operand"))
14740 (use (match_operand:MODEF 1 "general_operand"))]
14741 "TARGET_USE_FANCY_MATH_387
14742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14743 || TARGET_MIX_SSE_I387)
14744 && flag_unsafe_math_optimizations"
14746 rtx op0 = gen_reg_rtx (XFmode);
14747 rtx op1 = gen_reg_rtx (XFmode);
14749 if (optimize_insn_for_size_p ())
14752 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14753 emit_insn (gen_asinxf2 (op0, op1));
14754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14758 (define_expand "acosxf2"
14759 [(set (match_dup 2)
14760 (mult:XF (match_operand:XF 1 "register_operand")
14762 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14763 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14764 (parallel [(set (match_operand:XF 0 "register_operand")
14765 (unspec:XF [(match_dup 1) (match_dup 5)]
14767 (clobber (match_scratch:XF 6))])]
14768 "TARGET_USE_FANCY_MATH_387
14769 && flag_unsafe_math_optimizations"
14773 if (optimize_insn_for_size_p ())
14776 for (i = 2; i < 6; i++)
14777 operands[i] = gen_reg_rtx (XFmode);
14779 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14782 (define_expand "acos<mode>2"
14783 [(use (match_operand:MODEF 0 "register_operand"))
14784 (use (match_operand:MODEF 1 "general_operand"))]
14785 "TARGET_USE_FANCY_MATH_387
14786 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14787 || TARGET_MIX_SSE_I387)
14788 && flag_unsafe_math_optimizations"
14790 rtx op0 = gen_reg_rtx (XFmode);
14791 rtx op1 = gen_reg_rtx (XFmode);
14793 if (optimize_insn_for_size_p ())
14796 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14797 emit_insn (gen_acosxf2 (op0, op1));
14798 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14802 (define_insn "fyl2xxf3_i387"
14803 [(set (match_operand:XF 0 "register_operand" "=f")
14804 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14805 (match_operand:XF 2 "register_operand" "u")]
14807 (clobber (match_scratch:XF 3 "=2"))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && flag_unsafe_math_optimizations"
14811 [(set_attr "type" "fpspc")
14812 (set_attr "znver1_decode" "vector")
14813 (set_attr "mode" "XF")])
14815 (define_insn "fyl2x_extend<mode>xf3_i387"
14816 [(set (match_operand:XF 0 "register_operand" "=f")
14817 (unspec:XF [(float_extend:XF
14818 (match_operand:MODEF 1 "register_operand" "0"))
14819 (match_operand:XF 2 "register_operand" "u")]
14821 (clobber (match_scratch:XF 3 "=2"))]
14822 "TARGET_USE_FANCY_MATH_387
14823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14824 || TARGET_MIX_SSE_I387)
14825 && flag_unsafe_math_optimizations"
14827 [(set_attr "type" "fpspc")
14828 (set_attr "znver1_decode" "vector")
14829 (set_attr "mode" "XF")])
14831 (define_expand "logxf2"
14832 [(parallel [(set (match_operand:XF 0 "register_operand")
14833 (unspec:XF [(match_operand:XF 1 "register_operand")
14834 (match_dup 2)] UNSPEC_FYL2X))
14835 (clobber (match_scratch:XF 3))])]
14836 "TARGET_USE_FANCY_MATH_387
14837 && flag_unsafe_math_optimizations"
14839 operands[2] = gen_reg_rtx (XFmode);
14840 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14843 (define_expand "log<mode>2"
14844 [(use (match_operand:MODEF 0 "register_operand"))
14845 (use (match_operand:MODEF 1 "register_operand"))]
14846 "TARGET_USE_FANCY_MATH_387
14847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14848 || TARGET_MIX_SSE_I387)
14849 && flag_unsafe_math_optimizations"
14851 rtx op0 = gen_reg_rtx (XFmode);
14853 rtx op2 = gen_reg_rtx (XFmode);
14854 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14856 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14857 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14861 (define_expand "log10xf2"
14862 [(parallel [(set (match_operand:XF 0 "register_operand")
14863 (unspec:XF [(match_operand:XF 1 "register_operand")
14864 (match_dup 2)] UNSPEC_FYL2X))
14865 (clobber (match_scratch:XF 3))])]
14866 "TARGET_USE_FANCY_MATH_387
14867 && flag_unsafe_math_optimizations"
14869 operands[2] = gen_reg_rtx (XFmode);
14870 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14873 (define_expand "log10<mode>2"
14874 [(use (match_operand:MODEF 0 "register_operand"))
14875 (use (match_operand:MODEF 1 "register_operand"))]
14876 "TARGET_USE_FANCY_MATH_387
14877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878 || TARGET_MIX_SSE_I387)
14879 && flag_unsafe_math_optimizations"
14881 rtx op0 = gen_reg_rtx (XFmode);
14883 rtx op2 = gen_reg_rtx (XFmode);
14884 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14886 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14891 (define_expand "log2xf2"
14892 [(parallel [(set (match_operand:XF 0 "register_operand")
14893 (unspec:XF [(match_operand:XF 1 "register_operand")
14894 (match_dup 2)] UNSPEC_FYL2X))
14895 (clobber (match_scratch:XF 3))])]
14896 "TARGET_USE_FANCY_MATH_387
14897 && flag_unsafe_math_optimizations"
14899 operands[2] = gen_reg_rtx (XFmode);
14900 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14903 (define_expand "log2<mode>2"
14904 [(use (match_operand:MODEF 0 "register_operand"))
14905 (use (match_operand:MODEF 1 "register_operand"))]
14906 "TARGET_USE_FANCY_MATH_387
14907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14908 || TARGET_MIX_SSE_I387)
14909 && flag_unsafe_math_optimizations"
14911 rtx op0 = gen_reg_rtx (XFmode);
14913 rtx op2 = gen_reg_rtx (XFmode);
14914 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14916 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14917 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14921 (define_insn "fyl2xp1xf3_i387"
14922 [(set (match_operand:XF 0 "register_operand" "=f")
14923 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14924 (match_operand:XF 2 "register_operand" "u")]
14926 (clobber (match_scratch:XF 3 "=2"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && flag_unsafe_math_optimizations"
14930 [(set_attr "type" "fpspc")
14931 (set_attr "znver1_decode" "vector")
14932 (set_attr "mode" "XF")])
14934 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14935 [(set (match_operand:XF 0 "register_operand" "=f")
14936 (unspec:XF [(float_extend:XF
14937 (match_operand:MODEF 1 "register_operand" "0"))
14938 (match_operand:XF 2 "register_operand" "u")]
14940 (clobber (match_scratch:XF 3 "=2"))]
14941 "TARGET_USE_FANCY_MATH_387
14942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14943 || TARGET_MIX_SSE_I387)
14944 && flag_unsafe_math_optimizations"
14946 [(set_attr "type" "fpspc")
14947 (set_attr "znver1_decode" "vector")
14948 (set_attr "mode" "XF")])
14950 (define_expand "log1pxf2"
14951 [(use (match_operand:XF 0 "register_operand"))
14952 (use (match_operand:XF 1 "register_operand"))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14956 if (optimize_insn_for_size_p ())
14959 ix86_emit_i387_log1p (operands[0], operands[1]);
14963 (define_expand "log1p<mode>2"
14964 [(use (match_operand:MODEF 0 "register_operand"))
14965 (use (match_operand:MODEF 1 "register_operand"))]
14966 "TARGET_USE_FANCY_MATH_387
14967 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14968 || TARGET_MIX_SSE_I387)
14969 && flag_unsafe_math_optimizations"
14973 if (optimize_insn_for_size_p ())
14976 op0 = gen_reg_rtx (XFmode);
14978 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14980 ix86_emit_i387_log1p (op0, operands[1]);
14981 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14985 (define_insn "fxtractxf3_i387"
14986 [(set (match_operand:XF 0 "register_operand" "=f")
14987 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14988 UNSPEC_XTRACT_FRACT))
14989 (set (match_operand:XF 1 "register_operand" "=u")
14990 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14994 [(set_attr "type" "fpspc")
14995 (set_attr "znver1_decode" "vector")
14996 (set_attr "mode" "XF")])
14998 (define_insn "fxtract_extend<mode>xf3_i387"
14999 [(set (match_operand:XF 0 "register_operand" "=f")
15000 (unspec:XF [(float_extend:XF
15001 (match_operand:MODEF 2 "register_operand" "0"))]
15002 UNSPEC_XTRACT_FRACT))
15003 (set (match_operand:XF 1 "register_operand" "=u")
15004 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15005 "TARGET_USE_FANCY_MATH_387
15006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15007 || TARGET_MIX_SSE_I387)
15008 && flag_unsafe_math_optimizations"
15010 [(set_attr "type" "fpspc")
15011 (set_attr "znver1_decode" "vector")
15012 (set_attr "mode" "XF")])
15014 (define_expand "logbxf2"
15015 [(parallel [(set (match_dup 2)
15016 (unspec:XF [(match_operand:XF 1 "register_operand")]
15017 UNSPEC_XTRACT_FRACT))
15018 (set (match_operand:XF 0 "register_operand")
15019 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15020 "TARGET_USE_FANCY_MATH_387
15021 && flag_unsafe_math_optimizations"
15022 "operands[2] = gen_reg_rtx (XFmode);")
15024 (define_expand "logb<mode>2"
15025 [(use (match_operand:MODEF 0 "register_operand"))
15026 (use (match_operand:MODEF 1 "register_operand"))]
15027 "TARGET_USE_FANCY_MATH_387
15028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15029 || TARGET_MIX_SSE_I387)
15030 && flag_unsafe_math_optimizations"
15032 rtx op0 = gen_reg_rtx (XFmode);
15033 rtx op1 = gen_reg_rtx (XFmode);
15035 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15036 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15040 (define_expand "ilogbxf2"
15041 [(use (match_operand:SI 0 "register_operand"))
15042 (use (match_operand:XF 1 "register_operand"))]
15043 "TARGET_USE_FANCY_MATH_387
15044 && flag_unsafe_math_optimizations"
15048 if (optimize_insn_for_size_p ())
15051 op0 = gen_reg_rtx (XFmode);
15052 op1 = gen_reg_rtx (XFmode);
15054 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15055 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15059 (define_expand "ilogb<mode>2"
15060 [(use (match_operand:SI 0 "register_operand"))
15061 (use (match_operand:MODEF 1 "register_operand"))]
15062 "TARGET_USE_FANCY_MATH_387
15063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15064 || TARGET_MIX_SSE_I387)
15065 && flag_unsafe_math_optimizations"
15069 if (optimize_insn_for_size_p ())
15072 op0 = gen_reg_rtx (XFmode);
15073 op1 = gen_reg_rtx (XFmode);
15075 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15076 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15080 (define_insn "*f2xm1xf2_i387"
15081 [(set (match_operand:XF 0 "register_operand" "=f")
15082 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15084 "TARGET_USE_FANCY_MATH_387
15085 && flag_unsafe_math_optimizations"
15087 [(set_attr "type" "fpspc")
15088 (set_attr "znver1_decode" "vector")
15089 (set_attr "mode" "XF")])
15091 (define_insn "fscalexf4_i387"
15092 [(set (match_operand:XF 0 "register_operand" "=f")
15093 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15094 (match_operand:XF 3 "register_operand" "1")]
15095 UNSPEC_FSCALE_FRACT))
15096 (set (match_operand:XF 1 "register_operand" "=u")
15097 (unspec:XF [(match_dup 2) (match_dup 3)]
15098 UNSPEC_FSCALE_EXP))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations"
15102 [(set_attr "type" "fpspc")
15103 (set_attr "znver1_decode" "vector")
15104 (set_attr "mode" "XF")])
15106 (define_expand "expNcorexf3"
15107 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15108 (match_operand:XF 2 "register_operand")))
15109 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15110 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15111 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15112 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15113 (parallel [(set (match_operand:XF 0 "register_operand")
15114 (unspec:XF [(match_dup 8) (match_dup 4)]
15115 UNSPEC_FSCALE_FRACT))
15117 (unspec:XF [(match_dup 8) (match_dup 4)]
15118 UNSPEC_FSCALE_EXP))])]
15119 "TARGET_USE_FANCY_MATH_387
15120 && flag_unsafe_math_optimizations"
15124 if (optimize_insn_for_size_p ())
15127 for (i = 3; i < 10; i++)
15128 operands[i] = gen_reg_rtx (XFmode);
15130 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15133 (define_expand "expxf2"
15134 [(use (match_operand:XF 0 "register_operand"))
15135 (use (match_operand:XF 1 "register_operand"))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && flag_unsafe_math_optimizations"
15141 if (optimize_insn_for_size_p ())
15144 op2 = gen_reg_rtx (XFmode);
15145 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15147 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15151 (define_expand "exp<mode>2"
15152 [(use (match_operand:MODEF 0 "register_operand"))
15153 (use (match_operand:MODEF 1 "general_operand"))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15156 || TARGET_MIX_SSE_I387)
15157 && flag_unsafe_math_optimizations"
15161 if (optimize_insn_for_size_p ())
15164 op0 = gen_reg_rtx (XFmode);
15165 op1 = gen_reg_rtx (XFmode);
15167 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15168 emit_insn (gen_expxf2 (op0, op1));
15169 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15173 (define_expand "exp10xf2"
15174 [(use (match_operand:XF 0 "register_operand"))
15175 (use (match_operand:XF 1 "register_operand"))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations"
15181 if (optimize_insn_for_size_p ())
15184 op2 = gen_reg_rtx (XFmode);
15185 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15187 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15191 (define_expand "exp10<mode>2"
15192 [(use (match_operand:MODEF 0 "register_operand"))
15193 (use (match_operand:MODEF 1 "general_operand"))]
15194 "TARGET_USE_FANCY_MATH_387
15195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15196 || TARGET_MIX_SSE_I387)
15197 && flag_unsafe_math_optimizations"
15201 if (optimize_insn_for_size_p ())
15204 op0 = gen_reg_rtx (XFmode);
15205 op1 = gen_reg_rtx (XFmode);
15207 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15208 emit_insn (gen_exp10xf2 (op0, op1));
15209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15213 (define_expand "exp2xf2"
15214 [(use (match_operand:XF 0 "register_operand"))
15215 (use (match_operand:XF 1 "register_operand"))]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations"
15221 if (optimize_insn_for_size_p ())
15224 op2 = gen_reg_rtx (XFmode);
15225 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15227 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15231 (define_expand "exp2<mode>2"
15232 [(use (match_operand:MODEF 0 "register_operand"))
15233 (use (match_operand:MODEF 1 "general_operand"))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15236 || TARGET_MIX_SSE_I387)
15237 && flag_unsafe_math_optimizations"
15241 if (optimize_insn_for_size_p ())
15244 op0 = gen_reg_rtx (XFmode);
15245 op1 = gen_reg_rtx (XFmode);
15247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15248 emit_insn (gen_exp2xf2 (op0, op1));
15249 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15253 (define_expand "expm1xf2"
15254 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15256 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15257 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15258 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15259 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15260 (parallel [(set (match_dup 7)
15261 (unspec:XF [(match_dup 6) (match_dup 4)]
15262 UNSPEC_FSCALE_FRACT))
15264 (unspec:XF [(match_dup 6) (match_dup 4)]
15265 UNSPEC_FSCALE_EXP))])
15266 (parallel [(set (match_dup 10)
15267 (unspec:XF [(match_dup 9) (match_dup 8)]
15268 UNSPEC_FSCALE_FRACT))
15269 (set (match_dup 11)
15270 (unspec:XF [(match_dup 9) (match_dup 8)]
15271 UNSPEC_FSCALE_EXP))])
15272 (set (match_dup 12) (minus:XF (match_dup 10)
15273 (float_extend:XF (match_dup 13))))
15274 (set (match_operand:XF 0 "register_operand")
15275 (plus:XF (match_dup 12) (match_dup 7)))]
15276 "TARGET_USE_FANCY_MATH_387
15277 && flag_unsafe_math_optimizations"
15281 if (optimize_insn_for_size_p ())
15284 for (i = 2; i < 13; i++)
15285 operands[i] = gen_reg_rtx (XFmode);
15288 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15290 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15293 (define_expand "expm1<mode>2"
15294 [(use (match_operand:MODEF 0 "register_operand"))
15295 (use (match_operand:MODEF 1 "general_operand"))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15298 || TARGET_MIX_SSE_I387)
15299 && flag_unsafe_math_optimizations"
15303 if (optimize_insn_for_size_p ())
15306 op0 = gen_reg_rtx (XFmode);
15307 op1 = gen_reg_rtx (XFmode);
15309 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15310 emit_insn (gen_expm1xf2 (op0, op1));
15311 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15315 (define_expand "ldexpxf3"
15316 [(match_operand:XF 0 "register_operand")
15317 (match_operand:XF 1 "register_operand")
15318 (match_operand:SI 2 "register_operand")]
15319 "TARGET_USE_FANCY_MATH_387
15320 && flag_unsafe_math_optimizations"
15323 if (optimize_insn_for_size_p ())
15326 tmp1 = gen_reg_rtx (XFmode);
15327 tmp2 = gen_reg_rtx (XFmode);
15329 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15330 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15331 operands[1], tmp1));
15335 (define_expand "ldexp<mode>3"
15336 [(use (match_operand:MODEF 0 "register_operand"))
15337 (use (match_operand:MODEF 1 "general_operand"))
15338 (use (match_operand:SI 2 "register_operand"))]
15339 "TARGET_USE_FANCY_MATH_387
15340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15341 || TARGET_MIX_SSE_I387)
15342 && flag_unsafe_math_optimizations"
15346 if (optimize_insn_for_size_p ())
15349 op0 = gen_reg_rtx (XFmode);
15350 op1 = gen_reg_rtx (XFmode);
15352 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15353 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15354 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15358 (define_expand "scalbxf3"
15359 [(parallel [(set (match_operand:XF 0 " register_operand")
15360 (unspec:XF [(match_operand:XF 1 "register_operand")
15361 (match_operand:XF 2 "register_operand")]
15362 UNSPEC_FSCALE_FRACT))
15364 (unspec:XF [(match_dup 1) (match_dup 2)]
15365 UNSPEC_FSCALE_EXP))])]
15366 "TARGET_USE_FANCY_MATH_387
15367 && flag_unsafe_math_optimizations"
15369 if (optimize_insn_for_size_p ())
15372 operands[3] = gen_reg_rtx (XFmode);
15375 (define_expand "scalb<mode>3"
15376 [(use (match_operand:MODEF 0 "register_operand"))
15377 (use (match_operand:MODEF 1 "general_operand"))
15378 (use (match_operand:MODEF 2 "general_operand"))]
15379 "TARGET_USE_FANCY_MATH_387
15380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15381 || TARGET_MIX_SSE_I387)
15382 && flag_unsafe_math_optimizations"
15386 if (optimize_insn_for_size_p ())
15389 op0 = gen_reg_rtx (XFmode);
15390 op1 = gen_reg_rtx (XFmode);
15391 op2 = gen_reg_rtx (XFmode);
15393 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15394 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15395 emit_insn (gen_scalbxf3 (op0, op1, op2));
15396 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15400 (define_expand "significandxf2"
15401 [(parallel [(set (match_operand:XF 0 "register_operand")
15402 (unspec:XF [(match_operand:XF 1 "register_operand")]
15403 UNSPEC_XTRACT_FRACT))
15405 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15406 "TARGET_USE_FANCY_MATH_387
15407 && flag_unsafe_math_optimizations"
15408 "operands[2] = gen_reg_rtx (XFmode);")
15410 (define_expand "significand<mode>2"
15411 [(use (match_operand:MODEF 0 "register_operand"))
15412 (use (match_operand:MODEF 1 "register_operand"))]
15413 "TARGET_USE_FANCY_MATH_387
15414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15415 || TARGET_MIX_SSE_I387)
15416 && flag_unsafe_math_optimizations"
15418 rtx op0 = gen_reg_rtx (XFmode);
15419 rtx op1 = gen_reg_rtx (XFmode);
15421 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15427 (define_insn "sse4_1_round<mode>2"
15428 [(set (match_operand:MODEF 0 "register_operand" "=x")
15429 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15430 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15433 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15434 [(set_attr "type" "ssecvt")
15435 (set_attr "prefix_extra" "1")
15436 (set_attr "prefix" "maybe_vex")
15437 (set_attr "mode" "<MODE>")])
15439 (define_insn "rintxf2"
15440 [(set (match_operand:XF 0 "register_operand" "=f")
15441 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_unsafe_math_optimizations"
15446 [(set_attr "type" "fpspc")
15447 (set_attr "znver1_decode" "vector")
15448 (set_attr "mode" "XF")])
15450 (define_expand "rint<mode>2"
15451 [(use (match_operand:MODEF 0 "register_operand"))
15452 (use (match_operand:MODEF 1 "register_operand"))]
15453 "(TARGET_USE_FANCY_MATH_387
15454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15455 || TARGET_MIX_SSE_I387)
15456 && flag_unsafe_math_optimizations)
15457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15458 && !flag_trapping_math)"
15460 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15461 && !flag_trapping_math)
15464 emit_insn (gen_sse4_1_round<mode>2
15465 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15466 else if (optimize_insn_for_size_p ())
15469 ix86_expand_rint (operands[0], operands[1]);
15473 rtx op0 = gen_reg_rtx (XFmode);
15474 rtx op1 = gen_reg_rtx (XFmode);
15476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15477 emit_insn (gen_rintxf2 (op0, op1));
15479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15484 (define_expand "round<mode>2"
15485 [(match_operand:X87MODEF 0 "register_operand")
15486 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15487 "(TARGET_USE_FANCY_MATH_387
15488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15489 || TARGET_MIX_SSE_I387)
15490 && flag_unsafe_math_optimizations)
15491 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15492 && !flag_trapping_math && !flag_rounding_math)"
15494 if (optimize_insn_for_size_p ())
15497 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15498 && !flag_trapping_math && !flag_rounding_math)
15502 operands[1] = force_reg (<MODE>mode, operands[1]);
15503 ix86_expand_round_sse4 (operands[0], operands[1]);
15505 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15506 ix86_expand_round (operands[0], operands[1]);
15508 ix86_expand_rounddf_32 (operands[0], operands[1]);
15512 operands[1] = force_reg (<MODE>mode, operands[1]);
15513 ix86_emit_i387_round (operands[0], operands[1]);
15518 (define_insn_and_split "*fistdi2_1"
15519 [(set (match_operand:DI 0 "nonimmediate_operand")
15520 (unspec:DI [(match_operand:XF 1 "register_operand")]
15522 "TARGET_USE_FANCY_MATH_387
15523 && can_create_pseudo_p ()"
15528 if (memory_operand (operands[0], VOIDmode))
15529 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15532 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15533 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15538 [(set_attr "type" "fpspc")
15539 (set_attr "mode" "DI")])
15541 (define_insn "fistdi2"
15542 [(set (match_operand:DI 0 "memory_operand" "=m")
15543 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15545 (clobber (match_scratch:XF 2 "=&1f"))]
15546 "TARGET_USE_FANCY_MATH_387"
15547 "* return output_fix_trunc (insn, operands, false);"
15548 [(set_attr "type" "fpspc")
15549 (set_attr "mode" "DI")])
15551 (define_insn "fistdi2_with_temp"
15552 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15553 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15555 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15556 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15557 "TARGET_USE_FANCY_MATH_387"
15559 [(set_attr "type" "fpspc")
15560 (set_attr "mode" "DI")])
15563 [(set (match_operand:DI 0 "register_operand")
15564 (unspec:DI [(match_operand:XF 1 "register_operand")]
15566 (clobber (match_operand:DI 2 "memory_operand"))
15567 (clobber (match_scratch 3))]
15569 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15570 (clobber (match_dup 3))])
15571 (set (match_dup 0) (match_dup 2))])
15574 [(set (match_operand:DI 0 "memory_operand")
15575 (unspec:DI [(match_operand:XF 1 "register_operand")]
15577 (clobber (match_operand:DI 2 "memory_operand"))
15578 (clobber (match_scratch 3))]
15580 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15581 (clobber (match_dup 3))])])
15583 (define_insn_and_split "*fist<mode>2_1"
15584 [(set (match_operand:SWI24 0 "register_operand")
15585 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15587 "TARGET_USE_FANCY_MATH_387
15588 && can_create_pseudo_p ()"
15593 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15594 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15598 [(set_attr "type" "fpspc")
15599 (set_attr "mode" "<MODE>")])
15601 (define_insn "fist<mode>2"
15602 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15603 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15605 "TARGET_USE_FANCY_MATH_387"
15606 "* return output_fix_trunc (insn, operands, false);"
15607 [(set_attr "type" "fpspc")
15608 (set_attr "mode" "<MODE>")])
15610 (define_insn "fist<mode>2_with_temp"
15611 [(set (match_operand:SWI24 0 "register_operand" "=r")
15612 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15614 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15615 "TARGET_USE_FANCY_MATH_387"
15617 [(set_attr "type" "fpspc")
15618 (set_attr "mode" "<MODE>")])
15621 [(set (match_operand:SWI24 0 "register_operand")
15622 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15624 (clobber (match_operand:SWI24 2 "memory_operand"))]
15626 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15627 (set (match_dup 0) (match_dup 2))])
15630 [(set (match_operand:SWI24 0 "memory_operand")
15631 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15633 (clobber (match_operand:SWI24 2 "memory_operand"))]
15635 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15637 (define_expand "lrintxf<mode>2"
15638 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15639 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15641 "TARGET_USE_FANCY_MATH_387")
15643 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15644 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15645 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15646 UNSPEC_FIX_NOTRUNC))]
15647 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15649 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15650 [(match_operand:SWI248x 0 "nonimmediate_operand")
15651 (match_operand:X87MODEF 1 "register_operand")]
15652 "(TARGET_USE_FANCY_MATH_387
15653 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15654 || TARGET_MIX_SSE_I387)
15655 && flag_unsafe_math_optimizations)
15656 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15657 && <SWI248x:MODE>mode != HImode
15658 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15659 && !flag_trapping_math && !flag_rounding_math)"
15661 if (optimize_insn_for_size_p ())
15664 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15665 && <SWI248x:MODE>mode != HImode
15666 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15667 && !flag_trapping_math && !flag_rounding_math)
15668 ix86_expand_lround (operands[0], operands[1]);
15670 ix86_emit_i387_round (operands[0], operands[1]);
15674 (define_int_iterator FRNDINT_ROUNDING
15675 [UNSPEC_FRNDINT_FLOOR
15676 UNSPEC_FRNDINT_CEIL
15677 UNSPEC_FRNDINT_TRUNC])
15679 (define_int_iterator FIST_ROUNDING
15683 ;; Base name for define_insn
15684 (define_int_attr rounding_insn
15685 [(UNSPEC_FRNDINT_FLOOR "floor")
15686 (UNSPEC_FRNDINT_CEIL "ceil")
15687 (UNSPEC_FRNDINT_TRUNC "btrunc")
15688 (UNSPEC_FIST_FLOOR "floor")
15689 (UNSPEC_FIST_CEIL "ceil")])
15691 (define_int_attr rounding
15692 [(UNSPEC_FRNDINT_FLOOR "floor")
15693 (UNSPEC_FRNDINT_CEIL "ceil")
15694 (UNSPEC_FRNDINT_TRUNC "trunc")
15695 (UNSPEC_FIST_FLOOR "floor")
15696 (UNSPEC_FIST_CEIL "ceil")])
15698 (define_int_attr ROUNDING
15699 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15700 (UNSPEC_FRNDINT_CEIL "CEIL")
15701 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15702 (UNSPEC_FIST_FLOOR "FLOOR")
15703 (UNSPEC_FIST_CEIL "CEIL")])
15705 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15706 (define_insn_and_split "frndintxf2_<rounding>"
15707 [(set (match_operand:XF 0 "register_operand")
15708 (unspec:XF [(match_operand:XF 1 "register_operand")]
15710 (clobber (reg:CC FLAGS_REG))]
15711 "TARGET_USE_FANCY_MATH_387
15712 && flag_unsafe_math_optimizations
15713 && can_create_pseudo_p ()"
15718 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15720 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15721 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15723 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15724 operands[2], operands[3]));
15727 [(set_attr "type" "frndint")
15728 (set_attr "i387_cw" "<rounding>")
15729 (set_attr "mode" "XF")])
15731 (define_insn "frndintxf2_<rounding>_i387"
15732 [(set (match_operand:XF 0 "register_operand" "=f")
15733 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15735 (use (match_operand:HI 2 "memory_operand" "m"))
15736 (use (match_operand:HI 3 "memory_operand" "m"))]
15737 "TARGET_USE_FANCY_MATH_387
15738 && flag_unsafe_math_optimizations"
15739 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15740 [(set_attr "type" "frndint")
15741 (set_attr "i387_cw" "<rounding>")
15742 (set_attr "mode" "XF")])
15744 (define_expand "<rounding_insn>xf2"
15745 [(parallel [(set (match_operand:XF 0 "register_operand")
15746 (unspec:XF [(match_operand:XF 1 "register_operand")]
15748 (clobber (reg:CC FLAGS_REG))])]
15749 "TARGET_USE_FANCY_MATH_387
15750 && flag_unsafe_math_optimizations
15751 && !optimize_insn_for_size_p ()")
15753 (define_expand "<rounding_insn><mode>2"
15754 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15755 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15757 (clobber (reg:CC FLAGS_REG))])]
15758 "(TARGET_USE_FANCY_MATH_387
15759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15760 || TARGET_MIX_SSE_I387)
15761 && flag_unsafe_math_optimizations)
15762 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15763 && !flag_trapping_math)"
15765 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15766 && !flag_trapping_math)
15769 emit_insn (gen_sse4_1_round<mode>2
15770 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15771 else if (optimize_insn_for_size_p ())
15773 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15775 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15776 ix86_expand_floorceil (operands[0], operands[1], true);
15777 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15778 ix86_expand_floorceil (operands[0], operands[1], false);
15779 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15780 ix86_expand_trunc (operands[0], operands[1]);
15782 gcc_unreachable ();
15786 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15787 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15788 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15789 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15790 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15791 ix86_expand_truncdf_32 (operands[0], operands[1]);
15793 gcc_unreachable ();
15800 if (optimize_insn_for_size_p ())
15803 op0 = gen_reg_rtx (XFmode);
15804 op1 = gen_reg_rtx (XFmode);
15805 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15806 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15813 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15814 (define_insn_and_split "frndintxf2_mask_pm"
15815 [(set (match_operand:XF 0 "register_operand")
15816 (unspec:XF [(match_operand:XF 1 "register_operand")]
15817 UNSPEC_FRNDINT_MASK_PM))
15818 (clobber (reg:CC FLAGS_REG))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && flag_unsafe_math_optimizations
15821 && can_create_pseudo_p ()"
15826 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15828 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15829 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15831 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15832 operands[2], operands[3]));
15835 [(set_attr "type" "frndint")
15836 (set_attr "i387_cw" "mask_pm")
15837 (set_attr "mode" "XF")])
15839 (define_insn "frndintxf2_mask_pm_i387"
15840 [(set (match_operand:XF 0 "register_operand" "=f")
15841 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15842 UNSPEC_FRNDINT_MASK_PM))
15843 (use (match_operand:HI 2 "memory_operand" "m"))
15844 (use (match_operand:HI 3 "memory_operand" "m"))]
15845 "TARGET_USE_FANCY_MATH_387
15846 && flag_unsafe_math_optimizations"
15847 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15848 [(set_attr "type" "frndint")
15849 (set_attr "i387_cw" "mask_pm")
15850 (set_attr "mode" "XF")])
15852 (define_expand "nearbyintxf2"
15853 [(parallel [(set (match_operand:XF 0 "register_operand")
15854 (unspec:XF [(match_operand:XF 1 "register_operand")]
15855 UNSPEC_FRNDINT_MASK_PM))
15856 (clobber (reg:CC FLAGS_REG))])]
15857 "TARGET_USE_FANCY_MATH_387
15858 && flag_unsafe_math_optimizations")
15860 (define_expand "nearbyint<mode>2"
15861 [(use (match_operand:MODEF 0 "register_operand"))
15862 (use (match_operand:MODEF 1 "register_operand"))]
15863 "TARGET_USE_FANCY_MATH_387
15864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15865 || TARGET_MIX_SSE_I387)
15866 && flag_unsafe_math_optimizations"
15868 rtx op0 = gen_reg_rtx (XFmode);
15869 rtx op1 = gen_reg_rtx (XFmode);
15871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15872 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15878 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15879 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15880 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15881 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15883 (clobber (reg:CC FLAGS_REG))]
15884 "TARGET_USE_FANCY_MATH_387
15885 && flag_unsafe_math_optimizations
15886 && can_create_pseudo_p ()"
15891 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15893 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15894 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15895 if (memory_operand (operands[0], VOIDmode))
15896 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15897 operands[2], operands[3]));
15900 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15901 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15902 (operands[0], operands[1], operands[2],
15903 operands[3], operands[4]));
15907 [(set_attr "type" "fistp")
15908 (set_attr "i387_cw" "<rounding>")
15909 (set_attr "mode" "<MODE>")])
15911 (define_insn "fistdi2_<rounding>"
15912 [(set (match_operand:DI 0 "memory_operand" "=m")
15913 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15915 (use (match_operand:HI 2 "memory_operand" "m"))
15916 (use (match_operand:HI 3 "memory_operand" "m"))
15917 (clobber (match_scratch:XF 4 "=&1f"))]
15918 "TARGET_USE_FANCY_MATH_387
15919 && flag_unsafe_math_optimizations"
15920 "* return output_fix_trunc (insn, operands, false);"
15921 [(set_attr "type" "fistp")
15922 (set_attr "i387_cw" "<rounding>")
15923 (set_attr "mode" "DI")])
15925 (define_insn "fistdi2_<rounding>_with_temp"
15926 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15927 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15929 (use (match_operand:HI 2 "memory_operand" "m,m"))
15930 (use (match_operand:HI 3 "memory_operand" "m,m"))
15931 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15932 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15933 "TARGET_USE_FANCY_MATH_387
15934 && flag_unsafe_math_optimizations"
15936 [(set_attr "type" "fistp")
15937 (set_attr "i387_cw" "<rounding>")
15938 (set_attr "mode" "DI")])
15941 [(set (match_operand:DI 0 "register_operand")
15942 (unspec:DI [(match_operand:XF 1 "register_operand")]
15944 (use (match_operand:HI 2 "memory_operand"))
15945 (use (match_operand:HI 3 "memory_operand"))
15946 (clobber (match_operand:DI 4 "memory_operand"))
15947 (clobber (match_scratch 5))]
15949 [(parallel [(set (match_dup 4)
15950 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15951 (use (match_dup 2))
15952 (use (match_dup 3))
15953 (clobber (match_dup 5))])
15954 (set (match_dup 0) (match_dup 4))])
15957 [(set (match_operand:DI 0 "memory_operand")
15958 (unspec:DI [(match_operand:XF 1 "register_operand")]
15960 (use (match_operand:HI 2 "memory_operand"))
15961 (use (match_operand:HI 3 "memory_operand"))
15962 (clobber (match_operand:DI 4 "memory_operand"))
15963 (clobber (match_scratch 5))]
15965 [(parallel [(set (match_dup 0)
15966 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15967 (use (match_dup 2))
15968 (use (match_dup 3))
15969 (clobber (match_dup 5))])])
15971 (define_insn "fist<mode>2_<rounding>"
15972 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15973 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15975 (use (match_operand:HI 2 "memory_operand" "m"))
15976 (use (match_operand:HI 3 "memory_operand" "m"))]
15977 "TARGET_USE_FANCY_MATH_387
15978 && flag_unsafe_math_optimizations"
15979 "* return output_fix_trunc (insn, operands, false);"
15980 [(set_attr "type" "fistp")
15981 (set_attr "i387_cw" "<rounding>")
15982 (set_attr "mode" "<MODE>")])
15984 (define_insn "fist<mode>2_<rounding>_with_temp"
15985 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15986 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15988 (use (match_operand:HI 2 "memory_operand" "m,m"))
15989 (use (match_operand:HI 3 "memory_operand" "m,m"))
15990 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15991 "TARGET_USE_FANCY_MATH_387
15992 && flag_unsafe_math_optimizations"
15994 [(set_attr "type" "fistp")
15995 (set_attr "i387_cw" "<rounding>")
15996 (set_attr "mode" "<MODE>")])
15999 [(set (match_operand:SWI24 0 "register_operand")
16000 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16002 (use (match_operand:HI 2 "memory_operand"))
16003 (use (match_operand:HI 3 "memory_operand"))
16004 (clobber (match_operand:SWI24 4 "memory_operand"))]
16006 [(parallel [(set (match_dup 4)
16007 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16008 (use (match_dup 2))
16009 (use (match_dup 3))])
16010 (set (match_dup 0) (match_dup 4))])
16013 [(set (match_operand:SWI24 0 "memory_operand")
16014 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16016 (use (match_operand:HI 2 "memory_operand"))
16017 (use (match_operand:HI 3 "memory_operand"))
16018 (clobber (match_operand:SWI24 4 "memory_operand"))]
16020 [(parallel [(set (match_dup 0)
16021 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16022 (use (match_dup 2))
16023 (use (match_dup 3))])])
16025 (define_expand "l<rounding_insn>xf<mode>2"
16026 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16027 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16029 (clobber (reg:CC FLAGS_REG))])]
16030 "TARGET_USE_FANCY_MATH_387
16031 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16032 && flag_unsafe_math_optimizations")
16034 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16035 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16036 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16038 (clobber (reg:CC FLAGS_REG))])]
16039 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16040 && !flag_trapping_math"
16042 if (TARGET_64BIT && optimize_insn_for_size_p ())
16045 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16046 ix86_expand_lfloorceil (operands[0], operands[1], true);
16047 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16048 ix86_expand_lfloorceil (operands[0], operands[1], false);
16050 gcc_unreachable ();
16055 (define_insn "fxam<mode>2_i387"
16056 [(set (match_operand:HI 0 "register_operand" "=a")
16058 [(match_operand:X87MODEF 1 "register_operand" "f")]
16060 "TARGET_USE_FANCY_MATH_387"
16061 "fxam\n\tfnstsw\t%0"
16062 [(set_attr "type" "multi")
16063 (set_attr "length" "4")
16064 (set_attr "unit" "i387")
16065 (set_attr "mode" "<MODE>")])
16067 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16068 [(set (match_operand:HI 0 "register_operand")
16070 [(match_operand:MODEF 1 "memory_operand")]
16072 "TARGET_USE_FANCY_MATH_387
16073 && can_create_pseudo_p ()"
16076 [(set (match_dup 2)(match_dup 1))
16078 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16080 operands[2] = gen_reg_rtx (<MODE>mode);
16082 MEM_VOLATILE_P (operands[1]) = 1;
16084 [(set_attr "type" "multi")
16085 (set_attr "unit" "i387")
16086 (set_attr "mode" "<MODE>")])
16088 (define_expand "isinfxf2"
16089 [(use (match_operand:SI 0 "register_operand"))
16090 (use (match_operand:XF 1 "register_operand"))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && ix86_libc_has_function (function_c99_misc)"
16094 rtx mask = GEN_INT (0x45);
16095 rtx val = GEN_INT (0x05);
16099 rtx scratch = gen_reg_rtx (HImode);
16100 rtx res = gen_reg_rtx (QImode);
16102 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16104 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16105 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16106 cond = gen_rtx_fmt_ee (EQ, QImode,
16107 gen_rtx_REG (CCmode, FLAGS_REG),
16109 emit_insn (gen_rtx_SET (res, cond));
16110 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16114 (define_expand "isinf<mode>2"
16115 [(use (match_operand:SI 0 "register_operand"))
16116 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16117 "TARGET_USE_FANCY_MATH_387
16118 && ix86_libc_has_function (function_c99_misc)
16119 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16121 rtx mask = GEN_INT (0x45);
16122 rtx val = GEN_INT (0x05);
16126 rtx scratch = gen_reg_rtx (HImode);
16127 rtx res = gen_reg_rtx (QImode);
16129 /* Remove excess precision by forcing value through memory. */
16130 if (memory_operand (operands[1], VOIDmode))
16131 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16134 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16136 emit_move_insn (temp, operands[1]);
16137 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16140 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16141 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16142 cond = gen_rtx_fmt_ee (EQ, QImode,
16143 gen_rtx_REG (CCmode, FLAGS_REG),
16145 emit_insn (gen_rtx_SET (res, cond));
16146 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16150 (define_expand "signbitxf2"
16151 [(use (match_operand:SI 0 "register_operand"))
16152 (use (match_operand:XF 1 "register_operand"))]
16153 "TARGET_USE_FANCY_MATH_387"
16155 rtx scratch = gen_reg_rtx (HImode);
16157 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16158 emit_insn (gen_andsi3 (operands[0],
16159 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16163 (define_insn "movmsk_df"
16164 [(set (match_operand:SI 0 "register_operand" "=r")
16166 [(match_operand:DF 1 "register_operand" "x")]
16168 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16169 "%vmovmskpd\t{%1, %0|%0, %1}"
16170 [(set_attr "type" "ssemov")
16171 (set_attr "prefix" "maybe_vex")
16172 (set_attr "mode" "DF")])
16174 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16175 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16176 (define_expand "signbitdf2"
16177 [(use (match_operand:SI 0 "register_operand"))
16178 (use (match_operand:DF 1 "register_operand"))]
16179 "TARGET_USE_FANCY_MATH_387
16180 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16182 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16184 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16185 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16189 rtx scratch = gen_reg_rtx (HImode);
16191 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16192 emit_insn (gen_andsi3 (operands[0],
16193 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16198 (define_expand "signbitsf2"
16199 [(use (match_operand:SI 0 "register_operand"))
16200 (use (match_operand:SF 1 "register_operand"))]
16201 "TARGET_USE_FANCY_MATH_387
16202 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16204 rtx scratch = gen_reg_rtx (HImode);
16206 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16207 emit_insn (gen_andsi3 (operands[0],
16208 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16212 ;; Block operation instructions
16215 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16218 [(set_attr "length" "1")
16219 (set_attr "length_immediate" "0")
16220 (set_attr "modrm" "0")])
16222 (define_expand "movmem<mode>"
16223 [(use (match_operand:BLK 0 "memory_operand"))
16224 (use (match_operand:BLK 1 "memory_operand"))
16225 (use (match_operand:SWI48 2 "nonmemory_operand"))
16226 (use (match_operand:SWI48 3 "const_int_operand"))
16227 (use (match_operand:SI 4 "const_int_operand"))
16228 (use (match_operand:SI 5 "const_int_operand"))
16229 (use (match_operand:SI 6 ""))
16230 (use (match_operand:SI 7 ""))
16231 (use (match_operand:SI 8 ""))]
16234 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16235 operands[2], NULL, operands[3],
16236 operands[4], operands[5],
16237 operands[6], operands[7],
16238 operands[8], false))
16244 ;; Most CPUs don't like single string operations
16245 ;; Handle this case here to simplify previous expander.
16247 (define_expand "strmov"
16248 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16249 (set (match_operand 1 "memory_operand") (match_dup 4))
16250 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16251 (clobber (reg:CC FLAGS_REG))])
16252 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16253 (clobber (reg:CC FLAGS_REG))])]
16256 /* Can't use this for non-default address spaces. */
16257 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16260 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16262 /* If .md ever supports :P for Pmode, these can be directly
16263 in the pattern above. */
16264 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16265 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16267 /* Can't use this if the user has appropriated esi or edi. */
16268 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16269 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16271 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16272 operands[2], operands[3],
16273 operands[5], operands[6]));
16277 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16280 (define_expand "strmov_singleop"
16281 [(parallel [(set (match_operand 1 "memory_operand")
16282 (match_operand 3 "memory_operand"))
16283 (set (match_operand 0 "register_operand")
16285 (set (match_operand 2 "register_operand")
16286 (match_operand 5))])]
16288 "ix86_current_function_needs_cld = 1;")
16290 (define_insn "*strmovdi_rex_1"
16291 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16292 (mem:DI (match_operand:P 3 "register_operand" "1")))
16293 (set (match_operand:P 0 "register_operand" "=D")
16294 (plus:P (match_dup 2)
16296 (set (match_operand:P 1 "register_operand" "=S")
16297 (plus:P (match_dup 3)
16300 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16301 && ix86_check_no_addr_space (insn)"
16303 [(set_attr "type" "str")
16304 (set_attr "memory" "both")
16305 (set_attr "mode" "DI")])
16307 (define_insn "*strmovsi_1"
16308 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16309 (mem:SI (match_operand:P 3 "register_operand" "1")))
16310 (set (match_operand:P 0 "register_operand" "=D")
16311 (plus:P (match_dup 2)
16313 (set (match_operand:P 1 "register_operand" "=S")
16314 (plus:P (match_dup 3)
16316 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16317 && ix86_check_no_addr_space (insn)"
16319 [(set_attr "type" "str")
16320 (set_attr "memory" "both")
16321 (set_attr "mode" "SI")])
16323 (define_insn "*strmovhi_1"
16324 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16325 (mem:HI (match_operand:P 3 "register_operand" "1")))
16326 (set (match_operand:P 0 "register_operand" "=D")
16327 (plus:P (match_dup 2)
16329 (set (match_operand:P 1 "register_operand" "=S")
16330 (plus:P (match_dup 3)
16332 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16333 && ix86_check_no_addr_space (insn)"
16335 [(set_attr "type" "str")
16336 (set_attr "memory" "both")
16337 (set_attr "mode" "HI")])
16339 (define_insn "*strmovqi_1"
16340 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16341 (mem:QI (match_operand:P 3 "register_operand" "1")))
16342 (set (match_operand:P 0 "register_operand" "=D")
16343 (plus:P (match_dup 2)
16345 (set (match_operand:P 1 "register_operand" "=S")
16346 (plus:P (match_dup 3)
16348 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16349 && ix86_check_no_addr_space (insn)"
16351 [(set_attr "type" "str")
16352 (set_attr "memory" "both")
16353 (set (attr "prefix_rex")
16355 (match_test "<P:MODE>mode == DImode")
16357 (const_string "*")))
16358 (set_attr "mode" "QI")])
16360 (define_expand "rep_mov"
16361 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16362 (set (match_operand 0 "register_operand")
16364 (set (match_operand 2 "register_operand")
16366 (set (match_operand 1 "memory_operand")
16367 (match_operand 3 "memory_operand"))
16368 (use (match_dup 4))])]
16370 "ix86_current_function_needs_cld = 1;")
16372 (define_insn "*rep_movdi_rex64"
16373 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16374 (set (match_operand:P 0 "register_operand" "=D")
16375 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16377 (match_operand:P 3 "register_operand" "0")))
16378 (set (match_operand:P 1 "register_operand" "=S")
16379 (plus:P (ashift:P (match_dup 5) (const_int 3))
16380 (match_operand:P 4 "register_operand" "1")))
16381 (set (mem:BLK (match_dup 3))
16382 (mem:BLK (match_dup 4)))
16383 (use (match_dup 5))]
16385 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16386 && ix86_check_no_addr_space (insn)"
16388 [(set_attr "type" "str")
16389 (set_attr "prefix_rep" "1")
16390 (set_attr "memory" "both")
16391 (set_attr "mode" "DI")])
16393 (define_insn "*rep_movsi"
16394 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16395 (set (match_operand:P 0 "register_operand" "=D")
16396 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16398 (match_operand:P 3 "register_operand" "0")))
16399 (set (match_operand:P 1 "register_operand" "=S")
16400 (plus:P (ashift:P (match_dup 5) (const_int 2))
16401 (match_operand:P 4 "register_operand" "1")))
16402 (set (mem:BLK (match_dup 3))
16403 (mem:BLK (match_dup 4)))
16404 (use (match_dup 5))]
16405 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16406 && ix86_check_no_addr_space (insn)"
16407 "%^rep{%;} movs{l|d}"
16408 [(set_attr "type" "str")
16409 (set_attr "prefix_rep" "1")
16410 (set_attr "memory" "both")
16411 (set_attr "mode" "SI")])
16413 (define_insn "*rep_movqi"
16414 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16415 (set (match_operand:P 0 "register_operand" "=D")
16416 (plus:P (match_operand:P 3 "register_operand" "0")
16417 (match_operand:P 5 "register_operand" "2")))
16418 (set (match_operand:P 1 "register_operand" "=S")
16419 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16420 (set (mem:BLK (match_dup 3))
16421 (mem:BLK (match_dup 4)))
16422 (use (match_dup 5))]
16423 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16424 && ix86_check_no_addr_space (insn)"
16426 [(set_attr "type" "str")
16427 (set_attr "prefix_rep" "1")
16428 (set_attr "memory" "both")
16429 (set_attr "mode" "QI")])
16431 (define_expand "setmem<mode>"
16432 [(use (match_operand:BLK 0 "memory_operand"))
16433 (use (match_operand:SWI48 1 "nonmemory_operand"))
16434 (use (match_operand:QI 2 "nonmemory_operand"))
16435 (use (match_operand 3 "const_int_operand"))
16436 (use (match_operand:SI 4 "const_int_operand"))
16437 (use (match_operand:SI 5 "const_int_operand"))
16438 (use (match_operand:SI 6 ""))
16439 (use (match_operand:SI 7 ""))
16440 (use (match_operand:SI 8 ""))]
16443 if (ix86_expand_set_or_movmem (operands[0], NULL,
16444 operands[1], operands[2],
16445 operands[3], operands[4],
16446 operands[5], operands[6],
16447 operands[7], operands[8], true))
16453 ;; Most CPUs don't like single string operations
16454 ;; Handle this case here to simplify previous expander.
16456 (define_expand "strset"
16457 [(set (match_operand 1 "memory_operand")
16458 (match_operand 2 "register_operand"))
16459 (parallel [(set (match_operand 0 "register_operand")
16461 (clobber (reg:CC FLAGS_REG))])]
16464 /* Can't use this for non-default address spaces. */
16465 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16468 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16469 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16471 /* If .md ever supports :P for Pmode, this can be directly
16472 in the pattern above. */
16473 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16474 GEN_INT (GET_MODE_SIZE (GET_MODE
16476 /* Can't use this if the user has appropriated eax or edi. */
16477 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16478 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16480 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16486 (define_expand "strset_singleop"
16487 [(parallel [(set (match_operand 1 "memory_operand")
16488 (match_operand 2 "register_operand"))
16489 (set (match_operand 0 "register_operand")
16491 (unspec [(const_int 0)] UNSPEC_STOS)])]
16493 "ix86_current_function_needs_cld = 1;")
16495 (define_insn "*strsetdi_rex_1"
16496 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16497 (match_operand:DI 2 "register_operand" "a"))
16498 (set (match_operand:P 0 "register_operand" "=D")
16499 (plus:P (match_dup 1)
16501 (unspec [(const_int 0)] UNSPEC_STOS)]
16503 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16504 && ix86_check_no_addr_space (insn)"
16506 [(set_attr "type" "str")
16507 (set_attr "memory" "store")
16508 (set_attr "mode" "DI")])
16510 (define_insn "*strsetsi_1"
16511 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16512 (match_operand:SI 2 "register_operand" "a"))
16513 (set (match_operand:P 0 "register_operand" "=D")
16514 (plus:P (match_dup 1)
16516 (unspec [(const_int 0)] UNSPEC_STOS)]
16517 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16518 && ix86_check_no_addr_space (insn)"
16520 [(set_attr "type" "str")
16521 (set_attr "memory" "store")
16522 (set_attr "mode" "SI")])
16524 (define_insn "*strsethi_1"
16525 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16526 (match_operand:HI 2 "register_operand" "a"))
16527 (set (match_operand:P 0 "register_operand" "=D")
16528 (plus:P (match_dup 1)
16530 (unspec [(const_int 0)] UNSPEC_STOS)]
16531 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16532 && ix86_check_no_addr_space (insn)"
16534 [(set_attr "type" "str")
16535 (set_attr "memory" "store")
16536 (set_attr "mode" "HI")])
16538 (define_insn "*strsetqi_1"
16539 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16540 (match_operand:QI 2 "register_operand" "a"))
16541 (set (match_operand:P 0 "register_operand" "=D")
16542 (plus:P (match_dup 1)
16544 (unspec [(const_int 0)] UNSPEC_STOS)]
16545 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16546 && ix86_check_no_addr_space (insn)"
16548 [(set_attr "type" "str")
16549 (set_attr "memory" "store")
16550 (set (attr "prefix_rex")
16552 (match_test "<P:MODE>mode == DImode")
16554 (const_string "*")))
16555 (set_attr "mode" "QI")])
16557 (define_expand "rep_stos"
16558 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16559 (set (match_operand 0 "register_operand")
16561 (set (match_operand 2 "memory_operand") (const_int 0))
16562 (use (match_operand 3 "register_operand"))
16563 (use (match_dup 1))])]
16565 "ix86_current_function_needs_cld = 1;")
16567 (define_insn "*rep_stosdi_rex64"
16568 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16569 (set (match_operand:P 0 "register_operand" "=D")
16570 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16572 (match_operand:P 3 "register_operand" "0")))
16573 (set (mem:BLK (match_dup 3))
16575 (use (match_operand:DI 2 "register_operand" "a"))
16576 (use (match_dup 4))]
16578 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16579 && ix86_check_no_addr_space (insn)"
16581 [(set_attr "type" "str")
16582 (set_attr "prefix_rep" "1")
16583 (set_attr "memory" "store")
16584 (set_attr "mode" "DI")])
16586 (define_insn "*rep_stossi"
16587 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16588 (set (match_operand:P 0 "register_operand" "=D")
16589 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16591 (match_operand:P 3 "register_operand" "0")))
16592 (set (mem:BLK (match_dup 3))
16594 (use (match_operand:SI 2 "register_operand" "a"))
16595 (use (match_dup 4))]
16596 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16597 && ix86_check_no_addr_space (insn)"
16598 "%^rep{%;} stos{l|d}"
16599 [(set_attr "type" "str")
16600 (set_attr "prefix_rep" "1")
16601 (set_attr "memory" "store")
16602 (set_attr "mode" "SI")])
16604 (define_insn "*rep_stosqi"
16605 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16606 (set (match_operand:P 0 "register_operand" "=D")
16607 (plus:P (match_operand:P 3 "register_operand" "0")
16608 (match_operand:P 4 "register_operand" "1")))
16609 (set (mem:BLK (match_dup 3))
16611 (use (match_operand:QI 2 "register_operand" "a"))
16612 (use (match_dup 4))]
16613 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16614 && ix86_check_no_addr_space (insn)"
16616 [(set_attr "type" "str")
16617 (set_attr "prefix_rep" "1")
16618 (set_attr "memory" "store")
16619 (set (attr "prefix_rex")
16621 (match_test "<P:MODE>mode == DImode")
16623 (const_string "*")))
16624 (set_attr "mode" "QI")])
16626 (define_expand "cmpstrnsi"
16627 [(set (match_operand:SI 0 "register_operand")
16628 (compare:SI (match_operand:BLK 1 "general_operand")
16629 (match_operand:BLK 2 "general_operand")))
16630 (use (match_operand 3 "general_operand"))
16631 (use (match_operand 4 "immediate_operand"))]
16634 rtx addr1, addr2, out, outlow, count, countreg, align;
16636 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16639 /* Can't use this if the user has appropriated ecx, esi or edi. */
16640 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16645 out = gen_reg_rtx (SImode);
16647 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16648 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16649 if (addr1 != XEXP (operands[1], 0))
16650 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16651 if (addr2 != XEXP (operands[2], 0))
16652 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16654 count = operands[3];
16655 countreg = ix86_zero_extend_to_Pmode (count);
16657 /* %%% Iff we are testing strict equality, we can use known alignment
16658 to good advantage. This may be possible with combine, particularly
16659 once cc0 is dead. */
16660 align = operands[4];
16662 if (CONST_INT_P (count))
16664 if (INTVAL (count) == 0)
16666 emit_move_insn (operands[0], const0_rtx);
16669 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16670 operands[1], operands[2]));
16674 rtx (*gen_cmp) (rtx, rtx);
16676 gen_cmp = (TARGET_64BIT
16677 ? gen_cmpdi_1 : gen_cmpsi_1);
16679 emit_insn (gen_cmp (countreg, countreg));
16680 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16681 operands[1], operands[2]));
16684 outlow = gen_lowpart (QImode, out);
16685 emit_insn (gen_cmpintqi (outlow));
16686 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16688 if (operands[0] != out)
16689 emit_move_insn (operands[0], out);
16694 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16696 (define_expand "cmpintqi"
16697 [(set (match_dup 1)
16698 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16700 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16701 (parallel [(set (match_operand:QI 0 "register_operand")
16702 (minus:QI (match_dup 1)
16704 (clobber (reg:CC FLAGS_REG))])]
16707 operands[1] = gen_reg_rtx (QImode);
16708 operands[2] = gen_reg_rtx (QImode);
16711 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16712 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16714 (define_expand "cmpstrnqi_nz_1"
16715 [(parallel [(set (reg:CC FLAGS_REG)
16716 (compare:CC (match_operand 4 "memory_operand")
16717 (match_operand 5 "memory_operand")))
16718 (use (match_operand 2 "register_operand"))
16719 (use (match_operand:SI 3 "immediate_operand"))
16720 (clobber (match_operand 0 "register_operand"))
16721 (clobber (match_operand 1 "register_operand"))
16722 (clobber (match_dup 2))])]
16724 "ix86_current_function_needs_cld = 1;")
16726 (define_insn "*cmpstrnqi_nz_1"
16727 [(set (reg:CC FLAGS_REG)
16728 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16729 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16730 (use (match_operand:P 6 "register_operand" "2"))
16731 (use (match_operand:SI 3 "immediate_operand" "i"))
16732 (clobber (match_operand:P 0 "register_operand" "=S"))
16733 (clobber (match_operand:P 1 "register_operand" "=D"))
16734 (clobber (match_operand:P 2 "register_operand" "=c"))]
16735 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16736 && ix86_check_no_addr_space (insn)"
16738 [(set_attr "type" "str")
16739 (set_attr "mode" "QI")
16740 (set (attr "prefix_rex")
16742 (match_test "<P:MODE>mode == DImode")
16744 (const_string "*")))
16745 (set_attr "prefix_rep" "1")])
16747 ;; The same, but the count is not known to not be zero.
16749 (define_expand "cmpstrnqi_1"
16750 [(parallel [(set (reg:CC FLAGS_REG)
16751 (if_then_else:CC (ne (match_operand 2 "register_operand")
16753 (compare:CC (match_operand 4 "memory_operand")
16754 (match_operand 5 "memory_operand"))
16756 (use (match_operand:SI 3 "immediate_operand"))
16757 (use (reg:CC FLAGS_REG))
16758 (clobber (match_operand 0 "register_operand"))
16759 (clobber (match_operand 1 "register_operand"))
16760 (clobber (match_dup 2))])]
16762 "ix86_current_function_needs_cld = 1;")
16764 (define_insn "*cmpstrnqi_1"
16765 [(set (reg:CC FLAGS_REG)
16766 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16768 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16769 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16771 (use (match_operand:SI 3 "immediate_operand" "i"))
16772 (use (reg:CC FLAGS_REG))
16773 (clobber (match_operand:P 0 "register_operand" "=S"))
16774 (clobber (match_operand:P 1 "register_operand" "=D"))
16775 (clobber (match_operand:P 2 "register_operand" "=c"))]
16776 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16777 && ix86_check_no_addr_space (insn)"
16779 [(set_attr "type" "str")
16780 (set_attr "mode" "QI")
16781 (set (attr "prefix_rex")
16783 (match_test "<P:MODE>mode == DImode")
16785 (const_string "*")))
16786 (set_attr "prefix_rep" "1")])
16788 (define_expand "strlen<mode>"
16789 [(set (match_operand:P 0 "register_operand")
16790 (unspec:P [(match_operand:BLK 1 "general_operand")
16791 (match_operand:QI 2 "immediate_operand")
16792 (match_operand 3 "immediate_operand")]
16796 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16802 (define_expand "strlenqi_1"
16803 [(parallel [(set (match_operand 0 "register_operand")
16805 (clobber (match_operand 1 "register_operand"))
16806 (clobber (reg:CC FLAGS_REG))])]
16808 "ix86_current_function_needs_cld = 1;")
16810 (define_insn "*strlenqi_1"
16811 [(set (match_operand:P 0 "register_operand" "=&c")
16812 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16813 (match_operand:QI 2 "register_operand" "a")
16814 (match_operand:P 3 "immediate_operand" "i")
16815 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16816 (clobber (match_operand:P 1 "register_operand" "=D"))
16817 (clobber (reg:CC FLAGS_REG))]
16818 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16819 && ix86_check_no_addr_space (insn)"
16820 "%^repnz{%;} scasb"
16821 [(set_attr "type" "str")
16822 (set_attr "mode" "QI")
16823 (set (attr "prefix_rex")
16825 (match_test "<P:MODE>mode == DImode")
16827 (const_string "*")))
16828 (set_attr "prefix_rep" "1")])
16830 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16831 ;; handled in combine, but it is not currently up to the task.
16832 ;; When used for their truth value, the cmpstrn* expanders generate
16841 ;; The intermediate three instructions are unnecessary.
16843 ;; This one handles cmpstrn*_nz_1...
16846 (set (reg:CC FLAGS_REG)
16847 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16848 (mem:BLK (match_operand 5 "register_operand"))))
16849 (use (match_operand 6 "register_operand"))
16850 (use (match_operand:SI 3 "immediate_operand"))
16851 (clobber (match_operand 0 "register_operand"))
16852 (clobber (match_operand 1 "register_operand"))
16853 (clobber (match_operand 2 "register_operand"))])
16854 (set (match_operand:QI 7 "register_operand")
16855 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16856 (set (match_operand:QI 8 "register_operand")
16857 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16858 (set (reg FLAGS_REG)
16859 (compare (match_dup 7) (match_dup 8)))
16861 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16863 (set (reg:CC FLAGS_REG)
16864 (compare:CC (mem:BLK (match_dup 4))
16865 (mem:BLK (match_dup 5))))
16866 (use (match_dup 6))
16867 (use (match_dup 3))
16868 (clobber (match_dup 0))
16869 (clobber (match_dup 1))
16870 (clobber (match_dup 2))])])
16872 ;; ...and this one handles cmpstrn*_1.
16875 (set (reg:CC FLAGS_REG)
16876 (if_then_else:CC (ne (match_operand 6 "register_operand")
16878 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16879 (mem:BLK (match_operand 5 "register_operand")))
16881 (use (match_operand:SI 3 "immediate_operand"))
16882 (use (reg:CC FLAGS_REG))
16883 (clobber (match_operand 0 "register_operand"))
16884 (clobber (match_operand 1 "register_operand"))
16885 (clobber (match_operand 2 "register_operand"))])
16886 (set (match_operand:QI 7 "register_operand")
16887 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16888 (set (match_operand:QI 8 "register_operand")
16889 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16890 (set (reg FLAGS_REG)
16891 (compare (match_dup 7) (match_dup 8)))
16893 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16895 (set (reg:CC FLAGS_REG)
16896 (if_then_else:CC (ne (match_dup 6)
16898 (compare:CC (mem:BLK (match_dup 4))
16899 (mem:BLK (match_dup 5)))
16901 (use (match_dup 3))
16902 (use (reg:CC FLAGS_REG))
16903 (clobber (match_dup 0))
16904 (clobber (match_dup 1))
16905 (clobber (match_dup 2))])])
16907 ;; Conditional move instructions.
16909 (define_expand "mov<mode>cc"
16910 [(set (match_operand:SWIM 0 "register_operand")
16911 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16912 (match_operand:SWIM 2 "<general_operand>")
16913 (match_operand:SWIM 3 "<general_operand>")))]
16915 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16917 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16918 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16919 ;; So just document what we're doing explicitly.
16921 (define_expand "x86_mov<mode>cc_0_m1"
16923 [(set (match_operand:SWI48 0 "register_operand")
16924 (if_then_else:SWI48
16925 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16926 [(match_operand 1 "flags_reg_operand")
16930 (clobber (reg:CC FLAGS_REG))])])
16932 (define_insn "*x86_mov<mode>cc_0_m1"
16933 [(set (match_operand:SWI48 0 "register_operand" "=r")
16934 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16935 [(reg FLAGS_REG) (const_int 0)])
16938 (clobber (reg:CC FLAGS_REG))]
16940 "sbb{<imodesuffix>}\t%0, %0"
16941 ; Since we don't have the proper number of operands for an alu insn,
16942 ; fill in all the blanks.
16943 [(set_attr "type" "alu")
16944 (set_attr "modrm_class" "op0")
16945 (set_attr "use_carry" "1")
16946 (set_attr "pent_pair" "pu")
16947 (set_attr "memory" "none")
16948 (set_attr "imm_disp" "false")
16949 (set_attr "mode" "<MODE>")
16950 (set_attr "length_immediate" "0")])
16952 (define_insn "*x86_mov<mode>cc_0_m1_se"
16953 [(set (match_operand:SWI48 0 "register_operand" "=r")
16954 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16955 [(reg FLAGS_REG) (const_int 0)])
16958 (clobber (reg:CC FLAGS_REG))]
16960 "sbb{<imodesuffix>}\t%0, %0"
16961 [(set_attr "type" "alu")
16962 (set_attr "modrm_class" "op0")
16963 (set_attr "use_carry" "1")
16964 (set_attr "pent_pair" "pu")
16965 (set_attr "memory" "none")
16966 (set_attr "imm_disp" "false")
16967 (set_attr "mode" "<MODE>")
16968 (set_attr "length_immediate" "0")])
16970 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16971 [(set (match_operand:SWI48 0 "register_operand" "=r")
16972 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16973 [(reg FLAGS_REG) (const_int 0)])))
16974 (clobber (reg:CC FLAGS_REG))]
16976 "sbb{<imodesuffix>}\t%0, %0"
16977 [(set_attr "type" "alu")
16978 (set_attr "modrm_class" "op0")
16979 (set_attr "use_carry" "1")
16980 (set_attr "pent_pair" "pu")
16981 (set_attr "memory" "none")
16982 (set_attr "imm_disp" "false")
16983 (set_attr "mode" "<MODE>")
16984 (set_attr "length_immediate" "0")])
16986 (define_insn "*mov<mode>cc_noc"
16987 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16988 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16989 [(reg FLAGS_REG) (const_int 0)])
16990 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16991 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16992 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16994 cmov%O2%C1\t{%2, %0|%0, %2}
16995 cmov%O2%c1\t{%3, %0|%0, %3}"
16996 [(set_attr "type" "icmov")
16997 (set_attr "mode" "<MODE>")])
16999 (define_insn "*movsicc_noc_zext"
17000 [(set (match_operand:DI 0 "register_operand" "=r,r")
17001 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17002 [(reg FLAGS_REG) (const_int 0)])
17004 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17006 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17008 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17010 cmov%O2%C1\t{%2, %k0|%k0, %2}
17011 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17012 [(set_attr "type" "icmov")
17013 (set_attr "mode" "SI")])
17015 ;; Don't do conditional moves with memory inputs. This splitter helps
17016 ;; register starved x86_32 by forcing inputs into registers before reload.
17018 [(set (match_operand:SWI248 0 "register_operand")
17019 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17020 [(reg FLAGS_REG) (const_int 0)])
17021 (match_operand:SWI248 2 "nonimmediate_operand")
17022 (match_operand:SWI248 3 "nonimmediate_operand")))]
17023 "!TARGET_64BIT && TARGET_CMOVE
17024 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17025 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17026 && can_create_pseudo_p ()
17027 && optimize_insn_for_speed_p ()"
17028 [(set (match_dup 0)
17029 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17031 if (MEM_P (operands[2]))
17032 operands[2] = force_reg (<MODE>mode, operands[2]);
17033 if (MEM_P (operands[3]))
17034 operands[3] = force_reg (<MODE>mode, operands[3]);
17037 (define_insn "*movqicc_noc"
17038 [(set (match_operand:QI 0 "register_operand" "=r,r")
17039 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17040 [(reg FLAGS_REG) (const_int 0)])
17041 (match_operand:QI 2 "register_operand" "r,0")
17042 (match_operand:QI 3 "register_operand" "0,r")))]
17043 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17045 [(set_attr "type" "icmov")
17046 (set_attr "mode" "QI")])
17049 [(set (match_operand:SWI12 0 "register_operand")
17050 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17051 [(reg FLAGS_REG) (const_int 0)])
17052 (match_operand:SWI12 2 "register_operand")
17053 (match_operand:SWI12 3 "register_operand")))]
17054 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17055 && reload_completed"
17056 [(set (match_dup 0)
17057 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17059 operands[0] = gen_lowpart (SImode, operands[0]);
17060 operands[2] = gen_lowpart (SImode, operands[2]);
17061 operands[3] = gen_lowpart (SImode, operands[3]);
17064 ;; Don't do conditional moves with memory inputs
17066 [(match_scratch:SWI248 4 "r")
17067 (set (match_operand:SWI248 0 "register_operand")
17068 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17069 [(reg FLAGS_REG) (const_int 0)])
17070 (match_operand:SWI248 2 "nonimmediate_operand")
17071 (match_operand:SWI248 3 "nonimmediate_operand")))]
17072 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17073 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17074 && optimize_insn_for_speed_p ()"
17075 [(set (match_dup 4) (match_dup 5))
17077 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17079 if (MEM_P (operands[2]))
17081 operands[5] = operands[2];
17082 operands[2] = operands[4];
17084 else if (MEM_P (operands[3]))
17086 operands[5] = operands[3];
17087 operands[3] = operands[4];
17090 gcc_unreachable ();
17094 [(match_scratch:SI 4 "r")
17095 (set (match_operand:DI 0 "register_operand")
17096 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17097 [(reg FLAGS_REG) (const_int 0)])
17099 (match_operand:SI 2 "nonimmediate_operand"))
17101 (match_operand:SI 3 "nonimmediate_operand"))))]
17103 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17104 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17105 && optimize_insn_for_speed_p ()"
17106 [(set (match_dup 4) (match_dup 5))
17108 (if_then_else:DI (match_dup 1)
17109 (zero_extend:DI (match_dup 2))
17110 (zero_extend:DI (match_dup 3))))]
17112 if (MEM_P (operands[2]))
17114 operands[5] = operands[2];
17115 operands[2] = operands[4];
17117 else if (MEM_P (operands[3]))
17119 operands[5] = operands[3];
17120 operands[3] = operands[4];
17123 gcc_unreachable ();
17126 (define_expand "mov<mode>cc"
17127 [(set (match_operand:X87MODEF 0 "register_operand")
17128 (if_then_else:X87MODEF
17129 (match_operand 1 "comparison_operator")
17130 (match_operand:X87MODEF 2 "register_operand")
17131 (match_operand:X87MODEF 3 "register_operand")))]
17132 "(TARGET_80387 && TARGET_CMOVE)
17133 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17134 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17136 (define_insn "*movxfcc_1"
17137 [(set (match_operand:XF 0 "register_operand" "=f,f")
17138 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17139 [(reg FLAGS_REG) (const_int 0)])
17140 (match_operand:XF 2 "register_operand" "f,0")
17141 (match_operand:XF 3 "register_operand" "0,f")))]
17142 "TARGET_80387 && TARGET_CMOVE"
17144 fcmov%F1\t{%2, %0|%0, %2}
17145 fcmov%f1\t{%3, %0|%0, %3}"
17146 [(set_attr "type" "fcmov")
17147 (set_attr "mode" "XF")])
17149 (define_insn "*movdfcc_1"
17150 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17151 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17152 [(reg FLAGS_REG) (const_int 0)])
17153 (match_operand:DF 2 "nonimmediate_operand"
17155 (match_operand:DF 3 "nonimmediate_operand"
17156 "0 ,f,0 ,rm,0, rm")))]
17157 "TARGET_80387 && TARGET_CMOVE
17158 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17160 fcmov%F1\t{%2, %0|%0, %2}
17161 fcmov%f1\t{%3, %0|%0, %3}
17164 cmov%O2%C1\t{%2, %0|%0, %2}
17165 cmov%O2%c1\t{%3, %0|%0, %3}"
17166 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17167 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17168 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17171 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
17172 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17173 [(reg FLAGS_REG) (const_int 0)])
17174 (match_operand:DF 2 "nonimmediate_operand")
17175 (match_operand:DF 3 "nonimmediate_operand")))]
17176 "!TARGET_64BIT && reload_completed"
17177 [(set (match_dup 2)
17178 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17180 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17182 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17183 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17186 (define_insn "*movsfcc_1_387"
17187 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17188 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17189 [(reg FLAGS_REG) (const_int 0)])
17190 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17191 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17192 "TARGET_80387 && TARGET_CMOVE
17193 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17195 fcmov%F1\t{%2, %0|%0, %2}
17196 fcmov%f1\t{%3, %0|%0, %3}
17197 cmov%O2%C1\t{%2, %0|%0, %2}
17198 cmov%O2%c1\t{%3, %0|%0, %3}"
17199 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17200 (set_attr "mode" "SF,SF,SI,SI")])
17202 ;; Don't do conditional moves with memory inputs. This splitter helps
17203 ;; register starved x86_32 by forcing inputs into registers before reload.
17205 [(set (match_operand:MODEF 0 "register_operand")
17206 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17207 [(reg FLAGS_REG) (const_int 0)])
17208 (match_operand:MODEF 2 "nonimmediate_operand")
17209 (match_operand:MODEF 3 "nonimmediate_operand")))]
17210 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17211 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17212 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17213 && can_create_pseudo_p ()
17214 && optimize_insn_for_speed_p ()"
17215 [(set (match_dup 0)
17216 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17218 if (MEM_P (operands[2]))
17219 operands[2] = force_reg (<MODE>mode, operands[2]);
17220 if (MEM_P (operands[3]))
17221 operands[3] = force_reg (<MODE>mode, operands[3]);
17224 ;; Don't do conditional moves with memory inputs
17226 [(match_scratch:MODEF 4 "r")
17227 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
17228 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17229 [(reg FLAGS_REG) (const_int 0)])
17230 (match_operand:MODEF 2 "nonimmediate_operand")
17231 (match_operand:MODEF 3 "nonimmediate_operand")))]
17232 "(<MODE>mode != DFmode || TARGET_64BIT)
17233 && TARGET_80387 && TARGET_CMOVE
17234 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17235 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17236 && optimize_insn_for_speed_p ()"
17237 [(set (match_dup 4) (match_dup 5))
17239 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17241 if (MEM_P (operands[2]))
17243 operands[5] = operands[2];
17244 operands[2] = operands[4];
17246 else if (MEM_P (operands[3]))
17248 operands[5] = operands[3];
17249 operands[3] = operands[4];
17252 gcc_unreachable ();
17255 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17256 ;; the scalar versions to have only XMM registers as operands.
17258 ;; XOP conditional move
17259 (define_insn "*xop_pcmov_<mode>"
17260 [(set (match_operand:MODEF 0 "register_operand" "=x")
17261 (if_then_else:MODEF
17262 (match_operand:MODEF 1 "register_operand" "x")
17263 (match_operand:MODEF 2 "register_operand" "x")
17264 (match_operand:MODEF 3 "register_operand" "x")))]
17266 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17267 [(set_attr "type" "sse4arg")])
17269 ;; These versions of the min/max patterns are intentionally ignorant of
17270 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17271 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17272 ;; are undefined in this condition, we're certain this is correct.
17274 (define_insn "<code><mode>3"
17275 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17277 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17278 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17279 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17281 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17282 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17283 [(set_attr "isa" "noavx,avx")
17284 (set_attr "prefix" "orig,vex")
17285 (set_attr "type" "sseadd")
17286 (set_attr "mode" "<MODE>")])
17288 ;; These versions of the min/max patterns implement exactly the operations
17289 ;; min = (op1 < op2 ? op1 : op2)
17290 ;; max = (!(op1 < op2) ? op1 : op2)
17291 ;; Their operands are not commutative, and thus they may be used in the
17292 ;; presence of -0.0 and NaN.
17294 (define_int_iterator IEEE_MAXMIN
17298 (define_int_attr ieee_maxmin
17299 [(UNSPEC_IEEE_MAX "max")
17300 (UNSPEC_IEEE_MIN "min")])
17302 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17303 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17305 [(match_operand:MODEF 1 "register_operand" "0,v")
17306 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17310 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17311 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17312 [(set_attr "isa" "noavx,avx")
17313 (set_attr "prefix" "orig,maybe_evex")
17314 (set_attr "type" "sseadd")
17315 (set_attr "mode" "<MODE>")])
17317 ;; Make two stack loads independent:
17319 ;; fld %st(0) -> fld bb
17320 ;; fmul bb fmul %st(1), %st
17322 ;; Actually we only match the last two instructions for simplicity.
17324 [(set (match_operand 0 "fp_register_operand")
17325 (match_operand 1 "fp_register_operand"))
17327 (match_operator 2 "binary_fp_operator"
17329 (match_operand 3 "memory_operand")]))]
17330 "REGNO (operands[0]) != REGNO (operands[1])"
17331 [(set (match_dup 0) (match_dup 3))
17332 (set (match_dup 0) (match_dup 4))]
17334 ;; The % modifier is not operational anymore in peephole2's, so we have to
17335 ;; swap the operands manually in the case of addition and multiplication.
17339 if (COMMUTATIVE_ARITH_P (operands[2]))
17340 op0 = operands[0], op1 = operands[1];
17342 op0 = operands[1], op1 = operands[0];
17344 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17345 GET_MODE (operands[2]),
17349 ;; Conditional addition patterns
17350 (define_expand "add<mode>cc"
17351 [(match_operand:SWI 0 "register_operand")
17352 (match_operand 1 "ordered_comparison_operator")
17353 (match_operand:SWI 2 "register_operand")
17354 (match_operand:SWI 3 "const_int_operand")]
17356 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17358 ;; Misc patterns (?)
17360 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17361 ;; Otherwise there will be nothing to keep
17363 ;; [(set (reg ebp) (reg esp))]
17364 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17365 ;; (clobber (eflags)]
17366 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17368 ;; in proper program order.
17370 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17371 [(set (match_operand:P 0 "register_operand" "=r,r")
17372 (plus:P (match_operand:P 1 "register_operand" "0,r")
17373 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17374 (clobber (reg:CC FLAGS_REG))
17375 (clobber (mem:BLK (scratch)))]
17378 switch (get_attr_type (insn))
17381 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17384 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17385 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17386 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17388 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17391 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17392 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17395 [(set (attr "type")
17396 (cond [(and (eq_attr "alternative" "0")
17397 (not (match_test "TARGET_OPT_AGU")))
17398 (const_string "alu")
17399 (match_operand:<MODE> 2 "const0_operand")
17400 (const_string "imov")
17402 (const_string "lea")))
17403 (set (attr "length_immediate")
17404 (cond [(eq_attr "type" "imov")
17406 (and (eq_attr "type" "alu")
17407 (match_operand 2 "const128_operand"))
17410 (const_string "*")))
17411 (set_attr "mode" "<MODE>")])
17413 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17414 [(set (match_operand:P 0 "register_operand" "=r")
17415 (minus:P (match_operand:P 1 "register_operand" "0")
17416 (match_operand:P 2 "register_operand" "r")))
17417 (clobber (reg:CC FLAGS_REG))
17418 (clobber (mem:BLK (scratch)))]
17420 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17421 [(set_attr "type" "alu")
17422 (set_attr "mode" "<MODE>")])
17424 (define_insn "allocate_stack_worker_probe_<mode>"
17425 [(set (match_operand:P 0 "register_operand" "=a")
17426 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17427 UNSPECV_STACK_PROBE))
17428 (clobber (reg:CC FLAGS_REG))]
17429 "ix86_target_stack_probe ()"
17430 "call\t___chkstk_ms"
17431 [(set_attr "type" "multi")
17432 (set_attr "length" "5")])
17434 (define_expand "allocate_stack"
17435 [(match_operand 0 "register_operand")
17436 (match_operand 1 "general_operand")]
17437 "ix86_target_stack_probe ()"
17441 #ifndef CHECK_STACK_LIMIT
17442 #define CHECK_STACK_LIMIT 0
17445 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17446 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17450 rtx (*insn) (rtx, rtx);
17452 x = copy_to_mode_reg (Pmode, operands[1]);
17454 insn = (TARGET_64BIT
17455 ? gen_allocate_stack_worker_probe_di
17456 : gen_allocate_stack_worker_probe_si);
17458 emit_insn (insn (x, x));
17461 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17462 stack_pointer_rtx, 0, OPTAB_DIRECT);
17464 if (x != stack_pointer_rtx)
17465 emit_move_insn (stack_pointer_rtx, x);
17467 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17471 ;; Use IOR for stack probes, this is shorter.
17472 (define_expand "probe_stack"
17473 [(match_operand 0 "memory_operand")]
17476 rtx (*gen_ior3) (rtx, rtx, rtx);
17478 gen_ior3 = (GET_MODE (operands[0]) == DImode
17479 ? gen_iordi3 : gen_iorsi3);
17481 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17485 (define_insn "adjust_stack_and_probe<mode>"
17486 [(set (match_operand:P 0 "register_operand" "=r")
17487 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17488 UNSPECV_PROBE_STACK_RANGE))
17489 (set (reg:P SP_REG)
17490 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17491 (clobber (reg:CC FLAGS_REG))
17492 (clobber (mem:BLK (scratch)))]
17494 "* return output_adjust_stack_and_probe (operands[0]);"
17495 [(set_attr "type" "multi")])
17497 (define_insn "probe_stack_range<mode>"
17498 [(set (match_operand:P 0 "register_operand" "=r")
17499 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17500 (match_operand:P 2 "const_int_operand" "n")]
17501 UNSPECV_PROBE_STACK_RANGE))
17502 (clobber (reg:CC FLAGS_REG))]
17504 "* return output_probe_stack_range (operands[0], operands[2]);"
17505 [(set_attr "type" "multi")])
17507 (define_expand "builtin_setjmp_receiver"
17508 [(label_ref (match_operand 0))]
17509 "!TARGET_64BIT && flag_pic"
17515 rtx_code_label *label_rtx = gen_label_rtx ();
17516 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17517 xops[0] = xops[1] = pic_offset_table_rtx;
17518 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17519 ix86_expand_binary_operator (MINUS, SImode, xops);
17523 emit_insn (gen_set_got (pic_offset_table_rtx));
17527 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17528 ;; Do not split instructions with mask registers.
17530 [(set (match_operand 0 "general_reg_operand")
17531 (match_operator 3 "promotable_binary_operator"
17532 [(match_operand 1 "general_reg_operand")
17533 (match_operand 2 "aligned_operand")]))
17534 (clobber (reg:CC FLAGS_REG))]
17535 "! TARGET_PARTIAL_REG_STALL && reload_completed
17536 && ((GET_MODE (operands[0]) == HImode
17537 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17538 /* ??? next two lines just !satisfies_constraint_K (...) */
17539 || !CONST_INT_P (operands[2])
17540 || satisfies_constraint_K (operands[2])))
17541 || (GET_MODE (operands[0]) == QImode
17542 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17543 [(parallel [(set (match_dup 0)
17544 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17545 (clobber (reg:CC FLAGS_REG))])]
17547 operands[0] = gen_lowpart (SImode, operands[0]);
17548 operands[1] = gen_lowpart (SImode, operands[1]);
17549 if (GET_CODE (operands[3]) != ASHIFT)
17550 operands[2] = gen_lowpart (SImode, operands[2]);
17551 operands[3] = shallow_copy_rtx (operands[3]);
17552 PUT_MODE (operands[3], SImode);
17555 ; Promote the QImode tests, as i386 has encoding of the AND
17556 ; instruction with 32-bit sign-extended immediate and thus the
17557 ; instruction size is unchanged, except in the %eax case for
17558 ; which it is increased by one byte, hence the ! optimize_size.
17560 [(set (match_operand 0 "flags_reg_operand")
17561 (match_operator 2 "compare_operator"
17562 [(and (match_operand 3 "aligned_operand")
17563 (match_operand 4 "const_int_operand"))
17565 (set (match_operand 1 "register_operand")
17566 (and (match_dup 3) (match_dup 4)))]
17567 "! TARGET_PARTIAL_REG_STALL && reload_completed
17568 && optimize_insn_for_speed_p ()
17569 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17570 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17571 /* Ensure that the operand will remain sign-extended immediate. */
17572 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17573 [(parallel [(set (match_dup 0)
17574 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17577 (and:SI (match_dup 3) (match_dup 4)))])]
17580 = gen_int_mode (INTVAL (operands[4])
17581 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17582 operands[1] = gen_lowpart (SImode, operands[1]);
17583 operands[3] = gen_lowpart (SImode, operands[3]);
17586 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17587 ; the TEST instruction with 32-bit sign-extended immediate and thus
17588 ; the instruction size would at least double, which is not what we
17589 ; want even with ! optimize_size.
17591 [(set (match_operand 0 "flags_reg_operand")
17592 (match_operator 1 "compare_operator"
17593 [(and (match_operand:HI 2 "aligned_operand")
17594 (match_operand:HI 3 "const_int_operand"))
17596 "! TARGET_PARTIAL_REG_STALL && reload_completed
17597 && ! TARGET_FAST_PREFIX
17598 && optimize_insn_for_speed_p ()
17599 /* Ensure that the operand will remain sign-extended immediate. */
17600 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17601 [(set (match_dup 0)
17602 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17606 = gen_int_mode (INTVAL (operands[3])
17607 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17608 operands[2] = gen_lowpart (SImode, operands[2]);
17612 [(set (match_operand 0 "register_operand")
17613 (neg (match_operand 1 "register_operand")))
17614 (clobber (reg:CC FLAGS_REG))]
17615 "! TARGET_PARTIAL_REG_STALL && reload_completed
17616 && (GET_MODE (operands[0]) == HImode
17617 || (GET_MODE (operands[0]) == QImode
17618 && (TARGET_PROMOTE_QImode
17619 || optimize_insn_for_size_p ())))"
17620 [(parallel [(set (match_dup 0)
17621 (neg:SI (match_dup 1)))
17622 (clobber (reg:CC FLAGS_REG))])]
17624 operands[0] = gen_lowpart (SImode, operands[0]);
17625 operands[1] = gen_lowpart (SImode, operands[1]);
17628 ;; Do not split instructions with mask regs.
17630 [(set (match_operand 0 "general_reg_operand")
17631 (not (match_operand 1 "general_reg_operand")))]
17632 "! TARGET_PARTIAL_REG_STALL && reload_completed
17633 && (GET_MODE (operands[0]) == HImode
17634 || (GET_MODE (operands[0]) == QImode
17635 && (TARGET_PROMOTE_QImode
17636 || optimize_insn_for_size_p ())))"
17637 [(set (match_dup 0)
17638 (not:SI (match_dup 1)))]
17640 operands[0] = gen_lowpart (SImode, operands[0]);
17641 operands[1] = gen_lowpart (SImode, operands[1]);
17644 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17645 ;; transform a complex memory operation into two memory to register operations.
17647 ;; Don't push memory operands
17649 [(set (match_operand:SWI 0 "push_operand")
17650 (match_operand:SWI 1 "memory_operand"))
17651 (match_scratch:SWI 2 "<r>")]
17652 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17653 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17654 [(set (match_dup 2) (match_dup 1))
17655 (set (match_dup 0) (match_dup 2))])
17657 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17660 [(set (match_operand:SF 0 "push_operand")
17661 (match_operand:SF 1 "memory_operand"))
17662 (match_scratch:SF 2 "r")]
17663 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17664 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17665 [(set (match_dup 2) (match_dup 1))
17666 (set (match_dup 0) (match_dup 2))])
17668 ;; Don't move an immediate directly to memory when the instruction
17669 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17671 [(match_scratch:SWI124 1 "<r>")
17672 (set (match_operand:SWI124 0 "memory_operand")
17674 "optimize_insn_for_speed_p ()
17675 && ((<MODE>mode == HImode
17676 && TARGET_LCP_STALL)
17677 || (!TARGET_USE_MOV0
17678 && TARGET_SPLIT_LONG_MOVES
17679 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17680 && peep2_regno_dead_p (0, FLAGS_REG)"
17681 [(parallel [(set (match_dup 2) (const_int 0))
17682 (clobber (reg:CC FLAGS_REG))])
17683 (set (match_dup 0) (match_dup 1))]
17684 "operands[2] = gen_lowpart (SImode, operands[1]);")
17687 [(match_scratch:SWI124 2 "<r>")
17688 (set (match_operand:SWI124 0 "memory_operand")
17689 (match_operand:SWI124 1 "immediate_operand"))]
17690 "optimize_insn_for_speed_p ()
17691 && ((<MODE>mode == HImode
17692 && TARGET_LCP_STALL)
17693 || (TARGET_SPLIT_LONG_MOVES
17694 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17695 [(set (match_dup 2) (match_dup 1))
17696 (set (match_dup 0) (match_dup 2))])
17698 ;; Don't compare memory with zero, load and use a test instead.
17700 [(set (match_operand 0 "flags_reg_operand")
17701 (match_operator 1 "compare_operator"
17702 [(match_operand:SI 2 "memory_operand")
17704 (match_scratch:SI 3 "r")]
17705 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17706 [(set (match_dup 3) (match_dup 2))
17707 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17709 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17710 ;; Don't split NOTs with a displacement operand, because resulting XOR
17711 ;; will not be pairable anyway.
17713 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17714 ;; represented using a modRM byte. The XOR replacement is long decoded,
17715 ;; so this split helps here as well.
17717 ;; Note: Can't do this as a regular split because we can't get proper
17718 ;; lifetime information then.
17721 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17722 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17723 "optimize_insn_for_speed_p ()
17724 && ((TARGET_NOT_UNPAIRABLE
17725 && (!MEM_P (operands[0])
17726 || !memory_displacement_operand (operands[0], <MODE>mode)))
17727 || (TARGET_NOT_VECTORMODE
17728 && long_memory_operand (operands[0], <MODE>mode)))
17729 && peep2_regno_dead_p (0, FLAGS_REG)"
17730 [(parallel [(set (match_dup 0)
17731 (xor:SWI124 (match_dup 1) (const_int -1)))
17732 (clobber (reg:CC FLAGS_REG))])])
17734 ;; Non pairable "test imm, reg" instructions can be translated to
17735 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17736 ;; byte opcode instead of two, have a short form for byte operands),
17737 ;; so do it for other CPUs as well. Given that the value was dead,
17738 ;; this should not create any new dependencies. Pass on the sub-word
17739 ;; versions if we're concerned about partial register stalls.
17742 [(set (match_operand 0 "flags_reg_operand")
17743 (match_operator 1 "compare_operator"
17744 [(and:SI (match_operand:SI 2 "register_operand")
17745 (match_operand:SI 3 "immediate_operand"))
17747 "ix86_match_ccmode (insn, CCNOmode)
17748 && (true_regnum (operands[2]) != AX_REG
17749 || satisfies_constraint_K (operands[3]))
17750 && peep2_reg_dead_p (1, operands[2])"
17752 [(set (match_dup 0)
17753 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17756 (and:SI (match_dup 2) (match_dup 3)))])])
17758 ;; We don't need to handle HImode case, because it will be promoted to SImode
17759 ;; on ! TARGET_PARTIAL_REG_STALL
17762 [(set (match_operand 0 "flags_reg_operand")
17763 (match_operator 1 "compare_operator"
17764 [(and:QI (match_operand:QI 2 "register_operand")
17765 (match_operand:QI 3 "immediate_operand"))
17767 "! TARGET_PARTIAL_REG_STALL
17768 && ix86_match_ccmode (insn, CCNOmode)
17769 && true_regnum (operands[2]) != AX_REG
17770 && peep2_reg_dead_p (1, operands[2])"
17772 [(set (match_dup 0)
17773 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17776 (and:QI (match_dup 2) (match_dup 3)))])])
17779 [(set (match_operand 0 "flags_reg_operand")
17780 (match_operator 1 "compare_operator"
17783 (match_operand 2 "QIreg_operand")
17786 (match_operand 3 "const_int_operand"))
17788 "! TARGET_PARTIAL_REG_STALL
17789 && ix86_match_ccmode (insn, CCNOmode)
17790 && true_regnum (operands[2]) != AX_REG
17791 && peep2_reg_dead_p (1, operands[2])"
17792 [(parallel [(set (match_dup 0)
17801 (set (zero_extract:SI (match_dup 2)
17809 (match_dup 3)))])])
17811 ;; Don't do logical operations with memory inputs.
17813 [(match_scratch:SI 2 "r")
17814 (parallel [(set (match_operand:SI 0 "register_operand")
17815 (match_operator:SI 3 "arith_or_logical_operator"
17817 (match_operand:SI 1 "memory_operand")]))
17818 (clobber (reg:CC FLAGS_REG))])]
17819 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17820 [(set (match_dup 2) (match_dup 1))
17821 (parallel [(set (match_dup 0)
17822 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17823 (clobber (reg:CC FLAGS_REG))])])
17826 [(match_scratch:SI 2 "r")
17827 (parallel [(set (match_operand:SI 0 "register_operand")
17828 (match_operator:SI 3 "arith_or_logical_operator"
17829 [(match_operand:SI 1 "memory_operand")
17831 (clobber (reg:CC FLAGS_REG))])]
17832 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17833 [(set (match_dup 2) (match_dup 1))
17834 (parallel [(set (match_dup 0)
17835 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17836 (clobber (reg:CC FLAGS_REG))])])
17838 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17839 ;; refers to the destination of the load!
17842 [(set (match_operand:SI 0 "register_operand")
17843 (match_operand:SI 1 "register_operand"))
17844 (parallel [(set (match_dup 0)
17845 (match_operator:SI 3 "commutative_operator"
17847 (match_operand:SI 2 "memory_operand")]))
17848 (clobber (reg:CC FLAGS_REG))])]
17849 "REGNO (operands[0]) != REGNO (operands[1])
17850 && GENERAL_REGNO_P (REGNO (operands[0]))
17851 && GENERAL_REGNO_P (REGNO (operands[1]))"
17852 [(set (match_dup 0) (match_dup 4))
17853 (parallel [(set (match_dup 0)
17854 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17855 (clobber (reg:CC FLAGS_REG))])]
17856 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17859 [(set (match_operand 0 "register_operand")
17860 (match_operand 1 "register_operand"))
17862 (match_operator 3 "commutative_operator"
17864 (match_operand 2 "memory_operand")]))]
17865 "REGNO (operands[0]) != REGNO (operands[1])
17866 && ((MMX_REGNO_P (REGNO (operands[0]))
17867 && MMX_REGNO_P (REGNO (operands[1])))
17868 || (SSE_REGNO_P (REGNO (operands[0]))
17869 && SSE_REGNO_P (REGNO (operands[1]))))"
17870 [(set (match_dup 0) (match_dup 2))
17872 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17874 ; Don't do logical operations with memory outputs
17876 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17877 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17878 ; the same decoder scheduling characteristics as the original.
17881 [(match_scratch:SI 2 "r")
17882 (parallel [(set (match_operand:SI 0 "memory_operand")
17883 (match_operator:SI 3 "arith_or_logical_operator"
17885 (match_operand:SI 1 "nonmemory_operand")]))
17886 (clobber (reg:CC FLAGS_REG))])]
17887 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17888 /* Do not split stack checking probes. */
17889 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17890 [(set (match_dup 2) (match_dup 0))
17891 (parallel [(set (match_dup 2)
17892 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17893 (clobber (reg:CC FLAGS_REG))])
17894 (set (match_dup 0) (match_dup 2))])
17897 [(match_scratch:SI 2 "r")
17898 (parallel [(set (match_operand:SI 0 "memory_operand")
17899 (match_operator:SI 3 "arith_or_logical_operator"
17900 [(match_operand:SI 1 "nonmemory_operand")
17902 (clobber (reg:CC FLAGS_REG))])]
17903 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17904 /* Do not split stack checking probes. */
17905 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17906 [(set (match_dup 2) (match_dup 0))
17907 (parallel [(set (match_dup 2)
17908 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17909 (clobber (reg:CC FLAGS_REG))])
17910 (set (match_dup 0) (match_dup 2))])
17912 ;; Attempt to use arith or logical operations with memory outputs with
17913 ;; setting of flags.
17915 [(set (match_operand:SWI 0 "register_operand")
17916 (match_operand:SWI 1 "memory_operand"))
17917 (parallel [(set (match_dup 0)
17918 (match_operator:SWI 3 "plusminuslogic_operator"
17920 (match_operand:SWI 2 "<nonmemory_operand>")]))
17921 (clobber (reg:CC FLAGS_REG))])
17922 (set (match_dup 1) (match_dup 0))
17923 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17924 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17925 && peep2_reg_dead_p (4, operands[0])
17926 && !reg_overlap_mentioned_p (operands[0], operands[1])
17927 && !reg_overlap_mentioned_p (operands[0], operands[2])
17928 && (<MODE>mode != QImode
17929 || immediate_operand (operands[2], QImode)
17930 || any_QIreg_operand (operands[2], QImode))
17931 && ix86_match_ccmode (peep2_next_insn (3),
17932 (GET_CODE (operands[3]) == PLUS
17933 || GET_CODE (operands[3]) == MINUS)
17934 ? CCGOCmode : CCNOmode)"
17935 [(parallel [(set (match_dup 4) (match_dup 5))
17936 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17937 (match_dup 2)]))])]
17939 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17940 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17941 copy_rtx (operands[1]),
17942 copy_rtx (operands[2]));
17943 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17944 operands[5], const0_rtx);
17948 [(parallel [(set (match_operand:SWI 0 "register_operand")
17949 (match_operator:SWI 2 "plusminuslogic_operator"
17951 (match_operand:SWI 1 "memory_operand")]))
17952 (clobber (reg:CC FLAGS_REG))])
17953 (set (match_dup 1) (match_dup 0))
17954 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17955 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17956 && GET_CODE (operands[2]) != MINUS
17957 && peep2_reg_dead_p (3, operands[0])
17958 && !reg_overlap_mentioned_p (operands[0], operands[1])
17959 && ix86_match_ccmode (peep2_next_insn (2),
17960 GET_CODE (operands[2]) == PLUS
17961 ? CCGOCmode : CCNOmode)"
17962 [(parallel [(set (match_dup 3) (match_dup 4))
17963 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17964 (match_dup 0)]))])]
17966 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17967 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17968 copy_rtx (operands[1]),
17969 copy_rtx (operands[0]));
17970 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17971 operands[4], const0_rtx);
17975 [(set (match_operand:SWI12 0 "register_operand")
17976 (match_operand:SWI12 1 "memory_operand"))
17977 (parallel [(set (match_operand:SI 4 "register_operand")
17978 (match_operator:SI 3 "plusminuslogic_operator"
17980 (match_operand:SI 2 "nonmemory_operand")]))
17981 (clobber (reg:CC FLAGS_REG))])
17982 (set (match_dup 1) (match_dup 0))
17983 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17984 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17985 && REG_P (operands[0]) && REG_P (operands[4])
17986 && REGNO (operands[0]) == REGNO (operands[4])
17987 && peep2_reg_dead_p (4, operands[0])
17988 && (<MODE>mode != QImode
17989 || immediate_operand (operands[2], SImode)
17990 || any_QIreg_operand (operands[2], SImode))
17991 && !reg_overlap_mentioned_p (operands[0], operands[1])
17992 && !reg_overlap_mentioned_p (operands[0], operands[2])
17993 && ix86_match_ccmode (peep2_next_insn (3),
17994 (GET_CODE (operands[3]) == PLUS
17995 || GET_CODE (operands[3]) == MINUS)
17996 ? CCGOCmode : CCNOmode)"
17997 [(parallel [(set (match_dup 4) (match_dup 5))
17998 (set (match_dup 1) (match_dup 6))])]
18000 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
18001 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18002 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18003 copy_rtx (operands[1]), operands[2]);
18004 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18005 operands[5], const0_rtx);
18006 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18007 copy_rtx (operands[1]),
18008 copy_rtx (operands[2]));
18011 ;; Attempt to always use XOR for zeroing registers.
18013 [(set (match_operand 0 "register_operand")
18014 (match_operand 1 "const0_operand"))]
18015 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18016 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18017 && GENERAL_REGNO_P (REGNO (operands[0]))
18018 && peep2_regno_dead_p (0, FLAGS_REG)"
18019 [(parallel [(set (match_dup 0) (const_int 0))
18020 (clobber (reg:CC FLAGS_REG))])]
18021 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18024 [(set (strict_low_part (match_operand 0 "register_operand"))
18026 "(GET_MODE (operands[0]) == QImode
18027 || GET_MODE (operands[0]) == HImode)
18028 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18029 && peep2_regno_dead_p (0, FLAGS_REG)"
18030 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18031 (clobber (reg:CC FLAGS_REG))])])
18033 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18035 [(set (match_operand:SWI248 0 "register_operand")
18037 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18038 && GENERAL_REGNO_P (REGNO (operands[0]))
18039 && peep2_regno_dead_p (0, FLAGS_REG)"
18040 [(parallel [(set (match_dup 0) (const_int -1))
18041 (clobber (reg:CC FLAGS_REG))])]
18043 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18044 operands[0] = gen_lowpart (SImode, operands[0]);
18047 ;; Attempt to convert simple lea to add/shift.
18048 ;; These can be created by move expanders.
18049 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18050 ;; relevant lea instructions were already split.
18053 [(set (match_operand:SWI48 0 "register_operand")
18054 (plus:SWI48 (match_dup 0)
18055 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18057 && peep2_regno_dead_p (0, FLAGS_REG)"
18058 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18059 (clobber (reg:CC FLAGS_REG))])])
18062 [(set (match_operand:SWI48 0 "register_operand")
18063 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18066 && peep2_regno_dead_p (0, FLAGS_REG)"
18067 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18068 (clobber (reg:CC FLAGS_REG))])])
18071 [(set (match_operand:DI 0 "register_operand")
18073 (plus:SI (match_operand:SI 1 "register_operand")
18074 (match_operand:SI 2 "nonmemory_operand"))))]
18075 "TARGET_64BIT && !TARGET_OPT_AGU
18076 && REGNO (operands[0]) == REGNO (operands[1])
18077 && peep2_regno_dead_p (0, FLAGS_REG)"
18078 [(parallel [(set (match_dup 0)
18079 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18080 (clobber (reg:CC FLAGS_REG))])])
18083 [(set (match_operand:DI 0 "register_operand")
18085 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18086 (match_operand:SI 2 "register_operand"))))]
18087 "TARGET_64BIT && !TARGET_OPT_AGU
18088 && REGNO (operands[0]) == REGNO (operands[2])
18089 && peep2_regno_dead_p (0, FLAGS_REG)"
18090 [(parallel [(set (match_dup 0)
18091 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18092 (clobber (reg:CC FLAGS_REG))])])
18095 [(set (match_operand:SWI48 0 "register_operand")
18096 (mult:SWI48 (match_dup 0)
18097 (match_operand:SWI48 1 "const_int_operand")))]
18098 "exact_log2 (INTVAL (operands[1])) >= 0
18099 && peep2_regno_dead_p (0, FLAGS_REG)"
18100 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18101 (clobber (reg:CC FLAGS_REG))])]
18102 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18105 [(set (match_operand:DI 0 "register_operand")
18107 (mult:SI (match_operand:SI 1 "register_operand")
18108 (match_operand:SI 2 "const_int_operand"))))]
18110 && exact_log2 (INTVAL (operands[2])) >= 0
18111 && REGNO (operands[0]) == REGNO (operands[1])
18112 && peep2_regno_dead_p (0, FLAGS_REG)"
18113 [(parallel [(set (match_dup 0)
18114 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18115 (clobber (reg:CC FLAGS_REG))])]
18116 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18118 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18119 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18120 ;; On many CPUs it is also faster, since special hardware to avoid esp
18121 ;; dependencies is present.
18123 ;; While some of these conversions may be done using splitters, we use
18124 ;; peepholes in order to allow combine_stack_adjustments pass to see
18125 ;; nonobfuscated RTL.
18127 ;; Convert prologue esp subtractions to push.
18128 ;; We need register to push. In order to keep verify_flow_info happy we have
18130 ;; - use scratch and clobber it in order to avoid dependencies
18131 ;; - use already live register
18132 ;; We can't use the second way right now, since there is no reliable way how to
18133 ;; verify that given register is live. First choice will also most likely in
18134 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18135 ;; call clobbered registers are dead. We may want to use base pointer as an
18136 ;; alternative when no register is available later.
18139 [(match_scratch:W 1 "r")
18140 (parallel [(set (reg:P SP_REG)
18141 (plus:P (reg:P SP_REG)
18142 (match_operand:P 0 "const_int_operand")))
18143 (clobber (reg:CC FLAGS_REG))
18144 (clobber (mem:BLK (scratch)))])]
18145 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18146 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
18147 [(clobber (match_dup 1))
18148 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18149 (clobber (mem:BLK (scratch)))])])
18152 [(match_scratch:W 1 "r")
18153 (parallel [(set (reg:P SP_REG)
18154 (plus:P (reg:P SP_REG)
18155 (match_operand:P 0 "const_int_operand")))
18156 (clobber (reg:CC FLAGS_REG))
18157 (clobber (mem:BLK (scratch)))])]
18158 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18159 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
18160 [(clobber (match_dup 1))
18161 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18162 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18163 (clobber (mem:BLK (scratch)))])])
18165 ;; Convert esp subtractions to push.
18167 [(match_scratch:W 1 "r")
18168 (parallel [(set (reg:P SP_REG)
18169 (plus:P (reg:P SP_REG)
18170 (match_operand:P 0 "const_int_operand")))
18171 (clobber (reg:CC FLAGS_REG))])]
18172 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18173 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
18174 [(clobber (match_dup 1))
18175 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18178 [(match_scratch:W 1 "r")
18179 (parallel [(set (reg:P SP_REG)
18180 (plus:P (reg:P SP_REG)
18181 (match_operand:P 0 "const_int_operand")))
18182 (clobber (reg:CC FLAGS_REG))])]
18183 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18184 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
18185 [(clobber (match_dup 1))
18186 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18187 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18189 ;; Convert epilogue deallocator to pop.
18191 [(match_scratch:W 1 "r")
18192 (parallel [(set (reg:P SP_REG)
18193 (plus:P (reg:P SP_REG)
18194 (match_operand:P 0 "const_int_operand")))
18195 (clobber (reg:CC FLAGS_REG))
18196 (clobber (mem:BLK (scratch)))])]
18197 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18198 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18199 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18200 (clobber (mem:BLK (scratch)))])])
18202 ;; Two pops case is tricky, since pop causes dependency
18203 ;; on destination register. We use two registers if available.
18205 [(match_scratch:W 1 "r")
18206 (match_scratch:W 2 "r")
18207 (parallel [(set (reg:P SP_REG)
18208 (plus:P (reg:P SP_REG)
18209 (match_operand:P 0 "const_int_operand")))
18210 (clobber (reg:CC FLAGS_REG))
18211 (clobber (mem:BLK (scratch)))])]
18212 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18213 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18214 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18215 (clobber (mem:BLK (scratch)))])
18216 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18219 [(match_scratch:W 1 "r")
18220 (parallel [(set (reg:P SP_REG)
18221 (plus:P (reg:P SP_REG)
18222 (match_operand:P 0 "const_int_operand")))
18223 (clobber (reg:CC FLAGS_REG))
18224 (clobber (mem:BLK (scratch)))])]
18225 "optimize_insn_for_size_p ()
18226 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18227 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18228 (clobber (mem:BLK (scratch)))])
18229 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18231 ;; Convert esp additions to pop.
18233 [(match_scratch:W 1 "r")
18234 (parallel [(set (reg:P SP_REG)
18235 (plus:P (reg:P SP_REG)
18236 (match_operand:P 0 "const_int_operand")))
18237 (clobber (reg:CC FLAGS_REG))])]
18238 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18239 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18241 ;; Two pops case is tricky, since pop causes dependency
18242 ;; on destination register. We use two registers if available.
18244 [(match_scratch:W 1 "r")
18245 (match_scratch:W 2 "r")
18246 (parallel [(set (reg:P SP_REG)
18247 (plus:P (reg:P SP_REG)
18248 (match_operand:P 0 "const_int_operand")))
18249 (clobber (reg:CC FLAGS_REG))])]
18250 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18251 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18252 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18255 [(match_scratch:W 1 "r")
18256 (parallel [(set (reg:P SP_REG)
18257 (plus:P (reg:P SP_REG)
18258 (match_operand:P 0 "const_int_operand")))
18259 (clobber (reg:CC FLAGS_REG))])]
18260 "optimize_insn_for_size_p ()
18261 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18262 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18263 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18265 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18266 ;; required and register dies. Similarly for 128 to -128.
18268 [(set (match_operand 0 "flags_reg_operand")
18269 (match_operator 1 "compare_operator"
18270 [(match_operand 2 "register_operand")
18271 (match_operand 3 "const_int_operand")]))]
18272 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18273 && incdec_operand (operands[3], GET_MODE (operands[3])))
18274 || (!TARGET_FUSE_CMP_AND_BRANCH
18275 && INTVAL (operands[3]) == 128))
18276 && ix86_match_ccmode (insn, CCGCmode)
18277 && peep2_reg_dead_p (1, operands[2])"
18278 [(parallel [(set (match_dup 0)
18279 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18280 (clobber (match_dup 2))])])
18282 ;; Convert imul by three, five and nine into lea
18285 [(set (match_operand:SWI48 0 "register_operand")
18286 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18287 (match_operand:SWI48 2 "const359_operand")))
18288 (clobber (reg:CC FLAGS_REG))])]
18289 "!TARGET_PARTIAL_REG_STALL
18290 || <MODE>mode == SImode
18291 || optimize_function_for_size_p (cfun)"
18292 [(set (match_dup 0)
18293 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18295 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18299 [(set (match_operand:SWI48 0 "register_operand")
18300 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18301 (match_operand:SWI48 2 "const359_operand")))
18302 (clobber (reg:CC FLAGS_REG))])]
18303 "optimize_insn_for_speed_p ()
18304 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18305 [(set (match_dup 0) (match_dup 1))
18307 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18309 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18311 ;; imul $32bit_imm, mem, reg is vector decoded, while
18312 ;; imul $32bit_imm, reg, reg is direct decoded.
18314 [(match_scratch:SWI48 3 "r")
18315 (parallel [(set (match_operand:SWI48 0 "register_operand")
18316 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18317 (match_operand:SWI48 2 "immediate_operand")))
18318 (clobber (reg:CC FLAGS_REG))])]
18319 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18320 && !satisfies_constraint_K (operands[2])"
18321 [(set (match_dup 3) (match_dup 1))
18322 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18323 (clobber (reg:CC FLAGS_REG))])])
18326 [(match_scratch:SI 3 "r")
18327 (parallel [(set (match_operand:DI 0 "register_operand")
18329 (mult:SI (match_operand:SI 1 "memory_operand")
18330 (match_operand:SI 2 "immediate_operand"))))
18331 (clobber (reg:CC FLAGS_REG))])]
18333 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18334 && !satisfies_constraint_K (operands[2])"
18335 [(set (match_dup 3) (match_dup 1))
18336 (parallel [(set (match_dup 0)
18337 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18338 (clobber (reg:CC FLAGS_REG))])])
18340 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18341 ;; Convert it into imul reg, reg
18342 ;; It would be better to force assembler to encode instruction using long
18343 ;; immediate, but there is apparently no way to do so.
18345 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18347 (match_operand:SWI248 1 "nonimmediate_operand")
18348 (match_operand:SWI248 2 "const_int_operand")))
18349 (clobber (reg:CC FLAGS_REG))])
18350 (match_scratch:SWI248 3 "r")]
18351 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18352 && satisfies_constraint_K (operands[2])"
18353 [(set (match_dup 3) (match_dup 2))
18354 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18355 (clobber (reg:CC FLAGS_REG))])]
18357 if (!rtx_equal_p (operands[0], operands[1]))
18358 emit_move_insn (operands[0], operands[1]);
18361 ;; After splitting up read-modify operations, array accesses with memory
18362 ;; operands might end up in form:
18364 ;; movl 4(%esp), %edx
18366 ;; instead of pre-splitting:
18368 ;; addl 4(%esp), %eax
18370 ;; movl 4(%esp), %edx
18371 ;; leal (%edx,%eax,4), %eax
18374 [(match_scratch:W 5 "r")
18375 (parallel [(set (match_operand 0 "register_operand")
18376 (ashift (match_operand 1 "register_operand")
18377 (match_operand 2 "const_int_operand")))
18378 (clobber (reg:CC FLAGS_REG))])
18379 (parallel [(set (match_operand 3 "register_operand")
18380 (plus (match_dup 0)
18381 (match_operand 4 "x86_64_general_operand")))
18382 (clobber (reg:CC FLAGS_REG))])]
18383 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18384 /* Validate MODE for lea. */
18385 && ((!TARGET_PARTIAL_REG_STALL
18386 && (GET_MODE (operands[0]) == QImode
18387 || GET_MODE (operands[0]) == HImode))
18388 || GET_MODE (operands[0]) == SImode
18389 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18390 && (rtx_equal_p (operands[0], operands[3])
18391 || peep2_reg_dead_p (2, operands[0]))
18392 /* We reorder load and the shift. */
18393 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18394 [(set (match_dup 5) (match_dup 4))
18395 (set (match_dup 0) (match_dup 1))]
18397 machine_mode op1mode = GET_MODE (operands[1]);
18398 machine_mode mode = op1mode == DImode ? DImode : SImode;
18399 int scale = 1 << INTVAL (operands[2]);
18400 rtx index = gen_lowpart (word_mode, operands[1]);
18401 rtx base = gen_lowpart (word_mode, operands[5]);
18402 rtx dest = gen_lowpart (mode, operands[3]);
18404 operands[1] = gen_rtx_PLUS (word_mode, base,
18405 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18406 if (mode != word_mode)
18407 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18409 operands[5] = base;
18410 if (op1mode != word_mode)
18411 operands[5] = gen_lowpart (op1mode, operands[5]);
18413 operands[0] = dest;
18416 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18417 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18418 ;; caught for use by garbage collectors and the like. Using an insn that
18419 ;; maps to SIGILL makes it more likely the program will rightfully die.
18420 ;; Keeping with tradition, "6" is in honor of #UD.
18421 (define_insn "trap"
18422 [(trap_if (const_int 1) (const_int 6))]
18425 #ifdef HAVE_AS_IX86_UD2
18428 return ASM_SHORT "0x0b0f";
18431 [(set_attr "length" "2")])
18433 (define_expand "prefetch"
18434 [(prefetch (match_operand 0 "address_operand")
18435 (match_operand:SI 1 "const_int_operand")
18436 (match_operand:SI 2 "const_int_operand"))]
18437 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18439 bool write = INTVAL (operands[1]) != 0;
18440 int locality = INTVAL (operands[2]);
18442 gcc_assert (IN_RANGE (locality, 0, 3));
18444 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18445 supported by SSE counterpart or the SSE prefetch is not available
18446 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18448 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18449 operands[2] = const2_rtx;
18450 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18451 operands[2] = GEN_INT (3);
18453 operands[1] = const0_rtx;
18456 (define_insn "*prefetch_sse"
18457 [(prefetch (match_operand 0 "address_operand" "p")
18459 (match_operand:SI 1 "const_int_operand"))]
18460 "TARGET_PREFETCH_SSE"
18462 static const char * const patterns[4] = {
18463 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18466 int locality = INTVAL (operands[1]);
18467 gcc_assert (IN_RANGE (locality, 0, 3));
18469 return patterns[locality];
18471 [(set_attr "type" "sse")
18472 (set_attr "atom_sse_attr" "prefetch")
18473 (set (attr "length_address")
18474 (symbol_ref "memory_address_length (operands[0], false)"))
18475 (set_attr "memory" "none")])
18477 (define_insn "*prefetch_3dnow"
18478 [(prefetch (match_operand 0 "address_operand" "p")
18479 (match_operand:SI 1 "const_int_operand" "n")
18483 if (INTVAL (operands[1]) == 0)
18484 return "prefetch\t%a0";
18486 return "prefetchw\t%a0";
18488 [(set_attr "type" "mmx")
18489 (set (attr "length_address")
18490 (symbol_ref "memory_address_length (operands[0], false)"))
18491 (set_attr "memory" "none")])
18493 (define_insn "*prefetch_prefetchwt1"
18494 [(prefetch (match_operand 0 "address_operand" "p")
18497 "TARGET_PREFETCHWT1"
18498 "prefetchwt1\t%a0";
18499 [(set_attr "type" "sse")
18500 (set (attr "length_address")
18501 (symbol_ref "memory_address_length (operands[0], false)"))
18502 (set_attr "memory" "none")])
18504 (define_expand "stack_protect_set"
18505 [(match_operand 0 "memory_operand")
18506 (match_operand 1 "memory_operand")]
18507 "TARGET_SSP_TLS_GUARD"
18509 rtx (*insn)(rtx, rtx);
18511 #ifdef TARGET_THREAD_SSP_OFFSET
18512 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18513 insn = (TARGET_LP64
18514 ? gen_stack_tls_protect_set_di
18515 : gen_stack_tls_protect_set_si);
18517 insn = (TARGET_LP64
18518 ? gen_stack_protect_set_di
18519 : gen_stack_protect_set_si);
18522 emit_insn (insn (operands[0], operands[1]));
18526 (define_insn "stack_protect_set_<mode>"
18527 [(set (match_operand:PTR 0 "memory_operand" "=m")
18528 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18530 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18531 (clobber (reg:CC FLAGS_REG))]
18532 "TARGET_SSP_TLS_GUARD"
18533 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18534 [(set_attr "type" "multi")])
18536 (define_insn "stack_tls_protect_set_<mode>"
18537 [(set (match_operand:PTR 0 "memory_operand" "=m")
18538 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18539 UNSPEC_SP_TLS_SET))
18540 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18541 (clobber (reg:CC FLAGS_REG))]
18543 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18544 [(set_attr "type" "multi")])
18546 (define_expand "stack_protect_test"
18547 [(match_operand 0 "memory_operand")
18548 (match_operand 1 "memory_operand")
18550 "TARGET_SSP_TLS_GUARD"
18552 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18554 rtx (*insn)(rtx, rtx, rtx);
18556 #ifdef TARGET_THREAD_SSP_OFFSET
18557 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18558 insn = (TARGET_LP64
18559 ? gen_stack_tls_protect_test_di
18560 : gen_stack_tls_protect_test_si);
18562 insn = (TARGET_LP64
18563 ? gen_stack_protect_test_di
18564 : gen_stack_protect_test_si);
18567 emit_insn (insn (flags, operands[0], operands[1]));
18569 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18570 flags, const0_rtx, operands[2]));
18574 (define_insn "stack_protect_test_<mode>"
18575 [(set (match_operand:CCZ 0 "flags_reg_operand")
18576 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18577 (match_operand:PTR 2 "memory_operand" "m")]
18579 (clobber (match_scratch:PTR 3 "=&r"))]
18580 "TARGET_SSP_TLS_GUARD"
18581 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18582 [(set_attr "type" "multi")])
18584 (define_insn "stack_tls_protect_test_<mode>"
18585 [(set (match_operand:CCZ 0 "flags_reg_operand")
18586 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18587 (match_operand:PTR 2 "const_int_operand" "i")]
18588 UNSPEC_SP_TLS_TEST))
18589 (clobber (match_scratch:PTR 3 "=r"))]
18591 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18592 [(set_attr "type" "multi")])
18594 (define_insn "sse4_2_crc32<mode>"
18595 [(set (match_operand:SI 0 "register_operand" "=r")
18597 [(match_operand:SI 1 "register_operand" "0")
18598 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18600 "TARGET_SSE4_2 || TARGET_CRC32"
18601 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18602 [(set_attr "type" "sselog1")
18603 (set_attr "prefix_rep" "1")
18604 (set_attr "prefix_extra" "1")
18605 (set (attr "prefix_data16")
18606 (if_then_else (match_operand:HI 2)
18608 (const_string "*")))
18609 (set (attr "prefix_rex")
18610 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18612 (const_string "*")))
18613 (set_attr "mode" "SI")])
18615 (define_insn "sse4_2_crc32di"
18616 [(set (match_operand:DI 0 "register_operand" "=r")
18618 [(match_operand:DI 1 "register_operand" "0")
18619 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18621 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18622 "crc32{q}\t{%2, %0|%0, %2}"
18623 [(set_attr "type" "sselog1")
18624 (set_attr "prefix_rep" "1")
18625 (set_attr "prefix_extra" "1")
18626 (set_attr "mode" "DI")])
18628 (define_insn "rdpmc"
18629 [(set (match_operand:DI 0 "register_operand" "=A")
18630 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18634 [(set_attr "type" "other")
18635 (set_attr "length" "2")])
18637 (define_insn "rdpmc_rex64"
18638 [(set (match_operand:DI 0 "register_operand" "=a")
18639 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18641 (set (match_operand:DI 1 "register_operand" "=d")
18642 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18645 [(set_attr "type" "other")
18646 (set_attr "length" "2")])
18648 (define_insn "rdtsc"
18649 [(set (match_operand:DI 0 "register_operand" "=A")
18650 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18653 [(set_attr "type" "other")
18654 (set_attr "length" "2")])
18656 (define_insn "rdtsc_rex64"
18657 [(set (match_operand:DI 0 "register_operand" "=a")
18658 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18659 (set (match_operand:DI 1 "register_operand" "=d")
18660 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18663 [(set_attr "type" "other")
18664 (set_attr "length" "2")])
18666 (define_insn "rdtscp"
18667 [(set (match_operand:DI 0 "register_operand" "=A")
18668 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18669 (set (match_operand:SI 1 "register_operand" "=c")
18670 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18673 [(set_attr "type" "other")
18674 (set_attr "length" "3")])
18676 (define_insn "rdtscp_rex64"
18677 [(set (match_operand:DI 0 "register_operand" "=a")
18678 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18679 (set (match_operand:DI 1 "register_operand" "=d")
18680 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18681 (set (match_operand:SI 2 "register_operand" "=c")
18682 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18685 [(set_attr "type" "other")
18686 (set_attr "length" "3")])
18688 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18690 ;; FXSR, XSAVE and XSAVEOPT instructions
18692 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18694 (define_insn "fxsave"
18695 [(set (match_operand:BLK 0 "memory_operand" "=m")
18696 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18699 [(set_attr "type" "other")
18700 (set_attr "memory" "store")
18701 (set (attr "length")
18702 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18704 (define_insn "fxsave64"
18705 [(set (match_operand:BLK 0 "memory_operand" "=m")
18706 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18707 "TARGET_64BIT && TARGET_FXSR"
18709 [(set_attr "type" "other")
18710 (set_attr "memory" "store")
18711 (set (attr "length")
18712 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18714 (define_insn "fxrstor"
18715 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18719 [(set_attr "type" "other")
18720 (set_attr "memory" "load")
18721 (set (attr "length")
18722 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18724 (define_insn "fxrstor64"
18725 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18726 UNSPECV_FXRSTOR64)]
18727 "TARGET_64BIT && TARGET_FXSR"
18729 [(set_attr "type" "other")
18730 (set_attr "memory" "load")
18731 (set (attr "length")
18732 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18734 (define_int_iterator ANY_XSAVE
18736 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18737 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18738 (UNSPECV_XSAVES "TARGET_XSAVES")])
18740 (define_int_iterator ANY_XSAVE64
18742 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18743 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18744 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18746 (define_int_attr xsave
18747 [(UNSPECV_XSAVE "xsave")
18748 (UNSPECV_XSAVE64 "xsave64")
18749 (UNSPECV_XSAVEOPT "xsaveopt")
18750 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18751 (UNSPECV_XSAVEC "xsavec")
18752 (UNSPECV_XSAVEC64 "xsavec64")
18753 (UNSPECV_XSAVES "xsaves")
18754 (UNSPECV_XSAVES64 "xsaves64")])
18756 (define_int_iterator ANY_XRSTOR
18758 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18760 (define_int_iterator ANY_XRSTOR64
18762 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18764 (define_int_attr xrstor
18765 [(UNSPECV_XRSTOR "xrstor")
18766 (UNSPECV_XRSTOR64 "xrstor")
18767 (UNSPECV_XRSTORS "xrstors")
18768 (UNSPECV_XRSTORS64 "xrstors")])
18770 (define_insn "<xsave>"
18771 [(set (match_operand:BLK 0 "memory_operand" "=m")
18772 (unspec_volatile:BLK
18773 [(match_operand:DI 1 "register_operand" "A")]
18775 "!TARGET_64BIT && TARGET_XSAVE"
18777 [(set_attr "type" "other")
18778 (set_attr "memory" "store")
18779 (set (attr "length")
18780 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18782 (define_insn "<xsave>_rex64"
18783 [(set (match_operand:BLK 0 "memory_operand" "=m")
18784 (unspec_volatile:BLK
18785 [(match_operand:SI 1 "register_operand" "a")
18786 (match_operand:SI 2 "register_operand" "d")]
18788 "TARGET_64BIT && TARGET_XSAVE"
18790 [(set_attr "type" "other")
18791 (set_attr "memory" "store")
18792 (set (attr "length")
18793 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18795 (define_insn "<xsave>"
18796 [(set (match_operand:BLK 0 "memory_operand" "=m")
18797 (unspec_volatile:BLK
18798 [(match_operand:SI 1 "register_operand" "a")
18799 (match_operand:SI 2 "register_operand" "d")]
18801 "TARGET_64BIT && TARGET_XSAVE"
18803 [(set_attr "type" "other")
18804 (set_attr "memory" "store")
18805 (set (attr "length")
18806 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18808 (define_insn "<xrstor>"
18809 [(unspec_volatile:BLK
18810 [(match_operand:BLK 0 "memory_operand" "m")
18811 (match_operand:DI 1 "register_operand" "A")]
18813 "!TARGET_64BIT && TARGET_XSAVE"
18815 [(set_attr "type" "other")
18816 (set_attr "memory" "load")
18817 (set (attr "length")
18818 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18820 (define_insn "<xrstor>_rex64"
18821 [(unspec_volatile:BLK
18822 [(match_operand:BLK 0 "memory_operand" "m")
18823 (match_operand:SI 1 "register_operand" "a")
18824 (match_operand:SI 2 "register_operand" "d")]
18826 "TARGET_64BIT && TARGET_XSAVE"
18828 [(set_attr "type" "other")
18829 (set_attr "memory" "load")
18830 (set (attr "length")
18831 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18833 (define_insn "<xrstor>64"
18834 [(unspec_volatile:BLK
18835 [(match_operand:BLK 0 "memory_operand" "m")
18836 (match_operand:SI 1 "register_operand" "a")
18837 (match_operand:SI 2 "register_operand" "d")]
18839 "TARGET_64BIT && TARGET_XSAVE"
18841 [(set_attr "type" "other")
18842 (set_attr "memory" "load")
18843 (set (attr "length")
18844 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18848 ;; Floating-point instructions for atomic compound assignments
18850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18852 ; Clobber all floating-point registers on environment save and restore
18853 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18854 (define_insn "fnstenv"
18855 [(set (match_operand:BLK 0 "memory_operand" "=m")
18856 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18857 (clobber (reg:HI FPCR_REG))
18858 (clobber (reg:XF ST0_REG))
18859 (clobber (reg:XF ST1_REG))
18860 (clobber (reg:XF ST2_REG))
18861 (clobber (reg:XF ST3_REG))
18862 (clobber (reg:XF ST4_REG))
18863 (clobber (reg:XF ST5_REG))
18864 (clobber (reg:XF ST6_REG))
18865 (clobber (reg:XF ST7_REG))]
18868 [(set_attr "type" "other")
18869 (set_attr "memory" "store")
18870 (set (attr "length")
18871 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18873 (define_insn "fldenv"
18874 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18876 (clobber (reg:CCFP FPSR_REG))
18877 (clobber (reg:HI FPCR_REG))
18878 (clobber (reg:XF ST0_REG))
18879 (clobber (reg:XF ST1_REG))
18880 (clobber (reg:XF ST2_REG))
18881 (clobber (reg:XF ST3_REG))
18882 (clobber (reg:XF ST4_REG))
18883 (clobber (reg:XF ST5_REG))
18884 (clobber (reg:XF ST6_REG))
18885 (clobber (reg:XF ST7_REG))]
18888 [(set_attr "type" "other")
18889 (set_attr "memory" "load")
18890 (set (attr "length")
18891 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18893 (define_insn "fnstsw"
18894 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18895 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18898 [(set_attr "type" "other,other")
18899 (set_attr "memory" "none,store")
18900 (set (attr "length")
18901 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18903 (define_insn "fnclex"
18904 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18907 [(set_attr "type" "other")
18908 (set_attr "memory" "none")
18909 (set_attr "length" "2")])
18911 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18913 ;; LWP instructions
18915 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18917 (define_expand "lwp_llwpcb"
18918 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18919 UNSPECV_LLWP_INTRINSIC)]
18922 (define_insn "*lwp_llwpcb<mode>1"
18923 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18924 UNSPECV_LLWP_INTRINSIC)]
18927 [(set_attr "type" "lwp")
18928 (set_attr "mode" "<MODE>")
18929 (set_attr "length" "5")])
18931 (define_expand "lwp_slwpcb"
18932 [(set (match_operand 0 "register_operand" "=r")
18933 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18938 insn = (Pmode == DImode
18940 : gen_lwp_slwpcbsi);
18942 emit_insn (insn (operands[0]));
18946 (define_insn "lwp_slwpcb<mode>"
18947 [(set (match_operand:P 0 "register_operand" "=r")
18948 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18951 [(set_attr "type" "lwp")
18952 (set_attr "mode" "<MODE>")
18953 (set_attr "length" "5")])
18955 (define_expand "lwp_lwpval<mode>3"
18956 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18957 (match_operand:SI 2 "nonimmediate_operand" "rm")
18958 (match_operand:SI 3 "const_int_operand" "i")]
18959 UNSPECV_LWPVAL_INTRINSIC)]
18961 ;; Avoid unused variable warning.
18962 "(void) operands[0];")
18964 (define_insn "*lwp_lwpval<mode>3_1"
18965 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18966 (match_operand:SI 1 "nonimmediate_operand" "rm")
18967 (match_operand:SI 2 "const_int_operand" "i")]
18968 UNSPECV_LWPVAL_INTRINSIC)]
18970 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18971 [(set_attr "type" "lwp")
18972 (set_attr "mode" "<MODE>")
18973 (set (attr "length")
18974 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18976 (define_expand "lwp_lwpins<mode>3"
18977 [(set (reg:CCC FLAGS_REG)
18978 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18979 (match_operand:SI 2 "nonimmediate_operand" "rm")
18980 (match_operand:SI 3 "const_int_operand" "i")]
18981 UNSPECV_LWPINS_INTRINSIC))
18982 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18983 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18986 (define_insn "*lwp_lwpins<mode>3_1"
18987 [(set (reg:CCC FLAGS_REG)
18988 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18989 (match_operand:SI 1 "nonimmediate_operand" "rm")
18990 (match_operand:SI 2 "const_int_operand" "i")]
18991 UNSPECV_LWPINS_INTRINSIC))]
18993 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18994 [(set_attr "type" "lwp")
18995 (set_attr "mode" "<MODE>")
18996 (set (attr "length")
18997 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18999 (define_int_iterator RDFSGSBASE
19003 (define_int_iterator WRFSGSBASE
19007 (define_int_attr fsgs
19008 [(UNSPECV_RDFSBASE "fs")
19009 (UNSPECV_RDGSBASE "gs")
19010 (UNSPECV_WRFSBASE "fs")
19011 (UNSPECV_WRGSBASE "gs")])
19013 (define_insn "rd<fsgs>base<mode>"
19014 [(set (match_operand:SWI48 0 "register_operand" "=r")
19015 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19016 "TARGET_64BIT && TARGET_FSGSBASE"
19018 [(set_attr "type" "other")
19019 (set_attr "prefix_extra" "2")])
19021 (define_insn "wr<fsgs>base<mode>"
19022 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19024 "TARGET_64BIT && TARGET_FSGSBASE"
19026 [(set_attr "type" "other")
19027 (set_attr "prefix_extra" "2")])
19029 (define_insn "rdrand<mode>_1"
19030 [(set (match_operand:SWI248 0 "register_operand" "=r")
19031 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19032 (set (reg:CCC FLAGS_REG)
19033 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19036 [(set_attr "type" "other")
19037 (set_attr "prefix_extra" "1")])
19039 (define_insn "rdseed<mode>_1"
19040 [(set (match_operand:SWI248 0 "register_operand" "=r")
19041 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19042 (set (reg:CCC FLAGS_REG)
19043 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19046 [(set_attr "type" "other")
19047 (set_attr "prefix_extra" "1")])
19049 (define_expand "pause"
19050 [(set (match_dup 0)
19051 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19054 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19055 MEM_VOLATILE_P (operands[0]) = 1;
19058 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19059 ;; They have the same encoding.
19060 (define_insn "*pause"
19061 [(set (match_operand:BLK 0)
19062 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19065 [(set_attr "length" "2")
19066 (set_attr "memory" "unknown")])
19068 (define_expand "xbegin"
19069 [(set (match_operand:SI 0 "register_operand")
19070 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19073 rtx_code_label *label = gen_label_rtx ();
19075 /* xbegin is emitted as jump_insn, so reload won't be able
19076 to reload its operand. Force the value into AX hard register. */
19077 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19078 emit_move_insn (ax_reg, constm1_rtx);
19080 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19082 emit_label (label);
19083 LABEL_NUSES (label) = 1;
19085 emit_move_insn (operands[0], ax_reg);
19090 (define_insn "xbegin_1"
19092 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19094 (label_ref (match_operand 1))
19096 (set (match_operand:SI 0 "register_operand" "+a")
19097 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19100 [(set_attr "type" "other")
19101 (set_attr "length" "6")])
19103 (define_insn "xend"
19104 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19107 [(set_attr "type" "other")
19108 (set_attr "length" "3")])
19110 (define_insn "xabort"
19111 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19115 [(set_attr "type" "other")
19116 (set_attr "length" "3")])
19118 (define_expand "xtest"
19119 [(set (match_operand:QI 0 "register_operand")
19120 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19123 emit_insn (gen_xtest_1 ());
19125 ix86_expand_setcc (operands[0], NE,
19126 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19130 (define_insn "xtest_1"
19131 [(set (reg:CCZ FLAGS_REG)
19132 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19135 [(set_attr "type" "other")
19136 (set_attr "length" "3")])
19138 (define_insn "pcommit"
19139 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
19142 [(set_attr "type" "other")
19143 (set_attr "length" "4")])
19145 (define_insn "clwb"
19146 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19150 [(set_attr "type" "sse")
19151 (set_attr "atom_sse_attr" "fence")
19152 (set_attr "memory" "unknown")])
19154 (define_insn "clflushopt"
19155 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19156 UNSPECV_CLFLUSHOPT)]
19157 "TARGET_CLFLUSHOPT"
19159 [(set_attr "type" "sse")
19160 (set_attr "atom_sse_attr" "fence")
19161 (set_attr "memory" "unknown")])
19163 ;; MONITORX and MWAITX
19164 (define_insn "mwaitx"
19165 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19166 (match_operand:SI 1 "register_operand" "a")
19167 (match_operand:SI 2 "register_operand" "b")]
19170 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19171 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19172 ;; we only need to set up 32bit registers.
19174 [(set_attr "length" "3")])
19176 (define_insn "monitorx_<mode>"
19177 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19178 (match_operand:SI 1 "register_operand" "c")
19179 (match_operand:SI 2 "register_operand" "d")]
19182 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19183 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19184 ;; zero extended to 64bit, we only need to set up 32bit registers.
19186 [(set (attr "length")
19187 (symbol_ref ("(Pmode != word_mode) + 3")))])
19189 ;; MPX instructions
19191 (define_expand "<mode>_mk"
19192 [(set (match_operand:BND 0 "register_operand")
19196 [(match_operand:<bnd_ptr> 1 "register_operand")
19197 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19201 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19203 UNSPEC_BNDMK_ADDR);
19206 (define_insn "*<mode>_mk"
19207 [(set (match_operand:BND 0 "register_operand" "=w")
19209 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19211 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19212 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19213 UNSPEC_BNDMK_ADDR)])]
19216 "bndmk\t{%3, %0|%0, %3}"
19217 [(set_attr "type" "mpxmk")])
19219 (define_expand "mov<mode>"
19220 [(set (match_operand:BND 0 "general_operand")
19221 (match_operand:BND 1 "general_operand"))]
19223 "ix86_expand_move (<MODE>mode, operands); DONE;")
19225 (define_insn "*mov<mode>_internal_mpx"
19226 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19227 (match_operand:BND 1 "general_operand" "wm,w"))]
19229 "bndmov\t{%1, %0|%0, %1}"
19230 [(set_attr "type" "mpxmov")])
19232 (define_expand "<mode>_<bndcheck>"
19235 [(match_operand:BND 0 "register_operand")
19236 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19238 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19241 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19242 MEM_VOLATILE_P (operands[2]) = 1;
19245 (define_insn "*<mode>_<bndcheck>"
19247 [(match_operand:BND 0 "register_operand" "w")
19248 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19249 (set (match_operand:BLK 2 "bnd_mem_operator")
19250 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19252 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19253 [(set_attr "type" "mpxchk")])
19255 (define_expand "<mode>_ldx"
19257 [(set (match_operand:BND 0 "register_operand")
19261 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19262 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19264 (use (mem:BLK (match_dup 1)))])]
19267 /* Avoid registers which cannot be used as index. */
19268 if (!index_register_operand (operands[2], Pmode))
19269 operands[2] = copy_addr_to_reg (operands[2]);
19271 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19273 UNSPEC_BNDLDX_ADDR);
19276 (define_insn "*<mode>_ldx"
19277 [(set (match_operand:BND 0 "register_operand" "=w")
19279 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19281 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19282 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19283 UNSPEC_BNDLDX_ADDR)])]
19285 (use (mem:BLK (match_dup 1)))]
19287 "bndldx\t{%3, %0|%0, %3}"
19288 [(set_attr "type" "mpxld")])
19290 (define_expand "<mode>_stx"
19295 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19296 (match_operand:<bnd_ptr> 1 "register_operand")]))
19297 (match_operand:BND 2 "register_operand")]
19300 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19303 /* Avoid registers which cannot be used as index. */
19304 if (!index_register_operand (operands[1], Pmode))
19305 operands[1] = copy_addr_to_reg (operands[1]);
19307 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19309 UNSPEC_BNDLDX_ADDR);
19310 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19311 MEM_VOLATILE_P (operands[4]) = 1;
19314 (define_insn "*<mode>_stx"
19316 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19318 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19319 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19320 UNSPEC_BNDLDX_ADDR)])
19321 (match_operand:BND 2 "register_operand" "w")]
19323 (set (match_operand:BLK 4 "bnd_mem_operator")
19324 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19326 "bndstx\t{%2, %3|%3, %2}"
19327 [(set_attr "type" "mpxst")])
19329 (define_insn "move_size_reloc_<mode>"
19330 [(set (match_operand:SWI48 0 "register_operand" "=r")
19332 [(match_operand:SWI48 1 "symbol_operand")]
19336 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19337 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19339 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19341 [(set_attr "type" "imov")
19342 (set_attr "mode" "<MODE>")])
19346 (include "sync.md")