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.
394 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
397 ;; In C guard expressions, put expressions which may be compile-time
398 ;; constants first. This allows for better optimization. For
399 ;; example, write "TARGET_64BIT && reload_completed", not
400 ;; "reload_completed && TARGET_64BIT".
404 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
405 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
407 (const (symbol_ref "ix86_schedule")))
409 ;; A basic instruction type. Refinements due to arguments to be
410 ;; provided in other attributes.
413 alu,alu1,negnot,imov,imovx,lea,
414 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
415 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
416 push,pop,call,callv,leave,
418 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
419 fxch,fistp,fisttp,frndint,
420 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
421 ssemul,sseimul,ssediv,sselog,sselog1,
422 sseishft,sseishft1,ssecmp,ssecomi,
423 ssecvt,ssecvt1,sseicvt,sseins,
424 sseshuf,sseshuf1,ssemuladd,sse4arg,
426 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
427 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
428 (const_string "other"))
430 ;; Main data type used by the insn
432 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
434 (const_string "unknown"))
436 ;; The CPU unit operations uses.
437 (define_attr "unit" "integer,i387,sse,mmx,unknown"
438 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
439 fxch,fistp,fisttp,frndint")
440 (const_string "i387")
441 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
442 ssemul,sseimul,ssediv,sselog,sselog1,
443 sseishft,sseishft1,ssecmp,ssecomi,
444 ssecvt,ssecvt1,sseicvt,sseins,
445 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
447 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
449 (eq_attr "type" "other")
450 (const_string "unknown")]
451 (const_string "integer")))
453 ;; The minimum required alignment of vector mode memory operands of the SSE
454 ;; (non-VEX/EVEX) instruction in bits, if it is different from
455 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
456 ;; multiple alternatives, this should be conservative maximum of those minimum
457 ;; required alignments.
458 (define_attr "ssememalign" "" (const_int 0))
460 ;; The (bounding maximum) length of an instruction immediate.
461 (define_attr "length_immediate" ""
462 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
463 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
466 (eq_attr "unit" "i387,sse,mmx")
468 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
469 rotate,rotatex,rotate1,imul,icmp,push,pop")
470 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
471 (eq_attr "type" "imov,test")
472 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
473 (eq_attr "type" "call")
474 (if_then_else (match_operand 0 "constant_call_address_operand")
477 (eq_attr "type" "callv")
478 (if_then_else (match_operand 1 "constant_call_address_operand")
481 ;; We don't know the size before shorten_branches. Expect
482 ;; the instruction to fit for better scheduling.
483 (eq_attr "type" "ibr")
486 (symbol_ref "/* Update immediate_length and other attributes! */
487 gcc_unreachable (),1")))
489 ;; The (bounding maximum) length of an instruction address.
490 (define_attr "length_address" ""
491 (cond [(eq_attr "type" "str,other,multi,fxch")
493 (and (eq_attr "type" "call")
494 (match_operand 0 "constant_call_address_operand"))
496 (and (eq_attr "type" "callv")
497 (match_operand 1 "constant_call_address_operand"))
500 (symbol_ref "ix86_attr_length_address_default (insn)")))
502 ;; Set when length prefix is used.
503 (define_attr "prefix_data16" ""
504 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
506 (eq_attr "mode" "HI")
508 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
513 ;; Set when string REP prefix is used.
514 (define_attr "prefix_rep" ""
515 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
517 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
519 (and (eq_attr "type" "ibr,call,callv")
520 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
525 ;; Set when 0f opcode prefix is used.
526 (define_attr "prefix_0f" ""
528 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
529 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
530 (eq_attr "unit" "sse,mmx"))
534 ;; Set when REX opcode prefix is used.
535 (define_attr "prefix_rex" ""
536 (cond [(not (match_test "TARGET_64BIT"))
538 (and (eq_attr "mode" "DI")
539 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
540 (eq_attr "unit" "!mmx")))
542 (and (eq_attr "mode" "QI")
543 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
545 (match_test "x86_extended_reg_mentioned_p (insn)")
547 (and (eq_attr "type" "imovx")
548 (match_operand:QI 1 "ext_QIreg_operand"))
553 ;; There are also additional prefixes in 3DNOW, SSSE3.
554 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
555 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
556 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
557 (define_attr "prefix_extra" ""
558 (cond [(eq_attr "type" "ssemuladd,sse4arg")
560 (eq_attr "type" "sseiadd1,ssecvt1")
565 ;; Prefix used: original, VEX or maybe VEX.
566 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
567 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
569 (eq_attr "mode" "XI,V16SF,V8DF")
570 (const_string "evex")
572 (const_string "orig")))
574 ;; VEX W bit is used.
575 (define_attr "prefix_vex_w" "" (const_int 0))
577 ;; The length of VEX prefix
578 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
579 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
580 ;; still prefix_0f 1, with prefix_extra 1.
581 (define_attr "length_vex" ""
582 (if_then_else (and (eq_attr "prefix_0f" "1")
583 (eq_attr "prefix_extra" "0"))
584 (if_then_else (eq_attr "prefix_vex_w" "1")
585 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
586 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
587 (if_then_else (eq_attr "prefix_vex_w" "1")
588 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
589 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
591 ;; 4-bytes evex prefix and 1 byte opcode.
592 (define_attr "length_evex" "" (const_int 5))
594 ;; Set when modrm byte is used.
595 (define_attr "modrm" ""
596 (cond [(eq_attr "type" "str,leave")
598 (eq_attr "unit" "i387")
600 (and (eq_attr "type" "incdec")
601 (and (not (match_test "TARGET_64BIT"))
602 (ior (match_operand:SI 1 "register_operand")
603 (match_operand:HI 1 "register_operand"))))
605 (and (eq_attr "type" "push")
606 (not (match_operand 1 "memory_operand")))
608 (and (eq_attr "type" "pop")
609 (not (match_operand 0 "memory_operand")))
611 (and (eq_attr "type" "imov")
612 (and (not (eq_attr "mode" "DI"))
613 (ior (and (match_operand 0 "register_operand")
614 (match_operand 1 "immediate_operand"))
615 (ior (and (match_operand 0 "ax_reg_operand")
616 (match_operand 1 "memory_displacement_only_operand"))
617 (and (match_operand 0 "memory_displacement_only_operand")
618 (match_operand 1 "ax_reg_operand"))))))
620 (and (eq_attr "type" "call")
621 (match_operand 0 "constant_call_address_operand"))
623 (and (eq_attr "type" "callv")
624 (match_operand 1 "constant_call_address_operand"))
626 (and (eq_attr "type" "alu,alu1,icmp,test")
627 (match_operand 0 "ax_reg_operand"))
628 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
632 ;; When this attribute is set, calculate total insn length from
633 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
634 (define_attr "length_nobnd" "" (const_int 0))
636 ;; The (bounding maximum) length of an instruction in bytes.
637 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
638 ;; Later we may want to split them and compute proper length as for
640 (define_attr "length" ""
641 (cond [(eq_attr "length_nobnd" "!0")
642 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
643 (attr "length_nobnd"))
644 (eq_attr "type" "other,multi,fistp,frndint")
646 (eq_attr "type" "fcmp")
648 (eq_attr "unit" "i387")
650 (plus (attr "prefix_data16")
651 (attr "length_address")))
652 (ior (eq_attr "prefix" "evex")
653 (and (ior (eq_attr "prefix" "maybe_evex")
654 (eq_attr "prefix" "maybe_vex"))
655 (match_test "TARGET_AVX512F")))
656 (plus (attr "length_evex")
657 (plus (attr "length_immediate")
659 (attr "length_address"))))
660 (ior (eq_attr "prefix" "vex")
661 (and (ior (eq_attr "prefix" "maybe_vex")
662 (eq_attr "prefix" "maybe_evex"))
663 (match_test "TARGET_AVX")))
664 (plus (attr "length_vex")
665 (plus (attr "length_immediate")
667 (attr "length_address"))))]
668 (plus (plus (attr "modrm")
669 (plus (attr "prefix_0f")
670 (plus (attr "prefix_rex")
671 (plus (attr "prefix_extra")
673 (plus (attr "prefix_rep")
674 (plus (attr "prefix_data16")
675 (plus (attr "length_immediate")
676 (attr "length_address")))))))
678 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
679 ;; `store' if there is a simple memory reference therein, or `unknown'
680 ;; if the instruction is complex.
682 (define_attr "memory" "none,load,store,both,unknown"
683 (cond [(eq_attr "type" "other,multi,str,lwp")
684 (const_string "unknown")
685 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
686 (const_string "none")
687 (eq_attr "type" "fistp,leave")
688 (const_string "both")
689 (eq_attr "type" "frndint")
690 (const_string "load")
691 (eq_attr "type" "mpxld")
692 (const_string "load")
693 (eq_attr "type" "mpxst")
694 (const_string "store")
695 (eq_attr "type" "push")
696 (if_then_else (match_operand 1 "memory_operand")
697 (const_string "both")
698 (const_string "store"))
699 (eq_attr "type" "pop")
700 (if_then_else (match_operand 0 "memory_operand")
701 (const_string "both")
702 (const_string "load"))
703 (eq_attr "type" "setcc")
704 (if_then_else (match_operand 0 "memory_operand")
705 (const_string "store")
706 (const_string "none"))
707 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
708 (if_then_else (ior (match_operand 0 "memory_operand")
709 (match_operand 1 "memory_operand"))
710 (const_string "load")
711 (const_string "none"))
712 (eq_attr "type" "ibr")
713 (if_then_else (match_operand 0 "memory_operand")
714 (const_string "load")
715 (const_string "none"))
716 (eq_attr "type" "call")
717 (if_then_else (match_operand 0 "constant_call_address_operand")
718 (const_string "none")
719 (const_string "load"))
720 (eq_attr "type" "callv")
721 (if_then_else (match_operand 1 "constant_call_address_operand")
722 (const_string "none")
723 (const_string "load"))
724 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
725 (match_operand 1 "memory_operand"))
726 (const_string "both")
727 (and (match_operand 0 "memory_operand")
728 (match_operand 1 "memory_operand"))
729 (const_string "both")
730 (match_operand 0 "memory_operand")
731 (const_string "store")
732 (match_operand 1 "memory_operand")
733 (const_string "load")
735 "!alu1,negnot,ishift1,
736 imov,imovx,icmp,test,bitmanip,
738 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
739 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
740 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
741 (match_operand 2 "memory_operand"))
742 (const_string "load")
743 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
744 (match_operand 3 "memory_operand"))
745 (const_string "load")
747 (const_string "none")))
749 ;; Indicates if an instruction has both an immediate and a displacement.
751 (define_attr "imm_disp" "false,true,unknown"
752 (cond [(eq_attr "type" "other,multi")
753 (const_string "unknown")
754 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
755 (and (match_operand 0 "memory_displacement_operand")
756 (match_operand 1 "immediate_operand")))
757 (const_string "true")
758 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
759 (and (match_operand 0 "memory_displacement_operand")
760 (match_operand 2 "immediate_operand")))
761 (const_string "true")
763 (const_string "false")))
765 ;; Indicates if an FP operation has an integer source.
767 (define_attr "fp_int_src" "false,true"
768 (const_string "false"))
770 ;; Defines rounding mode of an FP operation.
772 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
773 (const_string "any"))
775 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
776 (define_attr "use_carry" "0,1" (const_string "0"))
778 ;; Define attribute to indicate unaligned ssemov insns
779 (define_attr "movu" "0,1" (const_string "0"))
781 ;; Used to control the "enabled" attribute on a per-instruction basis.
782 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
783 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
784 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
785 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
787 (const_string "base"))
789 (define_attr "enabled" ""
790 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
791 (eq_attr "isa" "x64_sse4")
792 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
793 (eq_attr "isa" "x64_sse4_noavx")
794 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
795 (eq_attr "isa" "x64_avx")
796 (symbol_ref "TARGET_64BIT && TARGET_AVX")
797 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
798 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
799 (eq_attr "isa" "sse2_noavx")
800 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
801 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
802 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
803 (eq_attr "isa" "sse4_noavx")
804 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
805 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
806 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
807 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
808 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
809 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
810 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
811 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
812 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
813 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
814 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
815 (eq_attr "isa" "fma_avx512f")
816 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
817 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
818 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
819 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
820 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
821 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
822 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
826 (define_attr "preferred_for_size" "" (const_int 1))
827 (define_attr "preferred_for_speed" "" (const_int 1))
829 ;; Describe a user's asm statement.
830 (define_asm_attributes
831 [(set_attr "length" "128")
832 (set_attr "type" "multi")])
834 (define_code_iterator plusminus [plus minus])
836 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
838 (define_code_iterator multdiv [mult div])
840 ;; Base name for define_insn
841 (define_code_attr plusminus_insn
842 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
843 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
845 ;; Base name for insn mnemonic.
846 (define_code_attr plusminus_mnemonic
847 [(plus "add") (ss_plus "adds") (us_plus "addus")
848 (minus "sub") (ss_minus "subs") (us_minus "subus")])
849 (define_code_attr multdiv_mnemonic
850 [(mult "mul") (div "div")])
852 ;; Mark commutative operators as such in constraints.
853 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
854 (minus "") (ss_minus "") (us_minus "")])
856 ;; Mapping of max and min
857 (define_code_iterator maxmin [smax smin umax umin])
859 ;; Mapping of signed max and min
860 (define_code_iterator smaxmin [smax smin])
862 ;; Mapping of unsigned max and min
863 (define_code_iterator umaxmin [umax umin])
865 ;; Base name for integer and FP insn mnemonic
866 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
867 (umax "maxu") (umin "minu")])
868 (define_code_attr maxmin_float [(smax "max") (smin "min")])
870 ;; Mapping of logic operators
871 (define_code_iterator any_logic [and ior xor])
872 (define_code_iterator any_or [ior xor])
873 (define_code_iterator fpint_logic [and xor])
875 ;; Base name for insn mnemonic.
876 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
878 ;; Mapping of logic-shift operators
879 (define_code_iterator any_lshift [ashift lshiftrt])
881 ;; Mapping of shift-right operators
882 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
884 ;; Mapping of all shift operators
885 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
887 ;; Base name for define_insn
888 (define_code_attr shift_insn
889 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
891 ;; Base name for insn mnemonic.
892 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
893 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
895 ;; Mapping of rotate operators
896 (define_code_iterator any_rotate [rotate rotatert])
898 ;; Base name for define_insn
899 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
901 ;; Base name for insn mnemonic.
902 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
904 ;; Mapping of abs neg operators
905 (define_code_iterator absneg [abs neg])
907 ;; Base name for x87 insn mnemonic.
908 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
910 ;; Used in signed and unsigned widening multiplications.
911 (define_code_iterator any_extend [sign_extend zero_extend])
913 ;; Prefix for insn menmonic.
914 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
916 ;; Prefix for define_insn
917 (define_code_attr u [(sign_extend "") (zero_extend "u")])
918 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
919 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
921 ;; Used in signed and unsigned truncations.
922 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
923 ;; Instruction suffix for truncations.
924 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
926 ;; Used in signed and unsigned fix.
927 (define_code_iterator any_fix [fix unsigned_fix])
928 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
930 ;; Used in signed and unsigned float.
931 (define_code_iterator any_float [float unsigned_float])
932 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
934 ;; All integer modes.
935 (define_mode_iterator SWI1248x [QI HI SI DI])
937 ;; All integer modes with AVX512BW.
938 (define_mode_iterator SWI1248_AVX512BW
939 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
941 ;; All integer modes without QImode.
942 (define_mode_iterator SWI248x [HI SI DI])
944 ;; All integer modes without QImode and HImode.
945 (define_mode_iterator SWI48x [SI DI])
947 ;; All integer modes without SImode and DImode.
948 (define_mode_iterator SWI12 [QI HI])
950 ;; All integer modes without DImode.
951 (define_mode_iterator SWI124 [QI HI SI])
953 ;; All integer modes without QImode and DImode.
954 (define_mode_iterator SWI24 [HI SI])
956 ;; Single word integer modes.
957 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
959 ;; Single word integer modes without QImode.
960 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
962 ;; Single word integer modes without QImode and HImode.
963 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
965 ;; All math-dependant single and double word integer modes.
966 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
967 (HI "TARGET_HIMODE_MATH")
968 SI DI (TI "TARGET_64BIT")])
970 ;; Math-dependant single word integer modes.
971 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
972 (HI "TARGET_HIMODE_MATH")
973 SI (DI "TARGET_64BIT")])
975 ;; Math-dependant integer modes without DImode.
976 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
977 (HI "TARGET_HIMODE_MATH")
980 ;; Math-dependant single word integer modes without QImode.
981 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
982 SI (DI "TARGET_64BIT")])
984 ;; Double word integer modes.
985 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
986 (TI "TARGET_64BIT")])
988 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
989 ;; compile time constant, it is faster to use <MODE_SIZE> than
990 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
991 ;; command line options just use GET_MODE_SIZE macro.
992 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
993 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
994 (V16QI "16") (V32QI "32") (V64QI "64")
995 (V8HI "16") (V16HI "32") (V32HI "64")
996 (V4SI "16") (V8SI "32") (V16SI "64")
997 (V2DI "16") (V4DI "32") (V8DI "64")
998 (V1TI "16") (V2TI "32") (V4TI "64")
999 (V2DF "16") (V4DF "32") (V8DF "64")
1000 (V4SF "16") (V8SF "32") (V16SF "64")])
1002 ;; Double word integer modes as mode attribute.
1003 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1004 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1006 ;; Half mode for double word integer modes.
1007 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1008 (DI "TARGET_64BIT")])
1011 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1012 (BND64 "TARGET_LP64")])
1014 ;; Pointer mode corresponding to bound mode.
1015 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1018 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1021 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1023 (UNSPEC_BNDCN "cn")])
1025 ;; Instruction suffix for integer modes.
1026 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1028 ;; Instruction suffix for masks.
1029 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1031 ;; Pointer size prefix for integer modes (Intel asm dialect)
1032 (define_mode_attr iptrsize [(QI "BYTE")
1037 ;; Register class for integer modes.
1038 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1040 ;; Immediate operand constraint for integer modes.
1041 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1043 ;; General operand constraint for word modes.
1044 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1046 ;; Immediate operand constraint for double integer modes.
1047 (define_mode_attr di [(SI "nF") (DI "e")])
1049 ;; Immediate operand constraint for shifts.
1050 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1052 ;; General operand predicate for integer modes.
1053 (define_mode_attr general_operand
1054 [(QI "general_operand")
1055 (HI "general_operand")
1056 (SI "x86_64_general_operand")
1057 (DI "x86_64_general_operand")
1058 (TI "x86_64_general_operand")])
1060 ;; General sign extend operand predicate for integer modes,
1061 ;; which disallows VOIDmode operands and thus it is suitable
1062 ;; for use inside sign_extend.
1063 (define_mode_attr general_sext_operand
1064 [(QI "sext_operand")
1066 (SI "x86_64_sext_operand")
1067 (DI "x86_64_sext_operand")])
1069 ;; General sign/zero extend operand predicate for integer modes.
1070 (define_mode_attr general_szext_operand
1071 [(QI "general_operand")
1072 (HI "general_operand")
1073 (SI "x86_64_szext_general_operand")
1074 (DI "x86_64_szext_general_operand")])
1076 ;; Immediate operand predicate for integer modes.
1077 (define_mode_attr immediate_operand
1078 [(QI "immediate_operand")
1079 (HI "immediate_operand")
1080 (SI "x86_64_immediate_operand")
1081 (DI "x86_64_immediate_operand")])
1083 ;; Nonmemory operand predicate for integer modes.
1084 (define_mode_attr nonmemory_operand
1085 [(QI "nonmemory_operand")
1086 (HI "nonmemory_operand")
1087 (SI "x86_64_nonmemory_operand")
1088 (DI "x86_64_nonmemory_operand")])
1090 ;; Operand predicate for shifts.
1091 (define_mode_attr shift_operand
1092 [(QI "nonimmediate_operand")
1093 (HI "nonimmediate_operand")
1094 (SI "nonimmediate_operand")
1095 (DI "shiftdi_operand")
1096 (TI "register_operand")])
1098 ;; Operand predicate for shift argument.
1099 (define_mode_attr shift_immediate_operand
1100 [(QI "const_1_to_31_operand")
1101 (HI "const_1_to_31_operand")
1102 (SI "const_1_to_31_operand")
1103 (DI "const_1_to_63_operand")])
1105 ;; Input operand predicate for arithmetic left shifts.
1106 (define_mode_attr ashl_input_operand
1107 [(QI "nonimmediate_operand")
1108 (HI "nonimmediate_operand")
1109 (SI "nonimmediate_operand")
1110 (DI "ashldi_input_operand")
1111 (TI "reg_or_pm1_operand")])
1113 ;; SSE and x87 SFmode and DFmode floating point modes
1114 (define_mode_iterator MODEF [SF DF])
1116 ;; All x87 floating point modes
1117 (define_mode_iterator X87MODEF [SF DF XF])
1119 ;; SSE instruction suffix for various modes
1120 (define_mode_attr ssemodesuffix
1121 [(SF "ss") (DF "sd")
1122 (V16SF "ps") (V8DF "pd")
1123 (V8SF "ps") (V4DF "pd")
1124 (V4SF "ps") (V2DF "pd")
1125 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1126 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1127 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1129 ;; SSE vector suffix for floating point modes
1130 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1132 ;; SSE vector mode corresponding to a scalar mode
1133 (define_mode_attr ssevecmode
1134 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1135 (define_mode_attr ssevecmodelower
1136 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1138 ;; Instruction suffix for REX 64bit operators.
1139 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1141 ;; This mode iterator allows :P to be used for patterns that operate on
1142 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1143 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1145 ;; This mode iterator allows :W to be used for patterns that operate on
1146 ;; word_mode sized quantities.
1147 (define_mode_iterator W
1148 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1150 ;; This mode iterator allows :PTR to be used for patterns that operate on
1151 ;; ptr_mode sized quantities.
1152 (define_mode_iterator PTR
1153 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1155 ;; Scheduling descriptions
1157 (include "pentium.md")
1160 (include "athlon.md")
1161 (include "bdver1.md")
1162 (include "bdver3.md")
1163 (include "btver2.md")
1164 (include "geode.md")
1167 (include "core2.md")
1170 ;; Operand and operator predicates and constraints
1172 (include "predicates.md")
1173 (include "constraints.md")
1176 ;; Compare and branch/compare and store instructions.
1178 (define_expand "cbranch<mode>4"
1179 [(set (reg:CC FLAGS_REG)
1180 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1181 (match_operand:SDWIM 2 "<general_operand>")))
1182 (set (pc) (if_then_else
1183 (match_operator 0 "ordered_comparison_operator"
1184 [(reg:CC FLAGS_REG) (const_int 0)])
1185 (label_ref (match_operand 3))
1189 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1190 operands[1] = force_reg (<MODE>mode, operands[1]);
1191 ix86_expand_branch (GET_CODE (operands[0]),
1192 operands[1], operands[2], operands[3]);
1196 (define_expand "cstore<mode>4"
1197 [(set (reg:CC FLAGS_REG)
1198 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1199 (match_operand:SWIM 3 "<general_operand>")))
1200 (set (match_operand:QI 0 "register_operand")
1201 (match_operator 1 "ordered_comparison_operator"
1202 [(reg:CC FLAGS_REG) (const_int 0)]))]
1205 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1206 operands[2] = force_reg (<MODE>mode, operands[2]);
1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208 operands[2], operands[3]);
1212 (define_expand "cmp<mode>_1"
1213 [(set (reg:CC FLAGS_REG)
1214 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1215 (match_operand:SWI48 1 "<general_operand>")))])
1217 (define_insn "*cmp<mode>_ccno_1"
1218 [(set (reg FLAGS_REG)
1219 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1220 (match_operand:SWI 1 "const0_operand")))]
1221 "ix86_match_ccmode (insn, CCNOmode)"
1223 test{<imodesuffix>}\t%0, %0
1224 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1225 [(set_attr "type" "test,icmp")
1226 (set_attr "length_immediate" "0,1")
1227 (set_attr "mode" "<MODE>")])
1229 (define_insn "*cmp<mode>_1"
1230 [(set (reg FLAGS_REG)
1231 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1232 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1233 "ix86_match_ccmode (insn, CCmode)"
1234 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1235 [(set_attr "type" "icmp")
1236 (set_attr "mode" "<MODE>")])
1238 (define_insn "*cmp<mode>_minus_1"
1239 [(set (reg FLAGS_REG)
1241 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1242 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1244 "ix86_match_ccmode (insn, CCGOCmode)"
1245 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1246 [(set_attr "type" "icmp")
1247 (set_attr "mode" "<MODE>")])
1249 (define_insn "*cmpqi_ext_1"
1250 [(set (reg FLAGS_REG)
1252 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1255 (match_operand 1 "ext_register_operand" "Q,Q")
1257 (const_int 8)) 0)))]
1258 "ix86_match_ccmode (insn, CCmode)"
1259 "cmp{b}\t{%h1, %0|%0, %h1}"
1260 [(set_attr "isa" "*,nox64")
1261 (set_attr "type" "icmp")
1262 (set_attr "mode" "QI")])
1264 (define_insn "*cmpqi_ext_2"
1265 [(set (reg FLAGS_REG)
1269 (match_operand 0 "ext_register_operand" "Q")
1272 (match_operand:QI 1 "const0_operand")))]
1273 "ix86_match_ccmode (insn, CCNOmode)"
1275 [(set_attr "type" "test")
1276 (set_attr "length_immediate" "0")
1277 (set_attr "mode" "QI")])
1279 (define_expand "cmpqi_ext_3"
1280 [(set (reg:CC FLAGS_REG)
1284 (match_operand 0 "ext_register_operand")
1287 (match_operand:QI 1 "const_int_operand")))])
1289 (define_insn "*cmpqi_ext_3"
1290 [(set (reg FLAGS_REG)
1294 (match_operand 0 "ext_register_operand" "Q,Q")
1297 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1298 "ix86_match_ccmode (insn, CCmode)"
1299 "cmp{b}\t{%1, %h0|%h0, %1}"
1300 [(set_attr "isa" "*,nox64")
1301 (set_attr "type" "icmp")
1302 (set_attr "modrm" "1")
1303 (set_attr "mode" "QI")])
1305 (define_insn "*cmpqi_ext_4"
1306 [(set (reg FLAGS_REG)
1310 (match_operand 0 "ext_register_operand" "Q")
1315 (match_operand 1 "ext_register_operand" "Q")
1317 (const_int 8)) 0)))]
1318 "ix86_match_ccmode (insn, CCmode)"
1319 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1320 [(set_attr "type" "icmp")
1321 (set_attr "mode" "QI")])
1323 ;; These implement float point compares.
1324 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1325 ;; which would allow mix and match FP modes on the compares. Which is what
1326 ;; the old patterns did, but with many more of them.
1328 (define_expand "cbranchxf4"
1329 [(set (reg:CC FLAGS_REG)
1330 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1331 (match_operand:XF 2 "nonmemory_operand")))
1332 (set (pc) (if_then_else
1333 (match_operator 0 "ix86_fp_comparison_operator"
1336 (label_ref (match_operand 3))
1340 ix86_expand_branch (GET_CODE (operands[0]),
1341 operands[1], operands[2], operands[3]);
1345 (define_expand "cstorexf4"
1346 [(set (reg:CC FLAGS_REG)
1347 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1348 (match_operand:XF 3 "nonmemory_operand")))
1349 (set (match_operand:QI 0 "register_operand")
1350 (match_operator 1 "ix86_fp_comparison_operator"
1355 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356 operands[2], operands[3]);
1360 (define_expand "cbranch<mode>4"
1361 [(set (reg:CC FLAGS_REG)
1362 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1363 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1364 (set (pc) (if_then_else
1365 (match_operator 0 "ix86_fp_comparison_operator"
1368 (label_ref (match_operand 3))
1370 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1372 ix86_expand_branch (GET_CODE (operands[0]),
1373 operands[1], operands[2], operands[3]);
1377 (define_expand "cstore<mode>4"
1378 [(set (reg:CC FLAGS_REG)
1379 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1380 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1381 (set (match_operand:QI 0 "register_operand")
1382 (match_operator 1 "ix86_fp_comparison_operator"
1385 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1387 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1388 operands[2], operands[3]);
1392 (define_expand "cbranchcc4"
1393 [(set (pc) (if_then_else
1394 (match_operator 0 "comparison_operator"
1395 [(match_operand 1 "flags_reg_operand")
1396 (match_operand 2 "const0_operand")])
1397 (label_ref (match_operand 3))
1401 ix86_expand_branch (GET_CODE (operands[0]),
1402 operands[1], operands[2], operands[3]);
1406 (define_expand "cstorecc4"
1407 [(set (match_operand:QI 0 "register_operand")
1408 (match_operator 1 "comparison_operator"
1409 [(match_operand 2 "flags_reg_operand")
1410 (match_operand 3 "const0_operand")]))]
1413 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1414 operands[2], operands[3]);
1419 ;; FP compares, step 1:
1420 ;; Set the FP condition codes.
1422 ;; CCFPmode compare with exceptions
1423 ;; CCFPUmode compare with no exceptions
1425 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1426 ;; used to manage the reg stack popping would not be preserved.
1428 (define_insn "*cmp<mode>_0_i387"
1429 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (match_operand:X87MODEF 1 "register_operand" "f")
1433 (match_operand:X87MODEF 2 "const0_operand"))]
1436 "* return output_fp_compare (insn, operands, false, false);"
1437 [(set_attr "type" "multi")
1438 (set_attr "unit" "i387")
1439 (set_attr "mode" "<MODE>")])
1441 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1442 [(set (reg:CCFP FLAGS_REG)
1444 (match_operand:X87MODEF 1 "register_operand" "f")
1445 (match_operand:X87MODEF 2 "const0_operand")))
1446 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1447 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1449 "&& reload_completed"
1452 [(compare:CCFP (match_dup 1)(match_dup 2))]
1454 (set (reg:CC FLAGS_REG)
1455 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1457 [(set_attr "type" "multi")
1458 (set_attr "unit" "i387")
1459 (set_attr "mode" "<MODE>")])
1461 (define_insn "*cmpxf_i387"
1462 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (match_operand:XF 1 "register_operand" "f")
1466 (match_operand:XF 2 "register_operand" "f"))]
1469 "* return output_fp_compare (insn, operands, false, false);"
1470 [(set_attr "type" "multi")
1471 (set_attr "unit" "i387")
1472 (set_attr "mode" "XF")])
1474 (define_insn_and_split "*cmpxf_cc_i387"
1475 [(set (reg:CCFP FLAGS_REG)
1477 (match_operand:XF 1 "register_operand" "f")
1478 (match_operand:XF 2 "register_operand" "f")))
1479 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1480 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1482 "&& reload_completed"
1485 [(compare:CCFP (match_dup 1)(match_dup 2))]
1487 (set (reg:CC FLAGS_REG)
1488 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1490 [(set_attr "type" "multi")
1491 (set_attr "unit" "i387")
1492 (set_attr "mode" "XF")])
1494 (define_insn "*cmp<mode>_i387"
1495 [(set (match_operand:HI 0 "register_operand" "=a")
1498 (match_operand:MODEF 1 "register_operand" "f")
1499 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1502 "* return output_fp_compare (insn, operands, false, false);"
1503 [(set_attr "type" "multi")
1504 (set_attr "unit" "i387")
1505 (set_attr "mode" "<MODE>")])
1507 (define_insn_and_split "*cmp<mode>_cc_i387"
1508 [(set (reg:CCFP FLAGS_REG)
1510 (match_operand:MODEF 1 "register_operand" "f")
1511 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1512 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1513 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1515 "&& reload_completed"
1518 [(compare:CCFP (match_dup 1)(match_dup 2))]
1520 (set (reg:CC FLAGS_REG)
1521 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1523 [(set_attr "type" "multi")
1524 (set_attr "unit" "i387")
1525 (set_attr "mode" "<MODE>")])
1527 (define_insn "*cmpu<mode>_i387"
1528 [(set (match_operand:HI 0 "register_operand" "=a")
1531 (match_operand:X87MODEF 1 "register_operand" "f")
1532 (match_operand:X87MODEF 2 "register_operand" "f"))]
1535 "* return output_fp_compare (insn, operands, false, true);"
1536 [(set_attr "type" "multi")
1537 (set_attr "unit" "i387")
1538 (set_attr "mode" "<MODE>")])
1540 (define_insn_and_split "*cmpu<mode>_cc_i387"
1541 [(set (reg:CCFPU FLAGS_REG)
1543 (match_operand:X87MODEF 1 "register_operand" "f")
1544 (match_operand:X87MODEF 2 "register_operand" "f")))
1545 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1546 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1548 "&& reload_completed"
1551 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1553 (set (reg:CC FLAGS_REG)
1554 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1556 [(set_attr "type" "multi")
1557 (set_attr "unit" "i387")
1558 (set_attr "mode" "<MODE>")])
1560 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1561 [(set (match_operand:HI 0 "register_operand" "=a")
1564 (match_operand:X87MODEF 1 "register_operand" "f")
1565 (match_operator:X87MODEF 3 "float_operator"
1566 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1569 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1570 || optimize_function_for_size_p (cfun))"
1571 "* return output_fp_compare (insn, operands, false, false);"
1572 [(set_attr "type" "multi")
1573 (set_attr "unit" "i387")
1574 (set_attr "fp_int_src" "true")
1575 (set_attr "mode" "<SWI24:MODE>")])
1577 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1578 [(set (reg:CCFP FLAGS_REG)
1580 (match_operand:X87MODEF 1 "register_operand" "f")
1581 (match_operator:X87MODEF 3 "float_operator"
1582 [(match_operand:SWI24 2 "memory_operand" "m")])))
1583 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1584 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1585 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1586 || optimize_function_for_size_p (cfun))"
1588 "&& reload_completed"
1593 (match_op_dup 3 [(match_dup 2)]))]
1595 (set (reg:CC FLAGS_REG)
1596 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1598 [(set_attr "type" "multi")
1599 (set_attr "unit" "i387")
1600 (set_attr "fp_int_src" "true")
1601 (set_attr "mode" "<SWI24:MODE>")])
1603 ;; FP compares, step 2
1604 ;; Move the fpsw to ax.
1606 (define_insn "x86_fnstsw_1"
1607 [(set (match_operand:HI 0 "register_operand" "=a")
1608 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1611 [(set_attr "length" "2")
1612 (set_attr "mode" "SI")
1613 (set_attr "unit" "i387")])
1615 ;; FP compares, step 3
1616 ;; Get ax into flags, general case.
1618 (define_insn "x86_sahf_1"
1619 [(set (reg:CC FLAGS_REG)
1620 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1624 #ifndef HAVE_AS_IX86_SAHF
1626 return ASM_BYTE "0x9e";
1631 [(set_attr "length" "1")
1632 (set_attr "athlon_decode" "vector")
1633 (set_attr "amdfam10_decode" "direct")
1634 (set_attr "bdver1_decode" "direct")
1635 (set_attr "mode" "SI")])
1637 ;; Pentium Pro can do steps 1 through 3 in one go.
1638 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1639 ;; (these i387 instructions set flags directly)
1641 (define_mode_iterator FPCMP [CCFP CCFPU])
1642 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1644 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1645 [(set (reg:FPCMP FLAGS_REG)
1647 (match_operand:MODEF 0 "register_operand" "f,x")
1648 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1649 "TARGET_MIX_SSE_I387
1650 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1651 "* return output_fp_compare (insn, operands, true,
1652 <FPCMP:MODE>mode == CCFPUmode);"
1653 [(set_attr "type" "fcmp,ssecomi")
1654 (set_attr "prefix" "orig,maybe_vex")
1655 (set_attr "mode" "<MODEF:MODE>")
1656 (set (attr "prefix_rep")
1657 (if_then_else (eq_attr "type" "ssecomi")
1659 (const_string "*")))
1660 (set (attr "prefix_data16")
1661 (cond [(eq_attr "type" "fcmp")
1663 (eq_attr "mode" "DF")
1666 (const_string "0")))
1667 (set_attr "athlon_decode" "vector")
1668 (set_attr "amdfam10_decode" "direct")
1669 (set_attr "bdver1_decode" "double")])
1671 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1672 [(set (reg:FPCMP FLAGS_REG)
1674 (match_operand:MODEF 0 "register_operand" "x")
1675 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1677 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1678 "* return output_fp_compare (insn, operands, true,
1679 <FPCMP:MODE>mode == CCFPUmode);"
1680 [(set_attr "type" "ssecomi")
1681 (set_attr "prefix" "maybe_vex")
1682 (set_attr "mode" "<MODEF:MODE>")
1683 (set_attr "prefix_rep" "0")
1684 (set (attr "prefix_data16")
1685 (if_then_else (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")])
1692 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1693 [(set (reg:FPCMP FLAGS_REG)
1695 (match_operand:X87MODEF 0 "register_operand" "f")
1696 (match_operand:X87MODEF 1 "register_operand" "f")))]
1697 "TARGET_80387 && TARGET_CMOVE
1698 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1699 "* return output_fp_compare (insn, operands, true,
1700 <FPCMP:MODE>mode == CCFPUmode);"
1701 [(set_attr "type" "fcmp")
1702 (set_attr "mode" "<X87MODEF:MODE>")
1703 (set_attr "athlon_decode" "vector")
1704 (set_attr "amdfam10_decode" "direct")
1705 (set_attr "bdver1_decode" "double")])
1707 ;; Push/pop instructions.
1709 (define_insn "*push<mode>2"
1710 [(set (match_operand:DWI 0 "push_operand" "=<")
1711 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1714 [(set_attr "type" "multi")
1715 (set_attr "mode" "<MODE>")])
1718 [(set (match_operand:TI 0 "push_operand")
1719 (match_operand:TI 1 "general_operand"))]
1720 "TARGET_64BIT && reload_completed
1721 && !SSE_REG_P (operands[1])"
1723 "ix86_split_long_move (operands); DONE;")
1725 (define_insn "*pushdi2_rex64"
1726 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1727 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1732 [(set_attr "type" "push,multi")
1733 (set_attr "mode" "DI")])
1735 ;; Convert impossible pushes of immediate to existing instructions.
1736 ;; First try to get scratch register and go through it. In case this
1737 ;; fails, push sign extended lower part first and then overwrite
1738 ;; upper part by 32bit move.
1740 [(match_scratch:DI 2 "r")
1741 (set (match_operand:DI 0 "push_operand")
1742 (match_operand:DI 1 "immediate_operand"))]
1743 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1744 && !x86_64_immediate_operand (operands[1], DImode)"
1745 [(set (match_dup 2) (match_dup 1))
1746 (set (match_dup 0) (match_dup 2))])
1748 ;; We need to define this as both peepholer and splitter for case
1749 ;; peephole2 pass is not run.
1750 ;; "&& 1" is needed to keep it from matching the previous pattern.
1752 [(set (match_operand:DI 0 "push_operand")
1753 (match_operand:DI 1 "immediate_operand"))]
1754 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1755 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1756 [(set (match_dup 0) (match_dup 1))
1757 (set (match_dup 2) (match_dup 3))]
1759 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1761 operands[1] = gen_lowpart (DImode, operands[2]);
1762 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1767 [(set (match_operand:DI 0 "push_operand")
1768 (match_operand:DI 1 "immediate_operand"))]
1769 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1770 ? epilogue_completed : reload_completed)
1771 && !symbolic_operand (operands[1], DImode)
1772 && !x86_64_immediate_operand (operands[1], DImode)"
1773 [(set (match_dup 0) (match_dup 1))
1774 (set (match_dup 2) (match_dup 3))]
1776 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1778 operands[1] = gen_lowpart (DImode, operands[2]);
1779 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1784 [(set (match_operand:DI 0 "push_operand")
1785 (match_operand:DI 1 "general_operand"))]
1786 "!TARGET_64BIT && reload_completed
1787 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1789 "ix86_split_long_move (operands); DONE;")
1791 (define_insn "*pushsi2"
1792 [(set (match_operand:SI 0 "push_operand" "=<")
1793 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1796 [(set_attr "type" "push")
1797 (set_attr "mode" "SI")])
1799 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1800 ;; "push a byte/word". But actually we use pushl, which has the effect
1801 ;; of rounding the amount pushed up to a word.
1803 ;; For TARGET_64BIT we always round up to 8 bytes.
1804 (define_insn "*push<mode>2_rex64"
1805 [(set (match_operand:SWI124 0 "push_operand" "=X")
1806 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1809 [(set_attr "type" "push")
1810 (set_attr "mode" "DI")])
1812 (define_insn "*push<mode>2"
1813 [(set (match_operand:SWI12 0 "push_operand" "=X")
1814 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1817 [(set_attr "type" "push")
1818 (set_attr "mode" "SI")])
1820 (define_insn "*push<mode>2_prologue"
1821 [(set (match_operand:W 0 "push_operand" "=<")
1822 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1823 (clobber (mem:BLK (scratch)))]
1825 "push{<imodesuffix>}\t%1"
1826 [(set_attr "type" "push")
1827 (set_attr "mode" "<MODE>")])
1829 (define_insn "*pop<mode>1"
1830 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1831 (match_operand:W 1 "pop_operand" ">"))]
1833 "pop{<imodesuffix>}\t%0"
1834 [(set_attr "type" "pop")
1835 (set_attr "mode" "<MODE>")])
1837 (define_insn "*pop<mode>1_epilogue"
1838 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1839 (match_operand:W 1 "pop_operand" ">"))
1840 (clobber (mem:BLK (scratch)))]
1842 "pop{<imodesuffix>}\t%0"
1843 [(set_attr "type" "pop")
1844 (set_attr "mode" "<MODE>")])
1846 (define_insn "*pushfl<mode>2"
1847 [(set (match_operand:W 0 "push_operand" "=<")
1848 (match_operand:W 1 "flags_reg_operand"))]
1850 "pushf{<imodesuffix>}"
1851 [(set_attr "type" "push")
1852 (set_attr "mode" "<MODE>")])
1854 (define_insn "*popfl<mode>1"
1855 [(set (match_operand:W 0 "flags_reg_operand")
1856 (match_operand:W 1 "pop_operand" ">"))]
1858 "popf{<imodesuffix>}"
1859 [(set_attr "type" "pop")
1860 (set_attr "mode" "<MODE>")])
1863 ;; Move instructions.
1865 (define_expand "movxi"
1866 [(set (match_operand:XI 0 "nonimmediate_operand")
1867 (match_operand:XI 1 "general_operand"))]
1869 "ix86_expand_move (XImode, operands); DONE;")
1871 ;; Reload patterns to support multi-word load/store
1872 ;; with non-offsetable address.
1873 (define_expand "reload_noff_store"
1874 [(parallel [(match_operand 0 "memory_operand" "=m")
1875 (match_operand 1 "register_operand" "r")
1876 (match_operand:DI 2 "register_operand" "=&r")])]
1879 rtx mem = operands[0];
1880 rtx addr = XEXP (mem, 0);
1882 emit_move_insn (operands[2], addr);
1883 mem = replace_equiv_address_nv (mem, operands[2]);
1885 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1889 (define_expand "reload_noff_load"
1890 [(parallel [(match_operand 0 "register_operand" "=r")
1891 (match_operand 1 "memory_operand" "m")
1892 (match_operand:DI 2 "register_operand" "=r")])]
1895 rtx mem = operands[1];
1896 rtx addr = XEXP (mem, 0);
1898 emit_move_insn (operands[2], addr);
1899 mem = replace_equiv_address_nv (mem, operands[2]);
1901 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1905 (define_expand "movoi"
1906 [(set (match_operand:OI 0 "nonimmediate_operand")
1907 (match_operand:OI 1 "general_operand"))]
1909 "ix86_expand_move (OImode, operands); DONE;")
1911 (define_expand "movti"
1912 [(set (match_operand:TI 0 "nonimmediate_operand")
1913 (match_operand:TI 1 "nonimmediate_operand"))]
1914 "TARGET_64BIT || TARGET_SSE"
1917 ix86_expand_move (TImode, operands);
1919 ix86_expand_vector_move (TImode, operands);
1923 ;; This expands to what emit_move_complex would generate if we didn't
1924 ;; have a movti pattern. Having this avoids problems with reload on
1925 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1926 ;; to have around all the time.
1927 (define_expand "movcdi"
1928 [(set (match_operand:CDI 0 "nonimmediate_operand")
1929 (match_operand:CDI 1 "general_operand"))]
1932 if (push_operand (operands[0], CDImode))
1933 emit_move_complex_push (CDImode, operands[0], operands[1]);
1935 emit_move_complex_parts (operands[0], operands[1]);
1939 (define_expand "mov<mode>"
1940 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1941 (match_operand:SWI1248x 1 "general_operand"))]
1943 "ix86_expand_move (<MODE>mode, operands); DONE;")
1945 (define_insn "*mov<mode>_xor"
1946 [(set (match_operand:SWI48 0 "register_operand" "=r")
1947 (match_operand:SWI48 1 "const0_operand"))
1948 (clobber (reg:CC FLAGS_REG))]
1951 [(set_attr "type" "alu1")
1952 (set_attr "mode" "SI")
1953 (set_attr "length_immediate" "0")])
1955 (define_insn "*mov<mode>_or"
1956 [(set (match_operand:SWI48 0 "register_operand" "=r")
1957 (match_operand:SWI48 1 "const_int_operand"))
1958 (clobber (reg:CC FLAGS_REG))]
1960 && operands[1] == constm1_rtx"
1961 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "alu1")
1963 (set_attr "mode" "<MODE>")
1964 (set_attr "length_immediate" "1")])
1966 (define_insn "*movxi_internal_avx512f"
1967 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1968 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1969 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 switch (which_alternative)
1974 return standard_sse_constant_opcode (insn, operands[1]);
1977 if (misaligned_operand (operands[0], XImode)
1978 || misaligned_operand (operands[1], XImode))
1979 return "vmovdqu32\t{%1, %0|%0, %1}";
1981 return "vmovdqa32\t{%1, %0|%0, %1}";
1986 [(set_attr "type" "sselog1,ssemov,ssemov")
1987 (set_attr "prefix" "evex")
1988 (set_attr "mode" "XI")])
1990 (define_insn "*movoi_internal_avx"
1991 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1992 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1993 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1995 switch (get_attr_type (insn))
1998 return standard_sse_constant_opcode (insn, operands[1]);
2001 if (misaligned_operand (operands[0], OImode)
2002 || misaligned_operand (operands[1], OImode))
2004 if (get_attr_mode (insn) == MODE_V8SF)
2005 return "vmovups\t{%1, %0|%0, %1}";
2006 else if (get_attr_mode (insn) == MODE_XI)
2007 return "vmovdqu32\t{%1, %0|%0, %1}";
2009 return "vmovdqu\t{%1, %0|%0, %1}";
2013 if (get_attr_mode (insn) == MODE_V8SF)
2014 return "vmovaps\t{%1, %0|%0, %1}";
2015 else if (get_attr_mode (insn) == MODE_XI)
2016 return "vmovdqa32\t{%1, %0|%0, %1}";
2018 return "vmovdqa\t{%1, %0|%0, %1}";
2025 [(set_attr "type" "sselog1,ssemov,ssemov")
2026 (set_attr "prefix" "vex")
2028 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2029 (match_operand 1 "ext_sse_reg_operand"))
2031 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2032 (const_string "V8SF")
2033 (and (eq_attr "alternative" "2")
2034 (match_test "TARGET_SSE_TYPELESS_STORES"))
2035 (const_string "V8SF")
2037 (const_string "OI")))])
2039 (define_insn "*movti_internal"
2040 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2041 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2042 "(TARGET_64BIT || TARGET_SSE)
2043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2045 switch (get_attr_type (insn))
2051 return standard_sse_constant_opcode (insn, operands[1]);
2054 /* TDmode values are passed as TImode on the stack. Moving them
2055 to stack may result in unaligned memory access. */
2056 if (misaligned_operand (operands[0], TImode)
2057 || misaligned_operand (operands[1], TImode))
2059 if (get_attr_mode (insn) == MODE_V4SF)
2060 return "%vmovups\t{%1, %0|%0, %1}";
2061 else if (get_attr_mode (insn) == MODE_XI)
2062 return "vmovdqu32\t{%1, %0|%0, %1}";
2064 return "%vmovdqu\t{%1, %0|%0, %1}";
2068 if (get_attr_mode (insn) == MODE_V4SF)
2069 return "%vmovaps\t{%1, %0|%0, %1}";
2070 else if (get_attr_mode (insn) == MODE_XI)
2071 return "vmovdqa32\t{%1, %0|%0, %1}";
2073 return "%vmovdqa\t{%1, %0|%0, %1}";
2080 [(set_attr "isa" "x64,x64,*,*,*")
2081 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2082 (set (attr "prefix")
2083 (if_then_else (eq_attr "type" "sselog1,ssemov")
2084 (const_string "maybe_vex")
2085 (const_string "orig")))
2087 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2088 (match_operand 1 "ext_sse_reg_operand"))
2090 (eq_attr "alternative" "0,1")
2092 (ior (not (match_test "TARGET_SSE2"))
2093 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2094 (const_string "V4SF")
2095 (and (eq_attr "alternative" "4")
2096 (match_test "TARGET_SSE_TYPELESS_STORES"))
2097 (const_string "V4SF")
2098 (match_test "TARGET_AVX")
2100 (match_test "optimize_function_for_size_p (cfun)")
2101 (const_string "V4SF")
2103 (const_string "TI")))])
2106 [(set (match_operand:TI 0 "nonimmediate_operand")
2107 (match_operand:TI 1 "general_operand"))]
2109 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2111 "ix86_split_long_move (operands); DONE;")
2113 (define_insn "*movdi_internal"
2114 [(set (match_operand:DI 0 "nonimmediate_operand"
2115 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2116 (match_operand:DI 1 "general_operand"
2117 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2118 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2120 switch (get_attr_type (insn))
2123 return "kmovq\t{%1, %0|%0, %1}";
2129 return "pxor\t%0, %0";
2132 /* Handle broken assemblers that require movd instead of movq. */
2133 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2134 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2135 return "movd\t{%1, %0|%0, %1}";
2136 return "movq\t{%1, %0|%0, %1}";
2139 if (GENERAL_REG_P (operands[0]))
2140 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2142 return standard_sse_constant_opcode (insn, operands[1]);
2145 switch (get_attr_mode (insn))
2148 /* Handle broken assemblers that require movd instead of movq. */
2149 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2150 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2151 return "%vmovd\t{%1, %0|%0, %1}";
2152 return "%vmovq\t{%1, %0|%0, %1}";
2154 return "%vmovdqa\t{%1, %0|%0, %1}";
2156 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2159 gcc_assert (!TARGET_AVX);
2160 return "movlps\t{%1, %0|%0, %1}";
2162 return "%vmovaps\t{%1, %0|%0, %1}";
2169 if (SSE_REG_P (operands[0]))
2170 return "movq2dq\t{%1, %0|%0, %1}";
2172 return "movdq2q\t{%1, %0|%0, %1}";
2175 return "lea{q}\t{%E1, %0|%0, %E1}";
2178 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2179 if (get_attr_mode (insn) == MODE_SI)
2180 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2181 else if (which_alternative == 4)
2182 return "movabs{q}\t{%1, %0|%0, %1}";
2183 else if (ix86_use_lea_for_mov (insn, operands))
2184 return "lea{q}\t{%E1, %0|%0, %E1}";
2186 return "mov{q}\t{%1, %0|%0, %1}";
2193 (cond [(eq_attr "alternative" "0,1")
2194 (const_string "nox64")
2195 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2196 (const_string "x64")
2197 (eq_attr "alternative" "17")
2198 (const_string "x64_sse4")
2200 (const_string "*")))
2202 (cond [(eq_attr "alternative" "0,1")
2203 (const_string "multi")
2204 (eq_attr "alternative" "6")
2205 (const_string "mmx")
2206 (eq_attr "alternative" "7,8,9,10,11")
2207 (const_string "mmxmov")
2208 (eq_attr "alternative" "12,17")
2209 (const_string "sselog1")
2210 (eq_attr "alternative" "13,14,15,16,18")
2211 (const_string "ssemov")
2212 (eq_attr "alternative" "19,20")
2213 (const_string "ssecvt")
2214 (eq_attr "alternative" "21,22,23,24")
2215 (const_string "mskmov")
2216 (and (match_operand 0 "register_operand")
2217 (match_operand 1 "pic_32bit_operand"))
2218 (const_string "lea")
2220 (const_string "imov")))
2223 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2225 (const_string "*")))
2226 (set (attr "length_immediate")
2227 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2229 (eq_attr "alternative" "17")
2232 (const_string "*")))
2233 (set (attr "prefix_rex")
2234 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2236 (const_string "*")))
2237 (set (attr "prefix_extra")
2238 (if_then_else (eq_attr "alternative" "17")
2240 (const_string "*")))
2241 (set (attr "prefix")
2242 (if_then_else (eq_attr "type" "sselog1,ssemov")
2243 (const_string "maybe_vex")
2244 (const_string "orig")))
2245 (set (attr "prefix_data16")
2246 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2248 (const_string "*")))
2250 (cond [(eq_attr "alternative" "2")
2252 (eq_attr "alternative" "12,13")
2253 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2254 (match_operand 1 "ext_sse_reg_operand"))
2256 (ior (not (match_test "TARGET_SSE2"))
2257 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2258 (const_string "V4SF")
2259 (match_test "TARGET_AVX")
2261 (match_test "optimize_function_for_size_p (cfun)")
2262 (const_string "V4SF")
2264 (const_string "TI"))
2266 (and (eq_attr "alternative" "14,15")
2267 (not (match_test "TARGET_SSE2")))
2268 (const_string "V2SF")
2269 (eq_attr "alternative" "17")
2272 (const_string "DI")))])
2275 [(set (match_operand:DI 0 "nonimmediate_operand")
2276 (match_operand:DI 1 "general_operand"))]
2277 "!TARGET_64BIT && reload_completed
2278 && !(MMX_REG_P (operands[0])
2279 || SSE_REG_P (operands[0])
2280 || MASK_REG_P (operands[0]))
2281 && !(MMX_REG_P (operands[1])
2282 || SSE_REG_P (operands[1])
2283 || MASK_REG_P (operands[1]))"
2285 "ix86_split_long_move (operands); DONE;")
2287 (define_insn "*movsi_internal"
2288 [(set (match_operand:SI 0 "nonimmediate_operand"
2289 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2290 (match_operand:SI 1 "general_operand"
2291 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2292 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2294 switch (get_attr_type (insn))
2297 if (GENERAL_REG_P (operands[0]))
2298 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2300 return standard_sse_constant_opcode (insn, operands[1]);
2303 return "kmovd\t{%1, %0|%0, %1}";
2306 switch (get_attr_mode (insn))
2309 return "%vmovd\t{%1, %0|%0, %1}";
2311 return "%vmovdqa\t{%1, %0|%0, %1}";
2313 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2316 return "%vmovaps\t{%1, %0|%0, %1}";
2319 gcc_assert (!TARGET_AVX);
2320 return "movss\t{%1, %0|%0, %1}";
2327 return "pxor\t%0, %0";
2330 switch (get_attr_mode (insn))
2333 return "movq\t{%1, %0|%0, %1}";
2335 return "movd\t{%1, %0|%0, %1}";
2342 return "lea{l}\t{%E1, %0|%0, %E1}";
2345 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2346 if (ix86_use_lea_for_mov (insn, operands))
2347 return "lea{l}\t{%E1, %0|%0, %E1}";
2349 return "mov{l}\t{%1, %0|%0, %1}";
2356 (if_then_else (eq_attr "alternative" "11")
2357 (const_string "sse4")
2358 (const_string "*")))
2360 (cond [(eq_attr "alternative" "2")
2361 (const_string "mmx")
2362 (eq_attr "alternative" "3,4,5")
2363 (const_string "mmxmov")
2364 (eq_attr "alternative" "6,11")
2365 (const_string "sselog1")
2366 (eq_attr "alternative" "7,8,9,10,12")
2367 (const_string "ssemov")
2368 (eq_attr "alternative" "13,14")
2369 (const_string "mskmov")
2370 (and (match_operand 0 "register_operand")
2371 (match_operand 1 "pic_32bit_operand"))
2372 (const_string "lea")
2374 (const_string "imov")))
2375 (set (attr "length_immediate")
2376 (if_then_else (eq_attr "alternative" "11")
2378 (const_string "*")))
2379 (set (attr "prefix_extra")
2380 (if_then_else (eq_attr "alternative" "11")
2382 (const_string "*")))
2383 (set (attr "prefix")
2384 (if_then_else (eq_attr "type" "sselog1,ssemov")
2385 (const_string "maybe_vex")
2386 (const_string "orig")))
2387 (set (attr "prefix_data16")
2388 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2390 (const_string "*")))
2392 (cond [(eq_attr "alternative" "2,3")
2394 (eq_attr "alternative" "6,7")
2395 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2396 (match_operand 1 "ext_sse_reg_operand"))
2398 (ior (not (match_test "TARGET_SSE2"))
2399 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2400 (const_string "V4SF")
2401 (match_test "TARGET_AVX")
2403 (match_test "optimize_function_for_size_p (cfun)")
2404 (const_string "V4SF")
2406 (const_string "TI"))
2408 (and (eq_attr "alternative" "8,9")
2409 (not (match_test "TARGET_SSE2")))
2411 (eq_attr "alternative" "11")
2414 (const_string "SI")))])
2416 (define_insn "kmovw"
2417 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2419 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2421 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2423 kmovw\t{%k1, %0|%0, %k1}
2424 kmovw\t{%1, %0|%0, %1}";
2425 [(set_attr "mode" "HI")
2426 (set_attr "type" "mskmov")
2427 (set_attr "prefix" "vex")])
2430 (define_insn "*movhi_internal"
2431 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2432 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2433 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2435 switch (get_attr_type (insn))
2438 /* movzwl is faster than movw on p2 due to partial word stalls,
2439 though not as fast as an aligned movl. */
2440 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2443 switch (which_alternative)
2445 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2446 case 5: return "kmovw\t{%1, %0|%0, %1}";
2447 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2448 default: gcc_unreachable ();
2452 if (get_attr_mode (insn) == MODE_SI)
2453 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2455 return "mov{w}\t{%1, %0|%0, %1}";
2459 (cond [(eq_attr "alternative" "4,5,6")
2460 (const_string "mskmov")
2461 (match_test "optimize_function_for_size_p (cfun)")
2462 (const_string "imov")
2463 (and (eq_attr "alternative" "0")
2464 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2465 (not (match_test "TARGET_HIMODE_MATH"))))
2466 (const_string "imov")
2467 (and (eq_attr "alternative" "1,2")
2468 (match_operand:HI 1 "aligned_operand"))
2469 (const_string "imov")
2470 (and (match_test "TARGET_MOVX")
2471 (eq_attr "alternative" "0,2"))
2472 (const_string "imovx")
2474 (const_string "imov")))
2475 (set (attr "prefix")
2476 (if_then_else (eq_attr "alternative" "4,5,6")
2477 (const_string "vex")
2478 (const_string "orig")))
2480 (cond [(eq_attr "type" "imovx")
2482 (and (eq_attr "alternative" "1,2")
2483 (match_operand:HI 1 "aligned_operand"))
2485 (and (eq_attr "alternative" "0")
2486 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2487 (not (match_test "TARGET_HIMODE_MATH"))))
2490 (const_string "HI")))])
2492 ;; Situation is quite tricky about when to choose full sized (SImode) move
2493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2494 ;; partial register dependency machines (such as AMD Athlon), where QImode
2495 ;; moves issue extra dependency and for partial register stalls machines
2496 ;; that don't use QImode patterns (and QImode move cause stall on the next
2499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2500 ;; register stall machines with, where we use QImode instructions, since
2501 ;; partial register stall can be caused there. Then we use movzx.
2503 (define_insn "*movqi_internal"
2504 [(set (match_operand:QI 0 "nonimmediate_operand"
2505 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2506 (match_operand:QI 1 "general_operand"
2507 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2508 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510 switch (get_attr_type (insn))
2513 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2514 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2517 switch (which_alternative)
2519 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2520 : "kmovw\t{%k1, %0|%0, %k1}";
2521 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2522 : "kmovw\t{%1, %0|%0, %1}";
2523 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2524 : "kmovw\t{%1, %k0|%k0, %1}";
2527 gcc_assert (TARGET_AVX512DQ);
2528 return "kmovb\t{%1, %0|%0, %1}";
2529 default: gcc_unreachable ();
2533 if (get_attr_mode (insn) == MODE_SI)
2534 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2536 return "mov{b}\t{%1, %0|%0, %1}";
2539 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2541 (cond [(eq_attr "alternative" "7,8,9,10,11")
2542 (const_string "mskmov")
2543 (and (eq_attr "alternative" "5")
2544 (not (match_operand:QI 1 "aligned_operand")))
2545 (const_string "imovx")
2546 (match_test "optimize_function_for_size_p (cfun)")
2547 (const_string "imov")
2548 (and (eq_attr "alternative" "3")
2549 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2550 (not (match_test "TARGET_QIMODE_MATH"))))
2551 (const_string "imov")
2552 (eq_attr "alternative" "3,5")
2553 (const_string "imovx")
2554 (and (match_test "TARGET_MOVX")
2555 (eq_attr "alternative" "2"))
2556 (const_string "imovx")
2558 (const_string "imov")))
2559 (set (attr "prefix")
2560 (if_then_else (eq_attr "alternative" "7,8,9")
2561 (const_string "vex")
2562 (const_string "orig")))
2564 (cond [(eq_attr "alternative" "3,4,5")
2566 (eq_attr "alternative" "6")
2568 (eq_attr "type" "imovx")
2570 (and (eq_attr "type" "imov")
2571 (and (eq_attr "alternative" "0,1")
2572 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2573 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2574 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2576 ;; Avoid partial register stalls when not using QImode arithmetic
2577 (and (eq_attr "type" "imov")
2578 (and (eq_attr "alternative" "0,1")
2579 (and (match_test "TARGET_PARTIAL_REG_STALL")
2580 (not (match_test "TARGET_QIMODE_MATH")))))
2583 (const_string "QI")))])
2585 ;; Stores and loads of ax to arbitrary constant address.
2586 ;; We fake an second form of instruction to force reload to load address
2587 ;; into register when rax is not available
2588 (define_insn "*movabs<mode>_1"
2589 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2590 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2591 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2593 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2594 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2595 [(set_attr "type" "imov")
2596 (set_attr "modrm" "0,*")
2597 (set_attr "length_address" "8,0")
2598 (set_attr "length_immediate" "0,*")
2599 (set_attr "memory" "store")
2600 (set_attr "mode" "<MODE>")])
2602 (define_insn "*movabs<mode>_2"
2603 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2604 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2605 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2607 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2608 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2609 [(set_attr "type" "imov")
2610 (set_attr "modrm" "0,*")
2611 (set_attr "length_address" "8,0")
2612 (set_attr "length_immediate" "0")
2613 (set_attr "memory" "load")
2614 (set_attr "mode" "<MODE>")])
2616 (define_insn "*swap<mode>"
2617 [(set (match_operand:SWI48 0 "register_operand" "+r")
2618 (match_operand:SWI48 1 "register_operand" "+r"))
2622 "xchg{<imodesuffix>}\t%1, %0"
2623 [(set_attr "type" "imov")
2624 (set_attr "mode" "<MODE>")
2625 (set_attr "pent_pair" "np")
2626 (set_attr "athlon_decode" "vector")
2627 (set_attr "amdfam10_decode" "double")
2628 (set_attr "bdver1_decode" "double")])
2630 (define_insn "*swap<mode>_1"
2631 [(set (match_operand:SWI12 0 "register_operand" "+r")
2632 (match_operand:SWI12 1 "register_operand" "+r"))
2635 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "SI")
2639 (set_attr "pent_pair" "np")
2640 (set_attr "athlon_decode" "vector")
2641 (set_attr "amdfam10_decode" "double")
2642 (set_attr "bdver1_decode" "double")])
2644 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2645 ;; is disabled for AMDFAM10
2646 (define_insn "*swap<mode>_2"
2647 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2648 (match_operand:SWI12 1 "register_operand" "+<r>"))
2651 "TARGET_PARTIAL_REG_STALL"
2652 "xchg{<imodesuffix>}\t%1, %0"
2653 [(set_attr "type" "imov")
2654 (set_attr "mode" "<MODE>")
2655 (set_attr "pent_pair" "np")
2656 (set_attr "athlon_decode" "vector")])
2658 (define_expand "movstrict<mode>"
2659 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2660 (match_operand:SWI12 1 "general_operand"))]
2663 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2665 if (GET_CODE (operands[0]) == SUBREG
2666 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2668 /* Don't generate memory->memory moves, go through a register */
2669 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2670 operands[1] = force_reg (<MODE>mode, operands[1]);
2673 (define_insn "*movstrict<mode>_1"
2674 [(set (strict_low_part
2675 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2676 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2677 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2678 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2679 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2680 [(set_attr "type" "imov")
2681 (set_attr "mode" "<MODE>")])
2683 (define_insn "*movstrict<mode>_xor"
2684 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2685 (match_operand:SWI12 1 "const0_operand"))
2686 (clobber (reg:CC FLAGS_REG))]
2688 "xor{<imodesuffix>}\t%0, %0"
2689 [(set_attr "type" "alu1")
2690 (set_attr "mode" "<MODE>")
2691 (set_attr "length_immediate" "0")])
2693 (define_insn "*mov<mode>_extv_1"
2694 [(set (match_operand:SWI24 0 "register_operand" "=R")
2695 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2699 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2700 [(set_attr "type" "imovx")
2701 (set_attr "mode" "SI")])
2703 (define_insn "*movqi_extv_1"
2704 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2705 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2710 switch (get_attr_type (insn))
2713 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2715 return "mov{b}\t{%h1, %0|%0, %h1}";
2718 [(set_attr "isa" "*,*,nox64")
2720 (if_then_else (and (match_operand:QI 0 "register_operand")
2721 (ior (not (match_operand:QI 0 "QIreg_operand"))
2722 (match_test "TARGET_MOVX")))
2723 (const_string "imovx")
2724 (const_string "imov")))
2726 (if_then_else (eq_attr "type" "imovx")
2728 (const_string "QI")))])
2730 (define_insn "*mov<mode>_extzv_1"
2731 [(set (match_operand:SWI48 0 "register_operand" "=R")
2732 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2736 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2737 [(set_attr "type" "imovx")
2738 (set_attr "mode" "SI")])
2740 (define_insn "*movqi_extzv_2"
2741 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2743 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2748 switch (get_attr_type (insn))
2751 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2753 return "mov{b}\t{%h1, %0|%0, %h1}";
2756 [(set_attr "isa" "*,*,nox64")
2758 (if_then_else (and (match_operand:QI 0 "register_operand")
2759 (ior (not (match_operand:QI 0 "QIreg_operand"))
2760 (match_test "TARGET_MOVX")))
2761 (const_string "imovx")
2762 (const_string "imov")))
2764 (if_then_else (eq_attr "type" "imovx")
2766 (const_string "QI")))])
2768 (define_insn "mov<mode>_insv_1"
2769 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2772 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2775 if (CONST_INT_P (operands[1]))
2776 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2777 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2779 [(set_attr "isa" "*,nox64")
2780 (set_attr "type" "imov")
2781 (set_attr "mode" "QI")])
2783 (define_insn "*movqi_insv_2"
2784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2790 "mov{b}\t{%h1, %h0|%h0, %h1}"
2791 [(set_attr "type" "imov")
2792 (set_attr "mode" "QI")])
2794 ;; Floating point push instructions.
2796 (define_insn "*pushtf"
2797 [(set (match_operand:TF 0 "push_operand" "=<,<")
2798 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2799 "TARGET_64BIT || TARGET_SSE"
2801 /* This insn should be already split before reg-stack. */
2804 [(set_attr "isa" "*,x64")
2805 (set_attr "type" "multi")
2806 (set_attr "unit" "sse,*")
2807 (set_attr "mode" "TF,DI")])
2809 ;; %%% Kill this when call knows how to work this out.
2811 [(set (match_operand:TF 0 "push_operand")
2812 (match_operand:TF 1 "sse_reg_operand"))]
2813 "TARGET_SSE && reload_completed"
2814 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2815 (set (match_dup 0) (match_dup 1))]
2817 /* Preserve memory attributes. */
2818 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2821 (define_insn "*pushxf"
2822 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2823 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2826 /* This insn should be already split before reg-stack. */
2829 [(set_attr "type" "multi")
2830 (set_attr "unit" "i387,*,*,*")
2832 (cond [(eq_attr "alternative" "1,2,3")
2833 (if_then_else (match_test "TARGET_64BIT")
2835 (const_string "SI"))
2837 (const_string "XF")))
2838 (set (attr "preferred_for_size")
2839 (cond [(eq_attr "alternative" "1")
2840 (symbol_ref "false")]
2841 (symbol_ref "true")))])
2843 ;; %%% Kill this when call knows how to work this out.
2845 [(set (match_operand:XF 0 "push_operand")
2846 (match_operand:XF 1 "fp_register_operand"))]
2848 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2849 (set (match_dup 0) (match_dup 1))]
2851 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2852 /* Preserve memory attributes. */
2853 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2856 (define_insn "*pushdf"
2857 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2858 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2861 /* This insn should be already split before reg-stack. */
2864 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2865 (set_attr "type" "multi")
2866 (set_attr "unit" "i387,*,*,*,*,sse")
2867 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2868 (set (attr "preferred_for_size")
2869 (cond [(eq_attr "alternative" "1")
2870 (symbol_ref "false")]
2871 (symbol_ref "true")))
2872 (set (attr "preferred_for_speed")
2873 (cond [(eq_attr "alternative" "1")
2874 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2875 (symbol_ref "true")))])
2877 ;; %%% Kill this when call knows how to work this out.
2879 [(set (match_operand:DF 0 "push_operand")
2880 (match_operand:DF 1 "any_fp_register_operand"))]
2882 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2883 (set (match_dup 0) (match_dup 1))]
2885 /* Preserve memory attributes. */
2886 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2889 (define_insn "*pushsf_rex64"
2890 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2891 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2894 /* Anything else should be already split before reg-stack. */
2895 gcc_assert (which_alternative == 1);
2896 return "push{q}\t%q1";
2898 [(set_attr "type" "multi,push,multi")
2899 (set_attr "unit" "i387,*,*")
2900 (set_attr "mode" "SF,DI,SF")])
2902 (define_insn "*pushsf"
2903 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2904 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2907 /* Anything else should be already split before reg-stack. */
2908 gcc_assert (which_alternative == 1);
2909 return "push{l}\t%1";
2911 [(set_attr "type" "multi,push,multi")
2912 (set_attr "unit" "i387,*,*")
2913 (set_attr "mode" "SF,SI,SF")])
2915 ;; %%% Kill this when call knows how to work this out.
2917 [(set (match_operand:SF 0 "push_operand")
2918 (match_operand:SF 1 "any_fp_register_operand"))]
2920 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2921 (set (match_dup 0) (match_dup 1))]
2923 rtx op = XEXP (operands[0], 0);
2924 if (GET_CODE (op) == PRE_DEC)
2926 gcc_assert (!TARGET_64BIT);
2931 op = XEXP (XEXP (op, 1), 1);
2932 gcc_assert (CONST_INT_P (op));
2935 /* Preserve memory attributes. */
2936 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2940 [(set (match_operand:SF 0 "push_operand")
2941 (match_operand:SF 1 "memory_operand"))]
2943 && (operands[2] = find_constant_src (insn))"
2944 [(set (match_dup 0) (match_dup 2))])
2947 [(set (match_operand 0 "push_operand")
2948 (match_operand 1 "general_operand"))]
2950 && (GET_MODE (operands[0]) == TFmode
2951 || GET_MODE (operands[0]) == XFmode
2952 || GET_MODE (operands[0]) == DFmode)
2953 && !ANY_FP_REG_P (operands[1])"
2955 "ix86_split_long_move (operands); DONE;")
2957 ;; Floating point move instructions.
2959 (define_expand "movtf"
2960 [(set (match_operand:TF 0 "nonimmediate_operand")
2961 (match_operand:TF 1 "nonimmediate_operand"))]
2962 "TARGET_64BIT || TARGET_SSE"
2963 "ix86_expand_move (TFmode, operands); DONE;")
2965 (define_expand "mov<mode>"
2966 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2967 (match_operand:X87MODEF 1 "general_operand"))]
2969 "ix86_expand_move (<MODE>mode, operands); DONE;")
2971 (define_insn "*movtf_internal"
2972 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2973 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2974 "(TARGET_64BIT || TARGET_SSE)
2975 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2976 && (!can_create_pseudo_p ()
2977 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2978 || GET_CODE (operands[1]) != CONST_DOUBLE
2979 || (optimize_function_for_size_p (cfun)
2980 && standard_sse_constant_p (operands[1])
2981 && !memory_operand (operands[0], TFmode))
2982 || (!TARGET_MEMORY_MISMATCH_STALL
2983 && memory_operand (operands[0], TFmode)))"
2985 switch (get_attr_type (insn))
2988 return standard_sse_constant_opcode (insn, operands[1]);
2991 /* Handle misaligned load/store since we
2992 don't have movmisaligntf pattern. */
2993 if (misaligned_operand (operands[0], TFmode)
2994 || misaligned_operand (operands[1], TFmode))
2996 if (get_attr_mode (insn) == MODE_V4SF)
2997 return "%vmovups\t{%1, %0|%0, %1}";
2999 return "%vmovdqu\t{%1, %0|%0, %1}";
3003 if (get_attr_mode (insn) == MODE_V4SF)
3004 return "%vmovaps\t{%1, %0|%0, %1}";
3006 return "%vmovdqa\t{%1, %0|%0, %1}";
3016 [(set_attr "isa" "*,*,*,x64,x64")
3017 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3018 (set (attr "prefix")
3019 (if_then_else (eq_attr "type" "sselog1,ssemov")
3020 (const_string "maybe_vex")
3021 (const_string "orig")))
3023 (cond [(eq_attr "alternative" "3,4")
3025 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3026 (const_string "V4SF")
3027 (and (eq_attr "alternative" "2")
3028 (match_test "TARGET_SSE_TYPELESS_STORES"))
3029 (const_string "V4SF")
3030 (match_test "TARGET_AVX")
3032 (ior (not (match_test "TARGET_SSE2"))
3033 (match_test "optimize_function_for_size_p (cfun)"))
3034 (const_string "V4SF")
3036 (const_string "TI")))])
3038 ;; Possible store forwarding (partial memory) stall
3039 ;; in alternatives 4, 6, 7 and 8.
3040 (define_insn "*movxf_internal"
3041 [(set (match_operand:XF 0 "nonimmediate_operand"
3042 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3043 (match_operand:XF 1 "general_operand"
3044 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3045 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3046 && (!can_create_pseudo_p ()
3047 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3048 || GET_CODE (operands[1]) != CONST_DOUBLE
3049 || (optimize_function_for_size_p (cfun)
3050 && standard_80387_constant_p (operands[1]) > 0
3051 && !memory_operand (operands[0], XFmode))
3052 || (!TARGET_MEMORY_MISMATCH_STALL
3053 && memory_operand (operands[0], XFmode)))"
3055 switch (get_attr_type (insn))
3058 if (which_alternative == 2)
3059 return standard_80387_constant_opcode (operands[1]);
3060 return output_387_reg_move (insn, operands);
3070 (cond [(eq_attr "alternative" "7")
3071 (const_string "nox64")
3072 (eq_attr "alternative" "8")
3073 (const_string "x64")
3075 (const_string "*")))
3077 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3078 (const_string "multi")
3080 (const_string "fmov")))
3082 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3083 (if_then_else (match_test "TARGET_64BIT")
3085 (const_string "SI"))
3087 (const_string "XF")))
3088 (set (attr "preferred_for_size")
3089 (cond [(eq_attr "alternative" "3,4")
3090 (symbol_ref "false")]
3091 (symbol_ref "true")))])
3093 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3094 (define_insn "*movdf_internal"
3095 [(set (match_operand:DF 0 "nonimmediate_operand"
3096 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3097 (match_operand:DF 1 "general_operand"
3098 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3099 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3100 && (!can_create_pseudo_p ()
3101 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3102 || GET_CODE (operands[1]) != CONST_DOUBLE
3103 || (optimize_function_for_size_p (cfun)
3104 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3105 && standard_80387_constant_p (operands[1]) > 0)
3106 || (TARGET_SSE2 && TARGET_SSE_MATH
3107 && standard_sse_constant_p (operands[1])))
3108 && !memory_operand (operands[0], DFmode))
3109 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3110 && memory_operand (operands[0], DFmode)))"
3112 switch (get_attr_type (insn))
3115 if (which_alternative == 2)
3116 return standard_80387_constant_opcode (operands[1]);
3117 return output_387_reg_move (insn, operands);
3123 if (get_attr_mode (insn) == MODE_SI)
3124 return "mov{l}\t{%1, %k0|%k0, %1}";
3125 else if (which_alternative == 11)
3126 return "movabs{q}\t{%1, %0|%0, %1}";
3128 return "mov{q}\t{%1, %0|%0, %1}";
3131 return standard_sse_constant_opcode (insn, operands[1]);
3134 switch (get_attr_mode (insn))
3137 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3138 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3139 return "%vmovsd\t{%1, %0|%0, %1}";
3142 return "%vmovaps\t{%1, %0|%0, %1}";
3144 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3146 return "%vmovapd\t{%1, %0|%0, %1}";
3149 gcc_assert (!TARGET_AVX);
3150 return "movlps\t{%1, %0|%0, %1}";
3152 gcc_assert (!TARGET_AVX);
3153 return "movlpd\t{%1, %0|%0, %1}";
3156 /* Handle broken assemblers that require movd instead of movq. */
3157 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3158 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3159 return "%vmovd\t{%1, %0|%0, %1}";
3160 return "%vmovq\t{%1, %0|%0, %1}";
3171 (cond [(eq_attr "alternative" "3,4,5,6,7")
3172 (const_string "nox64")
3173 (eq_attr "alternative" "8,9,10,11,20,21")
3174 (const_string "x64")
3175 (eq_attr "alternative" "12,13,14,15")
3176 (const_string "sse2")
3178 (const_string "*")))
3180 (cond [(eq_attr "alternative" "0,1,2")
3181 (const_string "fmov")
3182 (eq_attr "alternative" "3,4,5,6,7")
3183 (const_string "multi")
3184 (eq_attr "alternative" "8,9,10,11")
3185 (const_string "imov")
3186 (eq_attr "alternative" "12,16")
3187 (const_string "sselog1")
3189 (const_string "ssemov")))
3191 (if_then_else (eq_attr "alternative" "11")
3193 (const_string "*")))
3194 (set (attr "length_immediate")
3195 (if_then_else (eq_attr "alternative" "11")
3197 (const_string "*")))
3198 (set (attr "prefix")
3199 (if_then_else (eq_attr "type" "sselog1,ssemov")
3200 (const_string "maybe_vex")
3201 (const_string "orig")))
3202 (set (attr "prefix_data16")
3204 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3205 (eq_attr "mode" "V1DF"))
3207 (const_string "*")))
3209 (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3211 (eq_attr "alternative" "8,9,11,20,21")
3214 /* xorps is one byte shorter for non-AVX targets. */
3215 (eq_attr "alternative" "12,16")
3216 (cond [(not (match_test "TARGET_SSE2"))
3217 (const_string "V4SF")
3218 (match_test "TARGET_AVX512F")
3220 (match_test "TARGET_AVX")
3221 (const_string "V2DF")
3222 (match_test "optimize_function_for_size_p (cfun)")
3223 (const_string "V4SF")
3224 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3227 (const_string "V2DF"))
3229 /* For architectures resolving dependencies on
3230 whole SSE registers use movapd to break dependency
3231 chains, otherwise use short move to avoid extra work. */
3233 /* movaps is one byte shorter for non-AVX targets. */
3234 (eq_attr "alternative" "13,17")
3235 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3236 (match_operand 1 "ext_sse_reg_operand"))
3237 (const_string "V8DF")
3238 (ior (not (match_test "TARGET_SSE2"))
3239 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3240 (const_string "V4SF")
3241 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3242 (const_string "V2DF")
3243 (match_test "TARGET_AVX")
3245 (match_test "optimize_function_for_size_p (cfun)")
3246 (const_string "V4SF")
3248 (const_string "DF"))
3250 /* For architectures resolving dependencies on register
3251 parts we may avoid extra work to zero out upper part
3253 (eq_attr "alternative" "14,18")
3254 (cond [(not (match_test "TARGET_SSE2"))
3255 (const_string "V2SF")
3256 (match_test "TARGET_AVX")
3258 (match_test "TARGET_SSE_SPLIT_REGS")
3259 (const_string "V1DF")
3261 (const_string "DF"))
3263 (and (eq_attr "alternative" "15,19")
3264 (not (match_test "TARGET_SSE2")))
3265 (const_string "V2SF")
3267 (const_string "DF")))
3268 (set (attr "preferred_for_size")
3269 (cond [(eq_attr "alternative" "3,4")
3270 (symbol_ref "false")]
3271 (symbol_ref "true")))
3272 (set (attr "preferred_for_speed")
3273 (cond [(eq_attr "alternative" "3,4")
3274 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3275 (symbol_ref "true")))])
3277 (define_insn "*movsf_internal"
3278 [(set (match_operand:SF 0 "nonimmediate_operand"
3279 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3280 (match_operand:SF 1 "general_operand"
3281 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3282 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3283 && (!can_create_pseudo_p ()
3284 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3285 || GET_CODE (operands[1]) != CONST_DOUBLE
3286 || (optimize_function_for_size_p (cfun)
3287 && ((!TARGET_SSE_MATH
3288 && standard_80387_constant_p (operands[1]) > 0)
3290 && standard_sse_constant_p (operands[1]))))
3291 || memory_operand (operands[0], SFmode))"
3293 switch (get_attr_type (insn))
3296 if (which_alternative == 2)
3297 return standard_80387_constant_opcode (operands[1]);
3298 return output_387_reg_move (insn, operands);
3301 return "mov{l}\t{%1, %0|%0, %1}";
3304 return standard_sse_constant_opcode (insn, operands[1]);
3307 switch (get_attr_mode (insn))
3310 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3311 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3312 return "%vmovss\t{%1, %0|%0, %1}";
3315 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3317 return "%vmovaps\t{%1, %0|%0, %1}";
3320 return "%vmovd\t{%1, %0|%0, %1}";
3327 switch (get_attr_mode (insn))
3330 return "movq\t{%1, %0|%0, %1}";
3332 return "movd\t{%1, %0|%0, %1}";
3343 (cond [(eq_attr "alternative" "0,1,2")
3344 (const_string "fmov")
3345 (eq_attr "alternative" "3,4")
3346 (const_string "imov")
3347 (eq_attr "alternative" "5")
3348 (const_string "sselog1")
3349 (eq_attr "alternative" "11,12,13,14,15")
3350 (const_string "mmxmov")
3352 (const_string "ssemov")))
3353 (set (attr "prefix")
3354 (if_then_else (eq_attr "type" "sselog1,ssemov")
3355 (const_string "maybe_vex")
3356 (const_string "orig")))
3357 (set (attr "prefix_data16")
3358 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3360 (const_string "*")))
3362 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3364 (eq_attr "alternative" "11")
3366 (eq_attr "alternative" "5")
3367 (cond [(not (match_test "TARGET_SSE2"))
3368 (const_string "V4SF")
3369 (match_test "TARGET_AVX512F")
3370 (const_string "V16SF")
3371 (match_test "TARGET_AVX")
3372 (const_string "V4SF")
3373 (match_test "optimize_function_for_size_p (cfun)")
3374 (const_string "V4SF")
3375 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3378 (const_string "V4SF"))
3380 /* For architectures resolving dependencies on
3381 whole SSE registers use APS move to break dependency
3382 chains, otherwise use short move to avoid extra work.
3384 Do the same for architectures resolving dependencies on
3385 the parts. While in DF mode it is better to always handle
3386 just register parts, the SF mode is different due to lack
3387 of instructions to load just part of the register. It is
3388 better to maintain the whole registers in single format
3389 to avoid problems on using packed logical operations. */
3390 (eq_attr "alternative" "6")
3391 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3392 (match_operand 1 "ext_sse_reg_operand"))
3393 (const_string "V16SF")
3394 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3395 (match_test "TARGET_SSE_SPLIT_REGS"))
3396 (const_string "V4SF")
3398 (const_string "SF"))
3400 (const_string "SF")))])
3403 [(set (match_operand 0 "any_fp_register_operand")
3404 (match_operand 1 "memory_operand"))]
3406 && (GET_MODE (operands[0]) == TFmode
3407 || GET_MODE (operands[0]) == XFmode
3408 || GET_MODE (operands[0]) == DFmode
3409 || GET_MODE (operands[0]) == SFmode)
3410 && (operands[2] = find_constant_src (insn))"
3411 [(set (match_dup 0) (match_dup 2))]
3413 rtx c = operands[2];
3414 int r = REGNO (operands[0]);
3416 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3417 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3422 [(set (match_operand 0 "any_fp_register_operand")
3423 (float_extend (match_operand 1 "memory_operand")))]
3425 && (GET_MODE (operands[0]) == TFmode
3426 || GET_MODE (operands[0]) == XFmode
3427 || GET_MODE (operands[0]) == DFmode)
3428 && (operands[2] = find_constant_src (insn))"
3429 [(set (match_dup 0) (match_dup 2))]
3431 rtx c = operands[2];
3432 int r = REGNO (operands[0]);
3434 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3435 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3439 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3441 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3442 (match_operand:X87MODEF 1 "immediate_operand"))]
3444 && (standard_80387_constant_p (operands[1]) == 8
3445 || standard_80387_constant_p (operands[1]) == 9)"
3446 [(set (match_dup 0)(match_dup 1))
3448 (neg:X87MODEF (match_dup 0)))]
3452 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3453 if (real_isnegzero (&r))
3454 operands[1] = CONST0_RTX (<MODE>mode);
3456 operands[1] = CONST1_RTX (<MODE>mode);
3460 [(set (match_operand 0 "nonimmediate_operand")
3461 (match_operand 1 "general_operand"))]
3463 && (GET_MODE (operands[0]) == TFmode
3464 || GET_MODE (operands[0]) == XFmode
3465 || GET_MODE (operands[0]) == DFmode)
3466 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3468 "ix86_split_long_move (operands); DONE;")
3470 (define_insn "swapxf"
3471 [(set (match_operand:XF 0 "register_operand" "+f")
3472 (match_operand:XF 1 "register_operand" "+f"))
3477 if (STACK_TOP_P (operands[0]))
3482 [(set_attr "type" "fxch")
3483 (set_attr "mode" "XF")])
3485 (define_insn "*swap<mode>"
3486 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3487 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3490 "TARGET_80387 || reload_completed"
3492 if (STACK_TOP_P (operands[0]))
3497 [(set_attr "type" "fxch")
3498 (set_attr "mode" "<MODE>")])
3500 ;; Zero extension instructions
3502 (define_expand "zero_extendsidi2"
3503 [(set (match_operand:DI 0 "nonimmediate_operand")
3504 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3506 (define_insn "*zero_extendsidi2"
3507 [(set (match_operand:DI 0 "nonimmediate_operand"
3508 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3510 (match_operand:SI 1 "x86_64_zext_operand"
3511 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3514 switch (get_attr_type (insn))
3517 if (ix86_use_lea_for_mov (insn, operands))
3518 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3520 return "mov{l}\t{%1, %k0|%k0, %1}";
3526 return "movd\t{%1, %0|%0, %1}";
3529 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3532 if (GENERAL_REG_P (operands[0]))
3533 return "%vmovd\t{%1, %k0|%k0, %1}";
3535 return "%vmovd\t{%1, %0|%0, %1}";
3542 (cond [(eq_attr "alternative" "0,1,2")
3543 (const_string "nox64")
3544 (eq_attr "alternative" "3,7")
3545 (const_string "x64")
3546 (eq_attr "alternative" "8")
3547 (const_string "x64_sse4")
3548 (eq_attr "alternative" "10")
3549 (const_string "sse2")
3551 (const_string "*")))
3553 (cond [(eq_attr "alternative" "0,1,2,4")
3554 (const_string "multi")
3555 (eq_attr "alternative" "5,6")
3556 (const_string "mmxmov")
3557 (eq_attr "alternative" "7,9,10")
3558 (const_string "ssemov")
3559 (eq_attr "alternative" "8")
3560 (const_string "sselog1")
3562 (const_string "imovx")))
3563 (set (attr "prefix_extra")
3564 (if_then_else (eq_attr "alternative" "8")
3566 (const_string "*")))
3567 (set (attr "length_immediate")
3568 (if_then_else (eq_attr "alternative" "8")
3570 (const_string "*")))
3571 (set (attr "prefix")
3572 (if_then_else (eq_attr "type" "ssemov,sselog1")
3573 (const_string "maybe_vex")
3574 (const_string "orig")))
3575 (set (attr "prefix_0f")
3576 (if_then_else (eq_attr "type" "imovx")
3578 (const_string "*")))
3580 (cond [(eq_attr "alternative" "5,6")
3582 (eq_attr "alternative" "7,8,9")
3585 (const_string "SI")))])
3588 [(set (match_operand:DI 0 "memory_operand")
3589 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3591 [(set (match_dup 4) (const_int 0))]
3592 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3595 [(set (match_operand:DI 0 "register_operand")
3596 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3597 "!TARGET_64BIT && reload_completed
3598 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3599 && true_regnum (operands[0]) == true_regnum (operands[1])"
3600 [(set (match_dup 4) (const_int 0))]
3601 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3604 [(set (match_operand:DI 0 "nonimmediate_operand")
3605 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3606 "!TARGET_64BIT && reload_completed
3607 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3609 [(set (match_dup 3) (match_dup 1))
3610 (set (match_dup 4) (const_int 0))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613 (define_insn "zero_extend<mode>di2"
3614 [(set (match_operand:DI 0 "register_operand" "=r")
3616 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3618 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3619 [(set_attr "type" "imovx")
3620 (set_attr "mode" "SI")])
3622 (define_expand "zero_extend<mode>si2"
3623 [(set (match_operand:SI 0 "register_operand")
3624 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3627 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3629 operands[1] = force_reg (<MODE>mode, operands[1]);
3630 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3635 (define_insn_and_split "zero_extend<mode>si2_and"
3636 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3638 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3639 (clobber (reg:CC FLAGS_REG))]
3640 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3642 "&& reload_completed"
3643 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3644 (clobber (reg:CC FLAGS_REG))])]
3646 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3648 ix86_expand_clear (operands[0]);
3650 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3651 emit_insn (gen_movstrict<mode>
3652 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3656 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3658 [(set_attr "type" "alu1")
3659 (set_attr "mode" "SI")])
3661 (define_insn "*zero_extend<mode>si2"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3664 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3665 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3666 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "SI")])
3670 (define_expand "zero_extendqihi2"
3671 [(set (match_operand:HI 0 "register_operand")
3672 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3675 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3677 operands[1] = force_reg (QImode, operands[1]);
3678 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3683 (define_insn_and_split "zero_extendqihi2_and"
3684 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3685 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3686 (clobber (reg:CC FLAGS_REG))]
3687 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3689 "&& reload_completed"
3690 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3691 (clobber (reg:CC FLAGS_REG))])]
3693 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3695 ix86_expand_clear (operands[0]);
3697 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3698 emit_insn (gen_movstrictqi
3699 (gen_lowpart (QImode, operands[0]), operands[1]));
3703 operands[0] = gen_lowpart (SImode, operands[0]);
3705 [(set_attr "type" "alu1")
3706 (set_attr "mode" "SI")])
3708 ; zero extend to SImode to avoid partial register stalls
3709 (define_insn "*zero_extendqihi2"
3710 [(set (match_operand:HI 0 "register_operand" "=r")
3711 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3712 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3713 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI")])
3717 ;; Sign extension instructions
3719 (define_expand "extendsidi2"
3720 [(set (match_operand:DI 0 "register_operand")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3726 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3731 (define_insn "*extendsidi2_rex64"
3732 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3733 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3737 movs{lq|x}\t{%1, %0|%0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "DI")
3740 (set_attr "prefix_0f" "0")
3741 (set_attr "modrm" "0,1")])
3743 (define_insn "extendsidi2_1"
3744 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3745 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3746 (clobber (reg:CC FLAGS_REG))
3747 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3751 ;; Split the memory case. If the source register doesn't die, it will stay
3752 ;; this way, if it does die, following peephole2s take care of it.
3754 [(set (match_operand:DI 0 "memory_operand")
3755 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3756 (clobber (reg:CC FLAGS_REG))
3757 (clobber (match_operand:SI 2 "register_operand"))]
3761 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3763 emit_move_insn (operands[3], operands[1]);
3765 /* Generate a cltd if possible and doing so it profitable. */
3766 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3767 && true_regnum (operands[1]) == AX_REG
3768 && true_regnum (operands[2]) == DX_REG)
3770 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3774 emit_move_insn (operands[2], operands[1]);
3775 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3777 emit_move_insn (operands[4], operands[2]);
3781 ;; Peepholes for the case where the source register does die, after
3782 ;; being split with the above splitter.
3784 [(set (match_operand:SI 0 "memory_operand")
3785 (match_operand:SI 1 "register_operand"))
3786 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3787 (parallel [(set (match_dup 2)
3788 (ashiftrt:SI (match_dup 2) (const_int 31)))
3789 (clobber (reg:CC FLAGS_REG))])
3790 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3791 "REGNO (operands[1]) != REGNO (operands[2])
3792 && peep2_reg_dead_p (2, operands[1])
3793 && peep2_reg_dead_p (4, operands[2])
3794 && !reg_mentioned_p (operands[2], operands[3])"
3795 [(set (match_dup 0) (match_dup 1))
3796 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3797 (clobber (reg:CC FLAGS_REG))])
3798 (set (match_dup 3) (match_dup 1))])
3801 [(set (match_operand:SI 0 "memory_operand")
3802 (match_operand:SI 1 "register_operand"))
3803 (parallel [(set (match_operand:SI 2 "register_operand")
3804 (ashiftrt:SI (match_dup 1) (const_int 31)))
3805 (clobber (reg:CC FLAGS_REG))])
3806 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3807 "/* cltd is shorter than sarl $31, %eax */
3808 !optimize_function_for_size_p (cfun)
3809 && true_regnum (operands[1]) == AX_REG
3810 && true_regnum (operands[2]) == DX_REG
3811 && peep2_reg_dead_p (2, operands[1])
3812 && peep2_reg_dead_p (3, operands[2])
3813 && !reg_mentioned_p (operands[2], operands[3])"
3814 [(set (match_dup 0) (match_dup 1))
3815 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3816 (clobber (reg:CC FLAGS_REG))])
3817 (set (match_dup 3) (match_dup 1))])
3819 ;; Extend to register case. Optimize case where source and destination
3820 ;; registers match and cases where we can use cltd.
3822 [(set (match_operand:DI 0 "register_operand")
3823 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3824 (clobber (reg:CC FLAGS_REG))
3825 (clobber (match_scratch:SI 2))]
3829 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3831 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3832 emit_move_insn (operands[3], operands[1]);
3834 /* Generate a cltd if possible and doing so it profitable. */
3835 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3836 && true_regnum (operands[3]) == AX_REG
3837 && true_regnum (operands[4]) == DX_REG)
3839 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3843 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3844 emit_move_insn (operands[4], operands[1]);
3846 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3850 (define_insn "extend<mode>di2"
3851 [(set (match_operand:DI 0 "register_operand" "=r")
3853 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3855 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3856 [(set_attr "type" "imovx")
3857 (set_attr "mode" "DI")])
3859 (define_insn "extendhisi2"
3860 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3861 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3864 switch (get_attr_prefix_0f (insn))
3867 return "{cwtl|cwde}";
3869 return "movs{wl|x}\t{%1, %0|%0, %1}";
3872 [(set_attr "type" "imovx")
3873 (set_attr "mode" "SI")
3874 (set (attr "prefix_0f")
3875 ;; movsx is short decodable while cwtl is vector decoded.
3876 (if_then_else (and (eq_attr "cpu" "!k6")
3877 (eq_attr "alternative" "0"))
3879 (const_string "1")))
3881 (if_then_else (eq_attr "prefix_0f" "0")
3883 (const_string "1")))])
3885 (define_insn "*extendhisi2_zext"
3886 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3889 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3892 switch (get_attr_prefix_0f (insn))
3895 return "{cwtl|cwde}";
3897 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3900 [(set_attr "type" "imovx")
3901 (set_attr "mode" "SI")
3902 (set (attr "prefix_0f")
3903 ;; movsx is short decodable while cwtl is vector decoded.
3904 (if_then_else (and (eq_attr "cpu" "!k6")
3905 (eq_attr "alternative" "0"))
3907 (const_string "1")))
3909 (if_then_else (eq_attr "prefix_0f" "0")
3911 (const_string "1")))])
3913 (define_insn "extendqisi2"
3914 [(set (match_operand:SI 0 "register_operand" "=r")
3915 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3917 "movs{bl|x}\t{%1, %0|%0, %1}"
3918 [(set_attr "type" "imovx")
3919 (set_attr "mode" "SI")])
3921 (define_insn "*extendqisi2_zext"
3922 [(set (match_operand:DI 0 "register_operand" "=r")
3924 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3926 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3927 [(set_attr "type" "imovx")
3928 (set_attr "mode" "SI")])
3930 (define_insn "extendqihi2"
3931 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3932 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3935 switch (get_attr_prefix_0f (insn))
3938 return "{cbtw|cbw}";
3940 return "movs{bw|x}\t{%1, %0|%0, %1}";
3943 [(set_attr "type" "imovx")
3944 (set_attr "mode" "HI")
3945 (set (attr "prefix_0f")
3946 ;; movsx is short decodable while cwtl is vector decoded.
3947 (if_then_else (and (eq_attr "cpu" "!k6")
3948 (eq_attr "alternative" "0"))
3950 (const_string "1")))
3952 (if_then_else (eq_attr "prefix_0f" "0")
3954 (const_string "1")))])
3956 ;; Conversions between float and double.
3958 ;; These are all no-ops in the model used for the 80387.
3959 ;; So just emit moves.
3961 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3963 [(set (match_operand:DF 0 "push_operand")
3964 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3966 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3967 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3970 [(set (match_operand:XF 0 "push_operand")
3971 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3973 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3974 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3975 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3977 (define_expand "extendsfdf2"
3978 [(set (match_operand:DF 0 "nonimmediate_operand")
3979 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3980 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3982 /* ??? Needed for compress_float_constant since all fp constants
3983 are TARGET_LEGITIMATE_CONSTANT_P. */
3984 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3986 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3987 && standard_80387_constant_p (operands[1]) > 0)
3989 operands[1] = simplify_const_unary_operation
3990 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3991 emit_move_insn_1 (operands[0], operands[1]);
3994 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3998 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4000 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4002 We do the conversion post reload to avoid producing of 128bit spills
4003 that might lead to ICE on 32bit target. The sequence unlikely combine
4006 [(set (match_operand:DF 0 "register_operand")
4008 (match_operand:SF 1 "nonimmediate_operand")))]
4009 "TARGET_USE_VECTOR_FP_CONVERTS
4010 && optimize_insn_for_speed_p ()
4011 && reload_completed && SSE_REG_P (operands[0])"
4016 (parallel [(const_int 0) (const_int 1)]))))]
4018 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4019 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4020 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4021 Try to avoid move when unpacking can be done in source. */
4022 if (REG_P (operands[1]))
4024 /* If it is unsafe to overwrite upper half of source, we need
4025 to move to destination and unpack there. */
4026 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4027 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4028 && true_regnum (operands[0]) != true_regnum (operands[1]))
4030 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4031 emit_move_insn (tmp, operands[1]);
4034 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4035 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4039 emit_insn (gen_vec_setv4sf_0 (operands[3],
4040 CONST0_RTX (V4SFmode), operands[1]));
4043 ;; It's more profitable to split and then extend in the same register.
4045 [(set (match_operand:DF 0 "register_operand")
4047 (match_operand:SF 1 "memory_operand")))]
4048 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4049 && optimize_insn_for_speed_p ()
4050 && SSE_REG_P (operands[0])"
4051 [(set (match_dup 2) (match_dup 1))
4052 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4053 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4055 (define_insn "*extendsfdf2_mixed"
4056 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4058 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4059 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4061 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4068 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4074 [(set_attr "type" "fmov,fmov,ssecvt")
4075 (set_attr "prefix" "orig,orig,maybe_vex")
4076 (set_attr "mode" "SF,XF,DF")])
4078 (define_insn "*extendsfdf2_sse"
4079 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4080 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4081 "TARGET_SSE2 && TARGET_SSE_MATH"
4082 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4083 [(set_attr "type" "ssecvt")
4084 (set_attr "prefix" "maybe_vex")
4085 (set_attr "mode" "DF")])
4087 (define_insn "*extendsfdf2_i387"
4088 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4089 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4091 "* return output_387_reg_move (insn, operands);"
4092 [(set_attr "type" "fmov")
4093 (set_attr "mode" "SF,XF")])
4095 (define_expand "extend<mode>xf2"
4096 [(set (match_operand:XF 0 "nonimmediate_operand")
4097 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4100 /* ??? Needed for compress_float_constant since all fp constants
4101 are TARGET_LEGITIMATE_CONSTANT_P. */
4102 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4104 if (standard_80387_constant_p (operands[1]) > 0)
4106 operands[1] = simplify_const_unary_operation
4107 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4108 emit_move_insn_1 (operands[0], operands[1]);
4111 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4115 (define_insn "*extend<mode>xf2_i387"
4116 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4118 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4120 "* return output_387_reg_move (insn, operands);"
4121 [(set_attr "type" "fmov")
4122 (set_attr "mode" "<MODE>,XF")])
4124 ;; %%% This seems bad bad news.
4125 ;; This cannot output into an f-reg because there is no way to be sure
4126 ;; of truncating in that case. Otherwise this is just like a simple move
4127 ;; insn. So we pretend we can output to a reg in order to get better
4128 ;; register preferencing, but we really use a stack slot.
4130 ;; Conversion from DFmode to SFmode.
4132 (define_expand "truncdfsf2"
4133 [(set (match_operand:SF 0 "nonimmediate_operand")
4135 (match_operand:DF 1 "nonimmediate_operand")))]
4136 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4138 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4140 else if (flag_unsafe_math_optimizations)
4144 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4145 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4150 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4152 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4154 We do the conversion post reload to avoid producing of 128bit spills
4155 that might lead to ICE on 32bit target. The sequence unlikely combine
4158 [(set (match_operand:SF 0 "register_operand")
4160 (match_operand:DF 1 "nonimmediate_operand")))]
4161 "TARGET_USE_VECTOR_FP_CONVERTS
4162 && optimize_insn_for_speed_p ()
4163 && reload_completed && SSE_REG_P (operands[0])"
4166 (float_truncate:V2SF
4170 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4171 operands[3] = CONST0_RTX (V2SFmode);
4172 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4173 /* Use movsd for loading from memory, unpcklpd for registers.
4174 Try to avoid move when unpacking can be done in source, or SSE3
4175 movddup is available. */
4176 if (REG_P (operands[1]))
4179 && true_regnum (operands[0]) != true_regnum (operands[1])
4180 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4181 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4183 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4184 emit_move_insn (tmp, operands[1]);
4187 else if (!TARGET_SSE3)
4188 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4189 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4192 emit_insn (gen_sse2_loadlpd (operands[4],
4193 CONST0_RTX (V2DFmode), operands[1]));
4196 ;; It's more profitable to split and then extend in the same register.
4198 [(set (match_operand:SF 0 "register_operand")
4200 (match_operand:DF 1 "memory_operand")))]
4201 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4202 && optimize_insn_for_speed_p ()
4203 && SSE_REG_P (operands[0])"
4204 [(set (match_dup 2) (match_dup 1))
4205 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4206 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4208 (define_expand "truncdfsf2_with_temp"
4209 [(parallel [(set (match_operand:SF 0)
4210 (float_truncate:SF (match_operand:DF 1)))
4211 (clobber (match_operand:SF 2))])])
4213 (define_insn "*truncdfsf_fast_mixed"
4214 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4216 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4217 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4219 switch (which_alternative)
4222 return output_387_reg_move (insn, operands);
4224 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4229 [(set_attr "type" "fmov,ssecvt")
4230 (set_attr "prefix" "orig,maybe_vex")
4231 (set_attr "mode" "SF")])
4233 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4234 ;; because nothing we do here is unsafe.
4235 (define_insn "*truncdfsf_fast_sse"
4236 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4238 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4239 "TARGET_SSE2 && TARGET_SSE_MATH"
4240 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4241 [(set_attr "type" "ssecvt")
4242 (set_attr "prefix" "maybe_vex")
4243 (set_attr "mode" "SF")])
4245 (define_insn "*truncdfsf_fast_i387"
4246 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4248 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4249 "TARGET_80387 && flag_unsafe_math_optimizations"
4250 "* return output_387_reg_move (insn, operands);"
4251 [(set_attr "type" "fmov")
4252 (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_mixed"
4255 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4257 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4258 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4259 "TARGET_MIX_SSE_I387"
4261 switch (which_alternative)
4264 return output_387_reg_move (insn, operands);
4266 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4272 [(set_attr "isa" "*,sse2,*,*,*")
4273 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4274 (set_attr "unit" "*,*,i387,i387,i387")
4275 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4276 (set_attr "mode" "SF")])
4278 (define_insn "*truncdfsf_i387"
4279 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4281 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4282 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4285 switch (which_alternative)
4288 return output_387_reg_move (insn, operands);
4294 [(set_attr "type" "fmov,multi,multi,multi")
4295 (set_attr "unit" "*,i387,i387,i387")
4296 (set_attr "mode" "SF")])
4298 (define_insn "*truncdfsf2_i387_1"
4299 [(set (match_operand:SF 0 "memory_operand" "=m")
4301 (match_operand:DF 1 "register_operand" "f")))]
4303 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4304 && !TARGET_MIX_SSE_I387"
4305 "* return output_387_reg_move (insn, operands);"
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "SF")])
4310 [(set (match_operand:SF 0 "register_operand")
4312 (match_operand:DF 1 "fp_register_operand")))
4313 (clobber (match_operand 2))]
4315 [(set (match_dup 2) (match_dup 1))
4316 (set (match_dup 0) (match_dup 2))]
4317 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4319 ;; Conversion from XFmode to {SF,DF}mode
4321 (define_expand "truncxf<mode>2"
4322 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4323 (float_truncate:MODEF
4324 (match_operand:XF 1 "register_operand")))
4325 (clobber (match_dup 2))])]
4328 if (flag_unsafe_math_optimizations)
4330 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4331 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4332 if (reg != operands[0])
4333 emit_move_insn (operands[0], reg);
4337 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4343 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi,multi,multi")
4351 (set_attr "unit" "*,i387,i387,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4357 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "isa" "*,*,sse2,*")
4365 (set_attr "type" "fmov,multi,multi,multi")
4366 (set_attr "unit" "*,i387,i387,i387")
4367 (set_attr "mode" "DF")])
4369 (define_insn "truncxf<mode>2_i387_noop"
4370 [(set (match_operand:MODEF 0 "register_operand" "=f")
4371 (float_truncate:MODEF
4372 (match_operand:XF 1 "register_operand" "f")))]
4373 "TARGET_80387 && flag_unsafe_math_optimizations"
4374 "* return output_387_reg_move (insn, operands);"
4375 [(set_attr "type" "fmov")
4376 (set_attr "mode" "<MODE>")])
4378 (define_insn "*truncxf<mode>2_i387"
4379 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4380 (float_truncate:MODEF
4381 (match_operand:XF 1 "register_operand" "f")))]
4383 "* return output_387_reg_move (insn, operands);"
4384 [(set_attr "type" "fmov")
4385 (set_attr "mode" "<MODE>")])
4388 [(set (match_operand:MODEF 0 "register_operand")
4389 (float_truncate:MODEF
4390 (match_operand:XF 1 "register_operand")))
4391 (clobber (match_operand:MODEF 2 "memory_operand"))]
4392 "TARGET_80387 && reload_completed"
4393 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4394 (set (match_dup 0) (match_dup 2))])
4397 [(set (match_operand:MODEF 0 "memory_operand")
4398 (float_truncate:MODEF
4399 (match_operand:XF 1 "register_operand")))
4400 (clobber (match_operand:MODEF 2 "memory_operand"))]
4402 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4404 ;; Signed conversion to DImode.
4406 (define_expand "fix_truncxfdi2"
4407 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4408 (fix:DI (match_operand:XF 1 "register_operand")))
4409 (clobber (reg:CC FLAGS_REG))])]
4414 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4419 (define_expand "fix_trunc<mode>di2"
4420 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4421 (fix:DI (match_operand:MODEF 1 "register_operand")))
4422 (clobber (reg:CC FLAGS_REG))])]
4423 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4426 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4428 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4431 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4433 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4434 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4435 if (out != operands[0])
4436 emit_move_insn (operands[0], out);
4441 ;; Signed conversion to SImode.
4443 (define_expand "fix_truncxfsi2"
4444 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4445 (fix:SI (match_operand:XF 1 "register_operand")))
4446 (clobber (reg:CC FLAGS_REG))])]
4451 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4456 (define_expand "fix_trunc<mode>si2"
4457 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4458 (fix:SI (match_operand:MODEF 1 "register_operand")))
4459 (clobber (reg:CC FLAGS_REG))])]
4460 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4463 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4465 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4468 if (SSE_FLOAT_MODE_P (<MODE>mode))
4470 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4471 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4472 if (out != operands[0])
4473 emit_move_insn (operands[0], out);
4478 ;; Signed conversion to HImode.
4480 (define_expand "fix_trunc<mode>hi2"
4481 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4482 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4483 (clobber (reg:CC FLAGS_REG))])]
4485 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4489 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4494 ;; Unsigned conversion to SImode.
4496 (define_expand "fixuns_trunc<mode>si2"
4498 [(set (match_operand:SI 0 "register_operand")
4500 (match_operand:MODEF 1 "nonimmediate_operand")))
4502 (clobber (match_scratch:<ssevecmode> 3))
4503 (clobber (match_scratch:<ssevecmode> 4))])]
4504 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4506 machine_mode mode = <MODE>mode;
4507 machine_mode vecmode = <ssevecmode>mode;
4508 REAL_VALUE_TYPE TWO31r;
4511 if (optimize_insn_for_size_p ())
4514 real_ldexp (&TWO31r, &dconst1, 31);
4515 two31 = const_double_from_real_value (TWO31r, mode);
4516 two31 = ix86_build_const_vector (vecmode, true, two31);
4517 operands[2] = force_reg (vecmode, two31);
4520 (define_insn_and_split "*fixuns_trunc<mode>_1"
4521 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4523 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4524 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4525 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4526 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4527 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4528 && optimize_function_for_speed_p (cfun)"
4530 "&& reload_completed"
4533 ix86_split_convert_uns_si_sse (operands);
4537 ;; Unsigned conversion to HImode.
4538 ;; Without these patterns, we'll try the unsigned SI conversion which
4539 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4541 (define_expand "fixuns_trunc<mode>hi2"
4543 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4544 (set (match_operand:HI 0 "nonimmediate_operand")
4545 (subreg:HI (match_dup 2) 0))]
4546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4547 "operands[2] = gen_reg_rtx (SImode);")
4549 ;; When SSE is available, it is always faster to use it!
4550 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4551 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4552 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4553 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4554 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4555 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4556 [(set_attr "type" "sseicvt")
4557 (set_attr "prefix" "maybe_vex")
4558 (set (attr "prefix_rex")
4560 (match_test "<SWI48:MODE>mode == DImode")
4562 (const_string "*")))
4563 (set_attr "mode" "<MODEF:MODE>")
4564 (set_attr "athlon_decode" "double,vector")
4565 (set_attr "amdfam10_decode" "double,double")
4566 (set_attr "bdver1_decode" "double,double")])
4568 ;; Avoid vector decoded forms of the instruction.
4570 [(match_scratch:MODEF 2 "x")
4571 (set (match_operand:SWI48 0 "register_operand")
4572 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4573 "TARGET_AVOID_VECTOR_DECODE
4574 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4575 && optimize_insn_for_speed_p ()"
4576 [(set (match_dup 2) (match_dup 1))
4577 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4579 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4580 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4581 (fix:SWI248x (match_operand 1 "register_operand")))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && (TARGET_64BIT || <MODE>mode != DImode))
4587 && can_create_pseudo_p ()"
4592 if (memory_operand (operands[0], VOIDmode))
4593 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4596 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4597 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4603 [(set_attr "type" "fisttp")
4604 (set_attr "mode" "<MODE>")])
4606 (define_insn "fix_trunc<mode>_i387_fisttp"
4607 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4608 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4609 (clobber (match_scratch:XF 2 "=&1f"))]
4610 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && (TARGET_64BIT || <MODE>mode != DImode))
4614 && TARGET_SSE_MATH)"
4615 "* return output_fix_trunc (insn, operands, true);"
4616 [(set_attr "type" "fisttp")
4617 (set_attr "mode" "<MODE>")])
4619 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4620 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4621 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4622 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4623 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4624 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4626 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && (TARGET_64BIT || <MODE>mode != DImode))
4628 && TARGET_SSE_MATH)"
4630 [(set_attr "type" "fisttp")
4631 (set_attr "mode" "<MODE>")])
4634 [(set (match_operand:SWI248x 0 "register_operand")
4635 (fix:SWI248x (match_operand 1 "register_operand")))
4636 (clobber (match_operand:SWI248x 2 "memory_operand"))
4637 (clobber (match_scratch 3))]
4639 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4640 (clobber (match_dup 3))])
4641 (set (match_dup 0) (match_dup 2))])
4644 [(set (match_operand:SWI248x 0 "memory_operand")
4645 (fix:SWI248x (match_operand 1 "register_operand")))
4646 (clobber (match_operand:SWI248x 2 "memory_operand"))
4647 (clobber (match_scratch 3))]
4649 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4650 (clobber (match_dup 3))])])
4652 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4653 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4654 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4655 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4656 ;; function in i386.c.
4657 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4658 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4659 (fix:SWI248x (match_operand 1 "register_operand")))
4660 (clobber (reg:CC FLAGS_REG))]
4661 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4664 && (TARGET_64BIT || <MODE>mode != DImode))
4665 && can_create_pseudo_p ()"
4670 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4672 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4673 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4674 if (memory_operand (operands[0], VOIDmode))
4675 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4676 operands[2], operands[3]));
4679 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4680 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4681 operands[2], operands[3],
4686 [(set_attr "type" "fistp")
4687 (set_attr "i387_cw" "trunc")
4688 (set_attr "mode" "<MODE>")])
4690 (define_insn "fix_truncdi_i387"
4691 [(set (match_operand:DI 0 "memory_operand" "=m")
4692 (fix:DI (match_operand 1 "register_operand" "f")))
4693 (use (match_operand:HI 2 "memory_operand" "m"))
4694 (use (match_operand:HI 3 "memory_operand" "m"))
4695 (clobber (match_scratch:XF 4 "=&1f"))]
4696 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4698 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4699 "* return output_fix_trunc (insn, operands, false);"
4700 [(set_attr "type" "fistp")
4701 (set_attr "i387_cw" "trunc")
4702 (set_attr "mode" "DI")])
4704 (define_insn "fix_truncdi_i387_with_temp"
4705 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4706 (fix:DI (match_operand 1 "register_operand" "f,f")))
4707 (use (match_operand:HI 2 "memory_operand" "m,m"))
4708 (use (match_operand:HI 3 "memory_operand" "m,m"))
4709 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4710 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4711 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4713 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4715 [(set_attr "type" "fistp")
4716 (set_attr "i387_cw" "trunc")
4717 (set_attr "mode" "DI")])
4720 [(set (match_operand:DI 0 "register_operand")
4721 (fix:DI (match_operand 1 "register_operand")))
4722 (use (match_operand:HI 2 "memory_operand"))
4723 (use (match_operand:HI 3 "memory_operand"))
4724 (clobber (match_operand:DI 4 "memory_operand"))
4725 (clobber (match_scratch 5))]
4727 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4730 (clobber (match_dup 5))])
4731 (set (match_dup 0) (match_dup 4))])
4734 [(set (match_operand:DI 0 "memory_operand")
4735 (fix:DI (match_operand 1 "register_operand")))
4736 (use (match_operand:HI 2 "memory_operand"))
4737 (use (match_operand:HI 3 "memory_operand"))
4738 (clobber (match_operand:DI 4 "memory_operand"))
4739 (clobber (match_scratch 5))]
4741 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4744 (clobber (match_dup 5))])])
4746 (define_insn "fix_trunc<mode>_i387"
4747 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4748 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4749 (use (match_operand:HI 2 "memory_operand" "m"))
4750 (use (match_operand:HI 3 "memory_operand" "m"))]
4751 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4753 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4754 "* return output_fix_trunc (insn, operands, false);"
4755 [(set_attr "type" "fistp")
4756 (set_attr "i387_cw" "trunc")
4757 (set_attr "mode" "<MODE>")])
4759 (define_insn "fix_trunc<mode>_i387_with_temp"
4760 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4761 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4762 (use (match_operand:HI 2 "memory_operand" "m,m"))
4763 (use (match_operand:HI 3 "memory_operand" "m,m"))
4764 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4765 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4767 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4769 [(set_attr "type" "fistp")
4770 (set_attr "i387_cw" "trunc")
4771 (set_attr "mode" "<MODE>")])
4774 [(set (match_operand:SWI24 0 "register_operand")
4775 (fix:SWI24 (match_operand 1 "register_operand")))
4776 (use (match_operand:HI 2 "memory_operand"))
4777 (use (match_operand:HI 3 "memory_operand"))
4778 (clobber (match_operand:SWI24 4 "memory_operand"))]
4780 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4782 (use (match_dup 3))])
4783 (set (match_dup 0) (match_dup 4))])
4786 [(set (match_operand:SWI24 0 "memory_operand")
4787 (fix:SWI24 (match_operand 1 "register_operand")))
4788 (use (match_operand:HI 2 "memory_operand"))
4789 (use (match_operand:HI 3 "memory_operand"))
4790 (clobber (match_operand:SWI24 4 "memory_operand"))]
4792 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4794 (use (match_dup 3))])])
4796 (define_insn "x86_fnstcw_1"
4797 [(set (match_operand:HI 0 "memory_operand" "=m")
4798 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4801 [(set (attr "length")
4802 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4803 (set_attr "mode" "HI")
4804 (set_attr "unit" "i387")
4805 (set_attr "bdver1_decode" "vector")])
4807 (define_insn "x86_fldcw_1"
4808 [(set (reg:HI FPCR_REG)
4809 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4812 [(set (attr "length")
4813 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4814 (set_attr "mode" "HI")
4815 (set_attr "unit" "i387")
4816 (set_attr "athlon_decode" "vector")
4817 (set_attr "amdfam10_decode" "vector")
4818 (set_attr "bdver1_decode" "vector")])
4820 ;; Conversion between fixed point and floating point.
4822 ;; Even though we only accept memory inputs, the backend _really_
4823 ;; wants to be able to do this between registers. Thankfully, LRA
4824 ;; will fix this up for us during register allocation.
4826 (define_insn "floathi<mode>2"
4827 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4828 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4831 || TARGET_MIX_SSE_I387)"
4833 [(set_attr "type" "fmov")
4834 (set_attr "mode" "<MODE>")
4835 (set_attr "fp_int_src" "true")])
4837 (define_insn "float<SWI48x:mode>xf2"
4838 [(set (match_operand:XF 0 "register_operand" "=f")
4839 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4842 [(set_attr "type" "fmov")
4843 (set_attr "mode" "XF")
4844 (set_attr "fp_int_src" "true")])
4846 (define_expand "float<SWI48:mode><MODEF:mode>2"
4847 [(set (match_operand:MODEF 0 "register_operand")
4848 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4849 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4851 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4852 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4854 rtx reg = gen_reg_rtx (XFmode);
4855 rtx (*insn)(rtx, rtx);
4857 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4859 if (<MODEF:MODE>mode == SFmode)
4860 insn = gen_truncxfsf2;
4861 else if (<MODEF:MODE>mode == DFmode)
4862 insn = gen_truncxfdf2;
4866 emit_insn (insn (operands[0], reg));
4871 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4872 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4874 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4875 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4878 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4879 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4880 [(set_attr "type" "fmov,sseicvt,sseicvt")
4881 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4882 (set_attr "mode" "<MODEF:MODE>")
4883 (set (attr "prefix_rex")
4885 (and (eq_attr "prefix" "maybe_vex")
4886 (match_test "<SWI48:MODE>mode == DImode"))
4888 (const_string "*")))
4889 (set_attr "unit" "i387,*,*")
4890 (set_attr "athlon_decode" "*,double,direct")
4891 (set_attr "amdfam10_decode" "*,vector,double")
4892 (set_attr "bdver1_decode" "*,double,direct")
4893 (set_attr "fp_int_src" "true")
4894 (set (attr "enabled")
4895 (cond [(eq_attr "alternative" "0")
4896 (symbol_ref "TARGET_MIX_SSE_I387
4897 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4900 (symbol_ref "true")))
4901 (set (attr "preferred_for_speed")
4902 (cond [(eq_attr "alternative" "1")
4903 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4904 (symbol_ref "true")))])
4906 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4907 [(set (match_operand:MODEF 0 "register_operand" "=f")
4908 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4909 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4911 [(set_attr "type" "fmov")
4912 (set_attr "mode" "<MODEF:MODE>")
4913 (set_attr "fp_int_src" "true")])
4915 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4916 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4917 ;; alternative in sse2_loadld.
4919 [(set (match_operand:MODEF 0 "register_operand")
4920 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4923 && reload_completed && SSE_REG_P (operands[0])
4924 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4927 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4929 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931 emit_insn (gen_sse2_loadld (operands[4],
4932 CONST0_RTX (V4SImode), operands[1]));
4934 if (<ssevecmode>mode == V4SFmode)
4935 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4937 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4941 ;; Avoid partial SSE register dependency stalls
4943 [(set (match_operand:MODEF 0 "register_operand")
4944 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4945 "TARGET_SSE2 && TARGET_SSE_MATH
4946 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4947 && optimize_function_for_speed_p (cfun)
4948 && reload_completed && SSE_REG_P (operands[0])"
4951 const machine_mode vmode = <MODEF:ssevecmode>mode;
4952 const machine_mode mode = <MODEF:MODE>mode;
4953 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4955 emit_move_insn (op0, CONST0_RTX (vmode));
4957 t = gen_rtx_FLOAT (mode, operands[1]);
4958 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4959 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4960 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4964 ;; Break partial reg stall for cvtsd2ss.
4967 [(set (match_operand:SF 0 "register_operand")
4969 (match_operand:DF 1 "nonimmediate_operand")))]
4970 "TARGET_SSE2 && TARGET_SSE_MATH
4971 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4972 && optimize_function_for_speed_p (cfun)
4973 && SSE_REG_P (operands[0])
4974 && (!SSE_REG_P (operands[1])
4975 || REGNO (operands[0]) != REGNO (operands[1]))"
4979 (float_truncate:V2SF
4984 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4986 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4988 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4991 ;; Break partial reg stall for cvtss2sd.
4994 [(set (match_operand:DF 0 "register_operand")
4996 (match_operand:SF 1 "nonimmediate_operand")))]
4997 "TARGET_SSE2 && TARGET_SSE_MATH
4998 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4999 && optimize_function_for_speed_p (cfun)
5000 && SSE_REG_P (operands[0])
5001 && (!SSE_REG_P (operands[1])
5002 || REGNO (operands[0]) != REGNO (operands[1]))"
5008 (parallel [(const_int 0) (const_int 1)])))
5012 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5014 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5016 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5019 ;; Avoid store forwarding (partial memory) stall penalty
5020 ;; by passing DImode value through XMM registers. */
5022 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5023 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5025 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5026 (clobber (match_scratch:V4SI 3 "=X,x"))
5027 (clobber (match_scratch:V4SI 4 "=X,x"))
5028 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5029 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5030 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5031 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5033 [(set_attr "type" "multi")
5034 (set_attr "mode" "<X87MODEF:MODE>")
5035 (set_attr "unit" "i387")
5036 (set_attr "fp_int_src" "true")])
5039 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5040 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5041 (clobber (match_scratch:V4SI 3))
5042 (clobber (match_scratch:V4SI 4))
5043 (clobber (match_operand:DI 2 "memory_operand"))]
5044 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5045 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5046 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5047 && reload_completed"
5048 [(set (match_dup 2) (match_dup 3))
5049 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5051 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5052 Assemble the 64-bit DImode value in an xmm register. */
5053 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5054 gen_lowpart (SImode, operands[1])));
5055 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5056 gen_highpart (SImode, operands[1])));
5057 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5060 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5064 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5065 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5066 (clobber (match_scratch:V4SI 3))
5067 (clobber (match_scratch:V4SI 4))
5068 (clobber (match_operand:DI 2 "memory_operand"))]
5069 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5070 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5071 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5072 && reload_completed"
5073 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5075 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5076 [(set (match_operand:MODEF 0 "register_operand")
5077 (unsigned_float:MODEF
5078 (match_operand:SWI12 1 "nonimmediate_operand")))]
5080 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5082 operands[1] = convert_to_mode (SImode, operands[1], 1);
5083 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5087 ;; Avoid store forwarding (partial memory) stall penalty by extending
5088 ;; SImode value to DImode through XMM register instead of pushing two
5089 ;; SImode values to stack. Also note that fild loads from memory only.
5091 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5092 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5093 (unsigned_float:X87MODEF
5094 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5095 (clobber (match_scratch:DI 3 "=x"))
5096 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5098 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5099 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5101 "&& reload_completed"
5102 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5103 (set (match_dup 2) (match_dup 3))
5105 (float:X87MODEF (match_dup 2)))]
5107 [(set_attr "type" "multi")
5108 (set_attr "mode" "<MODE>")])
5110 (define_expand "floatunssi<mode>2"
5112 [(set (match_operand:X87MODEF 0 "register_operand")
5113 (unsigned_float:X87MODEF
5114 (match_operand:SI 1 "nonimmediate_operand")))
5115 (clobber (match_scratch:DI 3))
5116 (clobber (match_dup 2))])]
5118 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5119 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5120 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5122 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5124 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5128 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5131 (define_expand "floatunsdisf2"
5132 [(use (match_operand:SF 0 "register_operand"))
5133 (use (match_operand:DI 1 "nonimmediate_operand"))]
5134 "TARGET_64BIT && TARGET_SSE_MATH"
5135 "x86_emit_floatuns (operands); DONE;")
5137 (define_expand "floatunsdidf2"
5138 [(use (match_operand:DF 0 "register_operand"))
5139 (use (match_operand:DI 1 "nonimmediate_operand"))]
5140 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5141 && TARGET_SSE2 && TARGET_SSE_MATH"
5144 x86_emit_floatuns (operands);
5146 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5150 ;; Load effective address instructions
5152 (define_insn_and_split "*lea<mode>"
5153 [(set (match_operand:SWI48 0 "register_operand" "=r")
5154 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5157 if (SImode_address_operand (operands[1], VOIDmode))
5159 gcc_assert (TARGET_64BIT);
5160 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5163 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5165 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5168 machine_mode mode = <MODE>mode;
5171 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5172 change operands[] array behind our back. */
5173 pat = PATTERN (curr_insn);
5175 operands[0] = SET_DEST (pat);
5176 operands[1] = SET_SRC (pat);
5178 /* Emit all operations in SImode for zero-extended addresses. */
5179 if (SImode_address_operand (operands[1], VOIDmode))
5182 ix86_split_lea_for_addr (curr_insn, operands, mode);
5184 /* Zero-extend return register to DImode for zero-extended addresses. */
5185 if (mode != <MODE>mode)
5186 emit_insn (gen_zero_extendsidi2
5187 (operands[0], gen_lowpart (mode, operands[0])));
5191 [(set_attr "type" "lea")
5194 (match_operand 1 "SImode_address_operand")
5196 (const_string "<MODE>")))])
5200 (define_expand "add<mode>3"
5201 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5202 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5203 (match_operand:SDWIM 2 "<general_operand>")))]
5205 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5207 (define_insn_and_split "*add<dwi>3_doubleword"
5208 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5210 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5211 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5212 (clobber (reg:CC FLAGS_REG))]
5213 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5216 [(parallel [(set (reg:CCC FLAGS_REG)
5218 (plus:DWIH (match_dup 1) (match_dup 2))
5221 (plus:DWIH (match_dup 1) (match_dup 2)))])
5222 (parallel [(set (match_dup 3)
5225 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5228 (clobber (reg:CC FLAGS_REG))])]
5229 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5231 (define_insn "*add<mode>_1"
5232 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5234 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5235 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5236 (clobber (reg:CC FLAGS_REG))]
5237 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5239 switch (get_attr_type (insn))
5245 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5246 if (operands[2] == const1_rtx)
5247 return "inc{<imodesuffix>}\t%0";
5250 gcc_assert (operands[2] == constm1_rtx);
5251 return "dec{<imodesuffix>}\t%0";
5255 /* For most processors, ADD is faster than LEA. This alternative
5256 was added to use ADD as much as possible. */
5257 if (which_alternative == 2)
5258 std::swap (operands[1], operands[2]);
5260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5262 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5264 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5268 (cond [(eq_attr "alternative" "3")
5269 (const_string "lea")
5270 (match_operand:SWI48 2 "incdec_operand")
5271 (const_string "incdec")
5273 (const_string "alu")))
5274 (set (attr "length_immediate")
5276 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5278 (const_string "*")))
5279 (set_attr "mode" "<MODE>")])
5281 ;; It may seem that nonimmediate operand is proper one for operand 1.
5282 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5283 ;; we take care in ix86_binary_operator_ok to not allow two memory
5284 ;; operands so proper swapping will be done in reload. This allow
5285 ;; patterns constructed from addsi_1 to match.
5287 (define_insn "addsi_1_zext"
5288 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5290 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5291 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5292 (clobber (reg:CC FLAGS_REG))]
5293 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5295 switch (get_attr_type (insn))
5301 if (operands[2] == const1_rtx)
5302 return "inc{l}\t%k0";
5305 gcc_assert (operands[2] == constm1_rtx);
5306 return "dec{l}\t%k0";
5310 /* For most processors, ADD is faster than LEA. This alternative
5311 was added to use ADD as much as possible. */
5312 if (which_alternative == 1)
5313 std::swap (operands[1], operands[2]);
5315 if (x86_maybe_negate_const_int (&operands[2], SImode))
5316 return "sub{l}\t{%2, %k0|%k0, %2}";
5318 return "add{l}\t{%2, %k0|%k0, %2}";
5322 (cond [(eq_attr "alternative" "2")
5323 (const_string "lea")
5324 (match_operand:SI 2 "incdec_operand")
5325 (const_string "incdec")
5327 (const_string "alu")))
5328 (set (attr "length_immediate")
5330 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5332 (const_string "*")))
5333 (set_attr "mode" "SI")])
5335 (define_insn "*addhi_1"
5336 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5337 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5338 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5339 (clobber (reg:CC FLAGS_REG))]
5340 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5342 switch (get_attr_type (insn))
5348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349 if (operands[2] == const1_rtx)
5350 return "inc{w}\t%0";
5353 gcc_assert (operands[2] == constm1_rtx);
5354 return "dec{w}\t%0";
5358 /* For most processors, ADD is faster than LEA. This alternative
5359 was added to use ADD as much as possible. */
5360 if (which_alternative == 2)
5361 std::swap (operands[1], operands[2]);
5363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364 if (x86_maybe_negate_const_int (&operands[2], HImode))
5365 return "sub{w}\t{%2, %0|%0, %2}";
5367 return "add{w}\t{%2, %0|%0, %2}";
5371 (cond [(eq_attr "alternative" "3")
5372 (const_string "lea")
5373 (match_operand:HI 2 "incdec_operand")
5374 (const_string "incdec")
5376 (const_string "alu")))
5377 (set (attr "length_immediate")
5379 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5381 (const_string "*")))
5382 (set_attr "mode" "HI,HI,HI,SI")])
5384 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5385 (define_insn "*addqi_1"
5386 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5387 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5388 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5389 (clobber (reg:CC FLAGS_REG))]
5390 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5392 bool widen = (which_alternative == 3 || which_alternative == 4);
5394 switch (get_attr_type (insn))
5400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401 if (operands[2] == const1_rtx)
5402 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5405 gcc_assert (operands[2] == constm1_rtx);
5406 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5410 /* For most processors, ADD is faster than LEA. These alternatives
5411 were added to use ADD as much as possible. */
5412 if (which_alternative == 2 || which_alternative == 4)
5413 std::swap (operands[1], operands[2]);
5415 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5416 if (x86_maybe_negate_const_int (&operands[2], QImode))
5419 return "sub{l}\t{%2, %k0|%k0, %2}";
5421 return "sub{b}\t{%2, %0|%0, %2}";
5424 return "add{l}\t{%k2, %k0|%k0, %k2}";
5426 return "add{b}\t{%2, %0|%0, %2}";
5430 (cond [(eq_attr "alternative" "5")
5431 (const_string "lea")
5432 (match_operand:QI 2 "incdec_operand")
5433 (const_string "incdec")
5435 (const_string "alu")))
5436 (set (attr "length_immediate")
5438 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5440 (const_string "*")))
5441 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5443 (define_insn "*addqi_1_slp"
5444 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5445 (plus:QI (match_dup 0)
5446 (match_operand:QI 1 "general_operand" "qn,qm")))
5447 (clobber (reg:CC FLAGS_REG))]
5448 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5451 switch (get_attr_type (insn))
5454 if (operands[1] == const1_rtx)
5455 return "inc{b}\t%0";
5458 gcc_assert (operands[1] == constm1_rtx);
5459 return "dec{b}\t%0";
5463 if (x86_maybe_negate_const_int (&operands[1], QImode))
5464 return "sub{b}\t{%1, %0|%0, %1}";
5466 return "add{b}\t{%1, %0|%0, %1}";
5470 (if_then_else (match_operand:QI 1 "incdec_operand")
5471 (const_string "incdec")
5472 (const_string "alu1")))
5473 (set (attr "memory")
5474 (if_then_else (match_operand 1 "memory_operand")
5475 (const_string "load")
5476 (const_string "none")))
5477 (set_attr "mode" "QI")])
5479 ;; Split non destructive adds if we cannot use lea.
5481 [(set (match_operand:SWI48 0 "register_operand")
5482 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5483 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5484 (clobber (reg:CC FLAGS_REG))]
5485 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5486 [(set (match_dup 0) (match_dup 1))
5487 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5488 (clobber (reg:CC FLAGS_REG))])])
5490 ;; Convert add to the lea pattern to avoid flags dependency.
5492 [(set (match_operand:SWI 0 "register_operand")
5493 (plus:SWI (match_operand:SWI 1 "register_operand")
5494 (match_operand:SWI 2 "<nonmemory_operand>")))
5495 (clobber (reg:CC FLAGS_REG))]
5496 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5499 machine_mode mode = <MODE>mode;
5502 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5505 operands[0] = gen_lowpart (mode, operands[0]);
5506 operands[1] = gen_lowpart (mode, operands[1]);
5507 operands[2] = gen_lowpart (mode, operands[2]);
5510 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5512 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5516 ;; Split non destructive adds if we cannot use lea.
5518 [(set (match_operand:DI 0 "register_operand")
5520 (plus:SI (match_operand:SI 1 "register_operand")
5521 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5522 (clobber (reg:CC FLAGS_REG))]
5524 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5525 [(set (match_dup 3) (match_dup 1))
5526 (parallel [(set (match_dup 0)
5527 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5528 (clobber (reg:CC FLAGS_REG))])]
5529 "operands[3] = gen_lowpart (SImode, operands[0]);")
5531 ;; Convert add to the lea pattern to avoid flags dependency.
5533 [(set (match_operand:DI 0 "register_operand")
5535 (plus:SI (match_operand:SI 1 "register_operand")
5536 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5537 (clobber (reg:CC FLAGS_REG))]
5538 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5540 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5542 (define_insn "*add<mode>_2"
5543 [(set (reg FLAGS_REG)
5546 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5547 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5549 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5550 (plus:SWI (match_dup 1) (match_dup 2)))]
5551 "ix86_match_ccmode (insn, CCGOCmode)
5552 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5554 switch (get_attr_type (insn))
5557 if (operands[2] == const1_rtx)
5558 return "inc{<imodesuffix>}\t%0";
5561 gcc_assert (operands[2] == constm1_rtx);
5562 return "dec{<imodesuffix>}\t%0";
5566 if (which_alternative == 2)
5567 std::swap (operands[1], operands[2]);
5569 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5570 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5571 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5573 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5577 (if_then_else (match_operand:SWI 2 "incdec_operand")
5578 (const_string "incdec")
5579 (const_string "alu")))
5580 (set (attr "length_immediate")
5582 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5584 (const_string "*")))
5585 (set_attr "mode" "<MODE>")])
5587 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5588 (define_insn "*addsi_2_zext"
5589 [(set (reg FLAGS_REG)
5591 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5592 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5594 (set (match_operand:DI 0 "register_operand" "=r,r")
5595 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5596 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5597 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5599 switch (get_attr_type (insn))
5602 if (operands[2] == const1_rtx)
5603 return "inc{l}\t%k0";
5606 gcc_assert (operands[2] == constm1_rtx);
5607 return "dec{l}\t%k0";
5611 if (which_alternative == 1)
5612 std::swap (operands[1], operands[2]);
5614 if (x86_maybe_negate_const_int (&operands[2], SImode))
5615 return "sub{l}\t{%2, %k0|%k0, %2}";
5617 return "add{l}\t{%2, %k0|%k0, %2}";
5621 (if_then_else (match_operand:SI 2 "incdec_operand")
5622 (const_string "incdec")
5623 (const_string "alu")))
5624 (set (attr "length_immediate")
5626 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5628 (const_string "*")))
5629 (set_attr "mode" "SI")])
5631 (define_insn "*add<mode>_3"
5632 [(set (reg FLAGS_REG)
5634 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5635 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5636 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5637 "ix86_match_ccmode (insn, CCZmode)
5638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5640 switch (get_attr_type (insn))
5643 if (operands[2] == const1_rtx)
5644 return "inc{<imodesuffix>}\t%0";
5647 gcc_assert (operands[2] == constm1_rtx);
5648 return "dec{<imodesuffix>}\t%0";
5652 if (which_alternative == 1)
5653 std::swap (operands[1], operands[2]);
5655 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5656 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5657 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5659 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5663 (if_then_else (match_operand:SWI 2 "incdec_operand")
5664 (const_string "incdec")
5665 (const_string "alu")))
5666 (set (attr "length_immediate")
5668 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5670 (const_string "*")))
5671 (set_attr "mode" "<MODE>")])
5673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5674 (define_insn "*addsi_3_zext"
5675 [(set (reg FLAGS_REG)
5677 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5678 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5679 (set (match_operand:DI 0 "register_operand" "=r,r")
5680 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5681 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5682 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5684 switch (get_attr_type (insn))
5687 if (operands[2] == const1_rtx)
5688 return "inc{l}\t%k0";
5691 gcc_assert (operands[2] == constm1_rtx);
5692 return "dec{l}\t%k0";
5696 if (which_alternative == 1)
5697 std::swap (operands[1], operands[2]);
5699 if (x86_maybe_negate_const_int (&operands[2], SImode))
5700 return "sub{l}\t{%2, %k0|%k0, %2}";
5702 return "add{l}\t{%2, %k0|%k0, %2}";
5706 (if_then_else (match_operand:SI 2 "incdec_operand")
5707 (const_string "incdec")
5708 (const_string "alu")))
5709 (set (attr "length_immediate")
5711 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5713 (const_string "*")))
5714 (set_attr "mode" "SI")])
5716 ; For comparisons against 1, -1 and 128, we may generate better code
5717 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5718 ; is matched then. We can't accept general immediate, because for
5719 ; case of overflows, the result is messed up.
5720 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5721 ; only for comparisons not depending on it.
5723 (define_insn "*adddi_4"
5724 [(set (reg FLAGS_REG)
5726 (match_operand:DI 1 "nonimmediate_operand" "0")
5727 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5728 (clobber (match_scratch:DI 0 "=rm"))]
5730 && ix86_match_ccmode (insn, CCGCmode)"
5732 switch (get_attr_type (insn))
5735 if (operands[2] == constm1_rtx)
5736 return "inc{q}\t%0";
5739 gcc_assert (operands[2] == const1_rtx);
5740 return "dec{q}\t%0";
5744 if (x86_maybe_negate_const_int (&operands[2], DImode))
5745 return "add{q}\t{%2, %0|%0, %2}";
5747 return "sub{q}\t{%2, %0|%0, %2}";
5751 (if_then_else (match_operand:DI 2 "incdec_operand")
5752 (const_string "incdec")
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5758 (const_string "*")))
5759 (set_attr "mode" "DI")])
5761 ; For comparisons against 1, -1 and 128, we may generate better code
5762 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5763 ; is matched then. We can't accept general immediate, because for
5764 ; case of overflows, the result is messed up.
5765 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5766 ; only for comparisons not depending on it.
5768 (define_insn "*add<mode>_4"
5769 [(set (reg FLAGS_REG)
5771 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5772 (match_operand:SWI124 2 "const_int_operand" "n")))
5773 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5774 "ix86_match_ccmode (insn, CCGCmode)"
5776 switch (get_attr_type (insn))
5779 if (operands[2] == constm1_rtx)
5780 return "inc{<imodesuffix>}\t%0";
5783 gcc_assert (operands[2] == const1_rtx);
5784 return "dec{<imodesuffix>}\t%0";
5788 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5789 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5791 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5795 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5796 (const_string "incdec")
5797 (const_string "alu")))
5798 (set (attr "length_immediate")
5800 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5802 (const_string "*")))
5803 (set_attr "mode" "<MODE>")])
5805 (define_insn "*add<mode>_5"
5806 [(set (reg FLAGS_REG)
5809 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5810 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5812 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5813 "ix86_match_ccmode (insn, CCGOCmode)
5814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5816 switch (get_attr_type (insn))
5819 if (operands[2] == const1_rtx)
5820 return "inc{<imodesuffix>}\t%0";
5823 gcc_assert (operands[2] == constm1_rtx);
5824 return "dec{<imodesuffix>}\t%0";
5828 if (which_alternative == 1)
5829 std::swap (operands[1], operands[2]);
5831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5832 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5833 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5835 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5839 (if_then_else (match_operand:SWI 2 "incdec_operand")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set (attr "length_immediate")
5844 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5846 (const_string "*")))
5847 (set_attr "mode" "<MODE>")])
5849 (define_insn "addqi_ext_1"
5850 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5855 (match_operand 1 "ext_register_operand" "0,0")
5858 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5859 (clobber (reg:CC FLAGS_REG))]
5862 switch (get_attr_type (insn))
5865 if (operands[2] == const1_rtx)
5866 return "inc{b}\t%h0";
5869 gcc_assert (operands[2] == constm1_rtx);
5870 return "dec{b}\t%h0";
5874 return "add{b}\t{%2, %h0|%h0, %2}";
5877 [(set_attr "isa" "*,nox64")
5879 (if_then_else (match_operand:QI 2 "incdec_operand")
5880 (const_string "incdec")
5881 (const_string "alu")))
5882 (set_attr "modrm" "1")
5883 (set_attr "mode" "QI")])
5885 (define_insn "*addqi_ext_2"
5886 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5891 (match_operand 1 "ext_register_operand" "%0")
5895 (match_operand 2 "ext_register_operand" "Q")
5898 (clobber (reg:CC FLAGS_REG))]
5900 "add{b}\t{%h2, %h0|%h0, %h2}"
5901 [(set_attr "type" "alu")
5902 (set_attr "mode" "QI")])
5904 ;; Add with jump on overflow.
5905 (define_expand "addv<mode>4"
5906 [(parallel [(set (reg:CCO FLAGS_REG)
5909 (match_operand:SWI 1 "nonimmediate_operand"))
5912 (plus:SWI (match_dup 1)
5913 (match_operand:SWI 2
5914 "<general_operand>")))))
5915 (set (match_operand:SWI 0 "register_operand")
5916 (plus:SWI (match_dup 1) (match_dup 2)))])
5917 (set (pc) (if_then_else
5918 (eq (reg:CCO FLAGS_REG) (const_int 0))
5919 (label_ref (match_operand 3))
5923 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5924 if (CONST_INT_P (operands[2]))
5925 operands[4] = operands[2];
5927 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5930 (define_insn "*addv<mode>4"
5931 [(set (reg:CCO FLAGS_REG)
5934 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5936 (match_operand:SWI 2 "<general_sext_operand>"
5939 (plus:SWI (match_dup 1) (match_dup 2)))))
5940 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5941 (plus:SWI (match_dup 1) (match_dup 2)))]
5942 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5943 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5944 [(set_attr "type" "alu")
5945 (set_attr "mode" "<MODE>")])
5947 (define_insn "*addv<mode>4_1"
5948 [(set (reg:CCO FLAGS_REG)
5951 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5952 (match_operand:<DWI> 3 "const_int_operand" "i"))
5954 (plus:SWI (match_dup 1)
5955 (match_operand:SWI 2 "x86_64_immediate_operand"
5957 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5958 (plus:SWI (match_dup 1) (match_dup 2)))]
5959 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5960 && CONST_INT_P (operands[2])
5961 && INTVAL (operands[2]) == INTVAL (operands[3])"
5962 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5963 [(set_attr "type" "alu")
5964 (set_attr "mode" "<MODE>")
5965 (set (attr "length_immediate")
5966 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5968 (match_test "<MODE_SIZE> == 8")
5970 (const_string "<MODE_SIZE>")))])
5972 ;; The lea patterns for modes less than 32 bits need to be matched by
5973 ;; several insns converted to real lea by splitters.
5975 (define_insn_and_split "*lea_general_1"
5976 [(set (match_operand 0 "register_operand" "=r")
5977 (plus (plus (match_operand 1 "index_register_operand" "l")
5978 (match_operand 2 "register_operand" "r"))
5979 (match_operand 3 "immediate_operand" "i")))]
5980 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5981 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5982 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5983 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5984 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5985 || GET_MODE (operands[3]) == VOIDmode)"
5987 "&& reload_completed"
5990 machine_mode mode = SImode;
5993 operands[0] = gen_lowpart (mode, operands[0]);
5994 operands[1] = gen_lowpart (mode, operands[1]);
5995 operands[2] = gen_lowpart (mode, operands[2]);
5996 operands[3] = gen_lowpart (mode, operands[3]);
5998 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6004 [(set_attr "type" "lea")
6005 (set_attr "mode" "SI")])
6007 (define_insn_and_split "*lea_general_2"
6008 [(set (match_operand 0 "register_operand" "=r")
6009 (plus (mult (match_operand 1 "index_register_operand" "l")
6010 (match_operand 2 "const248_operand" "n"))
6011 (match_operand 3 "nonmemory_operand" "ri")))]
6012 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6013 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6014 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6015 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6016 || GET_MODE (operands[3]) == VOIDmode)"
6018 "&& reload_completed"
6021 machine_mode mode = SImode;
6024 operands[0] = gen_lowpart (mode, operands[0]);
6025 operands[1] = gen_lowpart (mode, operands[1]);
6026 operands[3] = gen_lowpart (mode, operands[3]);
6028 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6031 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6034 [(set_attr "type" "lea")
6035 (set_attr "mode" "SI")])
6037 (define_insn_and_split "*lea_general_3"
6038 [(set (match_operand 0 "register_operand" "=r")
6039 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6040 (match_operand 2 "const248_operand" "n"))
6041 (match_operand 3 "register_operand" "r"))
6042 (match_operand 4 "immediate_operand" "i")))]
6043 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6044 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6045 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6046 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6048 "&& reload_completed"
6051 machine_mode mode = SImode;
6054 operands[0] = gen_lowpart (mode, operands[0]);
6055 operands[1] = gen_lowpart (mode, operands[1]);
6056 operands[3] = gen_lowpart (mode, operands[3]);
6057 operands[4] = gen_lowpart (mode, operands[4]);
6059 pat = gen_rtx_PLUS (mode,
6061 gen_rtx_MULT (mode, operands[1],
6066 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6069 [(set_attr "type" "lea")
6070 (set_attr "mode" "SI")])
6072 (define_insn_and_split "*lea_general_4"
6073 [(set (match_operand 0 "register_operand" "=r")
6075 (match_operand 1 "index_register_operand" "l")
6076 (match_operand 2 "const_int_operand" "n"))
6077 (match_operand 3 "const_int_operand" "n")))]
6078 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6079 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6080 || GET_MODE (operands[0]) == SImode
6081 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6082 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6083 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6084 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6085 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6087 "&& reload_completed"
6090 machine_mode mode = GET_MODE (operands[0]);
6093 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6096 operands[0] = gen_lowpart (mode, operands[0]);
6097 operands[1] = gen_lowpart (mode, operands[1]);
6100 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6102 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6103 INTVAL (operands[3]));
6105 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6108 [(set_attr "type" "lea")
6110 (if_then_else (match_operand:DI 0)
6112 (const_string "SI")))])
6114 ;; Subtract instructions
6116 (define_expand "sub<mode>3"
6117 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6118 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6119 (match_operand:SDWIM 2 "<general_operand>")))]
6121 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6123 (define_insn_and_split "*sub<dwi>3_doubleword"
6124 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6126 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6127 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6128 (clobber (reg:CC FLAGS_REG))]
6129 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6132 [(parallel [(set (reg:CC FLAGS_REG)
6133 (compare:CC (match_dup 1) (match_dup 2)))
6135 (minus:DWIH (match_dup 1) (match_dup 2)))])
6136 (parallel [(set (match_dup 3)
6140 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6142 (clobber (reg:CC FLAGS_REG))])]
6143 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6145 (define_insn "*sub<mode>_1"
6146 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6148 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6149 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6150 (clobber (reg:CC FLAGS_REG))]
6151 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6152 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6153 [(set_attr "type" "alu")
6154 (set_attr "mode" "<MODE>")])
6156 (define_insn "*subsi_1_zext"
6157 [(set (match_operand:DI 0 "register_operand" "=r")
6159 (minus:SI (match_operand:SI 1 "register_operand" "0")
6160 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6161 (clobber (reg:CC FLAGS_REG))]
6162 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6163 "sub{l}\t{%2, %k0|%k0, %2}"
6164 [(set_attr "type" "alu")
6165 (set_attr "mode" "SI")])
6167 (define_insn "*subqi_1_slp"
6168 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6169 (minus:QI (match_dup 0)
6170 (match_operand:QI 1 "general_operand" "qn,qm")))
6171 (clobber (reg:CC FLAGS_REG))]
6172 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6174 "sub{b}\t{%1, %0|%0, %1}"
6175 [(set_attr "type" "alu1")
6176 (set_attr "mode" "QI")])
6178 (define_insn "*sub<mode>_2"
6179 [(set (reg FLAGS_REG)
6182 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6183 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6185 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6186 (minus:SWI (match_dup 1) (match_dup 2)))]
6187 "ix86_match_ccmode (insn, CCGOCmode)
6188 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6189 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6190 [(set_attr "type" "alu")
6191 (set_attr "mode" "<MODE>")])
6193 (define_insn "*subsi_2_zext"
6194 [(set (reg FLAGS_REG)
6196 (minus:SI (match_operand:SI 1 "register_operand" "0")
6197 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6199 (set (match_operand:DI 0 "register_operand" "=r")
6201 (minus:SI (match_dup 1)
6203 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6204 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6205 "sub{l}\t{%2, %k0|%k0, %2}"
6206 [(set_attr "type" "alu")
6207 (set_attr "mode" "SI")])
6209 ;; Subtract with jump on overflow.
6210 (define_expand "subv<mode>4"
6211 [(parallel [(set (reg:CCO FLAGS_REG)
6212 (eq:CCO (minus:<DWI>
6214 (match_operand:SWI 1 "nonimmediate_operand"))
6217 (minus:SWI (match_dup 1)
6218 (match_operand:SWI 2
6219 "<general_operand>")))))
6220 (set (match_operand:SWI 0 "register_operand")
6221 (minus:SWI (match_dup 1) (match_dup 2)))])
6222 (set (pc) (if_then_else
6223 (eq (reg:CCO FLAGS_REG) (const_int 0))
6224 (label_ref (match_operand 3))
6228 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6229 if (CONST_INT_P (operands[2]))
6230 operands[4] = operands[2];
6232 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6235 (define_insn "*subv<mode>4"
6236 [(set (reg:CCO FLAGS_REG)
6237 (eq:CCO (minus:<DWI>
6239 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6241 (match_operand:SWI 2 "<general_sext_operand>"
6244 (minus:SWI (match_dup 1) (match_dup 2)))))
6245 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6246 (minus:SWI (match_dup 1) (match_dup 2)))]
6247 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6248 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6249 [(set_attr "type" "alu")
6250 (set_attr "mode" "<MODE>")])
6252 (define_insn "*subv<mode>4_1"
6253 [(set (reg:CCO FLAGS_REG)
6254 (eq:CCO (minus:<DWI>
6256 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6257 (match_operand:<DWI> 3 "const_int_operand" "i"))
6259 (minus:SWI (match_dup 1)
6260 (match_operand:SWI 2 "x86_64_immediate_operand"
6262 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6263 (minus:SWI (match_dup 1) (match_dup 2)))]
6264 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6265 && CONST_INT_P (operands[2])
6266 && INTVAL (operands[2]) == INTVAL (operands[3])"
6267 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6268 [(set_attr "type" "alu")
6269 (set_attr "mode" "<MODE>")
6270 (set (attr "length_immediate")
6271 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6273 (match_test "<MODE_SIZE> == 8")
6275 (const_string "<MODE_SIZE>")))])
6277 (define_insn "*sub<mode>_3"
6278 [(set (reg FLAGS_REG)
6279 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6280 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6281 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6282 (minus:SWI (match_dup 1) (match_dup 2)))]
6283 "ix86_match_ccmode (insn, CCmode)
6284 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6285 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6286 [(set_attr "type" "alu")
6287 (set_attr "mode" "<MODE>")])
6289 (define_insn "*subsi_3_zext"
6290 [(set (reg FLAGS_REG)
6291 (compare (match_operand:SI 1 "register_operand" "0")
6292 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6293 (set (match_operand:DI 0 "register_operand" "=r")
6295 (minus:SI (match_dup 1)
6297 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6298 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6299 "sub{l}\t{%2, %1|%1, %2}"
6300 [(set_attr "type" "alu")
6301 (set_attr "mode" "SI")])
6303 ;; Add with carry and subtract with borrow
6305 (define_insn "add<mode>3_carry"
6306 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6309 (match_operator:SWI 4 "ix86_carry_flag_operator"
6310 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6311 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6312 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6313 (clobber (reg:CC FLAGS_REG))]
6314 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6315 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6316 [(set_attr "type" "alu")
6317 (set_attr "use_carry" "1")
6318 (set_attr "pent_pair" "pu")
6319 (set_attr "mode" "<MODE>")])
6321 (define_insn "*addsi3_carry_zext"
6322 [(set (match_operand:DI 0 "register_operand" "=r")
6325 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6326 [(reg FLAGS_REG) (const_int 0)])
6327 (match_operand:SI 1 "register_operand" "%0"))
6328 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6329 (clobber (reg:CC FLAGS_REG))]
6330 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6331 "adc{l}\t{%2, %k0|%k0, %2}"
6332 [(set_attr "type" "alu")
6333 (set_attr "use_carry" "1")
6334 (set_attr "pent_pair" "pu")
6335 (set_attr "mode" "SI")])
6337 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6339 (define_insn "addcarry<mode>"
6340 [(set (reg:CCC FLAGS_REG)
6344 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6345 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6346 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6347 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6349 (set (match_operand:SWI48 0 "register_operand" "=r")
6350 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6351 [(match_dup 3) (const_int 0)])
6354 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6355 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6356 [(set_attr "type" "alu")
6357 (set_attr "use_carry" "1")
6358 (set_attr "pent_pair" "pu")
6359 (set_attr "mode" "<MODE>")])
6361 (define_insn "sub<mode>3_carry"
6362 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6365 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6366 (match_operator:SWI 4 "ix86_carry_flag_operator"
6367 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6368 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6369 (clobber (reg:CC FLAGS_REG))]
6370 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6371 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6372 [(set_attr "type" "alu")
6373 (set_attr "use_carry" "1")
6374 (set_attr "pent_pair" "pu")
6375 (set_attr "mode" "<MODE>")])
6377 (define_insn "*subsi3_carry_zext"
6378 [(set (match_operand:DI 0 "register_operand" "=r")
6382 (match_operand:SI 1 "register_operand" "0")
6383 (match_operator:SI 3 "ix86_carry_flag_operator"
6384 [(reg FLAGS_REG) (const_int 0)]))
6385 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6386 (clobber (reg:CC FLAGS_REG))]
6387 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6388 "sbb{l}\t{%2, %k0|%k0, %2}"
6389 [(set_attr "type" "alu")
6390 (set_attr "use_carry" "1")
6391 (set_attr "pent_pair" "pu")
6392 (set_attr "mode" "SI")])
6394 (define_insn "subborrow<mode>"
6395 [(set (reg:CCC FLAGS_REG)
6397 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6399 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6400 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6401 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6402 (set (match_operand:SWI48 0 "register_operand" "=r")
6403 (minus:SWI48 (minus:SWI48 (match_dup 1)
6405 [(match_dup 3) (const_int 0)]))
6407 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6408 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6409 [(set_attr "type" "alu")
6410 (set_attr "use_carry" "1")
6411 (set_attr "pent_pair" "pu")
6412 (set_attr "mode" "<MODE>")])
6414 ;; Overflow setting add instructions
6416 (define_expand "addqi3_cconly_overflow"
6418 [(set (reg:CCC FLAGS_REG)
6421 (match_operand:QI 0 "nonimmediate_operand")
6422 (match_operand:QI 1 "general_operand"))
6424 (clobber (match_scratch:QI 2))])]
6425 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6427 (define_insn "*add<mode>3_cconly_overflow"
6428 [(set (reg:CCC FLAGS_REG)
6431 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6432 (match_operand:SWI 2 "<general_operand>" "<g>"))
6434 (clobber (match_scratch:SWI 0 "=<r>"))]
6435 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6436 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "<MODE>")])
6440 (define_insn "*add<mode>3_cc_overflow"
6441 [(set (reg:CCC FLAGS_REG)
6444 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6445 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6447 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448 (plus:SWI (match_dup 1) (match_dup 2)))]
6449 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6450 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "<MODE>")])
6454 (define_insn "*addsi3_zext_cc_overflow"
6455 [(set (reg:CCC FLAGS_REG)
6458 (match_operand:SI 1 "nonimmediate_operand" "%0")
6459 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6461 (set (match_operand:DI 0 "register_operand" "=r")
6462 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6463 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6464 "add{l}\t{%2, %k0|%k0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "mode" "SI")])
6468 ;; The patterns that match these are at the end of this file.
6470 (define_expand "<plusminus_insn>xf3"
6471 [(set (match_operand:XF 0 "register_operand")
6473 (match_operand:XF 1 "register_operand")
6474 (match_operand:XF 2 "register_operand")))]
6477 (define_expand "<plusminus_insn><mode>3"
6478 [(set (match_operand:MODEF 0 "register_operand")
6480 (match_operand:MODEF 1 "register_operand")
6481 (match_operand:MODEF 2 "nonimmediate_operand")))]
6482 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6483 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6485 ;; Multiply instructions
6487 (define_expand "mul<mode>3"
6488 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6490 (match_operand:SWIM248 1 "register_operand")
6491 (match_operand:SWIM248 2 "<general_operand>")))
6492 (clobber (reg:CC FLAGS_REG))])])
6494 (define_expand "mulqi3"
6495 [(parallel [(set (match_operand:QI 0 "register_operand")
6497 (match_operand:QI 1 "register_operand")
6498 (match_operand:QI 2 "nonimmediate_operand")))
6499 (clobber (reg:CC FLAGS_REG))])]
6500 "TARGET_QIMODE_MATH")
6503 ;; IMUL reg32/64, reg32/64, imm8 Direct
6504 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6505 ;; IMUL reg32/64, reg32/64, imm32 Direct
6506 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6507 ;; IMUL reg32/64, reg32/64 Direct
6508 ;; IMUL reg32/64, mem32/64 Direct
6510 ;; On BDVER1, all above IMULs use DirectPath
6512 (define_insn "*mul<mode>3_1"
6513 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6515 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6516 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6517 (clobber (reg:CC FLAGS_REG))]
6518 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6520 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6521 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6522 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6523 [(set_attr "type" "imul")
6524 (set_attr "prefix_0f" "0,0,1")
6525 (set (attr "athlon_decode")
6526 (cond [(eq_attr "cpu" "athlon")
6527 (const_string "vector")
6528 (eq_attr "alternative" "1")
6529 (const_string "vector")
6530 (and (eq_attr "alternative" "2")
6531 (match_operand 1 "memory_operand"))
6532 (const_string "vector")]
6533 (const_string "direct")))
6534 (set (attr "amdfam10_decode")
6535 (cond [(and (eq_attr "alternative" "0,1")
6536 (match_operand 1 "memory_operand"))
6537 (const_string "vector")]
6538 (const_string "direct")))
6539 (set_attr "bdver1_decode" "direct")
6540 (set_attr "mode" "<MODE>")])
6542 (define_insn "*mulsi3_1_zext"
6543 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6545 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6546 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6547 (clobber (reg:CC FLAGS_REG))]
6549 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6551 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6552 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6553 imul{l}\t{%2, %k0|%k0, %2}"
6554 [(set_attr "type" "imul")
6555 (set_attr "prefix_0f" "0,0,1")
6556 (set (attr "athlon_decode")
6557 (cond [(eq_attr "cpu" "athlon")
6558 (const_string "vector")
6559 (eq_attr "alternative" "1")
6560 (const_string "vector")
6561 (and (eq_attr "alternative" "2")
6562 (match_operand 1 "memory_operand"))
6563 (const_string "vector")]
6564 (const_string "direct")))
6565 (set (attr "amdfam10_decode")
6566 (cond [(and (eq_attr "alternative" "0,1")
6567 (match_operand 1 "memory_operand"))
6568 (const_string "vector")]
6569 (const_string "direct")))
6570 (set_attr "bdver1_decode" "direct")
6571 (set_attr "mode" "SI")])
6574 ;; IMUL reg16, reg16, imm8 VectorPath
6575 ;; IMUL reg16, mem16, imm8 VectorPath
6576 ;; IMUL reg16, reg16, imm16 VectorPath
6577 ;; IMUL reg16, mem16, imm16 VectorPath
6578 ;; IMUL reg16, reg16 Direct
6579 ;; IMUL reg16, mem16 Direct
6581 ;; On BDVER1, all HI MULs use DoublePath
6583 (define_insn "*mulhi3_1"
6584 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6585 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6586 (match_operand:HI 2 "general_operand" "K,n,mr")))
6587 (clobber (reg:CC FLAGS_REG))]
6589 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6591 imul{w}\t{%2, %1, %0|%0, %1, %2}
6592 imul{w}\t{%2, %1, %0|%0, %1, %2}
6593 imul{w}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "imul")
6595 (set_attr "prefix_0f" "0,0,1")
6596 (set (attr "athlon_decode")
6597 (cond [(eq_attr "cpu" "athlon")
6598 (const_string "vector")
6599 (eq_attr "alternative" "1,2")
6600 (const_string "vector")]
6601 (const_string "direct")))
6602 (set (attr "amdfam10_decode")
6603 (cond [(eq_attr "alternative" "0,1")
6604 (const_string "vector")]
6605 (const_string "direct")))
6606 (set_attr "bdver1_decode" "double")
6607 (set_attr "mode" "HI")])
6609 ;;On AMDFAM10 and BDVER1
6613 (define_insn "*mulqi3_1"
6614 [(set (match_operand:QI 0 "register_operand" "=a")
6615 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6616 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6617 (clobber (reg:CC FLAGS_REG))]
6619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621 [(set_attr "type" "imul")
6622 (set_attr "length_immediate" "0")
6623 (set (attr "athlon_decode")
6624 (if_then_else (eq_attr "cpu" "athlon")
6625 (const_string "vector")
6626 (const_string "direct")))
6627 (set_attr "amdfam10_decode" "direct")
6628 (set_attr "bdver1_decode" "direct")
6629 (set_attr "mode" "QI")])
6631 ;; Multiply with jump on overflow.
6632 (define_expand "mulv<mode>4"
6633 [(parallel [(set (reg:CCO FLAGS_REG)
6636 (match_operand:SWI48 1 "register_operand"))
6639 (mult:SWI48 (match_dup 1)
6640 (match_operand:SWI48 2
6641 "<general_operand>")))))
6642 (set (match_operand:SWI48 0 "register_operand")
6643 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6644 (set (pc) (if_then_else
6645 (eq (reg:CCO FLAGS_REG) (const_int 0))
6646 (label_ref (match_operand 3))
6650 if (CONST_INT_P (operands[2]))
6651 operands[4] = operands[2];
6653 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6656 (define_insn "*mulv<mode>4"
6657 [(set (reg:CCO FLAGS_REG)
6660 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6662 (match_operand:SWI48 2 "<general_sext_operand>"
6665 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6666 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6667 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6668 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6670 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6671 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6672 [(set_attr "type" "imul")
6673 (set_attr "prefix_0f" "0,1")
6674 (set (attr "athlon_decode")
6675 (cond [(eq_attr "cpu" "athlon")
6676 (const_string "vector")
6677 (eq_attr "alternative" "0")
6678 (const_string "vector")
6679 (and (eq_attr "alternative" "1")
6680 (match_operand 1 "memory_operand"))
6681 (const_string "vector")]
6682 (const_string "direct")))
6683 (set (attr "amdfam10_decode")
6684 (cond [(and (eq_attr "alternative" "1")
6685 (match_operand 1 "memory_operand"))
6686 (const_string "vector")]
6687 (const_string "direct")))
6688 (set_attr "bdver1_decode" "direct")
6689 (set_attr "mode" "<MODE>")])
6691 (define_insn "*mulv<mode>4_1"
6692 [(set (reg:CCO FLAGS_REG)
6695 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6696 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6698 (mult:SWI48 (match_dup 1)
6699 (match_operand:SWI 2 "x86_64_immediate_operand"
6701 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6702 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6703 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6704 && CONST_INT_P (operands[2])
6705 && INTVAL (operands[2]) == INTVAL (operands[3])"
6707 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6708 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6709 [(set_attr "type" "imul")
6710 (set (attr "athlon_decode")
6711 (cond [(eq_attr "cpu" "athlon")
6712 (const_string "vector")
6713 (eq_attr "alternative" "1")
6714 (const_string "vector")]
6715 (const_string "direct")))
6716 (set (attr "amdfam10_decode")
6717 (cond [(match_operand 1 "memory_operand")
6718 (const_string "vector")]
6719 (const_string "direct")))
6720 (set_attr "bdver1_decode" "direct")
6721 (set_attr "mode" "<MODE>")
6722 (set (attr "length_immediate")
6723 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6725 (match_test "<MODE_SIZE> == 8")
6727 (const_string "<MODE_SIZE>")))])
6729 (define_expand "umulv<mode>4"
6730 [(parallel [(set (reg:CCO FLAGS_REG)
6733 (match_operand:SWI48 1
6734 "nonimmediate_operand"))
6736 (match_operand:SWI48 2
6737 "nonimmediate_operand")))
6739 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6740 (set (match_operand:SWI48 0 "register_operand")
6741 (mult:SWI48 (match_dup 1) (match_dup 2)))
6742 (clobber (match_scratch:SWI48 4))])
6743 (set (pc) (if_then_else
6744 (eq (reg:CCO FLAGS_REG) (const_int 0))
6745 (label_ref (match_operand 3))
6749 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6750 operands[1] = force_reg (<MODE>mode, operands[1]);
6753 (define_insn "*umulv<mode>4"
6754 [(set (reg:CCO FLAGS_REG)
6757 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6759 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6761 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6762 (set (match_operand:SWI48 0 "register_operand" "=a")
6763 (mult:SWI48 (match_dup 1) (match_dup 2)))
6764 (clobber (match_scratch:SWI48 3 "=d"))]
6765 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6766 "mul{<imodesuffix>}\t%2"
6767 [(set_attr "type" "imul")
6768 (set_attr "length_immediate" "0")
6769 (set (attr "athlon_decode")
6770 (if_then_else (eq_attr "cpu" "athlon")
6771 (const_string "vector")
6772 (const_string "double")))
6773 (set_attr "amdfam10_decode" "double")
6774 (set_attr "bdver1_decode" "direct")
6775 (set_attr "mode" "<MODE>")])
6777 (define_expand "<u>mulvqi4"
6778 [(parallel [(set (reg:CCO FLAGS_REG)
6781 (match_operand:QI 1 "nonimmediate_operand"))
6783 (match_operand:QI 2 "nonimmediate_operand")))
6785 (mult:QI (match_dup 1) (match_dup 2)))))
6786 (set (match_operand:QI 0 "register_operand")
6787 (mult:QI (match_dup 1) (match_dup 2)))])
6788 (set (pc) (if_then_else
6789 (eq (reg:CCO FLAGS_REG) (const_int 0))
6790 (label_ref (match_operand 3))
6792 "TARGET_QIMODE_MATH"
6794 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6795 operands[1] = force_reg (QImode, operands[1]);
6798 (define_insn "*<u>mulvqi4"
6799 [(set (reg:CCO FLAGS_REG)
6802 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6804 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6806 (mult:QI (match_dup 1) (match_dup 2)))))
6807 (set (match_operand:QI 0 "register_operand" "=a")
6808 (mult:QI (match_dup 1) (match_dup 2)))]
6810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811 "<sgnprefix>mul{b}\t%2"
6812 [(set_attr "type" "imul")
6813 (set_attr "length_immediate" "0")
6814 (set (attr "athlon_decode")
6815 (if_then_else (eq_attr "cpu" "athlon")
6816 (const_string "vector")
6817 (const_string "direct")))
6818 (set_attr "amdfam10_decode" "direct")
6819 (set_attr "bdver1_decode" "direct")
6820 (set_attr "mode" "QI")])
6822 (define_expand "<u>mul<mode><dwi>3"
6823 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6826 (match_operand:DWIH 1 "nonimmediate_operand"))
6828 (match_operand:DWIH 2 "register_operand"))))
6829 (clobber (reg:CC FLAGS_REG))])])
6831 (define_expand "<u>mulqihi3"
6832 [(parallel [(set (match_operand:HI 0 "register_operand")
6835 (match_operand:QI 1 "nonimmediate_operand"))
6837 (match_operand:QI 2 "register_operand"))))
6838 (clobber (reg:CC FLAGS_REG))])]
6839 "TARGET_QIMODE_MATH")
6841 (define_insn "*bmi2_umulditi3_1"
6842 [(set (match_operand:DI 0 "register_operand" "=r")
6844 (match_operand:DI 2 "nonimmediate_operand" "%d")
6845 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6846 (set (match_operand:DI 1 "register_operand" "=r")
6849 (mult:TI (zero_extend:TI (match_dup 2))
6850 (zero_extend:TI (match_dup 3)))
6852 "TARGET_64BIT && TARGET_BMI2
6853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854 "mulx\t{%3, %0, %1|%1, %0, %3}"
6855 [(set_attr "type" "imulx")
6856 (set_attr "prefix" "vex")
6857 (set_attr "mode" "DI")])
6859 (define_insn "*bmi2_umulsidi3_1"
6860 [(set (match_operand:SI 0 "register_operand" "=r")
6862 (match_operand:SI 2 "nonimmediate_operand" "%d")
6863 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6864 (set (match_operand:SI 1 "register_operand" "=r")
6867 (mult:DI (zero_extend:DI (match_dup 2))
6868 (zero_extend:DI (match_dup 3)))
6870 "!TARGET_64BIT && TARGET_BMI2
6871 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872 "mulx\t{%3, %0, %1|%1, %0, %3}"
6873 [(set_attr "type" "imulx")
6874 (set_attr "prefix" "vex")
6875 (set_attr "mode" "SI")])
6877 (define_insn "*umul<mode><dwi>3_1"
6878 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6881 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6883 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6884 (clobber (reg:CC FLAGS_REG))]
6885 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888 mul{<imodesuffix>}\t%2"
6889 [(set_attr "isa" "bmi2,*")
6890 (set_attr "type" "imulx,imul")
6891 (set_attr "length_immediate" "*,0")
6892 (set (attr "athlon_decode")
6893 (cond [(eq_attr "alternative" "1")
6894 (if_then_else (eq_attr "cpu" "athlon")
6895 (const_string "vector")
6896 (const_string "double"))]
6897 (const_string "*")))
6898 (set_attr "amdfam10_decode" "*,double")
6899 (set_attr "bdver1_decode" "*,direct")
6900 (set_attr "prefix" "vex,orig")
6901 (set_attr "mode" "<MODE>")])
6903 ;; Convert mul to the mulx pattern to avoid flags dependency.
6905 [(set (match_operand:<DWI> 0 "register_operand")
6908 (match_operand:DWIH 1 "register_operand"))
6910 (match_operand:DWIH 2 "nonimmediate_operand"))))
6911 (clobber (reg:CC FLAGS_REG))]
6912 "TARGET_BMI2 && reload_completed
6913 && true_regnum (operands[1]) == DX_REG"
6914 [(parallel [(set (match_dup 3)
6915 (mult:DWIH (match_dup 1) (match_dup 2)))
6919 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6920 (zero_extend:<DWI> (match_dup 2)))
6923 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6925 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6928 (define_insn "*mul<mode><dwi>3_1"
6929 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6932 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6934 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6935 (clobber (reg:CC FLAGS_REG))]
6936 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 "imul{<imodesuffix>}\t%2"
6938 [(set_attr "type" "imul")
6939 (set_attr "length_immediate" "0")
6940 (set (attr "athlon_decode")
6941 (if_then_else (eq_attr "cpu" "athlon")
6942 (const_string "vector")
6943 (const_string "double")))
6944 (set_attr "amdfam10_decode" "double")
6945 (set_attr "bdver1_decode" "direct")
6946 (set_attr "mode" "<MODE>")])
6948 (define_insn "*<u>mulqihi3_1"
6949 [(set (match_operand:HI 0 "register_operand" "=a")
6952 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6954 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6955 (clobber (reg:CC FLAGS_REG))]
6957 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6958 "<sgnprefix>mul{b}\t%2"
6959 [(set_attr "type" "imul")
6960 (set_attr "length_immediate" "0")
6961 (set (attr "athlon_decode")
6962 (if_then_else (eq_attr "cpu" "athlon")
6963 (const_string "vector")
6964 (const_string "direct")))
6965 (set_attr "amdfam10_decode" "direct")
6966 (set_attr "bdver1_decode" "direct")
6967 (set_attr "mode" "QI")])
6969 (define_expand "<s>mul<mode>3_highpart"
6970 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6975 (match_operand:SWI48 1 "nonimmediate_operand"))
6977 (match_operand:SWI48 2 "register_operand")))
6979 (clobber (match_scratch:SWI48 3))
6980 (clobber (reg:CC FLAGS_REG))])]
6982 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6984 (define_insn "*<s>muldi3_highpart_1"
6985 [(set (match_operand:DI 0 "register_operand" "=d")
6990 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6992 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6994 (clobber (match_scratch:DI 3 "=1"))
6995 (clobber (reg:CC FLAGS_REG))]
6997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998 "<sgnprefix>mul{q}\t%2"
6999 [(set_attr "type" "imul")
7000 (set_attr "length_immediate" "0")
7001 (set (attr "athlon_decode")
7002 (if_then_else (eq_attr "cpu" "athlon")
7003 (const_string "vector")
7004 (const_string "double")))
7005 (set_attr "amdfam10_decode" "double")
7006 (set_attr "bdver1_decode" "direct")
7007 (set_attr "mode" "DI")])
7009 (define_insn "*<s>mulsi3_highpart_1"
7010 [(set (match_operand:SI 0 "register_operand" "=d")
7015 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7017 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7019 (clobber (match_scratch:SI 3 "=1"))
7020 (clobber (reg:CC FLAGS_REG))]
7021 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022 "<sgnprefix>mul{l}\t%2"
7023 [(set_attr "type" "imul")
7024 (set_attr "length_immediate" "0")
7025 (set (attr "athlon_decode")
7026 (if_then_else (eq_attr "cpu" "athlon")
7027 (const_string "vector")
7028 (const_string "double")))
7029 (set_attr "amdfam10_decode" "double")
7030 (set_attr "bdver1_decode" "direct")
7031 (set_attr "mode" "SI")])
7033 (define_insn "*<s>mulsi3_highpart_zext"
7034 [(set (match_operand:DI 0 "register_operand" "=d")
7035 (zero_extend:DI (truncate:SI
7037 (mult:DI (any_extend:DI
7038 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7040 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7042 (clobber (match_scratch:SI 3 "=1"))
7043 (clobber (reg:CC FLAGS_REG))]
7045 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 "<sgnprefix>mul{l}\t%2"
7047 [(set_attr "type" "imul")
7048 (set_attr "length_immediate" "0")
7049 (set (attr "athlon_decode")
7050 (if_then_else (eq_attr "cpu" "athlon")
7051 (const_string "vector")
7052 (const_string "double")))
7053 (set_attr "amdfam10_decode" "double")
7054 (set_attr "bdver1_decode" "direct")
7055 (set_attr "mode" "SI")])
7057 ;; The patterns that match these are at the end of this file.
7059 (define_expand "mulxf3"
7060 [(set (match_operand:XF 0 "register_operand")
7061 (mult:XF (match_operand:XF 1 "register_operand")
7062 (match_operand:XF 2 "register_operand")))]
7065 (define_expand "mul<mode>3"
7066 [(set (match_operand:MODEF 0 "register_operand")
7067 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7068 (match_operand:MODEF 2 "nonimmediate_operand")))]
7069 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7070 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7072 ;; Divide instructions
7074 ;; The patterns that match these are at the end of this file.
7076 (define_expand "divxf3"
7077 [(set (match_operand:XF 0 "register_operand")
7078 (div:XF (match_operand:XF 1 "register_operand")
7079 (match_operand:XF 2 "register_operand")))]
7082 (define_expand "divdf3"
7083 [(set (match_operand:DF 0 "register_operand")
7084 (div:DF (match_operand:DF 1 "register_operand")
7085 (match_operand:DF 2 "nonimmediate_operand")))]
7086 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7087 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7089 (define_expand "divsf3"
7090 [(set (match_operand:SF 0 "register_operand")
7091 (div:SF (match_operand:SF 1 "register_operand")
7092 (match_operand:SF 2 "nonimmediate_operand")))]
7093 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7098 && optimize_insn_for_speed_p ()
7099 && flag_finite_math_only && !flag_trapping_math
7100 && flag_unsafe_math_optimizations)
7102 ix86_emit_swdivsf (operands[0], operands[1],
7103 operands[2], SFmode);
7108 ;; Divmod instructions.
7110 (define_expand "divmod<mode>4"
7111 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7113 (match_operand:SWIM248 1 "register_operand")
7114 (match_operand:SWIM248 2 "nonimmediate_operand")))
7115 (set (match_operand:SWIM248 3 "register_operand")
7116 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7117 (clobber (reg:CC FLAGS_REG))])])
7119 ;; Split with 8bit unsigned divide:
7120 ;; if (dividend an divisor are in [0-255])
7121 ;; use 8bit unsigned integer divide
7123 ;; use original integer divide
7125 [(set (match_operand:SWI48 0 "register_operand")
7126 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7127 (match_operand:SWI48 3 "nonimmediate_operand")))
7128 (set (match_operand:SWI48 1 "register_operand")
7129 (mod:SWI48 (match_dup 2) (match_dup 3)))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "TARGET_USE_8BIT_IDIV
7132 && TARGET_QIMODE_MATH
7133 && can_create_pseudo_p ()
7134 && !optimize_insn_for_size_p ()"
7136 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7138 (define_insn_and_split "divmod<mode>4_1"
7139 [(set (match_operand:SWI48 0 "register_operand" "=a")
7140 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7141 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7142 (set (match_operand:SWI48 1 "register_operand" "=&d")
7143 (mod:SWI48 (match_dup 2) (match_dup 3)))
7144 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7145 (clobber (reg:CC FLAGS_REG))]
7149 [(parallel [(set (match_dup 1)
7150 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7151 (clobber (reg:CC FLAGS_REG))])
7152 (parallel [(set (match_dup 0)
7153 (div:SWI48 (match_dup 2) (match_dup 3)))
7155 (mod:SWI48 (match_dup 2) (match_dup 3)))
7157 (clobber (reg:CC FLAGS_REG))])]
7159 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7161 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7162 operands[4] = operands[2];
7165 /* Avoid use of cltd in favor of a mov+shift. */
7166 emit_move_insn (operands[1], operands[2]);
7167 operands[4] = operands[1];
7170 [(set_attr "type" "multi")
7171 (set_attr "mode" "<MODE>")])
7173 (define_insn_and_split "*divmod<mode>4"
7174 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7175 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7176 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7177 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7178 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7179 (clobber (reg:CC FLAGS_REG))]
7183 [(parallel [(set (match_dup 1)
7184 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7185 (clobber (reg:CC FLAGS_REG))])
7186 (parallel [(set (match_dup 0)
7187 (div:SWIM248 (match_dup 2) (match_dup 3)))
7189 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7191 (clobber (reg:CC FLAGS_REG))])]
7193 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7195 if (<MODE>mode != HImode
7196 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7197 operands[4] = operands[2];
7200 /* Avoid use of cltd in favor of a mov+shift. */
7201 emit_move_insn (operands[1], operands[2]);
7202 operands[4] = operands[1];
7205 [(set_attr "type" "multi")
7206 (set_attr "mode" "<MODE>")])
7208 (define_insn "*divmod<mode>4_noext"
7209 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7210 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7211 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7212 (set (match_operand:SWIM248 1 "register_operand" "=d")
7213 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7214 (use (match_operand:SWIM248 4 "register_operand" "1"))
7215 (clobber (reg:CC FLAGS_REG))]
7217 "idiv{<imodesuffix>}\t%3"
7218 [(set_attr "type" "idiv")
7219 (set_attr "mode" "<MODE>")])
7221 (define_expand "divmodqi4"
7222 [(parallel [(set (match_operand:QI 0 "register_operand")
7224 (match_operand:QI 1 "register_operand")
7225 (match_operand:QI 2 "nonimmediate_operand")))
7226 (set (match_operand:QI 3 "register_operand")
7227 (mod:QI (match_dup 1) (match_dup 2)))
7228 (clobber (reg:CC FLAGS_REG))])]
7229 "TARGET_QIMODE_MATH"
7234 tmp0 = gen_reg_rtx (HImode);
7235 tmp1 = gen_reg_rtx (HImode);
7237 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7239 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7240 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7242 /* Extract remainder from AH. */
7243 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7244 insn = emit_move_insn (operands[3], tmp1);
7246 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7247 set_unique_reg_note (insn, REG_EQUAL, mod);
7249 /* Extract quotient from AL. */
7250 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7252 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7253 set_unique_reg_note (insn, REG_EQUAL, div);
7258 ;; Divide AX by r/m8, with result stored in
7261 ;; Change div/mod to HImode and extend the second argument to HImode
7262 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7263 ;; combine may fail.
7264 (define_insn "divmodhiqi3"
7265 [(set (match_operand:HI 0 "register_operand" "=a")
7270 (mod:HI (match_operand:HI 1 "register_operand" "0")
7272 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7276 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "TARGET_QIMODE_MATH"
7280 [(set_attr "type" "idiv")
7281 (set_attr "mode" "QI")])
7283 (define_expand "udivmod<mode>4"
7284 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7286 (match_operand:SWIM248 1 "register_operand")
7287 (match_operand:SWIM248 2 "nonimmediate_operand")))
7288 (set (match_operand:SWIM248 3 "register_operand")
7289 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7290 (clobber (reg:CC FLAGS_REG))])])
7292 ;; Split with 8bit unsigned divide:
7293 ;; if (dividend an divisor are in [0-255])
7294 ;; use 8bit unsigned integer divide
7296 ;; use original integer divide
7298 [(set (match_operand:SWI48 0 "register_operand")
7299 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7300 (match_operand:SWI48 3 "nonimmediate_operand")))
7301 (set (match_operand:SWI48 1 "register_operand")
7302 (umod:SWI48 (match_dup 2) (match_dup 3)))
7303 (clobber (reg:CC FLAGS_REG))]
7304 "TARGET_USE_8BIT_IDIV
7305 && TARGET_QIMODE_MATH
7306 && can_create_pseudo_p ()
7307 && !optimize_insn_for_size_p ()"
7309 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7311 (define_insn_and_split "udivmod<mode>4_1"
7312 [(set (match_operand:SWI48 0 "register_operand" "=a")
7313 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7314 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7315 (set (match_operand:SWI48 1 "register_operand" "=&d")
7316 (umod:SWI48 (match_dup 2) (match_dup 3)))
7317 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7318 (clobber (reg:CC FLAGS_REG))]
7322 [(set (match_dup 1) (const_int 0))
7323 (parallel [(set (match_dup 0)
7324 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7326 (umod:SWI48 (match_dup 2) (match_dup 3)))
7328 (clobber (reg:CC FLAGS_REG))])]
7330 [(set_attr "type" "multi")
7331 (set_attr "mode" "<MODE>")])
7333 (define_insn_and_split "*udivmod<mode>4"
7334 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7335 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7336 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7337 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7338 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7339 (clobber (reg:CC FLAGS_REG))]
7343 [(set (match_dup 1) (const_int 0))
7344 (parallel [(set (match_dup 0)
7345 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7347 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7349 (clobber (reg:CC FLAGS_REG))])]
7351 [(set_attr "type" "multi")
7352 (set_attr "mode" "<MODE>")])
7354 ;; Optimize division or modulo by constant power of 2, if the constant
7355 ;; materializes only after expansion.
7356 (define_insn_and_split "*udivmod<mode>4_pow2"
7357 [(set (match_operand:SWI48 0 "register_operand" "=r")
7358 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7359 (match_operand:SWI48 3 "const_int_operand" "n")))
7360 (set (match_operand:SWI48 1 "register_operand" "=r")
7361 (umod:SWI48 (match_dup 2) (match_dup 3)))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7364 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7367 [(set (match_dup 1) (match_dup 2))
7368 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7369 (clobber (reg:CC FLAGS_REG))])
7370 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7371 (clobber (reg:CC FLAGS_REG))])]
7373 int v = exact_log2 (UINTVAL (operands[3]));
7374 operands[4] = GEN_INT (v);
7375 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7377 [(set_attr "type" "multi")
7378 (set_attr "mode" "<MODE>")])
7380 (define_insn "*udivmod<mode>4_noext"
7381 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7382 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7383 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7384 (set (match_operand:SWIM248 1 "register_operand" "=d")
7385 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7386 (use (match_operand:SWIM248 4 "register_operand" "1"))
7387 (clobber (reg:CC FLAGS_REG))]
7389 "div{<imodesuffix>}\t%3"
7390 [(set_attr "type" "idiv")
7391 (set_attr "mode" "<MODE>")])
7393 (define_expand "udivmodqi4"
7394 [(parallel [(set (match_operand:QI 0 "register_operand")
7396 (match_operand:QI 1 "register_operand")
7397 (match_operand:QI 2 "nonimmediate_operand")))
7398 (set (match_operand:QI 3 "register_operand")
7399 (umod:QI (match_dup 1) (match_dup 2)))
7400 (clobber (reg:CC FLAGS_REG))])]
7401 "TARGET_QIMODE_MATH"
7406 tmp0 = gen_reg_rtx (HImode);
7407 tmp1 = gen_reg_rtx (HImode);
7409 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7411 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7412 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7414 /* Extract remainder from AH. */
7415 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7416 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7417 insn = emit_move_insn (operands[3], tmp1);
7419 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7420 set_unique_reg_note (insn, REG_EQUAL, mod);
7422 /* Extract quotient from AL. */
7423 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7425 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7426 set_unique_reg_note (insn, REG_EQUAL, div);
7431 (define_insn "udivmodhiqi3"
7432 [(set (match_operand:HI 0 "register_operand" "=a")
7437 (mod:HI (match_operand:HI 1 "register_operand" "0")
7439 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7443 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7444 (clobber (reg:CC FLAGS_REG))]
7445 "TARGET_QIMODE_MATH"
7447 [(set_attr "type" "idiv")
7448 (set_attr "mode" "QI")])
7450 ;; We cannot use div/idiv for double division, because it causes
7451 ;; "division by zero" on the overflow and that's not what we expect
7452 ;; from truncate. Because true (non truncating) double division is
7453 ;; never generated, we can't create this insn anyway.
7456 ; [(set (match_operand:SI 0 "register_operand" "=a")
7458 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7460 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7461 ; (set (match_operand:SI 3 "register_operand" "=d")
7463 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7464 ; (clobber (reg:CC FLAGS_REG))]
7466 ; "div{l}\t{%2, %0|%0, %2}"
7467 ; [(set_attr "type" "idiv")])
7469 ;;- Logical AND instructions
7471 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7472 ;; Note that this excludes ah.
7474 (define_expand "testsi_ccno_1"
7475 [(set (reg:CCNO FLAGS_REG)
7477 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7478 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7481 (define_expand "testqi_ccz_1"
7482 [(set (reg:CCZ FLAGS_REG)
7483 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7484 (match_operand:QI 1 "nonmemory_operand"))
7487 (define_expand "testdi_ccno_1"
7488 [(set (reg:CCNO FLAGS_REG)
7490 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7491 (match_operand:DI 1 "x86_64_szext_general_operand"))
7493 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7495 (define_insn "*testdi_1"
7496 [(set (reg FLAGS_REG)
7499 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7500 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7502 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7503 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7505 test{l}\t{%k1, %k0|%k0, %k1}
7506 test{l}\t{%k1, %k0|%k0, %k1}
7507 test{q}\t{%1, %0|%0, %1}
7508 test{q}\t{%1, %0|%0, %1}
7509 test{q}\t{%1, %0|%0, %1}"
7510 [(set_attr "type" "test")
7511 (set_attr "modrm" "0,1,0,1,1")
7512 (set_attr "mode" "SI,SI,DI,DI,DI")])
7514 (define_insn "*testqi_1_maybe_si"
7515 [(set (reg FLAGS_REG)
7518 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7519 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7521 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7522 && ix86_match_ccmode (insn,
7523 CONST_INT_P (operands[1])
7524 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7526 if (which_alternative == 3)
7528 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7529 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7530 return "test{l}\t{%1, %k0|%k0, %1}";
7532 return "test{b}\t{%1, %0|%0, %1}";
7534 [(set_attr "type" "test")
7535 (set_attr "modrm" "0,1,1,1")
7536 (set_attr "mode" "QI,QI,QI,SI")
7537 (set_attr "pent_pair" "uv,np,uv,np")])
7539 (define_insn "*test<mode>_1"
7540 [(set (reg FLAGS_REG)
7543 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7544 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7546 "ix86_match_ccmode (insn, CCNOmode)
7547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7548 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7549 [(set_attr "type" "test")
7550 (set_attr "modrm" "0,1,1")
7551 (set_attr "mode" "<MODE>")
7552 (set_attr "pent_pair" "uv,np,uv")])
7554 (define_expand "testqi_ext_ccno_0"
7555 [(set (reg:CCNO FLAGS_REG)
7559 (match_operand 0 "ext_register_operand")
7562 (match_operand 1 "const_int_operand"))
7565 (define_insn "*testqi_ext_0"
7566 [(set (reg FLAGS_REG)
7570 (match_operand 0 "ext_register_operand" "Q")
7573 (match_operand 1 "const_int_operand" "n"))
7575 "ix86_match_ccmode (insn, CCNOmode)"
7576 "test{b}\t{%1, %h0|%h0, %1}"
7577 [(set_attr "type" "test")
7578 (set_attr "mode" "QI")
7579 (set_attr "length_immediate" "1")
7580 (set_attr "modrm" "1")
7581 (set_attr "pent_pair" "np")])
7583 (define_insn "*testqi_ext_1"
7584 [(set (reg FLAGS_REG)
7588 (match_operand 0 "ext_register_operand" "Q,Q")
7592 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7594 "ix86_match_ccmode (insn, CCNOmode)"
7595 "test{b}\t{%1, %h0|%h0, %1}"
7596 [(set_attr "isa" "*,nox64")
7597 (set_attr "type" "test")
7598 (set_attr "mode" "QI")])
7600 (define_insn "*testqi_ext_2"
7601 [(set (reg FLAGS_REG)
7605 (match_operand 0 "ext_register_operand" "Q")
7609 (match_operand 1 "ext_register_operand" "Q")
7613 "ix86_match_ccmode (insn, CCNOmode)"
7614 "test{b}\t{%h1, %h0|%h0, %h1}"
7615 [(set_attr "type" "test")
7616 (set_attr "mode" "QI")])
7618 ;; Combine likes to form bit extractions for some tests. Humor it.
7619 (define_insn "*testqi_ext_3"
7620 [(set (reg FLAGS_REG)
7621 (compare (zero_extract:SWI48
7622 (match_operand 0 "nonimmediate_operand" "rm")
7623 (match_operand:SWI48 1 "const_int_operand")
7624 (match_operand:SWI48 2 "const_int_operand"))
7626 "ix86_match_ccmode (insn, CCNOmode)
7627 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7628 || GET_MODE (operands[0]) == SImode
7629 || GET_MODE (operands[0]) == HImode
7630 || GET_MODE (operands[0]) == QImode)
7631 /* Ensure that resulting mask is zero or sign extended operand. */
7632 && INTVAL (operands[2]) >= 0
7633 && ((INTVAL (operands[1]) > 0
7634 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7635 || (<MODE>mode == DImode
7636 && INTVAL (operands[1]) > 32
7637 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7641 [(set (match_operand 0 "flags_reg_operand")
7642 (match_operator 1 "compare_operator"
7644 (match_operand 2 "nonimmediate_operand")
7645 (match_operand 3 "const_int_operand")
7646 (match_operand 4 "const_int_operand"))
7648 "ix86_match_ccmode (insn, CCNOmode)"
7649 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7651 rtx val = operands[2];
7652 HOST_WIDE_INT len = INTVAL (operands[3]);
7653 HOST_WIDE_INT pos = INTVAL (operands[4]);
7655 machine_mode mode, submode;
7657 mode = GET_MODE (val);
7660 /* ??? Combine likes to put non-volatile mem extractions in QImode
7661 no matter the size of the test. So find a mode that works. */
7662 if (! MEM_VOLATILE_P (val))
7664 mode = smallest_mode_for_size (pos + len, MODE_INT);
7665 val = adjust_address (val, mode, 0);
7668 else if (GET_CODE (val) == SUBREG
7669 && (submode = GET_MODE (SUBREG_REG (val)),
7670 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7671 && pos + len <= GET_MODE_BITSIZE (submode)
7672 && GET_MODE_CLASS (submode) == MODE_INT)
7674 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7676 val = SUBREG_REG (val);
7678 else if (mode == HImode && pos + len <= 8)
7680 /* Small HImode tests can be converted to QImode. */
7682 val = gen_lowpart (QImode, val);
7685 if (len == HOST_BITS_PER_WIDE_INT)
7688 mask = ((HOST_WIDE_INT)1 << len) - 1;
7691 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7694 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7695 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7696 ;; this is relatively important trick.
7697 ;; Do the conversion only post-reload to avoid limiting of the register class
7700 [(set (match_operand 0 "flags_reg_operand")
7701 (match_operator 1 "compare_operator"
7702 [(and (match_operand 2 "register_operand")
7703 (match_operand 3 "const_int_operand"))
7706 && QI_REG_P (operands[2])
7707 && GET_MODE (operands[2]) != QImode
7708 && ((ix86_match_ccmode (insn, CCZmode)
7709 && !(INTVAL (operands[3]) & ~(255 << 8)))
7710 || (ix86_match_ccmode (insn, CCNOmode)
7711 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7714 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7718 operands[2] = gen_lowpart (SImode, operands[2]);
7719 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7723 [(set (match_operand 0 "flags_reg_operand")
7724 (match_operator 1 "compare_operator"
7725 [(and (match_operand 2 "nonimmediate_operand")
7726 (match_operand 3 "const_int_operand"))
7729 && GET_MODE (operands[2]) != QImode
7730 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7731 && ((ix86_match_ccmode (insn, CCZmode)
7732 && !(INTVAL (operands[3]) & ~255))
7733 || (ix86_match_ccmode (insn, CCNOmode)
7734 && !(INTVAL (operands[3]) & ~127)))"
7736 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7739 operands[2] = gen_lowpart (QImode, operands[2]);
7740 operands[3] = gen_lowpart (QImode, operands[3]);
7744 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7745 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7746 (match_operand:SWI1248x 2 "mask_reg_operand")))
7747 (clobber (reg:CC FLAGS_REG))]
7748 "TARGET_AVX512F && reload_completed"
7750 (any_logic:SWI1248x (match_dup 1)
7753 (define_insn "*k<logic><mode>"
7754 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7755 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7756 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7759 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7760 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7762 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7764 [(set_attr "mode" "<MODE>")
7765 (set_attr "type" "msklog")
7766 (set_attr "prefix" "vex")])
7768 ;; %%% This used to optimize known byte-wide and operations to memory,
7769 ;; and sometimes to QImode registers. If this is considered useful,
7770 ;; it should be done with splitters.
7772 (define_expand "and<mode>3"
7773 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7774 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7775 (match_operand:SWIM 2 "<general_szext_operand>")))]
7778 machine_mode mode = <MODE>mode;
7779 rtx (*insn) (rtx, rtx);
7781 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7783 HOST_WIDE_INT ival = INTVAL (operands[2]);
7785 if (ival == (HOST_WIDE_INT) 0xffffffff)
7787 else if (ival == 0xffff)
7789 else if (ival == 0xff)
7793 if (mode == <MODE>mode)
7795 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7799 if (<MODE>mode == DImode)
7800 insn = (mode == SImode)
7801 ? gen_zero_extendsidi2
7803 ? gen_zero_extendhidi2
7804 : gen_zero_extendqidi2;
7805 else if (<MODE>mode == SImode)
7806 insn = (mode == HImode)
7807 ? gen_zero_extendhisi2
7808 : gen_zero_extendqisi2;
7809 else if (<MODE>mode == HImode)
7810 insn = gen_zero_extendqihi2;
7814 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7818 (define_insn "*anddi_1"
7819 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7821 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7822 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7826 switch (get_attr_type (insn))
7832 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7835 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7836 if (get_attr_mode (insn) == MODE_SI)
7837 return "and{l}\t{%k2, %k0|%k0, %k2}";
7839 return "and{q}\t{%2, %0|%0, %2}";
7842 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7843 (set_attr "length_immediate" "*,*,*,0,0")
7844 (set (attr "prefix_rex")
7846 (and (eq_attr "type" "imovx")
7847 (and (match_test "INTVAL (operands[2]) == 0xff")
7848 (match_operand 1 "ext_QIreg_operand")))
7850 (const_string "*")))
7851 (set_attr "mode" "SI,DI,DI,SI,DI")])
7853 (define_insn "*andsi_1"
7854 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7855 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7856 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7857 (clobber (reg:CC FLAGS_REG))]
7858 "ix86_binary_operator_ok (AND, SImode, operands)"
7860 switch (get_attr_type (insn))
7866 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7869 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7870 return "and{l}\t{%2, %0|%0, %2}";
7873 [(set_attr "type" "alu,alu,imovx,msklog")
7874 (set (attr "prefix_rex")
7876 (and (eq_attr "type" "imovx")
7877 (and (match_test "INTVAL (operands[2]) == 0xff")
7878 (match_operand 1 "ext_QIreg_operand")))
7880 (const_string "*")))
7881 (set_attr "length_immediate" "*,*,0,0")
7882 (set_attr "mode" "SI")])
7884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7885 (define_insn "*andsi_1_zext"
7886 [(set (match_operand:DI 0 "register_operand" "=r")
7888 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7889 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7892 "and{l}\t{%2, %k0|%k0, %2}"
7893 [(set_attr "type" "alu")
7894 (set_attr "mode" "SI")])
7896 (define_insn "*andhi_1"
7897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7898 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7899 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7900 (clobber (reg:CC FLAGS_REG))]
7901 "ix86_binary_operator_ok (AND, HImode, operands)"
7903 switch (get_attr_type (insn))
7909 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7912 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7913 return "and{w}\t{%2, %0|%0, %2}";
7916 [(set_attr "type" "alu,alu,imovx,msklog")
7917 (set_attr "length_immediate" "*,*,0,*")
7918 (set (attr "prefix_rex")
7920 (and (eq_attr "type" "imovx")
7921 (match_operand 1 "ext_QIreg_operand"))
7923 (const_string "*")))
7924 (set_attr "mode" "HI,HI,SI,HI")])
7926 ;; %%% Potential partial reg stall on alternative 2. What to do?
7927 (define_insn "*andqi_1"
7928 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7929 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7930 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7931 (clobber (reg:CC FLAGS_REG))]
7932 "ix86_binary_operator_ok (AND, QImode, operands)"
7934 switch (which_alternative)
7938 return "and{b}\t{%2, %0|%0, %2}";
7940 return "and{l}\t{%k2, %k0|%k0, %k2}";
7942 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7943 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7948 [(set_attr "type" "alu,alu,alu,msklog")
7949 (set_attr "mode" "QI,QI,SI,HI")])
7951 (define_insn "*andqi_1_slp"
7952 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7953 (and:QI (match_dup 0)
7954 (match_operand:QI 1 "general_operand" "qn,qmn")))
7955 (clobber (reg:CC FLAGS_REG))]
7956 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7957 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7958 "and{b}\t{%1, %0|%0, %1}"
7959 [(set_attr "type" "alu1")
7960 (set_attr "mode" "QI")])
7962 (define_insn "kandn<mode>"
7963 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7966 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7967 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7968 (clobber (reg:CC FLAGS_REG))]
7971 switch (which_alternative)
7974 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7978 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7979 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7981 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7986 [(set_attr "isa" "bmi,*,avx512f")
7987 (set_attr "type" "bitmanip,*,msklog")
7988 (set_attr "prefix" "*,*,vex")
7989 (set_attr "btver2_decode" "direct,*,*")
7990 (set_attr "mode" "<MODE>")])
7993 [(set (match_operand:SWI12 0 "general_reg_operand")
7997 (match_operand:SWI12 1 "general_reg_operand")))
7998 (clobber (reg:CC FLAGS_REG))]
7999 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8001 (not:HI (match_dup 0)))
8002 (parallel [(set (match_dup 0)
8003 (and:HI (match_dup 0)
8005 (clobber (reg:CC FLAGS_REG))])])
8007 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8009 [(set (match_operand:DI 0 "register_operand")
8010 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8011 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8012 (clobber (reg:CC FLAGS_REG))]
8014 [(parallel [(set (match_dup 0)
8015 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8016 (clobber (reg:CC FLAGS_REG))])]
8017 "operands[2] = gen_lowpart (SImode, operands[2]);")
8020 [(set (match_operand:SWI248 0 "register_operand")
8021 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8022 (match_operand:SWI248 2 "const_int_operand")))
8023 (clobber (reg:CC FLAGS_REG))]
8025 && true_regnum (operands[0]) != true_regnum (operands[1])"
8028 HOST_WIDE_INT ival = INTVAL (operands[2]);
8030 rtx (*insn) (rtx, rtx);
8032 if (ival == (HOST_WIDE_INT) 0xffffffff)
8034 else if (ival == 0xffff)
8038 gcc_assert (ival == 0xff);
8042 if (<MODE>mode == DImode)
8043 insn = (mode == SImode)
8044 ? gen_zero_extendsidi2
8046 ? gen_zero_extendhidi2
8047 : gen_zero_extendqidi2;
8050 if (<MODE>mode != SImode)
8051 /* Zero extend to SImode to avoid partial register stalls. */
8052 operands[0] = gen_lowpart (SImode, operands[0]);
8054 insn = (mode == HImode)
8055 ? gen_zero_extendhisi2
8056 : gen_zero_extendqisi2;
8058 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8063 [(set (match_operand 0 "register_operand")
8065 (const_int -65536)))
8066 (clobber (reg:CC FLAGS_REG))]
8067 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8068 || optimize_function_for_size_p (cfun)"
8069 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8070 "operands[1] = gen_lowpart (HImode, operands[0]);")
8073 [(set (match_operand 0 "ext_register_operand")
8076 (clobber (reg:CC FLAGS_REG))]
8077 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && reload_completed"
8079 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8080 "operands[1] = gen_lowpart (QImode, operands[0]);")
8083 [(set (match_operand 0 "ext_register_operand")
8085 (const_int -65281)))
8086 (clobber (reg:CC FLAGS_REG))]
8087 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8088 && reload_completed"
8089 [(parallel [(set (zero_extract:SI (match_dup 0)
8093 (zero_extract:SI (match_dup 0)
8096 (zero_extract:SI (match_dup 0)
8099 (clobber (reg:CC FLAGS_REG))])]
8100 "operands[0] = gen_lowpart (SImode, operands[0]);")
8102 (define_insn "*anddi_2"
8103 [(set (reg FLAGS_REG)
8106 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8107 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8109 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8110 (and:DI (match_dup 1) (match_dup 2)))]
8112 && ix86_match_ccmode
8114 /* If we are going to emit andl instead of andq, and the operands[2]
8115 constant might have the SImode sign bit set, make sure the sign
8116 flag isn't tested, because the instruction will set the sign flag
8117 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8118 conservatively assume it might have bit 31 set. */
8119 (satisfies_constraint_Z (operands[2])
8120 && (!CONST_INT_P (operands[2])
8121 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8122 ? CCZmode : CCNOmode)
8123 && ix86_binary_operator_ok (AND, DImode, operands)"
8125 and{l}\t{%k2, %k0|%k0, %k2}
8126 and{q}\t{%2, %0|%0, %2}
8127 and{q}\t{%2, %0|%0, %2}"
8128 [(set_attr "type" "alu")
8129 (set_attr "mode" "SI,DI,DI")])
8131 (define_insn "*andqi_2_maybe_si"
8132 [(set (reg FLAGS_REG)
8134 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8135 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8137 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8138 (and:QI (match_dup 1) (match_dup 2)))]
8139 "ix86_binary_operator_ok (AND, QImode, operands)
8140 && ix86_match_ccmode (insn,
8141 CONST_INT_P (operands[2])
8142 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8144 if (which_alternative == 2)
8146 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8147 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8148 return "and{l}\t{%2, %k0|%k0, %2}";
8150 return "and{b}\t{%2, %0|%0, %2}";
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "QI,QI,SI")])
8155 (define_insn "*and<mode>_2"
8156 [(set (reg FLAGS_REG)
8157 (compare (and:SWI124
8158 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8159 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8161 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8162 (and:SWI124 (match_dup 1) (match_dup 2)))]
8163 "ix86_match_ccmode (insn, CCNOmode)
8164 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8165 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8166 [(set_attr "type" "alu")
8167 (set_attr "mode" "<MODE>")])
8169 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8170 (define_insn "*andsi_2_zext"
8171 [(set (reg FLAGS_REG)
8173 (match_operand:SI 1 "nonimmediate_operand" "%0")
8174 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8176 (set (match_operand:DI 0 "register_operand" "=r")
8177 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8178 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179 && ix86_binary_operator_ok (AND, SImode, operands)"
8180 "and{l}\t{%2, %k0|%k0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "SI")])
8184 (define_insn "*andqi_2_slp"
8185 [(set (reg FLAGS_REG)
8187 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8188 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8190 (set (strict_low_part (match_dup 0))
8191 (and:QI (match_dup 0) (match_dup 1)))]
8192 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8193 && ix86_match_ccmode (insn, CCNOmode)
8194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8195 "and{b}\t{%1, %0|%0, %1}"
8196 [(set_attr "type" "alu1")
8197 (set_attr "mode" "QI")])
8199 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8200 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8201 ;; for a QImode operand, which of course failed.
8202 (define_insn "andqi_ext_0"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 (match_operand 1 "ext_register_operand" "0")
8211 (match_operand 2 "const_int_operand" "n")))
8212 (clobber (reg:CC FLAGS_REG))]
8214 "and{b}\t{%2, %h0|%h0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "length_immediate" "1")
8217 (set_attr "modrm" "1")
8218 (set_attr "mode" "QI")])
8220 ;; Generated by peephole translating test to and. This shows up
8221 ;; often in fp comparisons.
8222 (define_insn "*andqi_ext_0_cc"
8223 [(set (reg FLAGS_REG)
8227 (match_operand 1 "ext_register_operand" "0")
8230 (match_operand 2 "const_int_operand" "n"))
8232 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8241 "ix86_match_ccmode (insn, CCNOmode)"
8242 "and{b}\t{%2, %h0|%h0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "length_immediate" "1")
8245 (set_attr "modrm" "1")
8246 (set_attr "mode" "QI")])
8248 (define_insn "*andqi_ext_1"
8249 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8254 (match_operand 1 "ext_register_operand" "0,0")
8258 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8259 (clobber (reg:CC FLAGS_REG))]
8261 "and{b}\t{%2, %h0|%h0, %2}"
8262 [(set_attr "isa" "*,nox64")
8263 (set_attr "type" "alu")
8264 (set_attr "length_immediate" "0")
8265 (set_attr "mode" "QI")])
8267 (define_insn "*andqi_ext_2"
8268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8273 (match_operand 1 "ext_register_operand" "%0")
8277 (match_operand 2 "ext_register_operand" "Q")
8280 (clobber (reg:CC FLAGS_REG))]
8282 "and{b}\t{%h2, %h0|%h0, %h2}"
8283 [(set_attr "type" "alu")
8284 (set_attr "length_immediate" "0")
8285 (set_attr "mode" "QI")])
8287 ;; Convert wide AND instructions with immediate operand to shorter QImode
8288 ;; equivalents when possible.
8289 ;; Don't do the splitting with memory operands, since it introduces risk
8290 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8291 ;; for size, but that can (should?) be handled by generic code instead.
8293 [(set (match_operand 0 "register_operand")
8294 (and (match_operand 1 "register_operand")
8295 (match_operand 2 "const_int_operand")))
8296 (clobber (reg:CC FLAGS_REG))]
8298 && QI_REG_P (operands[0])
8299 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8300 && !(~INTVAL (operands[2]) & ~(255 << 8))
8301 && GET_MODE (operands[0]) != QImode"
8302 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8303 (and:SI (zero_extract:SI (match_dup 1)
8304 (const_int 8) (const_int 8))
8306 (clobber (reg:CC FLAGS_REG))])]
8308 operands[0] = gen_lowpart (SImode, operands[0]);
8309 operands[1] = gen_lowpart (SImode, operands[1]);
8310 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8313 ;; Since AND can be encoded with sign extended immediate, this is only
8314 ;; profitable when 7th bit is not set.
8316 [(set (match_operand 0 "register_operand")
8317 (and (match_operand 1 "general_operand")
8318 (match_operand 2 "const_int_operand")))
8319 (clobber (reg:CC FLAGS_REG))]
8321 && ANY_QI_REG_P (operands[0])
8322 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8323 && !(~INTVAL (operands[2]) & ~255)
8324 && !(INTVAL (operands[2]) & 128)
8325 && GET_MODE (operands[0]) != QImode"
8326 [(parallel [(set (strict_low_part (match_dup 0))
8327 (and:QI (match_dup 1)
8329 (clobber (reg:CC FLAGS_REG))])]
8331 operands[0] = gen_lowpart (QImode, operands[0]);
8332 operands[1] = gen_lowpart (QImode, operands[1]);
8333 operands[2] = gen_lowpart (QImode, operands[2]);
8336 ;; Logical inclusive and exclusive OR instructions
8338 ;; %%% This used to optimize known byte-wide and operations to memory.
8339 ;; If this is considered useful, it should be done with splitters.
8341 (define_expand "<code><mode>3"
8342 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8343 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8344 (match_operand:SWIM 2 "<general_operand>")))]
8346 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8348 (define_insn "*<code><mode>_1"
8349 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8351 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8352 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8356 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8357 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8358 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8359 [(set_attr "type" "alu,alu,msklog")
8360 (set_attr "mode" "<MODE>")])
8362 (define_insn "*<code>hi_1"
8363 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8365 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8366 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8367 (clobber (reg:CC FLAGS_REG))]
8368 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8370 <logic>{w}\t{%2, %0|%0, %2}
8371 <logic>{w}\t{%2, %0|%0, %2}
8372 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8373 [(set_attr "type" "alu,alu,msklog")
8374 (set_attr "mode" "HI")])
8376 ;; %%% Potential partial reg stall on alternative 2. What to do?
8377 (define_insn "*<code>qi_1"
8378 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8379 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8380 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8381 (clobber (reg:CC FLAGS_REG))]
8382 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8384 <logic>{b}\t{%2, %0|%0, %2}
8385 <logic>{b}\t{%2, %0|%0, %2}
8386 <logic>{l}\t{%k2, %k0|%k0, %k2}
8387 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8388 [(set_attr "type" "alu,alu,alu,msklog")
8389 (set_attr "mode" "QI,QI,SI,HI")])
8391 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8392 (define_insn "*<code>si_1_zext"
8393 [(set (match_operand:DI 0 "register_operand" "=r")
8395 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8396 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8399 "<logic>{l}\t{%2, %k0|%k0, %2}"
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "SI")])
8403 (define_insn "*<code>si_1_zext_imm"
8404 [(set (match_operand:DI 0 "register_operand" "=r")
8406 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8407 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8408 (clobber (reg:CC FLAGS_REG))]
8409 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8410 "<logic>{l}\t{%2, %k0|%k0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "SI")])
8414 (define_insn "*<code>qi_1_slp"
8415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8416 (any_or:QI (match_dup 0)
8417 (match_operand:QI 1 "general_operand" "qmn,qn")))
8418 (clobber (reg:CC FLAGS_REG))]
8419 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8421 "<logic>{b}\t{%1, %0|%0, %1}"
8422 [(set_attr "type" "alu1")
8423 (set_attr "mode" "QI")])
8425 (define_insn "*<code><mode>_2"
8426 [(set (reg FLAGS_REG)
8427 (compare (any_or:SWI
8428 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8429 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8432 (any_or:SWI (match_dup 1) (match_dup 2)))]
8433 "ix86_match_ccmode (insn, CCNOmode)
8434 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8435 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "mode" "<MODE>")])
8439 (define_insn "kxnor<mode>"
8440 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8443 (match_operand:SWI12 1 "register_operand" "0,k")
8444 (match_operand:SWI12 2 "register_operand" "r,k"))))
8445 (clobber (reg:CC FLAGS_REG))]
8448 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8449 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8450 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8452 [(set_attr "type" "*,msklog")
8453 (set_attr "prefix" "*,vex")
8454 (set_attr "mode" "<MODE>")])
8456 (define_insn "kxnor<mode>"
8457 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8460 (match_operand:SWI48x 1 "register_operand" "0,k")
8461 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8462 (clobber (reg:CC FLAGS_REG))]
8466 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8467 [(set_attr "type" "*,msklog")
8468 (set_attr "prefix" "*,vex")
8469 (set_attr "mode" "<MODE>")])
8472 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8476 (match_operand:SWI1248x 1 "general_reg_operand"))))
8477 (clobber (reg:CC FLAGS_REG))]
8478 "TARGET_AVX512F && reload_completed"
8479 [(parallel [(set (match_dup 0)
8480 (xor:SWI1248x (match_dup 0)
8482 (clobber (reg:CC FLAGS_REG))])
8484 (not:SWI1248x (match_dup 0)))])
8486 ;;There are kortrest[bdq] but no intrinsics for them.
8487 ;;We probably don't need to implement them.
8488 (define_insn "kortestzhi"
8489 [(set (reg:CCZ FLAGS_REG)
8492 (match_operand:HI 0 "register_operand" "k")
8493 (match_operand:HI 1 "register_operand" "k"))
8495 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8496 "kortestw\t{%1, %0|%0, %1}"
8497 [(set_attr "mode" "HI")
8498 (set_attr "type" "msklog")
8499 (set_attr "prefix" "vex")])
8501 (define_insn "kortestchi"
8502 [(set (reg:CCC FLAGS_REG)
8505 (match_operand:HI 0 "register_operand" "k")
8506 (match_operand:HI 1 "register_operand" "k"))
8508 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8509 "kortestw\t{%1, %0|%0, %1}"
8510 [(set_attr "mode" "HI")
8511 (set_attr "type" "msklog")
8512 (set_attr "prefix" "vex")])
8514 (define_insn "kunpckhi"
8515 [(set (match_operand:HI 0 "register_operand" "=k")
8518 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8520 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8522 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8523 [(set_attr "mode" "HI")
8524 (set_attr "type" "msklog")
8525 (set_attr "prefix" "vex")])
8527 (define_insn "kunpcksi"
8528 [(set (match_operand:SI 0 "register_operand" "=k")
8531 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8533 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8535 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8536 [(set_attr "mode" "SI")])
8538 (define_insn "kunpckdi"
8539 [(set (match_operand:DI 0 "register_operand" "=k")
8542 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8544 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8546 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8547 [(set_attr "mode" "DI")])
8549 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8550 ;; ??? Special case for immediate operand is missing - it is tricky.
8551 (define_insn "*<code>si_2_zext"
8552 [(set (reg FLAGS_REG)
8553 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8554 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8556 (set (match_operand:DI 0 "register_operand" "=r")
8557 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8558 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8559 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8560 "<logic>{l}\t{%2, %k0|%k0, %2}"
8561 [(set_attr "type" "alu")
8562 (set_attr "mode" "SI")])
8564 (define_insn "*<code>si_2_zext_imm"
8565 [(set (reg FLAGS_REG)
8567 (match_operand:SI 1 "nonimmediate_operand" "%0")
8568 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8570 (set (match_operand:DI 0 "register_operand" "=r")
8571 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8572 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8573 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8574 "<logic>{l}\t{%2, %k0|%k0, %2}"
8575 [(set_attr "type" "alu")
8576 (set_attr "mode" "SI")])
8578 (define_insn "*<code>qi_2_slp"
8579 [(set (reg FLAGS_REG)
8580 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8581 (match_operand:QI 1 "general_operand" "qmn,qn"))
8583 (set (strict_low_part (match_dup 0))
8584 (any_or:QI (match_dup 0) (match_dup 1)))]
8585 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8586 && ix86_match_ccmode (insn, CCNOmode)
8587 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8588 "<logic>{b}\t{%1, %0|%0, %1}"
8589 [(set_attr "type" "alu1")
8590 (set_attr "mode" "QI")])
8592 (define_insn "*<code><mode>_3"
8593 [(set (reg FLAGS_REG)
8594 (compare (any_or:SWI
8595 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8596 (match_operand:SWI 2 "<general_operand>" "<g>"))
8598 (clobber (match_scratch:SWI 0 "=<r>"))]
8599 "ix86_match_ccmode (insn, CCNOmode)
8600 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8601 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8602 [(set_attr "type" "alu")
8603 (set_attr "mode" "<MODE>")])
8605 (define_insn "*<code>qi_ext_0"
8606 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8611 (match_operand 1 "ext_register_operand" "0")
8614 (match_operand 2 "const_int_operand" "n")))
8615 (clobber (reg:CC FLAGS_REG))]
8616 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8617 "<logic>{b}\t{%2, %h0|%h0, %2}"
8618 [(set_attr "type" "alu")
8619 (set_attr "length_immediate" "1")
8620 (set_attr "modrm" "1")
8621 (set_attr "mode" "QI")])
8623 (define_insn "*<code>qi_ext_1"
8624 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8629 (match_operand 1 "ext_register_operand" "0,0")
8633 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8634 (clobber (reg:CC FLAGS_REG))]
8635 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8636 "<logic>{b}\t{%2, %h0|%h0, %2}"
8637 [(set_attr "isa" "*,nox64")
8638 (set_attr "type" "alu")
8639 (set_attr "length_immediate" "0")
8640 (set_attr "mode" "QI")])
8642 (define_insn "*<code>qi_ext_2"
8643 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8647 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8650 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8653 (clobber (reg:CC FLAGS_REG))]
8654 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8655 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8656 [(set_attr "type" "alu")
8657 (set_attr "length_immediate" "0")
8658 (set_attr "mode" "QI")])
8661 [(set (match_operand 0 "register_operand")
8662 (any_or (match_operand 1 "register_operand")
8663 (match_operand 2 "const_int_operand")))
8664 (clobber (reg:CC FLAGS_REG))]
8666 && QI_REG_P (operands[0])
8667 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8668 && !(INTVAL (operands[2]) & ~(255 << 8))
8669 && GET_MODE (operands[0]) != QImode"
8670 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8671 (any_or:SI (zero_extract:SI (match_dup 1)
8672 (const_int 8) (const_int 8))
8674 (clobber (reg:CC FLAGS_REG))])]
8676 operands[0] = gen_lowpart (SImode, operands[0]);
8677 operands[1] = gen_lowpart (SImode, operands[1]);
8678 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8681 ;; Since OR can be encoded with sign extended immediate, this is only
8682 ;; profitable when 7th bit is set.
8684 [(set (match_operand 0 "register_operand")
8685 (any_or (match_operand 1 "general_operand")
8686 (match_operand 2 "const_int_operand")))
8687 (clobber (reg:CC FLAGS_REG))]
8689 && ANY_QI_REG_P (operands[0])
8690 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8691 && !(INTVAL (operands[2]) & ~255)
8692 && (INTVAL (operands[2]) & 128)
8693 && GET_MODE (operands[0]) != QImode"
8694 [(parallel [(set (strict_low_part (match_dup 0))
8695 (any_or:QI (match_dup 1)
8697 (clobber (reg:CC FLAGS_REG))])]
8699 operands[0] = gen_lowpart (QImode, operands[0]);
8700 operands[1] = gen_lowpart (QImode, operands[1]);
8701 operands[2] = gen_lowpart (QImode, operands[2]);
8704 (define_expand "xorqi_cc_ext_1"
8706 (set (reg:CCNO FLAGS_REG)
8710 (match_operand 1 "ext_register_operand")
8713 (match_operand:QI 2 "const_int_operand"))
8715 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8725 (define_insn "*xorqi_cc_ext_1"
8726 [(set (reg FLAGS_REG)
8730 (match_operand 1 "ext_register_operand" "0,0")
8733 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8735 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8744 "ix86_match_ccmode (insn, CCNOmode)"
8745 "xor{b}\t{%2, %h0|%h0, %2}"
8746 [(set_attr "isa" "*,nox64")
8747 (set_attr "type" "alu")
8748 (set_attr "modrm" "1")
8749 (set_attr "mode" "QI")])
8751 ;; Negation instructions
8753 (define_expand "neg<mode>2"
8754 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8755 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8757 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8759 (define_insn_and_split "*neg<dwi>2_doubleword"
8760 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8761 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8762 (clobber (reg:CC FLAGS_REG))]
8763 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8767 [(set (reg:CCZ FLAGS_REG)
8768 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8769 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8772 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8775 (clobber (reg:CC FLAGS_REG))])
8778 (neg:DWIH (match_dup 2)))
8779 (clobber (reg:CC FLAGS_REG))])]
8780 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8782 (define_insn "*neg<mode>2_1"
8783 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8784 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8785 (clobber (reg:CC FLAGS_REG))]
8786 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8787 "neg{<imodesuffix>}\t%0"
8788 [(set_attr "type" "negnot")
8789 (set_attr "mode" "<MODE>")])
8791 ;; Combine is quite creative about this pattern.
8792 (define_insn "*negsi2_1_zext"
8793 [(set (match_operand:DI 0 "register_operand" "=r")
8795 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8798 (clobber (reg:CC FLAGS_REG))]
8799 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8801 [(set_attr "type" "negnot")
8802 (set_attr "mode" "SI")])
8804 ;; The problem with neg is that it does not perform (compare x 0),
8805 ;; it really performs (compare 0 x), which leaves us with the zero
8806 ;; flag being the only useful item.
8808 (define_insn "*neg<mode>2_cmpz"
8809 [(set (reg:CCZ FLAGS_REG)
8811 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8813 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8814 (neg:SWI (match_dup 1)))]
8815 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8816 "neg{<imodesuffix>}\t%0"
8817 [(set_attr "type" "negnot")
8818 (set_attr "mode" "<MODE>")])
8820 (define_insn "*negsi2_cmpz_zext"
8821 [(set (reg:CCZ FLAGS_REG)
8825 (match_operand:DI 1 "register_operand" "0")
8829 (set (match_operand:DI 0 "register_operand" "=r")
8830 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8833 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8835 [(set_attr "type" "negnot")
8836 (set_attr "mode" "SI")])
8838 ;; Negate with jump on overflow.
8839 (define_expand "negv<mode>3"
8840 [(parallel [(set (reg:CCO FLAGS_REG)
8841 (ne:CCO (match_operand:SWI 1 "register_operand")
8843 (set (match_operand:SWI 0 "register_operand")
8844 (neg:SWI (match_dup 1)))])
8845 (set (pc) (if_then_else
8846 (eq (reg:CCO FLAGS_REG) (const_int 0))
8847 (label_ref (match_operand 2))
8852 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8856 (define_insn "*negv<mode>3"
8857 [(set (reg:CCO FLAGS_REG)
8858 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8859 (match_operand:SWI 2 "const_int_operand")))
8860 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8861 (neg:SWI (match_dup 1)))]
8862 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8863 && mode_signbit_p (<MODE>mode, operands[2])"
8864 "neg{<imodesuffix>}\t%0"
8865 [(set_attr "type" "negnot")
8866 (set_attr "mode" "<MODE>")])
8868 ;; Changing of sign for FP values is doable using integer unit too.
8870 (define_expand "<code><mode>2"
8871 [(set (match_operand:X87MODEF 0 "register_operand")
8872 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8873 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8874 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8876 (define_insn "*absneg<mode>2_mixed"
8877 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8878 (match_operator:MODEF 3 "absneg_operator"
8879 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8880 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8881 (clobber (reg:CC FLAGS_REG))]
8882 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8885 (define_insn "*absneg<mode>2_sse"
8886 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8887 (match_operator:MODEF 3 "absneg_operator"
8888 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8889 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8890 (clobber (reg:CC FLAGS_REG))]
8891 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8894 (define_insn "*absneg<mode>2_i387"
8895 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8896 (match_operator:X87MODEF 3 "absneg_operator"
8897 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8898 (use (match_operand 2))
8899 (clobber (reg:CC FLAGS_REG))]
8900 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8903 (define_expand "<code>tf2"
8904 [(set (match_operand:TF 0 "register_operand")
8905 (absneg:TF (match_operand:TF 1 "register_operand")))]
8907 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8909 (define_insn "*absnegtf2_sse"
8910 [(set (match_operand:TF 0 "register_operand" "=x,x")
8911 (match_operator:TF 3 "absneg_operator"
8912 [(match_operand:TF 1 "register_operand" "0,x")]))
8913 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8914 (clobber (reg:CC FLAGS_REG))]
8918 ;; Splitters for fp abs and neg.
8921 [(set (match_operand 0 "fp_register_operand")
8922 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8923 (use (match_operand 2))
8924 (clobber (reg:CC FLAGS_REG))]
8926 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8929 [(set (match_operand 0 "register_operand")
8930 (match_operator 3 "absneg_operator"
8931 [(match_operand 1 "register_operand")]))
8932 (use (match_operand 2 "nonimmediate_operand"))
8933 (clobber (reg:CC FLAGS_REG))]
8934 "reload_completed && SSE_REG_P (operands[0])"
8935 [(set (match_dup 0) (match_dup 3))]
8937 machine_mode mode = GET_MODE (operands[0]);
8938 machine_mode vmode = GET_MODE (operands[2]);
8941 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8942 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8943 if (operands_match_p (operands[0], operands[2]))
8944 std::swap (operands[1], operands[2]);
8945 if (GET_CODE (operands[3]) == ABS)
8946 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8948 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8953 [(set (match_operand:SF 0 "register_operand")
8954 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8955 (use (match_operand:V4SF 2))
8956 (clobber (reg:CC FLAGS_REG))]
8958 [(parallel [(set (match_dup 0) (match_dup 1))
8959 (clobber (reg:CC FLAGS_REG))])]
8962 operands[0] = gen_lowpart (SImode, operands[0]);
8963 if (GET_CODE (operands[1]) == ABS)
8965 tmp = gen_int_mode (0x7fffffff, SImode);
8966 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8970 tmp = gen_int_mode (0x80000000, SImode);
8971 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8977 [(set (match_operand:DF 0 "register_operand")
8978 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8979 (use (match_operand 2))
8980 (clobber (reg:CC FLAGS_REG))]
8982 [(parallel [(set (match_dup 0) (match_dup 1))
8983 (clobber (reg:CC FLAGS_REG))])]
8988 tmp = gen_lowpart (DImode, operands[0]);
8989 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8992 if (GET_CODE (operands[1]) == ABS)
8995 tmp = gen_rtx_NOT (DImode, tmp);
8999 operands[0] = gen_highpart (SImode, operands[0]);
9000 if (GET_CODE (operands[1]) == ABS)
9002 tmp = gen_int_mode (0x7fffffff, SImode);
9003 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9007 tmp = gen_int_mode (0x80000000, SImode);
9008 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9015 [(set (match_operand:XF 0 "register_operand")
9016 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9017 (use (match_operand 2))
9018 (clobber (reg:CC FLAGS_REG))]
9020 [(parallel [(set (match_dup 0) (match_dup 1))
9021 (clobber (reg:CC FLAGS_REG))])]
9024 operands[0] = gen_rtx_REG (SImode,
9025 true_regnum (operands[0])
9026 + (TARGET_64BIT ? 1 : 2));
9027 if (GET_CODE (operands[1]) == ABS)
9029 tmp = GEN_INT (0x7fff);
9030 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9034 tmp = GEN_INT (0x8000);
9035 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9040 ;; Conditionalize these after reload. If they match before reload, we
9041 ;; lose the clobber and ability to use integer instructions.
9043 (define_insn "*<code><mode>2_1"
9044 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9045 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9047 && (reload_completed
9048 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9049 "f<absneg_mnemonic>"
9050 [(set_attr "type" "fsgn")
9051 (set_attr "mode" "<MODE>")])
9053 (define_insn "*<code>extendsfdf2"
9054 [(set (match_operand:DF 0 "register_operand" "=f")
9055 (absneg:DF (float_extend:DF
9056 (match_operand:SF 1 "register_operand" "0"))))]
9057 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9058 "f<absneg_mnemonic>"
9059 [(set_attr "type" "fsgn")
9060 (set_attr "mode" "DF")])
9062 (define_insn "*<code>extendsfxf2"
9063 [(set (match_operand:XF 0 "register_operand" "=f")
9064 (absneg:XF (float_extend:XF
9065 (match_operand:SF 1 "register_operand" "0"))))]
9067 "f<absneg_mnemonic>"
9068 [(set_attr "type" "fsgn")
9069 (set_attr "mode" "XF")])
9071 (define_insn "*<code>extenddfxf2"
9072 [(set (match_operand:XF 0 "register_operand" "=f")
9073 (absneg:XF (float_extend:XF
9074 (match_operand:DF 1 "register_operand" "0"))))]
9076 "f<absneg_mnemonic>"
9077 [(set_attr "type" "fsgn")
9078 (set_attr "mode" "XF")])
9080 ;; Copysign instructions
9082 (define_mode_iterator CSGNMODE [SF DF TF])
9083 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9085 (define_expand "copysign<mode>3"
9086 [(match_operand:CSGNMODE 0 "register_operand")
9087 (match_operand:CSGNMODE 1 "nonmemory_operand")
9088 (match_operand:CSGNMODE 2 "register_operand")]
9089 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9090 || (TARGET_SSE && (<MODE>mode == TFmode))"
9091 "ix86_expand_copysign (operands); DONE;")
9093 (define_insn_and_split "copysign<mode>3_const"
9094 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9096 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9097 (match_operand:CSGNMODE 2 "register_operand" "0")
9098 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9100 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9101 || (TARGET_SSE && (<MODE>mode == TFmode))"
9103 "&& reload_completed"
9105 "ix86_split_copysign_const (operands); DONE;")
9107 (define_insn "copysign<mode>3_var"
9108 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9110 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9111 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9112 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9113 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9115 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9116 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9117 || (TARGET_SSE && (<MODE>mode == TFmode))"
9121 [(set (match_operand:CSGNMODE 0 "register_operand")
9123 [(match_operand:CSGNMODE 2 "register_operand")
9124 (match_operand:CSGNMODE 3 "register_operand")
9125 (match_operand:<CSGNVMODE> 4)
9126 (match_operand:<CSGNVMODE> 5)]
9128 (clobber (match_scratch:<CSGNVMODE> 1))]
9129 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9130 || (TARGET_SSE && (<MODE>mode == TFmode)))
9131 && reload_completed"
9133 "ix86_split_copysign_var (operands); DONE;")
9135 ;; One complement instructions
9137 (define_expand "one_cmpl<mode>2"
9138 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9139 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9141 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9143 (define_insn "*one_cmpl<mode>2_1"
9144 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9145 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9146 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9148 not{<imodesuffix>}\t%0
9149 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9150 [(set_attr "isa" "*,avx512bw")
9151 (set_attr "type" "negnot,msklog")
9152 (set_attr "prefix" "*,vex")
9153 (set_attr "mode" "<MODE>")])
9155 (define_insn "*one_cmplhi2_1"
9156 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9157 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9158 "ix86_unary_operator_ok (NOT, HImode, operands)"
9161 knotw\t{%1, %0|%0, %1}"
9162 [(set_attr "isa" "*,avx512f")
9163 (set_attr "type" "negnot,msklog")
9164 (set_attr "prefix" "*,vex")
9165 (set_attr "mode" "HI")])
9167 ;; %%% Potential partial reg stall on alternative 1. What to do?
9168 (define_insn "*one_cmplqi2_1"
9169 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9170 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9171 "ix86_unary_operator_ok (NOT, QImode, operands)"
9173 switch (which_alternative)
9176 return "not{b}\t%0";
9178 return "not{l}\t%k0";
9180 if (TARGET_AVX512DQ)
9181 return "knotb\t{%1, %0|%0, %1}";
9182 return "knotw\t{%1, %0|%0, %1}";
9187 [(set_attr "isa" "*,*,avx512f")
9188 (set_attr "type" "negnot,negnot,msklog")
9189 (set_attr "prefix" "*,*,vex")
9190 (set_attr "mode" "QI,SI,QI")])
9192 ;; ??? Currently never generated - xor is used instead.
9193 (define_insn "*one_cmplsi2_1_zext"
9194 [(set (match_operand:DI 0 "register_operand" "=r")
9196 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9197 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9199 [(set_attr "type" "negnot")
9200 (set_attr "mode" "SI")])
9202 (define_insn "*one_cmpl<mode>2_2"
9203 [(set (reg FLAGS_REG)
9204 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9206 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9207 (not:SWI (match_dup 1)))]
9208 "ix86_match_ccmode (insn, CCNOmode)
9209 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9211 [(set_attr "type" "alu1")
9212 (set_attr "mode" "<MODE>")])
9215 [(set (match_operand 0 "flags_reg_operand")
9216 (match_operator 2 "compare_operator"
9217 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9219 (set (match_operand:SWI 1 "nonimmediate_operand")
9220 (not:SWI (match_dup 3)))]
9221 "ix86_match_ccmode (insn, CCNOmode)"
9222 [(parallel [(set (match_dup 0)
9223 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9226 (xor:SWI (match_dup 3) (const_int -1)))])])
9228 ;; ??? Currently never generated - xor is used instead.
9229 (define_insn "*one_cmplsi2_2_zext"
9230 [(set (reg FLAGS_REG)
9231 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9233 (set (match_operand:DI 0 "register_operand" "=r")
9234 (zero_extend:DI (not:SI (match_dup 1))))]
9235 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9236 && ix86_unary_operator_ok (NOT, SImode, operands)"
9238 [(set_attr "type" "alu1")
9239 (set_attr "mode" "SI")])
9242 [(set (match_operand 0 "flags_reg_operand")
9243 (match_operator 2 "compare_operator"
9244 [(not:SI (match_operand:SI 3 "register_operand"))
9246 (set (match_operand:DI 1 "register_operand")
9247 (zero_extend:DI (not:SI (match_dup 3))))]
9248 "ix86_match_ccmode (insn, CCNOmode)"
9249 [(parallel [(set (match_dup 0)
9250 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9253 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9255 ;; Shift instructions
9257 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9258 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9259 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9260 ;; from the assembler input.
9262 ;; This instruction shifts the target reg/mem as usual, but instead of
9263 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9264 ;; is a left shift double, bits are taken from the high order bits of
9265 ;; reg, else if the insn is a shift right double, bits are taken from the
9266 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9267 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9269 ;; Since sh[lr]d does not change the `reg' operand, that is done
9270 ;; separately, making all shifts emit pairs of shift double and normal
9271 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9272 ;; support a 63 bit shift, each shift where the count is in a reg expands
9273 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9275 ;; If the shift count is a constant, we need never emit more than one
9276 ;; shift pair, instead using moves and sign extension for counts greater
9279 (define_expand "ashl<mode>3"
9280 [(set (match_operand:SDWIM 0 "<shift_operand>")
9281 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9282 (match_operand:QI 2 "nonmemory_operand")))]
9284 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9286 (define_insn "*ashl<mode>3_doubleword"
9287 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9288 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9289 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9290 (clobber (reg:CC FLAGS_REG))]
9293 [(set_attr "type" "multi")])
9296 [(set (match_operand:DWI 0 "register_operand")
9297 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9298 (match_operand:QI 2 "nonmemory_operand")))
9299 (clobber (reg:CC FLAGS_REG))]
9300 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9302 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9304 ;; By default we don't ask for a scratch register, because when DWImode
9305 ;; values are manipulated, registers are already at a premium. But if
9306 ;; we have one handy, we won't turn it away.
9309 [(match_scratch:DWIH 3 "r")
9310 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9312 (match_operand:<DWI> 1 "nonmemory_operand")
9313 (match_operand:QI 2 "nonmemory_operand")))
9314 (clobber (reg:CC FLAGS_REG))])
9318 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9320 (define_insn "x86_64_shld"
9321 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9322 (ior:DI (ashift:DI (match_dup 0)
9323 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9324 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9325 (minus:QI (const_int 64) (match_dup 2)))))
9326 (clobber (reg:CC FLAGS_REG))]
9328 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9329 [(set_attr "type" "ishift")
9330 (set_attr "prefix_0f" "1")
9331 (set_attr "mode" "DI")
9332 (set_attr "athlon_decode" "vector")
9333 (set_attr "amdfam10_decode" "vector")
9334 (set_attr "bdver1_decode" "vector")])
9336 (define_insn "x86_shld"
9337 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9338 (ior:SI (ashift:SI (match_dup 0)
9339 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9340 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9341 (minus:QI (const_int 32) (match_dup 2)))))
9342 (clobber (reg:CC FLAGS_REG))]
9344 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9345 [(set_attr "type" "ishift")
9346 (set_attr "prefix_0f" "1")
9347 (set_attr "mode" "SI")
9348 (set_attr "pent_pair" "np")
9349 (set_attr "athlon_decode" "vector")
9350 (set_attr "amdfam10_decode" "vector")
9351 (set_attr "bdver1_decode" "vector")])
9353 (define_expand "x86_shift<mode>_adj_1"
9354 [(set (reg:CCZ FLAGS_REG)
9355 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9358 (set (match_operand:SWI48 0 "register_operand")
9359 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9360 (match_operand:SWI48 1 "register_operand")
9363 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9364 (match_operand:SWI48 3 "register_operand")
9367 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9369 (define_expand "x86_shift<mode>_adj_2"
9370 [(use (match_operand:SWI48 0 "register_operand"))
9371 (use (match_operand:SWI48 1 "register_operand"))
9372 (use (match_operand:QI 2 "register_operand"))]
9375 rtx_code_label *label = gen_label_rtx ();
9378 emit_insn (gen_testqi_ccz_1 (operands[2],
9379 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9381 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9382 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9383 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9384 gen_rtx_LABEL_REF (VOIDmode, label),
9386 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9387 JUMP_LABEL (tmp) = label;
9389 emit_move_insn (operands[0], operands[1]);
9390 ix86_expand_clear (operands[1]);
9393 LABEL_NUSES (label) = 1;
9398 ;; Avoid useless masking of count operand.
9399 (define_insn "*ashl<mode>3_mask"
9400 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9402 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9405 (match_operand:SI 2 "register_operand" "c")
9406 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9409 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9410 == GET_MODE_BITSIZE (<MODE>mode)-1"
9412 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9414 [(set_attr "type" "ishift")
9415 (set_attr "mode" "<MODE>")])
9417 (define_insn "*bmi2_ashl<mode>3_1"
9418 [(set (match_operand:SWI48 0 "register_operand" "=r")
9419 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9420 (match_operand:SWI48 2 "register_operand" "r")))]
9422 "shlx\t{%2, %1, %0|%0, %1, %2}"
9423 [(set_attr "type" "ishiftx")
9424 (set_attr "mode" "<MODE>")])
9426 (define_insn "*ashl<mode>3_1"
9427 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9428 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9429 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9430 (clobber (reg:CC FLAGS_REG))]
9431 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9433 switch (get_attr_type (insn))
9440 gcc_assert (operands[2] == const1_rtx);
9441 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9442 return "add{<imodesuffix>}\t%0, %0";
9445 if (operands[2] == const1_rtx
9446 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9447 return "sal{<imodesuffix>}\t%0";
9449 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9452 [(set_attr "isa" "*,*,bmi2")
9454 (cond [(eq_attr "alternative" "1")
9455 (const_string "lea")
9456 (eq_attr "alternative" "2")
9457 (const_string "ishiftx")
9458 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9459 (match_operand 0 "register_operand"))
9460 (match_operand 2 "const1_operand"))
9461 (const_string "alu")
9463 (const_string "ishift")))
9464 (set (attr "length_immediate")
9466 (ior (eq_attr "type" "alu")
9467 (and (eq_attr "type" "ishift")
9468 (and (match_operand 2 "const1_operand")
9469 (ior (match_test "TARGET_SHIFT1")
9470 (match_test "optimize_function_for_size_p (cfun)")))))
9472 (const_string "*")))
9473 (set_attr "mode" "<MODE>")])
9475 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9477 [(set (match_operand:SWI48 0 "register_operand")
9478 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9479 (match_operand:QI 2 "register_operand")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "TARGET_BMI2 && reload_completed"
9483 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9484 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9486 (define_insn "*bmi2_ashlsi3_1_zext"
9487 [(set (match_operand:DI 0 "register_operand" "=r")
9489 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9490 (match_operand:SI 2 "register_operand" "r"))))]
9491 "TARGET_64BIT && TARGET_BMI2"
9492 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9493 [(set_attr "type" "ishiftx")
9494 (set_attr "mode" "SI")])
9496 (define_insn "*ashlsi3_1_zext"
9497 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9499 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9500 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9501 (clobber (reg:CC FLAGS_REG))]
9502 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504 switch (get_attr_type (insn))
9511 gcc_assert (operands[2] == const1_rtx);
9512 return "add{l}\t%k0, %k0";
9515 if (operands[2] == const1_rtx
9516 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9517 return "sal{l}\t%k0";
9519 return "sal{l}\t{%2, %k0|%k0, %2}";
9522 [(set_attr "isa" "*,*,bmi2")
9524 (cond [(eq_attr "alternative" "1")
9525 (const_string "lea")
9526 (eq_attr "alternative" "2")
9527 (const_string "ishiftx")
9528 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9529 (match_operand 2 "const1_operand"))
9530 (const_string "alu")
9532 (const_string "ishift")))
9533 (set (attr "length_immediate")
9535 (ior (eq_attr "type" "alu")
9536 (and (eq_attr "type" "ishift")
9537 (and (match_operand 2 "const1_operand")
9538 (ior (match_test "TARGET_SHIFT1")
9539 (match_test "optimize_function_for_size_p (cfun)")))))
9541 (const_string "*")))
9542 (set_attr "mode" "SI")])
9544 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9546 [(set (match_operand:DI 0 "register_operand")
9548 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9549 (match_operand:QI 2 "register_operand"))))
9550 (clobber (reg:CC FLAGS_REG))]
9551 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9553 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9554 "operands[2] = gen_lowpart (SImode, operands[2]);")
9556 (define_insn "*ashlhi3_1"
9557 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9558 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9559 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9560 (clobber (reg:CC FLAGS_REG))]
9561 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9563 switch (get_attr_type (insn))
9569 gcc_assert (operands[2] == const1_rtx);
9570 return "add{w}\t%0, %0";
9573 if (operands[2] == const1_rtx
9574 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9575 return "sal{w}\t%0";
9577 return "sal{w}\t{%2, %0|%0, %2}";
9581 (cond [(eq_attr "alternative" "1")
9582 (const_string "lea")
9583 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584 (match_operand 0 "register_operand"))
9585 (match_operand 2 "const1_operand"))
9586 (const_string "alu")
9588 (const_string "ishift")))
9589 (set (attr "length_immediate")
9591 (ior (eq_attr "type" "alu")
9592 (and (eq_attr "type" "ishift")
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))))
9597 (const_string "*")))
9598 (set_attr "mode" "HI,SI")])
9600 ;; %%% Potential partial reg stall on alternative 1. What to do?
9601 (define_insn "*ashlqi3_1"
9602 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9603 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9604 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9608 switch (get_attr_type (insn))
9614 gcc_assert (operands[2] == const1_rtx);
9615 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9616 return "add{l}\t%k0, %k0";
9618 return "add{b}\t%0, %0";
9621 if (operands[2] == const1_rtx
9622 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9624 if (get_attr_mode (insn) == MODE_SI)
9625 return "sal{l}\t%k0";
9627 return "sal{b}\t%0";
9631 if (get_attr_mode (insn) == MODE_SI)
9632 return "sal{l}\t{%2, %k0|%k0, %2}";
9634 return "sal{b}\t{%2, %0|%0, %2}";
9639 (cond [(eq_attr "alternative" "2")
9640 (const_string "lea")
9641 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9642 (match_operand 0 "register_operand"))
9643 (match_operand 2 "const1_operand"))
9644 (const_string "alu")
9646 (const_string "ishift")))
9647 (set (attr "length_immediate")
9649 (ior (eq_attr "type" "alu")
9650 (and (eq_attr "type" "ishift")
9651 (and (match_operand 2 "const1_operand")
9652 (ior (match_test "TARGET_SHIFT1")
9653 (match_test "optimize_function_for_size_p (cfun)")))))
9655 (const_string "*")))
9656 (set_attr "mode" "QI,SI,SI")])
9658 (define_insn "*ashlqi3_1_slp"
9659 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9660 (ashift:QI (match_dup 0)
9661 (match_operand:QI 1 "nonmemory_operand" "cI")))
9662 (clobber (reg:CC FLAGS_REG))]
9663 "(optimize_function_for_size_p (cfun)
9664 || !TARGET_PARTIAL_FLAG_REG_STALL
9665 || (operands[1] == const1_rtx
9667 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9669 switch (get_attr_type (insn))
9672 gcc_assert (operands[1] == const1_rtx);
9673 return "add{b}\t%0, %0";
9676 if (operands[1] == const1_rtx
9677 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9678 return "sal{b}\t%0";
9680 return "sal{b}\t{%1, %0|%0, %1}";
9684 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9685 (match_operand 0 "register_operand"))
9686 (match_operand 1 "const1_operand"))
9687 (const_string "alu")
9689 (const_string "ishift1")))
9690 (set (attr "length_immediate")
9692 (ior (eq_attr "type" "alu")
9693 (and (eq_attr "type" "ishift1")
9694 (and (match_operand 1 "const1_operand")
9695 (ior (match_test "TARGET_SHIFT1")
9696 (match_test "optimize_function_for_size_p (cfun)")))))
9698 (const_string "*")))
9699 (set_attr "mode" "QI")])
9701 ;; Convert ashift to the lea pattern to avoid flags dependency.
9703 [(set (match_operand 0 "register_operand")
9704 (ashift (match_operand 1 "index_register_operand")
9705 (match_operand:QI 2 "const_int_operand")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9709 && true_regnum (operands[0]) != true_regnum (operands[1])"
9712 machine_mode mode = GET_MODE (operands[0]);
9715 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9718 operands[0] = gen_lowpart (mode, operands[0]);
9719 operands[1] = gen_lowpart (mode, operands[1]);
9722 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9724 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9726 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9730 ;; Convert ashift to the lea pattern to avoid flags dependency.
9732 [(set (match_operand:DI 0 "register_operand")
9734 (ashift:SI (match_operand:SI 1 "index_register_operand")
9735 (match_operand:QI 2 "const_int_operand"))))
9736 (clobber (reg:CC FLAGS_REG))]
9737 "TARGET_64BIT && reload_completed
9738 && true_regnum (operands[0]) != true_regnum (operands[1])"
9740 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9742 operands[1] = gen_lowpart (SImode, operands[1]);
9743 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9746 ;; This pattern can't accept a variable shift count, since shifts by
9747 ;; zero don't affect the flags. We assume that shifts by constant
9748 ;; zero are optimized away.
9749 (define_insn "*ashl<mode>3_cmp"
9750 [(set (reg FLAGS_REG)
9752 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9753 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9755 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9756 (ashift:SWI (match_dup 1) (match_dup 2)))]
9757 "(optimize_function_for_size_p (cfun)
9758 || !TARGET_PARTIAL_FLAG_REG_STALL
9759 || (operands[2] == const1_rtx
9761 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9762 && ix86_match_ccmode (insn, CCGOCmode)
9763 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9765 switch (get_attr_type (insn))
9768 gcc_assert (operands[2] == const1_rtx);
9769 return "add{<imodesuffix>}\t%0, %0";
9772 if (operands[2] == const1_rtx
9773 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9774 return "sal{<imodesuffix>}\t%0";
9776 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9780 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9781 (match_operand 0 "register_operand"))
9782 (match_operand 2 "const1_operand"))
9783 (const_string "alu")
9785 (const_string "ishift")))
9786 (set (attr "length_immediate")
9788 (ior (eq_attr "type" "alu")
9789 (and (eq_attr "type" "ishift")
9790 (and (match_operand 2 "const1_operand")
9791 (ior (match_test "TARGET_SHIFT1")
9792 (match_test "optimize_function_for_size_p (cfun)")))))
9794 (const_string "*")))
9795 (set_attr "mode" "<MODE>")])
9797 (define_insn "*ashlsi3_cmp_zext"
9798 [(set (reg FLAGS_REG)
9800 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9801 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9803 (set (match_operand:DI 0 "register_operand" "=r")
9804 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9806 && (optimize_function_for_size_p (cfun)
9807 || !TARGET_PARTIAL_FLAG_REG_STALL
9808 || (operands[2] == const1_rtx
9810 || TARGET_DOUBLE_WITH_ADD)))
9811 && ix86_match_ccmode (insn, CCGOCmode)
9812 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9814 switch (get_attr_type (insn))
9817 gcc_assert (operands[2] == const1_rtx);
9818 return "add{l}\t%k0, %k0";
9821 if (operands[2] == const1_rtx
9822 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9823 return "sal{l}\t%k0";
9825 return "sal{l}\t{%2, %k0|%k0, %2}";
9829 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9830 (match_operand 2 "const1_operand"))
9831 (const_string "alu")
9833 (const_string "ishift")))
9834 (set (attr "length_immediate")
9836 (ior (eq_attr "type" "alu")
9837 (and (eq_attr "type" "ishift")
9838 (and (match_operand 2 "const1_operand")
9839 (ior (match_test "TARGET_SHIFT1")
9840 (match_test "optimize_function_for_size_p (cfun)")))))
9842 (const_string "*")))
9843 (set_attr "mode" "SI")])
9845 (define_insn "*ashl<mode>3_cconly"
9846 [(set (reg FLAGS_REG)
9848 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9849 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9851 (clobber (match_scratch:SWI 0 "=<r>"))]
9852 "(optimize_function_for_size_p (cfun)
9853 || !TARGET_PARTIAL_FLAG_REG_STALL
9854 || (operands[2] == const1_rtx
9856 || TARGET_DOUBLE_WITH_ADD)))
9857 && ix86_match_ccmode (insn, CCGOCmode)"
9859 switch (get_attr_type (insn))
9862 gcc_assert (operands[2] == const1_rtx);
9863 return "add{<imodesuffix>}\t%0, %0";
9866 if (operands[2] == const1_rtx
9867 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9868 return "sal{<imodesuffix>}\t%0";
9870 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9874 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9875 (match_operand 0 "register_operand"))
9876 (match_operand 2 "const1_operand"))
9877 (const_string "alu")
9879 (const_string "ishift")))
9880 (set (attr "length_immediate")
9882 (ior (eq_attr "type" "alu")
9883 (and (eq_attr "type" "ishift")
9884 (and (match_operand 2 "const1_operand")
9885 (ior (match_test "TARGET_SHIFT1")
9886 (match_test "optimize_function_for_size_p (cfun)")))))
9888 (const_string "*")))
9889 (set_attr "mode" "<MODE>")])
9891 ;; See comment above `ashl<mode>3' about how this works.
9893 (define_expand "<shift_insn><mode>3"
9894 [(set (match_operand:SDWIM 0 "<shift_operand>")
9895 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9896 (match_operand:QI 2 "nonmemory_operand")))]
9898 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9900 ;; Avoid useless masking of count operand.
9901 (define_insn "*<shift_insn><mode>3_mask"
9902 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9904 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9907 (match_operand:SI 2 "register_operand" "c")
9908 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9909 (clobber (reg:CC FLAGS_REG))]
9910 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9911 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9912 == GET_MODE_BITSIZE (<MODE>mode)-1"
9914 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9916 [(set_attr "type" "ishift")
9917 (set_attr "mode" "<MODE>")])
9919 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9920 [(set (match_operand:DWI 0 "register_operand" "=r")
9921 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9922 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9923 (clobber (reg:CC FLAGS_REG))]
9926 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9928 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9929 [(set_attr "type" "multi")])
9931 ;; By default we don't ask for a scratch register, because when DWImode
9932 ;; values are manipulated, registers are already at a premium. But if
9933 ;; we have one handy, we won't turn it away.
9936 [(match_scratch:DWIH 3 "r")
9937 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9939 (match_operand:<DWI> 1 "register_operand")
9940 (match_operand:QI 2 "nonmemory_operand")))
9941 (clobber (reg:CC FLAGS_REG))])
9945 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9947 (define_insn "x86_64_shrd"
9948 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9949 (ior:DI (lshiftrt:DI (match_dup 0)
9950 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9951 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9952 (minus:QI (const_int 64) (match_dup 2)))))
9953 (clobber (reg:CC FLAGS_REG))]
9955 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9956 [(set_attr "type" "ishift")
9957 (set_attr "prefix_0f" "1")
9958 (set_attr "mode" "DI")
9959 (set_attr "athlon_decode" "vector")
9960 (set_attr "amdfam10_decode" "vector")
9961 (set_attr "bdver1_decode" "vector")])
9963 (define_insn "x86_shrd"
9964 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9965 (ior:SI (lshiftrt:SI (match_dup 0)
9966 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9967 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9968 (minus:QI (const_int 32) (match_dup 2)))))
9969 (clobber (reg:CC FLAGS_REG))]
9971 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9972 [(set_attr "type" "ishift")
9973 (set_attr "prefix_0f" "1")
9974 (set_attr "mode" "SI")
9975 (set_attr "pent_pair" "np")
9976 (set_attr "athlon_decode" "vector")
9977 (set_attr "amdfam10_decode" "vector")
9978 (set_attr "bdver1_decode" "vector")])
9980 (define_insn "ashrdi3_cvt"
9981 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9982 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9983 (match_operand:QI 2 "const_int_operand")))
9984 (clobber (reg:CC FLAGS_REG))]
9985 "TARGET_64BIT && INTVAL (operands[2]) == 63
9986 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9987 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9990 sar{q}\t{%2, %0|%0, %2}"
9991 [(set_attr "type" "imovx,ishift")
9992 (set_attr "prefix_0f" "0,*")
9993 (set_attr "length_immediate" "0,*")
9994 (set_attr "modrm" "0,1")
9995 (set_attr "mode" "DI")])
9997 (define_insn "ashrsi3_cvt"
9998 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9999 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10000 (match_operand:QI 2 "const_int_operand")))
10001 (clobber (reg:CC FLAGS_REG))]
10002 "INTVAL (operands[2]) == 31
10003 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10004 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10007 sar{l}\t{%2, %0|%0, %2}"
10008 [(set_attr "type" "imovx,ishift")
10009 (set_attr "prefix_0f" "0,*")
10010 (set_attr "length_immediate" "0,*")
10011 (set_attr "modrm" "0,1")
10012 (set_attr "mode" "SI")])
10014 (define_insn "*ashrsi3_cvt_zext"
10015 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10017 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10018 (match_operand:QI 2 "const_int_operand"))))
10019 (clobber (reg:CC FLAGS_REG))]
10020 "TARGET_64BIT && INTVAL (operands[2]) == 31
10021 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10022 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10025 sar{l}\t{%2, %k0|%k0, %2}"
10026 [(set_attr "type" "imovx,ishift")
10027 (set_attr "prefix_0f" "0,*")
10028 (set_attr "length_immediate" "0,*")
10029 (set_attr "modrm" "0,1")
10030 (set_attr "mode" "SI")])
10032 (define_expand "x86_shift<mode>_adj_3"
10033 [(use (match_operand:SWI48 0 "register_operand"))
10034 (use (match_operand:SWI48 1 "register_operand"))
10035 (use (match_operand:QI 2 "register_operand"))]
10038 rtx_code_label *label = gen_label_rtx ();
10041 emit_insn (gen_testqi_ccz_1 (operands[2],
10042 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10044 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10045 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10046 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10047 gen_rtx_LABEL_REF (VOIDmode, label),
10049 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10050 JUMP_LABEL (tmp) = label;
10052 emit_move_insn (operands[0], operands[1]);
10053 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10054 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10055 emit_label (label);
10056 LABEL_NUSES (label) = 1;
10061 (define_insn "*bmi2_<shift_insn><mode>3_1"
10062 [(set (match_operand:SWI48 0 "register_operand" "=r")
10063 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10064 (match_operand:SWI48 2 "register_operand" "r")))]
10066 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10067 [(set_attr "type" "ishiftx")
10068 (set_attr "mode" "<MODE>")])
10070 (define_insn "*<shift_insn><mode>3_1"
10071 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10073 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10074 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10075 (clobber (reg:CC FLAGS_REG))]
10076 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10078 switch (get_attr_type (insn))
10084 if (operands[2] == const1_rtx
10085 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086 return "<shift>{<imodesuffix>}\t%0";
10088 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10091 [(set_attr "isa" "*,bmi2")
10092 (set_attr "type" "ishift,ishiftx")
10093 (set (attr "length_immediate")
10095 (and (match_operand 2 "const1_operand")
10096 (ior (match_test "TARGET_SHIFT1")
10097 (match_test "optimize_function_for_size_p (cfun)")))
10099 (const_string "*")))
10100 (set_attr "mode" "<MODE>")])
10102 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10104 [(set (match_operand:SWI48 0 "register_operand")
10105 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10106 (match_operand:QI 2 "register_operand")))
10107 (clobber (reg:CC FLAGS_REG))]
10108 "TARGET_BMI2 && reload_completed"
10109 [(set (match_dup 0)
10110 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10111 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10113 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10114 [(set (match_operand:DI 0 "register_operand" "=r")
10116 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10117 (match_operand:SI 2 "register_operand" "r"))))]
10118 "TARGET_64BIT && TARGET_BMI2"
10119 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10120 [(set_attr "type" "ishiftx")
10121 (set_attr "mode" "SI")])
10123 (define_insn "*<shift_insn>si3_1_zext"
10124 [(set (match_operand:DI 0 "register_operand" "=r,r")
10126 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10127 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10128 (clobber (reg:CC FLAGS_REG))]
10129 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10131 switch (get_attr_type (insn))
10137 if (operands[2] == const1_rtx
10138 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10139 return "<shift>{l}\t%k0";
10141 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10144 [(set_attr "isa" "*,bmi2")
10145 (set_attr "type" "ishift,ishiftx")
10146 (set (attr "length_immediate")
10148 (and (match_operand 2 "const1_operand")
10149 (ior (match_test "TARGET_SHIFT1")
10150 (match_test "optimize_function_for_size_p (cfun)")))
10152 (const_string "*")))
10153 (set_attr "mode" "SI")])
10155 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10157 [(set (match_operand:DI 0 "register_operand")
10159 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10160 (match_operand:QI 2 "register_operand"))))
10161 (clobber (reg:CC FLAGS_REG))]
10162 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10163 [(set (match_dup 0)
10164 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10165 "operands[2] = gen_lowpart (SImode, operands[2]);")
10167 (define_insn "*<shift_insn><mode>3_1"
10168 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10170 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10171 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10172 (clobber (reg:CC FLAGS_REG))]
10173 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10175 if (operands[2] == const1_rtx
10176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10177 return "<shift>{<imodesuffix>}\t%0";
10179 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10181 [(set_attr "type" "ishift")
10182 (set (attr "length_immediate")
10184 (and (match_operand 2 "const1_operand")
10185 (ior (match_test "TARGET_SHIFT1")
10186 (match_test "optimize_function_for_size_p (cfun)")))
10188 (const_string "*")))
10189 (set_attr "mode" "<MODE>")])
10191 (define_insn "*<shift_insn>qi3_1_slp"
10192 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10193 (any_shiftrt:QI (match_dup 0)
10194 (match_operand:QI 1 "nonmemory_operand" "cI")))
10195 (clobber (reg:CC FLAGS_REG))]
10196 "(optimize_function_for_size_p (cfun)
10197 || !TARGET_PARTIAL_REG_STALL
10198 || (operands[1] == const1_rtx
10199 && TARGET_SHIFT1))"
10201 if (operands[1] == const1_rtx
10202 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10203 return "<shift>{b}\t%0";
10205 return "<shift>{b}\t{%1, %0|%0, %1}";
10207 [(set_attr "type" "ishift1")
10208 (set (attr "length_immediate")
10210 (and (match_operand 1 "const1_operand")
10211 (ior (match_test "TARGET_SHIFT1")
10212 (match_test "optimize_function_for_size_p (cfun)")))
10214 (const_string "*")))
10215 (set_attr "mode" "QI")])
10217 ;; This pattern can't accept a variable shift count, since shifts by
10218 ;; zero don't affect the flags. We assume that shifts by constant
10219 ;; zero are optimized away.
10220 (define_insn "*<shift_insn><mode>3_cmp"
10221 [(set (reg FLAGS_REG)
10224 (match_operand:SWI 1 "nonimmediate_operand" "0")
10225 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10227 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10228 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10229 "(optimize_function_for_size_p (cfun)
10230 || !TARGET_PARTIAL_FLAG_REG_STALL
10231 || (operands[2] == const1_rtx
10233 && ix86_match_ccmode (insn, CCGOCmode)
10234 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10236 if (operands[2] == const1_rtx
10237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238 return "<shift>{<imodesuffix>}\t%0";
10240 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10242 [(set_attr "type" "ishift")
10243 (set (attr "length_immediate")
10245 (and (match_operand 2 "const1_operand")
10246 (ior (match_test "TARGET_SHIFT1")
10247 (match_test "optimize_function_for_size_p (cfun)")))
10249 (const_string "*")))
10250 (set_attr "mode" "<MODE>")])
10252 (define_insn "*<shift_insn>si3_cmp_zext"
10253 [(set (reg FLAGS_REG)
10255 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10256 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10258 (set (match_operand:DI 0 "register_operand" "=r")
10259 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10261 && (optimize_function_for_size_p (cfun)
10262 || !TARGET_PARTIAL_FLAG_REG_STALL
10263 || (operands[2] == const1_rtx
10265 && ix86_match_ccmode (insn, CCGOCmode)
10266 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10268 if (operands[2] == const1_rtx
10269 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10270 return "<shift>{l}\t%k0";
10272 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10274 [(set_attr "type" "ishift")
10275 (set (attr "length_immediate")
10277 (and (match_operand 2 "const1_operand")
10278 (ior (match_test "TARGET_SHIFT1")
10279 (match_test "optimize_function_for_size_p (cfun)")))
10281 (const_string "*")))
10282 (set_attr "mode" "SI")])
10284 (define_insn "*<shift_insn><mode>3_cconly"
10285 [(set (reg FLAGS_REG)
10288 (match_operand:SWI 1 "register_operand" "0")
10289 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10291 (clobber (match_scratch:SWI 0 "=<r>"))]
10292 "(optimize_function_for_size_p (cfun)
10293 || !TARGET_PARTIAL_FLAG_REG_STALL
10294 || (operands[2] == const1_rtx
10296 && ix86_match_ccmode (insn, CCGOCmode)"
10298 if (operands[2] == const1_rtx
10299 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10300 return "<shift>{<imodesuffix>}\t%0";
10302 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10304 [(set_attr "type" "ishift")
10305 (set (attr "length_immediate")
10307 (and (match_operand 2 "const1_operand")
10308 (ior (match_test "TARGET_SHIFT1")
10309 (match_test "optimize_function_for_size_p (cfun)")))
10311 (const_string "*")))
10312 (set_attr "mode" "<MODE>")])
10314 ;; Rotate instructions
10316 (define_expand "<rotate_insn>ti3"
10317 [(set (match_operand:TI 0 "register_operand")
10318 (any_rotate:TI (match_operand:TI 1 "register_operand")
10319 (match_operand:QI 2 "nonmemory_operand")))]
10322 if (const_1_to_63_operand (operands[2], VOIDmode))
10323 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10324 (operands[0], operands[1], operands[2]));
10331 (define_expand "<rotate_insn>di3"
10332 [(set (match_operand:DI 0 "shiftdi_operand")
10333 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10334 (match_operand:QI 2 "nonmemory_operand")))]
10338 ix86_expand_binary_operator (<CODE>, DImode, operands);
10339 else if (const_1_to_31_operand (operands[2], VOIDmode))
10340 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10341 (operands[0], operands[1], operands[2]));
10348 (define_expand "<rotate_insn><mode>3"
10349 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10350 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10351 (match_operand:QI 2 "nonmemory_operand")))]
10353 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10355 ;; Avoid useless masking of count operand.
10356 (define_insn "*<rotate_insn><mode>3_mask"
10357 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10359 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10362 (match_operand:SI 2 "register_operand" "c")
10363 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10366 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10367 == GET_MODE_BITSIZE (<MODE>mode)-1"
10369 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10371 [(set_attr "type" "rotate")
10372 (set_attr "mode" "<MODE>")])
10374 ;; Implement rotation using two double-precision
10375 ;; shift instructions and a scratch register.
10377 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10378 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10379 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10380 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10381 (clobber (reg:CC FLAGS_REG))
10382 (clobber (match_scratch:DWIH 3 "=&r"))]
10386 [(set (match_dup 3) (match_dup 4))
10388 [(set (match_dup 4)
10389 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10390 (lshiftrt:DWIH (match_dup 5)
10391 (minus:QI (match_dup 6) (match_dup 2)))))
10392 (clobber (reg:CC FLAGS_REG))])
10394 [(set (match_dup 5)
10395 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10396 (lshiftrt:DWIH (match_dup 3)
10397 (minus:QI (match_dup 6) (match_dup 2)))))
10398 (clobber (reg:CC FLAGS_REG))])]
10400 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10402 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10405 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10406 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10407 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10408 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10409 (clobber (reg:CC FLAGS_REG))
10410 (clobber (match_scratch:DWIH 3 "=&r"))]
10414 [(set (match_dup 3) (match_dup 4))
10416 [(set (match_dup 4)
10417 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10418 (ashift:DWIH (match_dup 5)
10419 (minus:QI (match_dup 6) (match_dup 2)))))
10420 (clobber (reg:CC FLAGS_REG))])
10422 [(set (match_dup 5)
10423 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10424 (ashift:DWIH (match_dup 3)
10425 (minus:QI (match_dup 6) (match_dup 2)))))
10426 (clobber (reg:CC FLAGS_REG))])]
10428 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10430 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10433 (define_insn "*bmi2_rorx<mode>3_1"
10434 [(set (match_operand:SWI48 0 "register_operand" "=r")
10435 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10436 (match_operand:QI 2 "immediate_operand" "<S>")))]
10438 "rorx\t{%2, %1, %0|%0, %1, %2}"
10439 [(set_attr "type" "rotatex")
10440 (set_attr "mode" "<MODE>")])
10442 (define_insn "*<rotate_insn><mode>3_1"
10443 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10445 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10446 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10447 (clobber (reg:CC FLAGS_REG))]
10448 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10450 switch (get_attr_type (insn))
10456 if (operands[2] == const1_rtx
10457 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10458 return "<rotate>{<imodesuffix>}\t%0";
10460 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10463 [(set_attr "isa" "*,bmi2")
10464 (set_attr "type" "rotate,rotatex")
10465 (set (attr "length_immediate")
10467 (and (eq_attr "type" "rotate")
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 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10477 [(set (match_operand:SWI48 0 "register_operand")
10478 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10479 (match_operand:QI 2 "immediate_operand")))
10480 (clobber (reg:CC FLAGS_REG))]
10481 "TARGET_BMI2 && reload_completed"
10482 [(set (match_dup 0)
10483 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10486 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10490 [(set (match_operand:SWI48 0 "register_operand")
10491 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10492 (match_operand:QI 2 "immediate_operand")))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "TARGET_BMI2 && reload_completed"
10495 [(set (match_dup 0)
10496 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10498 (define_insn "*bmi2_rorxsi3_1_zext"
10499 [(set (match_operand:DI 0 "register_operand" "=r")
10501 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10502 (match_operand:QI 2 "immediate_operand" "I"))))]
10503 "TARGET_64BIT && TARGET_BMI2"
10504 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10505 [(set_attr "type" "rotatex")
10506 (set_attr "mode" "SI")])
10508 (define_insn "*<rotate_insn>si3_1_zext"
10509 [(set (match_operand:DI 0 "register_operand" "=r,r")
10511 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10512 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10516 switch (get_attr_type (insn))
10522 if (operands[2] == const1_rtx
10523 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10524 return "<rotate>{l}\t%k0";
10526 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10529 [(set_attr "isa" "*,bmi2")
10530 (set_attr "type" "rotate,rotatex")
10531 (set (attr "length_immediate")
10533 (and (eq_attr "type" "rotate")
10534 (and (match_operand 2 "const1_operand")
10535 (ior (match_test "TARGET_SHIFT1")
10536 (match_test "optimize_function_for_size_p (cfun)"))))
10538 (const_string "*")))
10539 (set_attr "mode" "SI")])
10541 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10543 [(set (match_operand:DI 0 "register_operand")
10545 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10546 (match_operand:QI 2 "immediate_operand"))))
10547 (clobber (reg:CC FLAGS_REG))]
10548 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10549 [(set (match_dup 0)
10550 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10553 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10557 [(set (match_operand:DI 0 "register_operand")
10559 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10560 (match_operand:QI 2 "immediate_operand"))))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10563 [(set (match_dup 0)
10564 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10566 (define_insn "*<rotate_insn><mode>3_1"
10567 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10568 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10569 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10570 (clobber (reg:CC FLAGS_REG))]
10571 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10573 if (operands[2] == const1_rtx
10574 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10575 return "<rotate>{<imodesuffix>}\t%0";
10577 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10579 [(set_attr "type" "rotate")
10580 (set (attr "length_immediate")
10582 (and (match_operand 2 "const1_operand")
10583 (ior (match_test "TARGET_SHIFT1")
10584 (match_test "optimize_function_for_size_p (cfun)")))
10586 (const_string "*")))
10587 (set_attr "mode" "<MODE>")])
10589 (define_insn "*<rotate_insn>qi3_1_slp"
10590 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10591 (any_rotate:QI (match_dup 0)
10592 (match_operand:QI 1 "nonmemory_operand" "cI")))
10593 (clobber (reg:CC FLAGS_REG))]
10594 "(optimize_function_for_size_p (cfun)
10595 || !TARGET_PARTIAL_REG_STALL
10596 || (operands[1] == const1_rtx
10597 && TARGET_SHIFT1))"
10599 if (operands[1] == const1_rtx
10600 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10601 return "<rotate>{b}\t%0";
10603 return "<rotate>{b}\t{%1, %0|%0, %1}";
10605 [(set_attr "type" "rotate1")
10606 (set (attr "length_immediate")
10608 (and (match_operand 1 "const1_operand")
10609 (ior (match_test "TARGET_SHIFT1")
10610 (match_test "optimize_function_for_size_p (cfun)")))
10612 (const_string "*")))
10613 (set_attr "mode" "QI")])
10616 [(set (match_operand:HI 0 "register_operand")
10617 (any_rotate:HI (match_dup 0) (const_int 8)))
10618 (clobber (reg:CC FLAGS_REG))]
10620 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10621 [(parallel [(set (strict_low_part (match_dup 0))
10622 (bswap:HI (match_dup 0)))
10623 (clobber (reg:CC FLAGS_REG))])])
10625 ;; Bit set / bit test instructions
10627 (define_expand "extv"
10628 [(set (match_operand:SI 0 "register_operand")
10629 (sign_extract:SI (match_operand:SI 1 "register_operand")
10630 (match_operand:SI 2 "const8_operand")
10631 (match_operand:SI 3 "const8_operand")))]
10634 /* Handle extractions from %ah et al. */
10635 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10638 /* From mips.md: extract_bit_field doesn't verify that our source
10639 matches the predicate, so check it again here. */
10640 if (! ext_register_operand (operands[1], VOIDmode))
10644 (define_expand "extzv"
10645 [(set (match_operand:SI 0 "register_operand")
10646 (zero_extract:SI (match_operand 1 "ext_register_operand")
10647 (match_operand:SI 2 "const8_operand")
10648 (match_operand:SI 3 "const8_operand")))]
10651 /* Handle extractions from %ah et al. */
10652 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10655 /* From mips.md: extract_bit_field doesn't verify that our source
10656 matches the predicate, so check it again here. */
10657 if (! ext_register_operand (operands[1], VOIDmode))
10661 (define_expand "insv"
10662 [(set (zero_extract (match_operand 0 "register_operand")
10663 (match_operand 1 "const_int_operand")
10664 (match_operand 2 "const_int_operand"))
10665 (match_operand 3 "register_operand"))]
10668 rtx (*gen_mov_insv_1) (rtx, rtx);
10670 if (ix86_expand_pinsr (operands))
10673 /* Handle insertions to %ah et al. */
10674 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10677 /* From mips.md: insert_bit_field doesn't verify that our source
10678 matches the predicate, so check it again here. */
10679 if (! ext_register_operand (operands[0], VOIDmode))
10682 gen_mov_insv_1 = (TARGET_64BIT
10683 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10685 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10689 ;; %%% bts, btr, btc, bt.
10690 ;; In general these instructions are *slow* when applied to memory,
10691 ;; since they enforce atomic operation. When applied to registers,
10692 ;; it depends on the cpu implementation. They're never faster than
10693 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10694 ;; no point. But in 64-bit, we can't hold the relevant immediates
10695 ;; within the instruction itself, so operating on bits in the high
10696 ;; 32-bits of a register becomes easier.
10698 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10699 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10700 ;; negdf respectively, so they can never be disabled entirely.
10702 (define_insn "*btsq"
10703 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10705 (match_operand:DI 1 "const_0_to_63_operand"))
10707 (clobber (reg:CC FLAGS_REG))]
10708 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10709 "bts{q}\t{%1, %0|%0, %1}"
10710 [(set_attr "type" "alu1")
10711 (set_attr "prefix_0f" "1")
10712 (set_attr "mode" "DI")])
10714 (define_insn "*btrq"
10715 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10717 (match_operand:DI 1 "const_0_to_63_operand"))
10719 (clobber (reg:CC FLAGS_REG))]
10720 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10721 "btr{q}\t{%1, %0|%0, %1}"
10722 [(set_attr "type" "alu1")
10723 (set_attr "prefix_0f" "1")
10724 (set_attr "mode" "DI")])
10726 (define_insn "*btcq"
10727 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10729 (match_operand:DI 1 "const_0_to_63_operand"))
10730 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10731 (clobber (reg:CC FLAGS_REG))]
10732 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10733 "btc{q}\t{%1, %0|%0, %1}"
10734 [(set_attr "type" "alu1")
10735 (set_attr "prefix_0f" "1")
10736 (set_attr "mode" "DI")])
10738 ;; Allow Nocona to avoid these instructions if a register is available.
10741 [(match_scratch:DI 2 "r")
10742 (parallel [(set (zero_extract:DI
10743 (match_operand:DI 0 "register_operand")
10745 (match_operand:DI 1 "const_0_to_63_operand"))
10747 (clobber (reg:CC FLAGS_REG))])]
10748 "TARGET_64BIT && !TARGET_USE_BT"
10751 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10754 if (HOST_BITS_PER_WIDE_INT >= 64)
10755 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10756 else if (i < HOST_BITS_PER_WIDE_INT)
10757 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10759 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10761 op1 = immed_double_const (lo, hi, DImode);
10764 emit_move_insn (operands[2], op1);
10768 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10773 [(match_scratch:DI 2 "r")
10774 (parallel [(set (zero_extract:DI
10775 (match_operand:DI 0 "register_operand")
10777 (match_operand:DI 1 "const_0_to_63_operand"))
10779 (clobber (reg:CC FLAGS_REG))])]
10780 "TARGET_64BIT && !TARGET_USE_BT"
10783 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10786 if (HOST_BITS_PER_WIDE_INT >= 64)
10787 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10788 else if (i < HOST_BITS_PER_WIDE_INT)
10789 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10791 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10793 op1 = immed_double_const (~lo, ~hi, DImode);
10796 emit_move_insn (operands[2], op1);
10800 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10805 [(match_scratch:DI 2 "r")
10806 (parallel [(set (zero_extract:DI
10807 (match_operand:DI 0 "register_operand")
10809 (match_operand:DI 1 "const_0_to_63_operand"))
10810 (not:DI (zero_extract:DI
10811 (match_dup 0) (const_int 1) (match_dup 1))))
10812 (clobber (reg:CC FLAGS_REG))])]
10813 "TARGET_64BIT && !TARGET_USE_BT"
10816 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10819 if (HOST_BITS_PER_WIDE_INT >= 64)
10820 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10821 else if (i < HOST_BITS_PER_WIDE_INT)
10822 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10824 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10826 op1 = immed_double_const (lo, hi, DImode);
10829 emit_move_insn (operands[2], op1);
10833 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10837 (define_insn "*bt<mode>"
10838 [(set (reg:CCC FLAGS_REG)
10840 (zero_extract:SWI48
10841 (match_operand:SWI48 0 "register_operand" "r")
10843 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10845 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10846 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10847 [(set_attr "type" "alu1")
10848 (set_attr "prefix_0f" "1")
10849 (set_attr "mode" "<MODE>")])
10851 ;; Store-flag instructions.
10853 ;; For all sCOND expanders, also expand the compare or test insn that
10854 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10856 (define_insn_and_split "*setcc_di_1"
10857 [(set (match_operand:DI 0 "register_operand" "=q")
10858 (match_operator:DI 1 "ix86_comparison_operator"
10859 [(reg FLAGS_REG) (const_int 0)]))]
10860 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10862 "&& reload_completed"
10863 [(set (match_dup 2) (match_dup 1))
10864 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10866 operands[1] = shallow_copy_rtx (operands[1]);
10867 PUT_MODE (operands[1], QImode);
10868 operands[2] = gen_lowpart (QImode, operands[0]);
10871 (define_insn_and_split "*setcc_si_1_and"
10872 [(set (match_operand:SI 0 "register_operand" "=q")
10873 (match_operator:SI 1 "ix86_comparison_operator"
10874 [(reg FLAGS_REG) (const_int 0)]))
10875 (clobber (reg:CC FLAGS_REG))]
10876 "!TARGET_PARTIAL_REG_STALL
10877 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10879 "&& reload_completed"
10880 [(set (match_dup 2) (match_dup 1))
10881 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10882 (clobber (reg:CC FLAGS_REG))])]
10884 operands[1] = shallow_copy_rtx (operands[1]);
10885 PUT_MODE (operands[1], QImode);
10886 operands[2] = gen_lowpart (QImode, operands[0]);
10889 (define_insn_and_split "*setcc_si_1_movzbl"
10890 [(set (match_operand:SI 0 "register_operand" "=q")
10891 (match_operator:SI 1 "ix86_comparison_operator"
10892 [(reg FLAGS_REG) (const_int 0)]))]
10893 "!TARGET_PARTIAL_REG_STALL
10894 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10896 "&& reload_completed"
10897 [(set (match_dup 2) (match_dup 1))
10898 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10900 operands[1] = shallow_copy_rtx (operands[1]);
10901 PUT_MODE (operands[1], QImode);
10902 operands[2] = gen_lowpart (QImode, operands[0]);
10905 (define_insn "*setcc_qi"
10906 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10907 (match_operator:QI 1 "ix86_comparison_operator"
10908 [(reg FLAGS_REG) (const_int 0)]))]
10911 [(set_attr "type" "setcc")
10912 (set_attr "mode" "QI")])
10914 (define_insn "*setcc_qi_slp"
10915 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10916 (match_operator:QI 1 "ix86_comparison_operator"
10917 [(reg FLAGS_REG) (const_int 0)]))]
10920 [(set_attr "type" "setcc")
10921 (set_attr "mode" "QI")])
10923 ;; In general it is not safe to assume too much about CCmode registers,
10924 ;; so simplify-rtx stops when it sees a second one. Under certain
10925 ;; conditions this is safe on x86, so help combine not create
10932 [(set (match_operand:QI 0 "nonimmediate_operand")
10933 (ne:QI (match_operator 1 "ix86_comparison_operator"
10934 [(reg FLAGS_REG) (const_int 0)])
10937 [(set (match_dup 0) (match_dup 1))]
10939 operands[1] = shallow_copy_rtx (operands[1]);
10940 PUT_MODE (operands[1], QImode);
10944 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10945 (ne:QI (match_operator 1 "ix86_comparison_operator"
10946 [(reg FLAGS_REG) (const_int 0)])
10949 [(set (match_dup 0) (match_dup 1))]
10951 operands[1] = shallow_copy_rtx (operands[1]);
10952 PUT_MODE (operands[1], QImode);
10956 [(set (match_operand:QI 0 "nonimmediate_operand")
10957 (eq:QI (match_operator 1 "ix86_comparison_operator"
10958 [(reg FLAGS_REG) (const_int 0)])
10961 [(set (match_dup 0) (match_dup 1))]
10963 operands[1] = shallow_copy_rtx (operands[1]);
10964 PUT_MODE (operands[1], QImode);
10965 PUT_CODE (operands[1],
10966 ix86_reverse_condition (GET_CODE (operands[1]),
10967 GET_MODE (XEXP (operands[1], 0))));
10969 /* Make sure that (a) the CCmode we have for the flags is strong
10970 enough for the reversed compare or (b) we have a valid FP compare. */
10971 if (! ix86_comparison_operator (operands[1], VOIDmode))
10976 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10977 (eq:QI (match_operator 1 "ix86_comparison_operator"
10978 [(reg FLAGS_REG) (const_int 0)])
10981 [(set (match_dup 0) (match_dup 1))]
10983 operands[1] = shallow_copy_rtx (operands[1]);
10984 PUT_MODE (operands[1], QImode);
10985 PUT_CODE (operands[1],
10986 ix86_reverse_condition (GET_CODE (operands[1]),
10987 GET_MODE (XEXP (operands[1], 0))));
10989 /* Make sure that (a) the CCmode we have for the flags is strong
10990 enough for the reversed compare or (b) we have a valid FP compare. */
10991 if (! ix86_comparison_operator (operands[1], VOIDmode))
10995 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10996 ;; subsequent logical operations are used to imitate conditional moves.
10997 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11000 (define_insn "setcc_<mode>_sse"
11001 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11002 (match_operator:MODEF 3 "sse_comparison_operator"
11003 [(match_operand:MODEF 1 "register_operand" "0,x")
11004 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11005 "SSE_FLOAT_MODE_P (<MODE>mode)"
11007 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11008 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11009 [(set_attr "isa" "noavx,avx")
11010 (set_attr "type" "ssecmp")
11011 (set_attr "length_immediate" "1")
11012 (set_attr "prefix" "orig,vex")
11013 (set_attr "mode" "<MODE>")])
11015 ;; Basic conditional jump instructions.
11016 ;; We ignore the overflow flag for signed branch instructions.
11018 (define_insn "*jcc_1_bnd"
11020 (if_then_else (match_operator 1 "ix86_comparison_operator"
11021 [(reg FLAGS_REG) (const_int 0)])
11022 (label_ref (match_operand 0))
11024 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11026 [(set_attr "type" "ibr")
11027 (set_attr "modrm" "0")
11028 (set (attr "length")
11029 (if_then_else (and (ge (minus (match_dup 0) (pc))
11031 (lt (minus (match_dup 0) (pc))
11036 (define_insn "*jcc_1"
11038 (if_then_else (match_operator 1 "ix86_comparison_operator"
11039 [(reg FLAGS_REG) (const_int 0)])
11040 (label_ref (match_operand 0))
11044 [(set_attr "type" "ibr")
11045 (set_attr "modrm" "0")
11046 (set (attr "length")
11047 (if_then_else (and (ge (minus (match_dup 0) (pc))
11049 (lt (minus (match_dup 0) (pc))
11054 (define_insn "*jcc_2_bnd"
11056 (if_then_else (match_operator 1 "ix86_comparison_operator"
11057 [(reg FLAGS_REG) (const_int 0)])
11059 (label_ref (match_operand 0))))]
11060 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11062 [(set_attr "type" "ibr")
11063 (set_attr "modrm" "0")
11064 (set (attr "length")
11065 (if_then_else (and (ge (minus (match_dup 0) (pc))
11067 (lt (minus (match_dup 0) (pc))
11072 (define_insn "*jcc_2"
11074 (if_then_else (match_operator 1 "ix86_comparison_operator"
11075 [(reg FLAGS_REG) (const_int 0)])
11077 (label_ref (match_operand 0))))]
11080 [(set_attr "type" "ibr")
11081 (set_attr "modrm" "0")
11082 (set (attr "length")
11083 (if_then_else (and (ge (minus (match_dup 0) (pc))
11085 (lt (minus (match_dup 0) (pc))
11090 ;; In general it is not safe to assume too much about CCmode registers,
11091 ;; so simplify-rtx stops when it sees a second one. Under certain
11092 ;; conditions this is safe on x86, so help combine not create
11100 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11101 [(reg FLAGS_REG) (const_int 0)])
11103 (label_ref (match_operand 1))
11107 (if_then_else (match_dup 0)
11108 (label_ref (match_dup 1))
11111 operands[0] = shallow_copy_rtx (operands[0]);
11112 PUT_MODE (operands[0], VOIDmode);
11117 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11118 [(reg FLAGS_REG) (const_int 0)])
11120 (label_ref (match_operand 1))
11124 (if_then_else (match_dup 0)
11125 (label_ref (match_dup 1))
11128 operands[0] = shallow_copy_rtx (operands[0]);
11129 PUT_MODE (operands[0], VOIDmode);
11130 PUT_CODE (operands[0],
11131 ix86_reverse_condition (GET_CODE (operands[0]),
11132 GET_MODE (XEXP (operands[0], 0))));
11134 /* Make sure that (a) the CCmode we have for the flags is strong
11135 enough for the reversed compare or (b) we have a valid FP compare. */
11136 if (! ix86_comparison_operator (operands[0], VOIDmode))
11140 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11141 ;; pass generates from shift insn with QImode operand. Actually, the mode
11142 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11143 ;; appropriate modulo of the bit offset value.
11145 (define_insn_and_split "*jcc_bt<mode>"
11147 (if_then_else (match_operator 0 "bt_comparison_operator"
11148 [(zero_extract:SWI48
11149 (match_operand:SWI48 1 "register_operand" "r")
11152 (match_operand:QI 2 "register_operand" "r")))
11154 (label_ref (match_operand 3))
11156 (clobber (reg:CC FLAGS_REG))]
11157 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
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 3))
11172 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11173 operands[0] = shallow_copy_rtx (operands[0]);
11174 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11177 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11178 ;; zero extended to SImode.
11179 (define_insn_and_split "*jcc_bt<mode>_1"
11181 (if_then_else (match_operator 0 "bt_comparison_operator"
11182 [(zero_extract:SWI48
11183 (match_operand:SWI48 1 "register_operand" "r")
11185 (match_operand:SI 2 "register_operand" "r"))
11187 (label_ref (match_operand 3))
11189 (clobber (reg:CC FLAGS_REG))]
11190 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11193 [(set (reg:CCC FLAGS_REG)
11195 (zero_extract:SWI48
11201 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11202 (label_ref (match_dup 3))
11205 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11206 operands[0] = shallow_copy_rtx (operands[0]);
11207 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11210 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11211 ;; also for DImode, this is what combine produces.
11212 (define_insn_and_split "*jcc_bt<mode>_mask"
11214 (if_then_else (match_operator 0 "bt_comparison_operator"
11215 [(zero_extract:SWI48
11216 (match_operand:SWI48 1 "register_operand" "r")
11219 (match_operand:SI 2 "register_operand" "r")
11220 (match_operand:SI 3 "const_int_operand" "n")))])
11221 (label_ref (match_operand 4))
11223 (clobber (reg:CC FLAGS_REG))]
11224 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11226 == GET_MODE_BITSIZE (<MODE>mode)-1"
11229 [(set (reg:CCC FLAGS_REG)
11231 (zero_extract:SWI48
11237 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11238 (label_ref (match_dup 4))
11241 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11242 operands[0] = shallow_copy_rtx (operands[0]);
11243 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11246 (define_insn_and_split "*jcc_btsi_1"
11248 (if_then_else (match_operator 0 "bt_comparison_operator"
11251 (match_operand:SI 1 "register_operand" "r")
11252 (match_operand:QI 2 "register_operand" "r"))
11255 (label_ref (match_operand 3))
11257 (clobber (reg:CC FLAGS_REG))]
11258 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11261 [(set (reg:CCC FLAGS_REG)
11269 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11270 (label_ref (match_dup 3))
11273 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11274 operands[0] = shallow_copy_rtx (operands[0]);
11275 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11278 ;; avoid useless masking of bit offset operand
11279 (define_insn_and_split "*jcc_btsi_mask_1"
11282 (match_operator 0 "bt_comparison_operator"
11285 (match_operand:SI 1 "register_operand" "r")
11288 (match_operand:SI 2 "register_operand" "r")
11289 (match_operand:SI 3 "const_int_operand" "n")) 0))
11292 (label_ref (match_operand 4))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11296 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11299 [(set (reg:CCC FLAGS_REG)
11307 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11308 (label_ref (match_dup 4))
11311 operands[0] = shallow_copy_rtx (operands[0]);
11312 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11315 ;; Define combination compare-and-branch fp compare instructions to help
11318 (define_insn "*jcc<mode>_0_i387"
11320 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11321 [(match_operand:X87MODEF 1 "register_operand" "f")
11322 (match_operand:X87MODEF 2 "const0_operand")])
11323 (label_ref (match_operand 3))
11325 (clobber (reg:CCFP FPSR_REG))
11326 (clobber (reg:CCFP FLAGS_REG))
11327 (clobber (match_scratch:HI 4 "=a"))]
11328 "TARGET_80387 && !TARGET_CMOVE"
11331 (define_insn "*jcc<mode>_0_r_i387"
11333 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11334 [(match_operand:X87MODEF 1 "register_operand" "f")
11335 (match_operand:X87MODEF 2 "const0_operand")])
11337 (label_ref (match_operand 3))))
11338 (clobber (reg:CCFP FPSR_REG))
11339 (clobber (reg:CCFP FLAGS_REG))
11340 (clobber (match_scratch:HI 4 "=a"))]
11341 "TARGET_80387 && !TARGET_CMOVE"
11344 (define_insn "*jccxf_i387"
11346 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11347 [(match_operand:XF 1 "register_operand" "f")
11348 (match_operand:XF 2 "register_operand" "f")])
11349 (label_ref (match_operand 3))
11351 (clobber (reg:CCFP FPSR_REG))
11352 (clobber (reg:CCFP FLAGS_REG))
11353 (clobber (match_scratch:HI 4 "=a"))]
11354 "TARGET_80387 && !TARGET_CMOVE"
11357 (define_insn "*jccxf_r_i387"
11359 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11360 [(match_operand:XF 1 "register_operand" "f")
11361 (match_operand:XF 2 "register_operand" "f")])
11363 (label_ref (match_operand 3))))
11364 (clobber (reg:CCFP FPSR_REG))
11365 (clobber (reg:CCFP FLAGS_REG))
11366 (clobber (match_scratch:HI 4 "=a"))]
11367 "TARGET_80387 && !TARGET_CMOVE"
11370 (define_insn "*jcc<mode>_i387"
11372 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11373 [(match_operand:MODEF 1 "register_operand" "f")
11374 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11375 (label_ref (match_operand 3))
11377 (clobber (reg:CCFP FPSR_REG))
11378 (clobber (reg:CCFP FLAGS_REG))
11379 (clobber (match_scratch:HI 4 "=a"))]
11380 "TARGET_80387 && !TARGET_CMOVE"
11383 (define_insn "*jcc<mode>_r_i387"
11385 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11386 [(match_operand:MODEF 1 "register_operand" "f")
11387 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11389 (label_ref (match_operand 3))))
11390 (clobber (reg:CCFP FPSR_REG))
11391 (clobber (reg:CCFP FLAGS_REG))
11392 (clobber (match_scratch:HI 4 "=a"))]
11393 "TARGET_80387 && !TARGET_CMOVE"
11396 (define_insn "*jccu<mode>_i387"
11398 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11399 [(match_operand:X87MODEF 1 "register_operand" "f")
11400 (match_operand:X87MODEF 2 "register_operand" "f")])
11401 (label_ref (match_operand 3))
11403 (clobber (reg:CCFP FPSR_REG))
11404 (clobber (reg:CCFP FLAGS_REG))
11405 (clobber (match_scratch:HI 4 "=a"))]
11406 "TARGET_80387 && !TARGET_CMOVE"
11409 (define_insn "*jccu<mode>_r_i387"
11411 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11412 [(match_operand:X87MODEF 1 "register_operand" "f")
11413 (match_operand:X87MODEF 2 "register_operand" "f")])
11415 (label_ref (match_operand 3))))
11416 (clobber (reg:CCFP FPSR_REG))
11417 (clobber (reg:CCFP FLAGS_REG))
11418 (clobber (match_scratch:HI 4 "=a"))]
11419 "TARGET_80387 && !TARGET_CMOVE"
11424 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11425 [(match_operand:X87MODEF 1 "register_operand")
11426 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11428 (match_operand 4)))
11429 (clobber (reg:CCFP FPSR_REG))
11430 (clobber (reg:CCFP FLAGS_REG))]
11431 "TARGET_80387 && !TARGET_CMOVE
11432 && reload_completed"
11435 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11436 operands[3], operands[4], NULL_RTX);
11442 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11443 [(match_operand:X87MODEF 1 "register_operand")
11444 (match_operand:X87MODEF 2 "general_operand")])
11446 (match_operand 4)))
11447 (clobber (reg:CCFP FPSR_REG))
11448 (clobber (reg:CCFP FLAGS_REG))
11449 (clobber (match_scratch:HI 5))]
11450 "TARGET_80387 && !TARGET_CMOVE
11451 && reload_completed"
11454 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11455 operands[3], operands[4], operands[5]);
11459 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11460 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11461 ;; with a precedence over other operators and is always put in the first
11462 ;; place. Swap condition and operands to match ficom instruction.
11464 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11467 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11468 [(match_operator:X87MODEF 1 "float_operator"
11469 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11470 (match_operand:X87MODEF 3 "register_operand" "f")])
11471 (label_ref (match_operand 4))
11473 (clobber (reg:CCFP FPSR_REG))
11474 (clobber (reg:CCFP FLAGS_REG))
11475 (clobber (match_scratch:HI 5 "=a"))]
11476 "TARGET_80387 && !TARGET_CMOVE
11477 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11478 || optimize_function_for_size_p (cfun))"
11481 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11484 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11485 [(match_operator:X87MODEF 1 "float_operator"
11486 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11487 (match_operand:X87MODEF 3 "register_operand" "f")])
11489 (label_ref (match_operand 4))))
11490 (clobber (reg:CCFP FPSR_REG))
11491 (clobber (reg:CCFP FLAGS_REG))
11492 (clobber (match_scratch:HI 5 "=a"))]
11493 "TARGET_80387 && !TARGET_CMOVE
11494 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11495 || optimize_function_for_size_p (cfun))"
11501 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11502 [(match_operator:X87MODEF 1 "float_operator"
11503 [(match_operand:SWI24 2 "memory_operand")])
11504 (match_operand:X87MODEF 3 "register_operand")])
11506 (match_operand 5)))
11507 (clobber (reg:CCFP FPSR_REG))
11508 (clobber (reg:CCFP FLAGS_REG))
11509 (clobber (match_scratch:HI 6))]
11510 "TARGET_80387 && !TARGET_CMOVE
11511 && reload_completed"
11514 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11515 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11516 operands[4], operands[5], operands[6]);
11520 ;; Unconditional and other jump instructions
11522 (define_insn "jump_bnd"
11524 (label_ref (match_operand 0)))]
11525 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11527 [(set_attr "type" "ibr")
11528 (set (attr "length")
11529 (if_then_else (and (ge (minus (match_dup 0) (pc))
11531 (lt (minus (match_dup 0) (pc))
11535 (set_attr "modrm" "0")])
11537 (define_insn "jump"
11539 (label_ref (match_operand 0)))]
11542 [(set_attr "type" "ibr")
11543 (set (attr "length")
11544 (if_then_else (and (ge (minus (match_dup 0) (pc))
11546 (lt (minus (match_dup 0) (pc))
11550 (set_attr "modrm" "0")])
11552 (define_expand "indirect_jump"
11553 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11557 operands[0] = convert_memory_address (word_mode, operands[0]);
11560 (define_insn "*indirect_jump"
11561 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11564 [(set_attr "type" "ibr")
11565 (set_attr "length_immediate" "0")])
11567 (define_expand "tablejump"
11568 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11569 (use (label_ref (match_operand 1)))])]
11572 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11573 relative. Convert the relative address to an absolute address. */
11577 enum rtx_code code;
11579 /* We can't use @GOTOFF for text labels on VxWorks;
11580 see gotoff_operand. */
11581 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11585 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11587 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11591 op1 = pic_offset_table_rtx;
11596 op0 = pic_offset_table_rtx;
11600 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11605 operands[0] = convert_memory_address (word_mode, operands[0]);
11608 (define_insn "*tablejump_1"
11609 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11610 (use (label_ref (match_operand 1)))]
11613 [(set_attr "type" "ibr")
11614 (set_attr "length_immediate" "0")])
11616 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11619 [(set (reg FLAGS_REG) (match_operand 0))
11620 (set (match_operand:QI 1 "register_operand")
11621 (match_operator:QI 2 "ix86_comparison_operator"
11622 [(reg FLAGS_REG) (const_int 0)]))
11623 (set (match_operand 3 "q_regs_operand")
11624 (zero_extend (match_dup 1)))]
11625 "(peep2_reg_dead_p (3, operands[1])
11626 || operands_match_p (operands[1], operands[3]))
11627 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11628 [(set (match_dup 4) (match_dup 0))
11629 (set (strict_low_part (match_dup 5))
11632 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11633 operands[5] = gen_lowpart (QImode, operands[3]);
11634 ix86_expand_clear (operands[3]);
11638 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11639 (match_operand 4)])
11640 (set (match_operand:QI 1 "register_operand")
11641 (match_operator:QI 2 "ix86_comparison_operator"
11642 [(reg FLAGS_REG) (const_int 0)]))
11643 (set (match_operand 3 "q_regs_operand")
11644 (zero_extend (match_dup 1)))]
11645 "(peep2_reg_dead_p (3, operands[1])
11646 || operands_match_p (operands[1], operands[3]))
11647 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11648 [(parallel [(set (match_dup 5) (match_dup 0))
11650 (set (strict_low_part (match_dup 6))
11653 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11654 operands[6] = gen_lowpart (QImode, operands[3]);
11655 ix86_expand_clear (operands[3]);
11658 ;; Similar, but match zero extend with andsi3.
11661 [(set (reg FLAGS_REG) (match_operand 0))
11662 (set (match_operand:QI 1 "register_operand")
11663 (match_operator:QI 2 "ix86_comparison_operator"
11664 [(reg FLAGS_REG) (const_int 0)]))
11665 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11666 (and:SI (match_dup 3) (const_int 255)))
11667 (clobber (reg:CC FLAGS_REG))])]
11668 "REGNO (operands[1]) == REGNO (operands[3])
11669 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11670 [(set (match_dup 4) (match_dup 0))
11671 (set (strict_low_part (match_dup 5))
11674 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11675 operands[5] = gen_lowpart (QImode, operands[3]);
11676 ix86_expand_clear (operands[3]);
11680 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11681 (match_operand 4)])
11682 (set (match_operand:QI 1 "register_operand")
11683 (match_operator:QI 2 "ix86_comparison_operator"
11684 [(reg FLAGS_REG) (const_int 0)]))
11685 (parallel [(set (match_operand 3 "q_regs_operand")
11686 (zero_extend (match_dup 1)))
11687 (clobber (reg:CC FLAGS_REG))])]
11688 "(peep2_reg_dead_p (3, operands[1])
11689 || operands_match_p (operands[1], operands[3]))
11690 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11691 [(parallel [(set (match_dup 5) (match_dup 0))
11693 (set (strict_low_part (match_dup 6))
11696 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11697 operands[6] = gen_lowpart (QImode, operands[3]);
11698 ix86_expand_clear (operands[3]);
11701 ;; Call instructions.
11703 ;; The predicates normally associated with named expanders are not properly
11704 ;; checked for calls. This is a bug in the generic code, but it isn't that
11705 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11707 ;; P6 processors will jump to the address after the decrement when %esp
11708 ;; is used as a call operand, so they will execute return address as a code.
11709 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11711 ;; Register constraint for call instruction.
11712 (define_mode_attr c [(SI "l") (DI "r")])
11714 ;; Call subroutine returning no value.
11716 (define_expand "call"
11717 [(call (match_operand:QI 0)
11719 (use (match_operand 2))]
11722 ix86_expand_call (NULL, operands[0], operands[1],
11723 operands[2], NULL, false);
11727 (define_expand "sibcall"
11728 [(call (match_operand:QI 0)
11730 (use (match_operand 2))]
11733 ix86_expand_call (NULL, operands[0], operands[1],
11734 operands[2], NULL, true);
11738 (define_insn "*call"
11739 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11740 (match_operand 1))]
11741 "!SIBLING_CALL_P (insn)"
11742 "* return ix86_output_call_insn (insn, operands[0]);"
11743 [(set_attr "type" "call")])
11745 (define_insn "*sibcall"
11746 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11747 (match_operand 1))]
11748 "SIBLING_CALL_P (insn)"
11749 "* return ix86_output_call_insn (insn, operands[0]);"
11750 [(set_attr "type" "call")])
11752 (define_insn "*sibcall_memory"
11753 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11755 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11757 "* return ix86_output_call_insn (insn, operands[0]);"
11758 [(set_attr "type" "call")])
11761 [(set (match_operand:W 0 "register_operand")
11762 (match_operand:W 1 "memory_operand"))
11763 (call (mem:QI (match_dup 0))
11764 (match_operand 3))]
11765 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11766 && peep2_reg_dead_p (2, operands[0])"
11767 [(parallel [(call (mem:QI (match_dup 1))
11769 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11772 [(set (match_operand:W 0 "register_operand")
11773 (match_operand:W 1 "memory_operand"))
11774 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11775 (call (mem:QI (match_dup 0))
11776 (match_operand 3))]
11777 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11778 && peep2_reg_dead_p (3, operands[0])"
11779 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11780 (parallel [(call (mem:QI (match_dup 1))
11782 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11784 (define_expand "call_pop"
11785 [(parallel [(call (match_operand:QI 0)
11786 (match_operand:SI 1))
11787 (set (reg:SI SP_REG)
11788 (plus:SI (reg:SI SP_REG)
11789 (match_operand:SI 3)))])]
11792 ix86_expand_call (NULL, operands[0], operands[1],
11793 operands[2], operands[3], false);
11797 (define_insn "*call_pop"
11798 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11800 (set (reg:SI SP_REG)
11801 (plus:SI (reg:SI SP_REG)
11802 (match_operand:SI 2 "immediate_operand" "i")))]
11803 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11804 "* return ix86_output_call_insn (insn, operands[0]);"
11805 [(set_attr "type" "call")])
11807 (define_insn "*sibcall_pop"
11808 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11810 (set (reg:SI SP_REG)
11811 (plus:SI (reg:SI SP_REG)
11812 (match_operand:SI 2 "immediate_operand" "i")))]
11813 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11814 "* return ix86_output_call_insn (insn, operands[0]);"
11815 [(set_attr "type" "call")])
11817 (define_insn "*sibcall_pop_memory"
11818 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11820 (set (reg:SI SP_REG)
11821 (plus:SI (reg:SI SP_REG)
11822 (match_operand:SI 2 "immediate_operand" "i")))
11823 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11825 "* return ix86_output_call_insn (insn, operands[0]);"
11826 [(set_attr "type" "call")])
11829 [(set (match_operand:SI 0 "register_operand")
11830 (match_operand:SI 1 "memory_operand"))
11831 (parallel [(call (mem:QI (match_dup 0))
11833 (set (reg:SI SP_REG)
11834 (plus:SI (reg:SI SP_REG)
11835 (match_operand:SI 4 "immediate_operand")))])]
11836 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11837 && peep2_reg_dead_p (2, operands[0])"
11838 [(parallel [(call (mem:QI (match_dup 1))
11840 (set (reg:SI SP_REG)
11841 (plus:SI (reg:SI SP_REG)
11843 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11846 [(set (match_operand:SI 0 "register_operand")
11847 (match_operand:SI 1 "memory_operand"))
11848 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11849 (parallel [(call (mem:QI (match_dup 0))
11851 (set (reg:SI SP_REG)
11852 (plus:SI (reg:SI SP_REG)
11853 (match_operand:SI 4 "immediate_operand")))])]
11854 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11855 && peep2_reg_dead_p (3, operands[0])"
11856 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11857 (parallel [(call (mem:QI (match_dup 1))
11859 (set (reg:SI SP_REG)
11860 (plus:SI (reg:SI SP_REG)
11862 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11864 ;; Combining simple memory jump instruction
11867 [(set (match_operand:W 0 "register_operand")
11868 (match_operand:W 1 "memory_operand"))
11869 (set (pc) (match_dup 0))]
11870 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11871 [(set (pc) (match_dup 1))])
11873 ;; Call subroutine, returning value in operand 0
11875 (define_expand "call_value"
11876 [(set (match_operand 0)
11877 (call (match_operand:QI 1)
11878 (match_operand 2)))
11879 (use (match_operand 3))]
11882 ix86_expand_call (operands[0], operands[1], operands[2],
11883 operands[3], NULL, false);
11887 (define_expand "sibcall_value"
11888 [(set (match_operand 0)
11889 (call (match_operand:QI 1)
11890 (match_operand 2)))
11891 (use (match_operand 3))]
11894 ix86_expand_call (operands[0], operands[1], operands[2],
11895 operands[3], NULL, true);
11899 (define_insn "*call_value"
11900 [(set (match_operand 0)
11901 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11902 (match_operand 2)))]
11903 "!SIBLING_CALL_P (insn)"
11904 "* return ix86_output_call_insn (insn, operands[1]);"
11905 [(set_attr "type" "callv")])
11907 (define_insn "*sibcall_value"
11908 [(set (match_operand 0)
11909 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11910 (match_operand 2)))]
11911 "SIBLING_CALL_P (insn)"
11912 "* return ix86_output_call_insn (insn, operands[1]);"
11913 [(set_attr "type" "callv")])
11915 (define_insn "*sibcall_value_memory"
11916 [(set (match_operand 0)
11917 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11918 (match_operand 2)))
11919 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11921 "* return ix86_output_call_insn (insn, operands[1]);"
11922 [(set_attr "type" "callv")])
11925 [(set (match_operand:W 0 "register_operand")
11926 (match_operand:W 1 "memory_operand"))
11927 (set (match_operand 2)
11928 (call (mem:QI (match_dup 0))
11929 (match_operand 3)))]
11930 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11931 && peep2_reg_dead_p (2, operands[0])"
11932 [(parallel [(set (match_dup 2)
11933 (call (mem:QI (match_dup 1))
11935 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11938 [(set (match_operand:W 0 "register_operand")
11939 (match_operand:W 1 "memory_operand"))
11940 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11941 (set (match_operand 2)
11942 (call (mem:QI (match_dup 0))
11943 (match_operand 3)))]
11944 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11945 && peep2_reg_dead_p (3, operands[0])"
11946 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11947 (parallel [(set (match_dup 2)
11948 (call (mem:QI (match_dup 1))
11950 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11952 (define_expand "call_value_pop"
11953 [(parallel [(set (match_operand 0)
11954 (call (match_operand:QI 1)
11955 (match_operand:SI 2)))
11956 (set (reg:SI SP_REG)
11957 (plus:SI (reg:SI SP_REG)
11958 (match_operand:SI 4)))])]
11961 ix86_expand_call (operands[0], operands[1], operands[2],
11962 operands[3], operands[4], false);
11966 (define_insn "*call_value_pop"
11967 [(set (match_operand 0)
11968 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11969 (match_operand 2)))
11970 (set (reg:SI SP_REG)
11971 (plus:SI (reg:SI SP_REG)
11972 (match_operand:SI 3 "immediate_operand" "i")))]
11973 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11974 "* return ix86_output_call_insn (insn, operands[1]);"
11975 [(set_attr "type" "callv")])
11977 (define_insn "*sibcall_value_pop"
11978 [(set (match_operand 0)
11979 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11980 (match_operand 2)))
11981 (set (reg:SI SP_REG)
11982 (plus:SI (reg:SI SP_REG)
11983 (match_operand:SI 3 "immediate_operand" "i")))]
11984 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11985 "* return ix86_output_call_insn (insn, operands[1]);"
11986 [(set_attr "type" "callv")])
11988 (define_insn "*sibcall_value_pop_memory"
11989 [(set (match_operand 0)
11990 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11991 (match_operand 2)))
11992 (set (reg:SI SP_REG)
11993 (plus:SI (reg:SI SP_REG)
11994 (match_operand:SI 3 "immediate_operand" "i")))
11995 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11997 "* return ix86_output_call_insn (insn, operands[1]);"
11998 [(set_attr "type" "callv")])
12001 [(set (match_operand:SI 0 "register_operand")
12002 (match_operand:SI 1 "memory_operand"))
12003 (parallel [(set (match_operand 2)
12004 (call (mem:QI (match_dup 0))
12005 (match_operand 3)))
12006 (set (reg:SI SP_REG)
12007 (plus:SI (reg:SI SP_REG)
12008 (match_operand:SI 4 "immediate_operand")))])]
12009 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12010 && peep2_reg_dead_p (2, operands[0])"
12011 [(parallel [(set (match_dup 2)
12012 (call (mem:QI (match_dup 1))
12014 (set (reg:SI SP_REG)
12015 (plus:SI (reg:SI SP_REG)
12017 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12020 [(set (match_operand:SI 0 "register_operand")
12021 (match_operand:SI 1 "memory_operand"))
12022 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12023 (parallel [(set (match_operand 2)
12024 (call (mem:QI (match_dup 0))
12025 (match_operand 3)))
12026 (set (reg:SI SP_REG)
12027 (plus:SI (reg:SI SP_REG)
12028 (match_operand:SI 4 "immediate_operand")))])]
12029 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12030 && peep2_reg_dead_p (3, operands[0])"
12031 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12032 (parallel [(set (match_dup 2)
12033 (call (mem:QI (match_dup 1))
12035 (set (reg:SI SP_REG)
12036 (plus:SI (reg:SI SP_REG)
12038 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12040 ;; Call subroutine returning any type.
12042 (define_expand "untyped_call"
12043 [(parallel [(call (match_operand 0)
12046 (match_operand 2)])]
12051 /* In order to give reg-stack an easier job in validating two
12052 coprocessor registers as containing a possible return value,
12053 simply pretend the untyped call returns a complex long double
12056 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12057 and should have the default ABI. */
12059 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12060 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12061 operands[0], const0_rtx,
12062 GEN_INT ((TARGET_64BIT
12063 ? (ix86_abi == SYSV_ABI
12064 ? X86_64_SSE_REGPARM_MAX
12065 : X86_64_MS_SSE_REGPARM_MAX)
12066 : X86_32_SSE_REGPARM_MAX)
12070 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12072 rtx set = XVECEXP (operands[2], 0, i);
12073 emit_move_insn (SET_DEST (set), SET_SRC (set));
12076 /* The optimizer does not know that the call sets the function value
12077 registers we stored in the result block. We avoid problems by
12078 claiming that all hard registers are used and clobbered at this
12080 emit_insn (gen_blockage ());
12085 ;; Prologue and epilogue instructions
12087 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12088 ;; all of memory. This blocks insns from being moved across this point.
12090 (define_insn "blockage"
12091 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12094 [(set_attr "length" "0")])
12096 ;; Do not schedule instructions accessing memory across this point.
12098 (define_expand "memory_blockage"
12099 [(set (match_dup 0)
12100 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12103 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12104 MEM_VOLATILE_P (operands[0]) = 1;
12107 (define_insn "*memory_blockage"
12108 [(set (match_operand:BLK 0)
12109 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12112 [(set_attr "length" "0")])
12114 ;; As USE insns aren't meaningful after reload, this is used instead
12115 ;; to prevent deleting instructions setting registers for PIC code
12116 (define_insn "prologue_use"
12117 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12120 [(set_attr "length" "0")])
12122 ;; Insn emitted into the body of a function to return from a function.
12123 ;; This is only done if the function's epilogue is known to be simple.
12124 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12126 (define_expand "return"
12128 "ix86_can_use_return_insn_p ()"
12130 if (crtl->args.pops_args)
12132 rtx popc = GEN_INT (crtl->args.pops_args);
12133 emit_jump_insn (gen_simple_return_pop_internal (popc));
12138 ;; We need to disable this for TARGET_SEH, as otherwise
12139 ;; shrink-wrapped prologue gets enabled too. This might exceed
12140 ;; the maximum size of prologue in unwind information.
12141 ;; Also disallow shrink-wrapping if using stack slot to pass the
12142 ;; static chain pointer - the first instruction has to be pushl %esi
12143 ;; and it can't be moved around, as we use alternate entry points
12146 (define_expand "simple_return"
12148 "!TARGET_SEH && !ix86_static_chain_on_stack"
12150 if (crtl->args.pops_args)
12152 rtx popc = GEN_INT (crtl->args.pops_args);
12153 emit_jump_insn (gen_simple_return_pop_internal (popc));
12158 (define_insn "simple_return_internal"
12162 [(set_attr "length_nobnd" "1")
12163 (set_attr "atom_unit" "jeu")
12164 (set_attr "length_immediate" "0")
12165 (set_attr "modrm" "0")])
12167 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12168 ;; instruction Athlon and K8 have.
12170 (define_insn "simple_return_internal_long"
12172 (unspec [(const_int 0)] UNSPEC_REP)]
12175 if (ix86_bnd_prefixed_insn_p (insn))
12178 return "rep%; ret";
12180 [(set_attr "length" "2")
12181 (set_attr "atom_unit" "jeu")
12182 (set_attr "length_immediate" "0")
12183 (set_attr "prefix_rep" "1")
12184 (set_attr "modrm" "0")])
12186 (define_insn "simple_return_pop_internal"
12188 (use (match_operand:SI 0 "const_int_operand"))]
12191 [(set_attr "length_nobnd" "3")
12192 (set_attr "atom_unit" "jeu")
12193 (set_attr "length_immediate" "2")
12194 (set_attr "modrm" "0")])
12196 (define_insn "simple_return_indirect_internal"
12198 (use (match_operand:SI 0 "register_operand" "r"))]
12201 [(set_attr "type" "ibr")
12202 (set_attr "length_immediate" "0")])
12208 [(set_attr "length" "1")
12209 (set_attr "length_immediate" "0")
12210 (set_attr "modrm" "0")])
12212 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12213 (define_insn "nops"
12214 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12218 int num = INTVAL (operands[0]);
12220 gcc_assert (IN_RANGE (num, 1, 8));
12223 fputs ("\tnop\n", asm_out_file);
12227 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12228 (set_attr "length_immediate" "0")
12229 (set_attr "modrm" "0")])
12231 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12232 ;; branch prediction penalty for the third jump in a 16-byte
12236 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12239 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12240 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12242 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12243 The align insn is used to avoid 3 jump instructions in the row to improve
12244 branch prediction and the benefits hardly outweigh the cost of extra 8
12245 nops on the average inserted by full alignment pseudo operation. */
12249 [(set_attr "length" "16")])
12251 (define_expand "prologue"
12254 "ix86_expand_prologue (); DONE;")
12256 (define_insn "set_got"
12257 [(set (match_operand:SI 0 "register_operand" "=r")
12258 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12259 (clobber (reg:CC FLAGS_REG))]
12261 "* return output_set_got (operands[0], NULL_RTX);"
12262 [(set_attr "type" "multi")
12263 (set_attr "length" "12")])
12265 (define_insn "set_got_labelled"
12266 [(set (match_operand:SI 0 "register_operand" "=r")
12267 (unspec:SI [(label_ref (match_operand 1))]
12269 (clobber (reg:CC FLAGS_REG))]
12271 "* return output_set_got (operands[0], operands[1]);"
12272 [(set_attr "type" "multi")
12273 (set_attr "length" "12")])
12275 (define_insn "set_got_rex64"
12276 [(set (match_operand:DI 0 "register_operand" "=r")
12277 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12279 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12280 [(set_attr "type" "lea")
12281 (set_attr "length_address" "4")
12282 (set_attr "mode" "DI")])
12284 (define_insn "set_rip_rex64"
12285 [(set (match_operand:DI 0 "register_operand" "=r")
12286 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12288 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12289 [(set_attr "type" "lea")
12290 (set_attr "length_address" "4")
12291 (set_attr "mode" "DI")])
12293 (define_insn "set_got_offset_rex64"
12294 [(set (match_operand:DI 0 "register_operand" "=r")
12296 [(label_ref (match_operand 1))]
12297 UNSPEC_SET_GOT_OFFSET))]
12299 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12300 [(set_attr "type" "imov")
12301 (set_attr "length_immediate" "0")
12302 (set_attr "length_address" "8")
12303 (set_attr "mode" "DI")])
12305 (define_expand "epilogue"
12308 "ix86_expand_epilogue (1); DONE;")
12310 (define_expand "sibcall_epilogue"
12313 "ix86_expand_epilogue (0); DONE;")
12315 (define_expand "eh_return"
12316 [(use (match_operand 0 "register_operand"))]
12319 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12321 /* Tricky bit: we write the address of the handler to which we will
12322 be returning into someone else's stack frame, one word below the
12323 stack address we wish to restore. */
12324 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12325 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12326 tmp = gen_rtx_MEM (Pmode, tmp);
12327 emit_move_insn (tmp, ra);
12329 emit_jump_insn (gen_eh_return_internal ());
12334 (define_insn_and_split "eh_return_internal"
12338 "epilogue_completed"
12340 "ix86_expand_epilogue (2); DONE;")
12342 (define_insn "leave"
12343 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12344 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12345 (clobber (mem:BLK (scratch)))]
12348 [(set_attr "type" "leave")])
12350 (define_insn "leave_rex64"
12351 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12352 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12353 (clobber (mem:BLK (scratch)))]
12356 [(set_attr "type" "leave")])
12358 ;; Handle -fsplit-stack.
12360 (define_expand "split_stack_prologue"
12364 ix86_expand_split_stack_prologue ();
12368 ;; In order to support the call/return predictor, we use a return
12369 ;; instruction which the middle-end doesn't see.
12370 (define_insn "split_stack_return"
12371 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12372 UNSPECV_SPLIT_STACK_RETURN)]
12375 if (operands[0] == const0_rtx)
12380 [(set_attr "atom_unit" "jeu")
12381 (set_attr "modrm" "0")
12382 (set (attr "length")
12383 (if_then_else (match_operand:SI 0 "const0_operand")
12386 (set (attr "length_immediate")
12387 (if_then_else (match_operand:SI 0 "const0_operand")
12391 ;; If there are operand 0 bytes available on the stack, jump to
12394 (define_expand "split_stack_space_check"
12395 [(set (pc) (if_then_else
12396 (ltu (minus (reg SP_REG)
12397 (match_operand 0 "register_operand"))
12398 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12399 (label_ref (match_operand 1))
12403 rtx reg, size, limit;
12405 reg = gen_reg_rtx (Pmode);
12406 size = force_reg (Pmode, operands[0]);
12407 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12408 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12409 UNSPEC_STACK_CHECK);
12410 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12411 ix86_expand_branch (GEU, reg, limit, operands[1]);
12416 ;; Bit manipulation instructions.
12418 (define_expand "ffs<mode>2"
12419 [(set (match_dup 2) (const_int -1))
12420 (parallel [(set (match_dup 3) (match_dup 4))
12421 (set (match_operand:SWI48 0 "register_operand")
12423 (match_operand:SWI48 1 "nonimmediate_operand")))])
12424 (set (match_dup 0) (if_then_else:SWI48
12425 (eq (match_dup 3) (const_int 0))
12428 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12429 (clobber (reg:CC FLAGS_REG))])]
12432 machine_mode flags_mode;
12434 if (<MODE>mode == SImode && !TARGET_CMOVE)
12436 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12441 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12443 operands[2] = gen_reg_rtx (<MODE>mode);
12444 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12445 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12448 (define_insn_and_split "ffssi2_no_cmove"
12449 [(set (match_operand:SI 0 "register_operand" "=r")
12450 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12451 (clobber (match_scratch:SI 2 "=&q"))
12452 (clobber (reg:CC FLAGS_REG))]
12455 "&& reload_completed"
12456 [(parallel [(set (match_dup 4) (match_dup 5))
12457 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12458 (set (strict_low_part (match_dup 3))
12459 (eq:QI (match_dup 4) (const_int 0)))
12460 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12461 (clobber (reg:CC FLAGS_REG))])
12462 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12463 (clobber (reg:CC FLAGS_REG))])
12464 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12465 (clobber (reg:CC FLAGS_REG))])]
12467 machine_mode flags_mode
12468 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12470 operands[3] = gen_lowpart (QImode, operands[2]);
12471 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12472 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12474 ix86_expand_clear (operands[2]);
12477 (define_insn "*tzcnt<mode>_1"
12478 [(set (reg:CCC FLAGS_REG)
12479 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12481 (set (match_operand:SWI48 0 "register_operand" "=r")
12482 (ctz:SWI48 (match_dup 1)))]
12483 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12484 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12485 [(set_attr "type" "alu1")
12486 (set_attr "prefix_0f" "1")
12487 (set_attr "prefix_rep" "1")
12488 (set_attr "btver2_decode" "double")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "*bsf<mode>_1"
12492 [(set (reg:CCZ FLAGS_REG)
12493 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12495 (set (match_operand:SWI48 0 "register_operand" "=r")
12496 (ctz:SWI48 (match_dup 1)))]
12498 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12499 [(set_attr "type" "alu1")
12500 (set_attr "prefix_0f" "1")
12501 (set_attr "btver2_decode" "double")
12502 (set_attr "mode" "<MODE>")])
12504 (define_expand "ctz<mode>2"
12506 [(set (match_operand:SWI248 0 "register_operand")
12508 (match_operand:SWI248 1 "nonimmediate_operand")))
12509 (clobber (reg:CC FLAGS_REG))])])
12511 ; False dependency happens when destination is only updated by tzcnt,
12512 ; lzcnt or popcnt. There is no false dependency when destination is
12513 ; also used in source.
12514 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12515 [(set (match_operand:SWI48 0 "register_operand" "=r")
12517 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12518 (clobber (reg:CC FLAGS_REG))]
12519 "(TARGET_BMI || TARGET_GENERIC)
12520 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12522 "&& reload_completed"
12524 [(set (match_dup 0)
12525 (ctz:SWI48 (match_dup 1)))
12526 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12527 (clobber (reg:CC FLAGS_REG))])]
12529 if (!reg_mentioned_p (operands[0], operands[1]))
12530 ix86_expand_clear (operands[0]);
12533 (define_insn "*ctz<mode>2_falsedep"
12534 [(set (match_operand:SWI48 0 "register_operand" "=r")
12536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12537 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12538 UNSPEC_INSN_FALSE_DEP)
12539 (clobber (reg:CC FLAGS_REG))]
12543 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12544 else if (TARGET_GENERIC)
12545 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12546 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12548 gcc_unreachable ();
12550 [(set_attr "type" "alu1")
12551 (set_attr "prefix_0f" "1")
12552 (set_attr "prefix_rep" "1")
12553 (set_attr "mode" "<MODE>")])
12555 (define_insn "*ctz<mode>2"
12556 [(set (match_operand:SWI248 0 "register_operand" "=r")
12557 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12558 (clobber (reg:CC FLAGS_REG))]
12562 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12563 else if (optimize_function_for_size_p (cfun))
12565 else if (TARGET_GENERIC)
12566 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12567 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12569 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12571 [(set_attr "type" "alu1")
12572 (set_attr "prefix_0f" "1")
12573 (set (attr "prefix_rep")
12575 (ior (match_test "TARGET_BMI")
12576 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12577 (match_test "TARGET_GENERIC")))
12579 (const_string "0")))
12580 (set_attr "mode" "<MODE>")])
12582 (define_expand "clz<mode>2"
12584 [(set (match_operand:SWI248 0 "register_operand")
12587 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12588 (clobber (reg:CC FLAGS_REG))])
12590 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12591 (clobber (reg:CC FLAGS_REG))])]
12596 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12599 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12602 (define_expand "clz<mode>2_lzcnt"
12604 [(set (match_operand:SWI248 0 "register_operand")
12606 (match_operand:SWI248 1 "nonimmediate_operand")))
12607 (clobber (reg:CC FLAGS_REG))])]
12610 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12611 [(set (match_operand:SWI48 0 "register_operand" "=r")
12613 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12614 (clobber (reg:CC FLAGS_REG))]
12616 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12618 "&& reload_completed"
12620 [(set (match_dup 0)
12621 (clz:SWI48 (match_dup 1)))
12622 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12623 (clobber (reg:CC FLAGS_REG))])]
12625 if (!reg_mentioned_p (operands[0], operands[1]))
12626 ix86_expand_clear (operands[0]);
12629 (define_insn "*clz<mode>2_lzcnt_falsedep"
12630 [(set (match_operand:SWI48 0 "register_operand" "=r")
12632 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12633 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12634 UNSPEC_INSN_FALSE_DEP)
12635 (clobber (reg:CC FLAGS_REG))]
12637 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12638 [(set_attr "prefix_rep" "1")
12639 (set_attr "type" "bitmanip")
12640 (set_attr "mode" "<MODE>")])
12642 (define_insn "*clz<mode>2_lzcnt"
12643 [(set (match_operand:SWI248 0 "register_operand" "=r")
12644 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12645 (clobber (reg:CC FLAGS_REG))]
12647 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12648 [(set_attr "prefix_rep" "1")
12649 (set_attr "type" "bitmanip")
12650 (set_attr "mode" "<MODE>")])
12652 ;; BMI instructions.
12653 (define_insn "*bmi_andn_<mode>"
12654 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12657 (match_operand:SWI48 1 "register_operand" "r,r"))
12658 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12659 (clobber (reg:CC FLAGS_REG))]
12661 "andn\t{%2, %1, %0|%0, %1, %2}"
12662 [(set_attr "type" "bitmanip")
12663 (set_attr "btver2_decode" "direct, double")
12664 (set_attr "mode" "<MODE>")])
12666 (define_insn "bmi_bextr_<mode>"
12667 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12668 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12669 (match_operand:SWI48 2 "register_operand" "r,r")]
12671 (clobber (reg:CC FLAGS_REG))]
12673 "bextr\t{%2, %1, %0|%0, %1, %2}"
12674 [(set_attr "type" "bitmanip")
12675 (set_attr "btver2_decode" "direct, double")
12676 (set_attr "mode" "<MODE>")])
12678 (define_insn "*bmi_blsi_<mode>"
12679 [(set (match_operand:SWI48 0 "register_operand" "=r")
12682 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12684 (clobber (reg:CC FLAGS_REG))]
12686 "blsi\t{%1, %0|%0, %1}"
12687 [(set_attr "type" "bitmanip")
12688 (set_attr "btver2_decode" "double")
12689 (set_attr "mode" "<MODE>")])
12691 (define_insn "*bmi_blsmsk_<mode>"
12692 [(set (match_operand:SWI48 0 "register_operand" "=r")
12695 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12698 (clobber (reg:CC FLAGS_REG))]
12700 "blsmsk\t{%1, %0|%0, %1}"
12701 [(set_attr "type" "bitmanip")
12702 (set_attr "btver2_decode" "double")
12703 (set_attr "mode" "<MODE>")])
12705 (define_insn "*bmi_blsr_<mode>"
12706 [(set (match_operand:SWI48 0 "register_operand" "=r")
12709 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12712 (clobber (reg:CC FLAGS_REG))]
12714 "blsr\t{%1, %0|%0, %1}"
12715 [(set_attr "type" "bitmanip")
12716 (set_attr "btver2_decode" "double")
12717 (set_attr "mode" "<MODE>")])
12719 ;; BMI2 instructions.
12720 (define_expand "bmi2_bzhi_<mode>3"
12722 [(set (match_operand:SWI48 0 "register_operand")
12723 (zero_extract:SWI48
12724 (match_operand:SWI48 1 "nonimmediate_operand")
12726 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12730 (clobber (reg:CC FLAGS_REG))])]
12732 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12734 (define_insn "*bmi2_bzhi_<mode>3"
12735 [(set (match_operand:SWI48 0 "register_operand" "=r")
12736 (zero_extract:SWI48
12737 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12739 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12741 (match_operand:SWI48 3 "const_int_operand" "n"))
12743 (clobber (reg:CC FLAGS_REG))]
12744 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12745 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12746 [(set_attr "type" "bitmanip")
12747 (set_attr "prefix" "vex")
12748 (set_attr "mode" "<MODE>")])
12750 (define_mode_attr k [(SI "k") (DI "q")])
12751 (define_insn "*bmi2_bzhi_<mode>3_1"
12752 [(set (match_operand:SWI48 0 "register_operand" "=r")
12753 (zero_extract:SWI48
12754 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12756 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12757 (match_operand:SWI48 3 "const_int_operand" "n"))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12761 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12762 [(set_attr "type" "bitmanip")
12763 (set_attr "prefix" "vex")
12764 (set_attr "mode" "<MODE>")])
12766 (define_insn "bmi2_pdep_<mode>3"
12767 [(set (match_operand:SWI48 0 "register_operand" "=r")
12768 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12769 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12772 "pdep\t{%2, %1, %0|%0, %1, %2}"
12773 [(set_attr "type" "bitmanip")
12774 (set_attr "prefix" "vex")
12775 (set_attr "mode" "<MODE>")])
12777 (define_insn "bmi2_pext_<mode>3"
12778 [(set (match_operand:SWI48 0 "register_operand" "=r")
12779 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12780 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12783 "pext\t{%2, %1, %0|%0, %1, %2}"
12784 [(set_attr "type" "bitmanip")
12785 (set_attr "prefix" "vex")
12786 (set_attr "mode" "<MODE>")])
12788 ;; TBM instructions.
12789 (define_insn "tbm_bextri_<mode>"
12790 [(set (match_operand:SWI48 0 "register_operand" "=r")
12791 (zero_extract:SWI48
12792 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12793 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12794 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12795 (clobber (reg:CC FLAGS_REG))]
12798 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12799 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12801 [(set_attr "type" "bitmanip")
12802 (set_attr "mode" "<MODE>")])
12804 (define_insn "*tbm_blcfill_<mode>"
12805 [(set (match_operand:SWI48 0 "register_operand" "=r")
12808 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12811 (clobber (reg:CC FLAGS_REG))]
12813 "blcfill\t{%1, %0|%0, %1}"
12814 [(set_attr "type" "bitmanip")
12815 (set_attr "mode" "<MODE>")])
12817 (define_insn "*tbm_blci_<mode>"
12818 [(set (match_operand:SWI48 0 "register_operand" "=r")
12822 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12825 (clobber (reg:CC FLAGS_REG))]
12827 "blci\t{%1, %0|%0, %1}"
12828 [(set_attr "type" "bitmanip")
12829 (set_attr "mode" "<MODE>")])
12831 (define_insn "*tbm_blcic_<mode>"
12832 [(set (match_operand:SWI48 0 "register_operand" "=r")
12835 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12839 (clobber (reg:CC FLAGS_REG))]
12841 "blcic\t{%1, %0|%0, %1}"
12842 [(set_attr "type" "bitmanip")
12843 (set_attr "mode" "<MODE>")])
12845 (define_insn "*tbm_blcmsk_<mode>"
12846 [(set (match_operand:SWI48 0 "register_operand" "=r")
12849 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12852 (clobber (reg:CC FLAGS_REG))]
12854 "blcmsk\t{%1, %0|%0, %1}"
12855 [(set_attr "type" "bitmanip")
12856 (set_attr "mode" "<MODE>")])
12858 (define_insn "*tbm_blcs_<mode>"
12859 [(set (match_operand:SWI48 0 "register_operand" "=r")
12862 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12865 (clobber (reg:CC FLAGS_REG))]
12867 "blcs\t{%1, %0|%0, %1}"
12868 [(set_attr "type" "bitmanip")
12869 (set_attr "mode" "<MODE>")])
12871 (define_insn "*tbm_blsfill_<mode>"
12872 [(set (match_operand:SWI48 0 "register_operand" "=r")
12875 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12878 (clobber (reg:CC FLAGS_REG))]
12880 "blsfill\t{%1, %0|%0, %1}"
12881 [(set_attr "type" "bitmanip")
12882 (set_attr "mode" "<MODE>")])
12884 (define_insn "*tbm_blsic_<mode>"
12885 [(set (match_operand:SWI48 0 "register_operand" "=r")
12888 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12892 (clobber (reg:CC FLAGS_REG))]
12894 "blsic\t{%1, %0|%0, %1}"
12895 [(set_attr "type" "bitmanip")
12896 (set_attr "mode" "<MODE>")])
12898 (define_insn "*tbm_t1mskc_<mode>"
12899 [(set (match_operand:SWI48 0 "register_operand" "=r")
12902 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12906 (clobber (reg:CC FLAGS_REG))]
12908 "t1mskc\t{%1, %0|%0, %1}"
12909 [(set_attr "type" "bitmanip")
12910 (set_attr "mode" "<MODE>")])
12912 (define_insn "*tbm_tzmsk_<mode>"
12913 [(set (match_operand:SWI48 0 "register_operand" "=r")
12916 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12920 (clobber (reg:CC FLAGS_REG))]
12922 "tzmsk\t{%1, %0|%0, %1}"
12923 [(set_attr "type" "bitmanip")
12924 (set_attr "mode" "<MODE>")])
12926 (define_insn "bsr_rex64"
12927 [(set (match_operand:DI 0 "register_operand" "=r")
12928 (minus:DI (const_int 63)
12929 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12930 (clobber (reg:CC FLAGS_REG))]
12932 "bsr{q}\t{%1, %0|%0, %1}"
12933 [(set_attr "type" "alu1")
12934 (set_attr "prefix_0f" "1")
12935 (set_attr "mode" "DI")])
12938 [(set (match_operand:SI 0 "register_operand" "=r")
12939 (minus:SI (const_int 31)
12940 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12941 (clobber (reg:CC FLAGS_REG))]
12943 "bsr{l}\t{%1, %0|%0, %1}"
12944 [(set_attr "type" "alu1")
12945 (set_attr "prefix_0f" "1")
12946 (set_attr "mode" "SI")])
12948 (define_insn "*bsrhi"
12949 [(set (match_operand:HI 0 "register_operand" "=r")
12950 (minus:HI (const_int 15)
12951 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12952 (clobber (reg:CC FLAGS_REG))]
12954 "bsr{w}\t{%1, %0|%0, %1}"
12955 [(set_attr "type" "alu1")
12956 (set_attr "prefix_0f" "1")
12957 (set_attr "mode" "HI")])
12959 (define_expand "popcount<mode>2"
12961 [(set (match_operand:SWI248 0 "register_operand")
12963 (match_operand:SWI248 1 "nonimmediate_operand")))
12964 (clobber (reg:CC FLAGS_REG))])]
12967 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12968 [(set (match_operand:SWI48 0 "register_operand" "=r")
12970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12971 (clobber (reg:CC FLAGS_REG))]
12973 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12975 "&& reload_completed"
12977 [(set (match_dup 0)
12978 (popcount:SWI48 (match_dup 1)))
12979 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12980 (clobber (reg:CC FLAGS_REG))])]
12982 if (!reg_mentioned_p (operands[0], operands[1]))
12983 ix86_expand_clear (operands[0]);
12986 (define_insn "*popcount<mode>2_falsedep"
12987 [(set (match_operand:SWI48 0 "register_operand" "=r")
12989 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12990 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12991 UNSPEC_INSN_FALSE_DEP)
12992 (clobber (reg:CC FLAGS_REG))]
12996 return "popcnt\t{%1, %0|%0, %1}";
12998 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13001 [(set_attr "prefix_rep" "1")
13002 (set_attr "type" "bitmanip")
13003 (set_attr "mode" "<MODE>")])
13005 (define_insn "*popcount<mode>2"
13006 [(set (match_operand:SWI248 0 "register_operand" "=r")
13008 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13009 (clobber (reg:CC FLAGS_REG))]
13013 return "popcnt\t{%1, %0|%0, %1}";
13015 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13018 [(set_attr "prefix_rep" "1")
13019 (set_attr "type" "bitmanip")
13020 (set_attr "mode" "<MODE>")])
13022 (define_expand "bswapdi2"
13023 [(set (match_operand:DI 0 "register_operand")
13024 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13028 operands[1] = force_reg (DImode, operands[1]);
13031 (define_expand "bswapsi2"
13032 [(set (match_operand:SI 0 "register_operand")
13033 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13038 else if (TARGET_BSWAP)
13039 operands[1] = force_reg (SImode, operands[1]);
13042 rtx x = operands[0];
13044 emit_move_insn (x, operands[1]);
13045 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13046 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13047 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13052 (define_insn "*bswap<mode>2_movbe"
13053 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13054 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13056 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13059 movbe\t{%1, %0|%0, %1}
13060 movbe\t{%1, %0|%0, %1}"
13061 [(set_attr "type" "bitmanip,imov,imov")
13062 (set_attr "modrm" "0,1,1")
13063 (set_attr "prefix_0f" "*,1,1")
13064 (set_attr "prefix_extra" "*,1,1")
13065 (set_attr "mode" "<MODE>")])
13067 (define_insn "*bswap<mode>2"
13068 [(set (match_operand:SWI48 0 "register_operand" "=r")
13069 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13072 [(set_attr "type" "bitmanip")
13073 (set_attr "modrm" "0")
13074 (set_attr "mode" "<MODE>")])
13076 (define_insn "*bswaphi_lowpart_1"
13077 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13078 (bswap:HI (match_dup 0)))
13079 (clobber (reg:CC FLAGS_REG))]
13080 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13082 xchg{b}\t{%h0, %b0|%b0, %h0}
13083 rol{w}\t{$8, %0|%0, 8}"
13084 [(set_attr "length" "2,4")
13085 (set_attr "mode" "QI,HI")])
13087 (define_insn "bswaphi_lowpart"
13088 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13089 (bswap:HI (match_dup 0)))
13090 (clobber (reg:CC FLAGS_REG))]
13092 "rol{w}\t{$8, %0|%0, 8}"
13093 [(set_attr "length" "4")
13094 (set_attr "mode" "HI")])
13096 (define_expand "paritydi2"
13097 [(set (match_operand:DI 0 "register_operand")
13098 (parity:DI (match_operand:DI 1 "register_operand")))]
13101 rtx scratch = gen_reg_rtx (QImode);
13104 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13105 NULL_RTX, operands[1]));
13107 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13108 gen_rtx_REG (CCmode, FLAGS_REG),
13110 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13113 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13116 rtx tmp = gen_reg_rtx (SImode);
13118 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13119 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13124 (define_expand "paritysi2"
13125 [(set (match_operand:SI 0 "register_operand")
13126 (parity:SI (match_operand:SI 1 "register_operand")))]
13129 rtx scratch = gen_reg_rtx (QImode);
13132 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13134 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13135 gen_rtx_REG (CCmode, FLAGS_REG),
13137 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13139 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13143 (define_insn_and_split "paritydi2_cmp"
13144 [(set (reg:CC FLAGS_REG)
13145 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13147 (clobber (match_scratch:DI 0 "=r"))
13148 (clobber (match_scratch:SI 1 "=&r"))
13149 (clobber (match_scratch:HI 2 "=Q"))]
13152 "&& reload_completed"
13154 [(set (match_dup 1)
13155 (xor:SI (match_dup 1) (match_dup 4)))
13156 (clobber (reg:CC FLAGS_REG))])
13158 [(set (reg:CC FLAGS_REG)
13159 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13160 (clobber (match_dup 1))
13161 (clobber (match_dup 2))])]
13163 operands[4] = gen_lowpart (SImode, operands[3]);
13167 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13168 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13171 operands[1] = gen_highpart (SImode, operands[3]);
13174 (define_insn_and_split "paritysi2_cmp"
13175 [(set (reg:CC FLAGS_REG)
13176 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13178 (clobber (match_scratch:SI 0 "=r"))
13179 (clobber (match_scratch:HI 1 "=&Q"))]
13182 "&& reload_completed"
13184 [(set (match_dup 1)
13185 (xor:HI (match_dup 1) (match_dup 3)))
13186 (clobber (reg:CC FLAGS_REG))])
13188 [(set (reg:CC FLAGS_REG)
13189 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13190 (clobber (match_dup 1))])]
13192 operands[3] = gen_lowpart (HImode, operands[2]);
13194 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13195 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13198 (define_insn "*parityhi2_cmp"
13199 [(set (reg:CC FLAGS_REG)
13200 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13202 (clobber (match_scratch:HI 0 "=Q"))]
13204 "xor{b}\t{%h0, %b0|%b0, %h0}"
13205 [(set_attr "length" "2")
13206 (set_attr "mode" "HI")])
13209 ;; Thread-local storage patterns for ELF.
13211 ;; Note that these code sequences must appear exactly as shown
13212 ;; in order to allow linker relaxation.
13214 (define_insn "*tls_global_dynamic_32_gnu"
13215 [(set (match_operand:SI 0 "register_operand" "=a")
13217 [(match_operand:SI 1 "register_operand" "b")
13218 (match_operand 2 "tls_symbolic_operand")
13219 (match_operand 3 "constant_call_address_operand" "Bz")
13222 (clobber (match_scratch:SI 4 "=d"))
13223 (clobber (match_scratch:SI 5 "=c"))
13224 (clobber (reg:CC FLAGS_REG))]
13225 "!TARGET_64BIT && TARGET_GNU_TLS"
13228 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13229 if (TARGET_SUN_TLS)
13230 #ifdef HAVE_AS_IX86_TLSGDPLT
13231 return "call\t%a2@tlsgdplt";
13233 return "call\t%p3@plt";
13235 return "call\t%P3";
13237 [(set_attr "type" "multi")
13238 (set_attr "length" "12")])
13240 (define_expand "tls_global_dynamic_32"
13242 [(set (match_operand:SI 0 "register_operand")
13243 (unspec:SI [(match_operand:SI 2 "register_operand")
13244 (match_operand 1 "tls_symbolic_operand")
13245 (match_operand 3 "constant_call_address_operand")
13248 (clobber (match_scratch:SI 4))
13249 (clobber (match_scratch:SI 5))
13250 (clobber (reg:CC FLAGS_REG))])]
13252 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13254 (define_insn "*tls_global_dynamic_64_<mode>"
13255 [(set (match_operand:P 0 "register_operand" "=a")
13257 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13258 (match_operand 3)))
13259 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13265 fputs (ASM_BYTE "0x66\n", asm_out_file);
13267 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13268 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13269 fputs ("\trex64\n", asm_out_file);
13270 if (TARGET_SUN_TLS)
13271 return "call\t%p2@plt";
13272 return "call\t%P2";
13274 [(set_attr "type" "multi")
13275 (set (attr "length")
13276 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13278 (define_insn "*tls_global_dynamic_64_largepic"
13279 [(set (match_operand:DI 0 "register_operand" "=a")
13281 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13282 (match_operand:DI 3 "immediate_operand" "i")))
13283 (match_operand 4)))
13284 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13287 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13288 && GET_CODE (operands[3]) == CONST
13289 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13290 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13293 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13294 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13295 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13296 return "call\t{*%%rax|rax}";
13298 [(set_attr "type" "multi")
13299 (set_attr "length" "22")])
13301 (define_expand "tls_global_dynamic_64_<mode>"
13303 [(set (match_operand:P 0 "register_operand")
13305 (mem:QI (match_operand 2))
13307 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13311 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13313 (define_insn "*tls_local_dynamic_base_32_gnu"
13314 [(set (match_operand:SI 0 "register_operand" "=a")
13316 [(match_operand:SI 1 "register_operand" "b")
13317 (match_operand 2 "constant_call_address_operand" "Bz")
13319 UNSPEC_TLS_LD_BASE))
13320 (clobber (match_scratch:SI 3 "=d"))
13321 (clobber (match_scratch:SI 4 "=c"))
13322 (clobber (reg:CC FLAGS_REG))]
13323 "!TARGET_64BIT && TARGET_GNU_TLS"
13326 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13327 if (TARGET_SUN_TLS)
13329 if (HAVE_AS_IX86_TLSLDMPLT)
13330 return "call\t%&@tlsldmplt";
13332 return "call\t%p2@plt";
13334 return "call\t%P2";
13336 [(set_attr "type" "multi")
13337 (set_attr "length" "11")])
13339 (define_expand "tls_local_dynamic_base_32"
13341 [(set (match_operand:SI 0 "register_operand")
13343 [(match_operand:SI 1 "register_operand")
13344 (match_operand 2 "constant_call_address_operand")
13346 UNSPEC_TLS_LD_BASE))
13347 (clobber (match_scratch:SI 3))
13348 (clobber (match_scratch:SI 4))
13349 (clobber (reg:CC FLAGS_REG))])]
13351 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13353 (define_insn "*tls_local_dynamic_base_64_<mode>"
13354 [(set (match_operand:P 0 "register_operand" "=a")
13356 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13357 (match_operand 2)))
13358 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13362 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13363 if (TARGET_SUN_TLS)
13364 return "call\t%p1@plt";
13365 return "call\t%P1";
13367 [(set_attr "type" "multi")
13368 (set_attr "length" "12")])
13370 (define_insn "*tls_local_dynamic_base_64_largepic"
13371 [(set (match_operand:DI 0 "register_operand" "=a")
13373 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13374 (match_operand:DI 2 "immediate_operand" "i")))
13375 (match_operand 3)))
13376 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13377 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13378 && GET_CODE (operands[2]) == CONST
13379 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13380 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13383 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13384 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13385 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13386 return "call\t{*%%rax|rax}";
13388 [(set_attr "type" "multi")
13389 (set_attr "length" "22")])
13391 (define_expand "tls_local_dynamic_base_64_<mode>"
13393 [(set (match_operand:P 0 "register_operand")
13395 (mem:QI (match_operand 1))
13397 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13399 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13401 ;; Local dynamic of a single variable is a lose. Show combine how
13402 ;; to convert that back to global dynamic.
13404 (define_insn_and_split "*tls_local_dynamic_32_once"
13405 [(set (match_operand:SI 0 "register_operand" "=a")
13407 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13408 (match_operand 2 "constant_call_address_operand" "Bz")
13410 UNSPEC_TLS_LD_BASE)
13411 (const:SI (unspec:SI
13412 [(match_operand 3 "tls_symbolic_operand")]
13414 (clobber (match_scratch:SI 4 "=d"))
13415 (clobber (match_scratch:SI 5 "=c"))
13416 (clobber (reg:CC FLAGS_REG))]
13421 [(set (match_dup 0)
13422 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13425 (clobber (match_dup 4))
13426 (clobber (match_dup 5))
13427 (clobber (reg:CC FLAGS_REG))])])
13429 ;; Segment register for the thread base ptr load
13430 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13432 ;; Load and add the thread base pointer from %<tp_seg>:0.
13433 (define_insn "*load_tp_x32"
13434 [(set (match_operand:SI 0 "register_operand" "=r")
13435 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13437 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13438 [(set_attr "type" "imov")
13439 (set_attr "modrm" "0")
13440 (set_attr "length" "7")
13441 (set_attr "memory" "load")
13442 (set_attr "imm_disp" "false")])
13444 (define_insn "*load_tp_x32_zext"
13445 [(set (match_operand:DI 0 "register_operand" "=r")
13446 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13448 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13449 [(set_attr "type" "imov")
13450 (set_attr "modrm" "0")
13451 (set_attr "length" "7")
13452 (set_attr "memory" "load")
13453 (set_attr "imm_disp" "false")])
13455 (define_insn "*load_tp_<mode>"
13456 [(set (match_operand:P 0 "register_operand" "=r")
13457 (unspec:P [(const_int 0)] UNSPEC_TP))]
13459 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13460 [(set_attr "type" "imov")
13461 (set_attr "modrm" "0")
13462 (set_attr "length" "7")
13463 (set_attr "memory" "load")
13464 (set_attr "imm_disp" "false")])
13466 (define_insn "*add_tp_x32"
13467 [(set (match_operand:SI 0 "register_operand" "=r")
13468 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13469 (match_operand:SI 1 "register_operand" "0")))
13470 (clobber (reg:CC FLAGS_REG))]
13472 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13473 [(set_attr "type" "alu")
13474 (set_attr "modrm" "0")
13475 (set_attr "length" "7")
13476 (set_attr "memory" "load")
13477 (set_attr "imm_disp" "false")])
13479 (define_insn "*add_tp_x32_zext"
13480 [(set (match_operand:DI 0 "register_operand" "=r")
13482 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13483 (match_operand:SI 1 "register_operand" "0"))))
13484 (clobber (reg:CC FLAGS_REG))]
13486 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13487 [(set_attr "type" "alu")
13488 (set_attr "modrm" "0")
13489 (set_attr "length" "7")
13490 (set_attr "memory" "load")
13491 (set_attr "imm_disp" "false")])
13493 (define_insn "*add_tp_<mode>"
13494 [(set (match_operand:P 0 "register_operand" "=r")
13495 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13496 (match_operand:P 1 "register_operand" "0")))
13497 (clobber (reg:CC FLAGS_REG))]
13499 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13500 [(set_attr "type" "alu")
13501 (set_attr "modrm" "0")
13502 (set_attr "length" "7")
13503 (set_attr "memory" "load")
13504 (set_attr "imm_disp" "false")])
13506 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13507 ;; %rax as destination of the initial executable code sequence.
13508 (define_insn "tls_initial_exec_64_sun"
13509 [(set (match_operand:DI 0 "register_operand" "=a")
13511 [(match_operand 1 "tls_symbolic_operand")]
13512 UNSPEC_TLS_IE_SUN))
13513 (clobber (reg:CC FLAGS_REG))]
13514 "TARGET_64BIT && TARGET_SUN_TLS"
13517 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13518 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13520 [(set_attr "type" "multi")])
13522 ;; GNU2 TLS patterns can be split.
13524 (define_expand "tls_dynamic_gnu2_32"
13525 [(set (match_dup 3)
13526 (plus:SI (match_operand:SI 2 "register_operand")
13528 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13531 [(set (match_operand:SI 0 "register_operand")
13532 (unspec:SI [(match_dup 1) (match_dup 3)
13533 (match_dup 2) (reg:SI SP_REG)]
13535 (clobber (reg:CC FLAGS_REG))])]
13536 "!TARGET_64BIT && TARGET_GNU2_TLS"
13538 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13539 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13542 (define_insn "*tls_dynamic_gnu2_lea_32"
13543 [(set (match_operand:SI 0 "register_operand" "=r")
13544 (plus:SI (match_operand:SI 1 "register_operand" "b")
13546 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13547 UNSPEC_TLSDESC))))]
13548 "!TARGET_64BIT && TARGET_GNU2_TLS"
13549 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13550 [(set_attr "type" "lea")
13551 (set_attr "mode" "SI")
13552 (set_attr "length" "6")
13553 (set_attr "length_address" "4")])
13555 (define_insn "*tls_dynamic_gnu2_call_32"
13556 [(set (match_operand:SI 0 "register_operand" "=a")
13557 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13558 (match_operand:SI 2 "register_operand" "0")
13559 ;; we have to make sure %ebx still points to the GOT
13560 (match_operand:SI 3 "register_operand" "b")
13563 (clobber (reg:CC FLAGS_REG))]
13564 "!TARGET_64BIT && TARGET_GNU2_TLS"
13565 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13566 [(set_attr "type" "call")
13567 (set_attr "length" "2")
13568 (set_attr "length_address" "0")])
13570 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13571 [(set (match_operand:SI 0 "register_operand" "=&a")
13573 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13574 (match_operand:SI 4)
13575 (match_operand:SI 2 "register_operand" "b")
13578 (const:SI (unspec:SI
13579 [(match_operand 1 "tls_symbolic_operand")]
13581 (clobber (reg:CC FLAGS_REG))]
13582 "!TARGET_64BIT && TARGET_GNU2_TLS"
13585 [(set (match_dup 0) (match_dup 5))]
13587 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13588 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13591 (define_expand "tls_dynamic_gnu2_64"
13592 [(set (match_dup 2)
13593 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13596 [(set (match_operand:DI 0 "register_operand")
13597 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13599 (clobber (reg:CC FLAGS_REG))])]
13600 "TARGET_64BIT && TARGET_GNU2_TLS"
13602 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13603 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13606 (define_insn "*tls_dynamic_gnu2_lea_64"
13607 [(set (match_operand:DI 0 "register_operand" "=r")
13608 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13610 "TARGET_64BIT && TARGET_GNU2_TLS"
13611 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13612 [(set_attr "type" "lea")
13613 (set_attr "mode" "DI")
13614 (set_attr "length" "7")
13615 (set_attr "length_address" "4")])
13617 (define_insn "*tls_dynamic_gnu2_call_64"
13618 [(set (match_operand:DI 0 "register_operand" "=a")
13619 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13620 (match_operand:DI 2 "register_operand" "0")
13623 (clobber (reg:CC FLAGS_REG))]
13624 "TARGET_64BIT && TARGET_GNU2_TLS"
13625 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13626 [(set_attr "type" "call")
13627 (set_attr "length" "2")
13628 (set_attr "length_address" "0")])
13630 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13631 [(set (match_operand:DI 0 "register_operand" "=&a")
13633 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13634 (match_operand:DI 3)
13637 (const:DI (unspec:DI
13638 [(match_operand 1 "tls_symbolic_operand")]
13640 (clobber (reg:CC FLAGS_REG))]
13641 "TARGET_64BIT && TARGET_GNU2_TLS"
13644 [(set (match_dup 0) (match_dup 4))]
13646 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13647 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13650 ;; These patterns match the binary 387 instructions for addM3, subM3,
13651 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13652 ;; SFmode. The first is the normal insn, the second the same insn but
13653 ;; with one operand a conversion, and the third the same insn but with
13654 ;; the other operand a conversion. The conversion may be SFmode or
13655 ;; SImode if the target mode DFmode, but only SImode if the target mode
13658 ;; Gcc is slightly more smart about handling normal two address instructions
13659 ;; so use special patterns for add and mull.
13661 (define_insn "*fop_<mode>_comm_mixed"
13662 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13663 (match_operator:MODEF 3 "binary_fp_operator"
13664 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13665 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13666 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13667 && COMMUTATIVE_ARITH_P (operands[3])
13668 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13669 "* return output_387_binary_op (insn, operands);"
13670 [(set (attr "type")
13671 (if_then_else (eq_attr "alternative" "1,2")
13672 (if_then_else (match_operand:MODEF 3 "mult_operator")
13673 (const_string "ssemul")
13674 (const_string "sseadd"))
13675 (if_then_else (match_operand:MODEF 3 "mult_operator")
13676 (const_string "fmul")
13677 (const_string "fop"))))
13678 (set_attr "isa" "*,noavx,avx")
13679 (set_attr "prefix" "orig,orig,vex")
13680 (set_attr "mode" "<MODE>")])
13682 (define_insn "*fop_<mode>_comm_sse"
13683 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13684 (match_operator:MODEF 3 "binary_fp_operator"
13685 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13686 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13687 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13688 && COMMUTATIVE_ARITH_P (operands[3])
13689 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13690 "* return output_387_binary_op (insn, operands);"
13691 [(set (attr "type")
13692 (if_then_else (match_operand:MODEF 3 "mult_operator")
13693 (const_string "ssemul")
13694 (const_string "sseadd")))
13695 (set_attr "isa" "noavx,avx")
13696 (set_attr "prefix" "orig,vex")
13697 (set_attr "mode" "<MODE>")])
13699 (define_insn "*fop_<mode>_comm_i387"
13700 [(set (match_operand:MODEF 0 "register_operand" "=f")
13701 (match_operator:MODEF 3 "binary_fp_operator"
13702 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13703 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13704 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13705 && COMMUTATIVE_ARITH_P (operands[3])
13706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13707 "* return output_387_binary_op (insn, operands);"
13708 [(set (attr "type")
13709 (if_then_else (match_operand:MODEF 3 "mult_operator")
13710 (const_string "fmul")
13711 (const_string "fop")))
13712 (set_attr "mode" "<MODE>")])
13714 (define_insn "*fop_<mode>_1_mixed"
13715 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13716 (match_operator:MODEF 3 "binary_fp_operator"
13717 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13718 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13719 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13720 && !COMMUTATIVE_ARITH_P (operands[3])
13721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13722 "* return output_387_binary_op (insn, operands);"
13723 [(set (attr "type")
13724 (cond [(and (eq_attr "alternative" "2,3")
13725 (match_operand:MODEF 3 "mult_operator"))
13726 (const_string "ssemul")
13727 (and (eq_attr "alternative" "2,3")
13728 (match_operand:MODEF 3 "div_operator"))
13729 (const_string "ssediv")
13730 (eq_attr "alternative" "2,3")
13731 (const_string "sseadd")
13732 (match_operand:MODEF 3 "mult_operator")
13733 (const_string "fmul")
13734 (match_operand:MODEF 3 "div_operator")
13735 (const_string "fdiv")
13737 (const_string "fop")))
13738 (set_attr "isa" "*,*,noavx,avx")
13739 (set_attr "prefix" "orig,orig,orig,vex")
13740 (set_attr "mode" "<MODE>")])
13742 (define_insn "*rcpsf2_sse"
13743 [(set (match_operand:SF 0 "register_operand" "=x")
13744 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13747 "%vrcpss\t{%1, %d0|%d0, %1}"
13748 [(set_attr "type" "sse")
13749 (set_attr "atom_sse_attr" "rcp")
13750 (set_attr "btver2_sse_attr" "rcp")
13751 (set_attr "prefix" "maybe_vex")
13752 (set_attr "mode" "SF")])
13754 (define_insn "*fop_<mode>_1_sse"
13755 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13756 (match_operator:MODEF 3 "binary_fp_operator"
13757 [(match_operand:MODEF 1 "register_operand" "0,x")
13758 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13759 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13760 && !COMMUTATIVE_ARITH_P (operands[3])"
13761 "* return output_387_binary_op (insn, operands);"
13762 [(set (attr "type")
13763 (cond [(match_operand:MODEF 3 "mult_operator")
13764 (const_string "ssemul")
13765 (match_operand:MODEF 3 "div_operator")
13766 (const_string "ssediv")
13768 (const_string "sseadd")))
13769 (set_attr "isa" "noavx,avx")
13770 (set_attr "prefix" "orig,vex")
13771 (set_attr "mode" "<MODE>")])
13773 ;; This pattern is not fully shadowed by the pattern above.
13774 (define_insn "*fop_<mode>_1_i387"
13775 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13776 (match_operator:MODEF 3 "binary_fp_operator"
13777 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13778 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13779 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13780 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 && !COMMUTATIVE_ARITH_P (operands[3])
13782 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13783 "* return output_387_binary_op (insn, operands);"
13784 [(set (attr "type")
13785 (cond [(match_operand:MODEF 3 "mult_operator")
13786 (const_string "fmul")
13787 (match_operand:MODEF 3 "div_operator")
13788 (const_string "fdiv")
13790 (const_string "fop")))
13791 (set_attr "mode" "<MODE>")])
13793 ;; ??? Add SSE splitters for these!
13794 (define_insn "*fop_<MODEF:mode>_2_i387"
13795 [(set (match_operand:MODEF 0 "register_operand" "=f")
13796 (match_operator:MODEF 3 "binary_fp_operator"
13798 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13799 (match_operand:MODEF 2 "register_operand" "0")]))]
13800 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13801 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13802 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13803 || optimize_function_for_size_p (cfun))"
13804 { return output_387_binary_op (insn, operands); }
13805 [(set (attr "type")
13806 (cond [(match_operand:MODEF 3 "mult_operator")
13807 (const_string "fmul")
13808 (match_operand:MODEF 3 "div_operator")
13809 (const_string "fdiv")
13811 (const_string "fop")))
13812 (set_attr "fp_int_src" "true")
13813 (set_attr "mode" "<SWI24:MODE>")])
13815 (define_insn "*fop_<MODEF:mode>_3_i387"
13816 [(set (match_operand:MODEF 0 "register_operand" "=f")
13817 (match_operator:MODEF 3 "binary_fp_operator"
13818 [(match_operand:MODEF 1 "register_operand" "0")
13820 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13821 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13822 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13823 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13824 || optimize_function_for_size_p (cfun))"
13825 { return output_387_binary_op (insn, operands); }
13826 [(set (attr "type")
13827 (cond [(match_operand:MODEF 3 "mult_operator")
13828 (const_string "fmul")
13829 (match_operand:MODEF 3 "div_operator")
13830 (const_string "fdiv")
13832 (const_string "fop")))
13833 (set_attr "fp_int_src" "true")
13834 (set_attr "mode" "<MODE>")])
13836 (define_insn "*fop_df_4_i387"
13837 [(set (match_operand:DF 0 "register_operand" "=f,f")
13838 (match_operator:DF 3 "binary_fp_operator"
13840 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13841 (match_operand:DF 2 "register_operand" "0,f")]))]
13842 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13843 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13844 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13845 "* return output_387_binary_op (insn, operands);"
13846 [(set (attr "type")
13847 (cond [(match_operand:DF 3 "mult_operator")
13848 (const_string "fmul")
13849 (match_operand:DF 3 "div_operator")
13850 (const_string "fdiv")
13852 (const_string "fop")))
13853 (set_attr "mode" "SF")])
13855 (define_insn "*fop_df_5_i387"
13856 [(set (match_operand:DF 0 "register_operand" "=f,f")
13857 (match_operator:DF 3 "binary_fp_operator"
13858 [(match_operand:DF 1 "register_operand" "0,f")
13860 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13861 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13862 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13863 "* return output_387_binary_op (insn, operands);"
13864 [(set (attr "type")
13865 (cond [(match_operand:DF 3 "mult_operator")
13866 (const_string "fmul")
13867 (match_operand:DF 3 "div_operator")
13868 (const_string "fdiv")
13870 (const_string "fop")))
13871 (set_attr "mode" "SF")])
13873 (define_insn "*fop_df_6_i387"
13874 [(set (match_operand:DF 0 "register_operand" "=f,f")
13875 (match_operator:DF 3 "binary_fp_operator"
13877 (match_operand:SF 1 "register_operand" "0,f"))
13879 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13880 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13881 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13882 "* return output_387_binary_op (insn, operands);"
13883 [(set (attr "type")
13884 (cond [(match_operand:DF 3 "mult_operator")
13885 (const_string "fmul")
13886 (match_operand:DF 3 "div_operator")
13887 (const_string "fdiv")
13889 (const_string "fop")))
13890 (set_attr "mode" "SF")])
13892 (define_insn "*fop_xf_comm_i387"
13893 [(set (match_operand:XF 0 "register_operand" "=f")
13894 (match_operator:XF 3 "binary_fp_operator"
13895 [(match_operand:XF 1 "register_operand" "%0")
13896 (match_operand:XF 2 "register_operand" "f")]))]
13898 && COMMUTATIVE_ARITH_P (operands[3])"
13899 "* return output_387_binary_op (insn, operands);"
13900 [(set (attr "type")
13901 (if_then_else (match_operand:XF 3 "mult_operator")
13902 (const_string "fmul")
13903 (const_string "fop")))
13904 (set_attr "mode" "XF")])
13906 (define_insn "*fop_xf_1_i387"
13907 [(set (match_operand:XF 0 "register_operand" "=f,f")
13908 (match_operator:XF 3 "binary_fp_operator"
13909 [(match_operand:XF 1 "register_operand" "0,f")
13910 (match_operand:XF 2 "register_operand" "f,0")]))]
13912 && !COMMUTATIVE_ARITH_P (operands[3])"
13913 "* return output_387_binary_op (insn, operands);"
13914 [(set (attr "type")
13915 (cond [(match_operand:XF 3 "mult_operator")
13916 (const_string "fmul")
13917 (match_operand:XF 3 "div_operator")
13918 (const_string "fdiv")
13920 (const_string "fop")))
13921 (set_attr "mode" "XF")])
13923 (define_insn "*fop_xf_2_i387"
13924 [(set (match_operand:XF 0 "register_operand" "=f")
13925 (match_operator:XF 3 "binary_fp_operator"
13927 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13928 (match_operand:XF 2 "register_operand" "0")]))]
13930 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13931 { return output_387_binary_op (insn, operands); }
13932 [(set (attr "type")
13933 (cond [(match_operand:XF 3 "mult_operator")
13934 (const_string "fmul")
13935 (match_operand:XF 3 "div_operator")
13936 (const_string "fdiv")
13938 (const_string "fop")))
13939 (set_attr "fp_int_src" "true")
13940 (set_attr "mode" "<MODE>")])
13942 (define_insn "*fop_xf_3_i387"
13943 [(set (match_operand:XF 0 "register_operand" "=f")
13944 (match_operator:XF 3 "binary_fp_operator"
13945 [(match_operand:XF 1 "register_operand" "0")
13947 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13949 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13950 { return output_387_binary_op (insn, operands); }
13951 [(set (attr "type")
13952 (cond [(match_operand:XF 3 "mult_operator")
13953 (const_string "fmul")
13954 (match_operand:XF 3 "div_operator")
13955 (const_string "fdiv")
13957 (const_string "fop")))
13958 (set_attr "fp_int_src" "true")
13959 (set_attr "mode" "<MODE>")])
13961 (define_insn "*fop_xf_4_i387"
13962 [(set (match_operand:XF 0 "register_operand" "=f,f")
13963 (match_operator:XF 3 "binary_fp_operator"
13965 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13966 (match_operand:XF 2 "register_operand" "0,f")]))]
13968 "* return output_387_binary_op (insn, operands);"
13969 [(set (attr "type")
13970 (cond [(match_operand:XF 3 "mult_operator")
13971 (const_string "fmul")
13972 (match_operand:XF 3 "div_operator")
13973 (const_string "fdiv")
13975 (const_string "fop")))
13976 (set_attr "mode" "<MODE>")])
13978 (define_insn "*fop_xf_5_i387"
13979 [(set (match_operand:XF 0 "register_operand" "=f,f")
13980 (match_operator:XF 3 "binary_fp_operator"
13981 [(match_operand:XF 1 "register_operand" "0,f")
13983 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13985 "* return output_387_binary_op (insn, operands);"
13986 [(set (attr "type")
13987 (cond [(match_operand:XF 3 "mult_operator")
13988 (const_string "fmul")
13989 (match_operand:XF 3 "div_operator")
13990 (const_string "fdiv")
13992 (const_string "fop")))
13993 (set_attr "mode" "<MODE>")])
13995 (define_insn "*fop_xf_6_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f,f")
13997 (match_operator:XF 3 "binary_fp_operator"
13999 (match_operand:MODEF 1 "register_operand" "0,f"))
14001 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14003 "* return output_387_binary_op (insn, operands);"
14004 [(set (attr "type")
14005 (cond [(match_operand:XF 3 "mult_operator")
14006 (const_string "fmul")
14007 (match_operand:XF 3 "div_operator")
14008 (const_string "fdiv")
14010 (const_string "fop")))
14011 (set_attr "mode" "<MODE>")])
14013 ;; FPU special functions.
14015 ;; This pattern implements a no-op XFmode truncation for
14016 ;; all fancy i386 XFmode math functions.
14018 (define_insn "truncxf<mode>2_i387_noop_unspec"
14019 [(set (match_operand:MODEF 0 "register_operand" "=f")
14020 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14021 UNSPEC_TRUNC_NOOP))]
14022 "TARGET_USE_FANCY_MATH_387"
14023 "* return output_387_reg_move (insn, operands);"
14024 [(set_attr "type" "fmov")
14025 (set_attr "mode" "<MODE>")])
14027 (define_insn "sqrtxf2"
14028 [(set (match_operand:XF 0 "register_operand" "=f")
14029 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14030 "TARGET_USE_FANCY_MATH_387"
14032 [(set_attr "type" "fpspc")
14033 (set_attr "mode" "XF")
14034 (set_attr "athlon_decode" "direct")
14035 (set_attr "amdfam10_decode" "direct")
14036 (set_attr "bdver1_decode" "direct")])
14038 (define_insn "sqrt_extend<mode>xf2_i387"
14039 [(set (match_operand:XF 0 "register_operand" "=f")
14042 (match_operand:MODEF 1 "register_operand" "0"))))]
14043 "TARGET_USE_FANCY_MATH_387"
14045 [(set_attr "type" "fpspc")
14046 (set_attr "mode" "XF")
14047 (set_attr "athlon_decode" "direct")
14048 (set_attr "amdfam10_decode" "direct")
14049 (set_attr "bdver1_decode" "direct")])
14051 (define_insn "*rsqrtsf2_sse"
14052 [(set (match_operand:SF 0 "register_operand" "=x")
14053 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14056 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14057 [(set_attr "type" "sse")
14058 (set_attr "atom_sse_attr" "rcp")
14059 (set_attr "btver2_sse_attr" "rcp")
14060 (set_attr "prefix" "maybe_vex")
14061 (set_attr "mode" "SF")])
14063 (define_expand "rsqrtsf2"
14064 [(set (match_operand:SF 0 "register_operand")
14065 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14069 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14073 (define_insn "*sqrt<mode>2_sse"
14074 [(set (match_operand:MODEF 0 "register_operand" "=x")
14076 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14077 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14078 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14079 [(set_attr "type" "sse")
14080 (set_attr "atom_sse_attr" "sqrt")
14081 (set_attr "btver2_sse_attr" "sqrt")
14082 (set_attr "prefix" "maybe_vex")
14083 (set_attr "mode" "<MODE>")
14084 (set_attr "athlon_decode" "*")
14085 (set_attr "amdfam10_decode" "*")
14086 (set_attr "bdver1_decode" "*")])
14088 (define_expand "sqrt<mode>2"
14089 [(set (match_operand:MODEF 0 "register_operand")
14091 (match_operand:MODEF 1 "nonimmediate_operand")))]
14092 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14093 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14095 if (<MODE>mode == SFmode
14097 && TARGET_RECIP_SQRT
14098 && !optimize_function_for_size_p (cfun)
14099 && flag_finite_math_only && !flag_trapping_math
14100 && flag_unsafe_math_optimizations)
14102 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14106 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14108 rtx op0 = gen_reg_rtx (XFmode);
14109 rtx op1 = force_reg (<MODE>mode, operands[1]);
14111 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14112 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14117 (define_insn "fpremxf4_i387"
14118 [(set (match_operand:XF 0 "register_operand" "=f")
14119 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14120 (match_operand:XF 3 "register_operand" "1")]
14122 (set (match_operand:XF 1 "register_operand" "=u")
14123 (unspec:XF [(match_dup 2) (match_dup 3)]
14125 (set (reg:CCFP FPSR_REG)
14126 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14128 "TARGET_USE_FANCY_MATH_387
14129 && flag_finite_math_only"
14131 [(set_attr "type" "fpspc")
14132 (set_attr "mode" "XF")])
14134 (define_expand "fmodxf3"
14135 [(use (match_operand:XF 0 "register_operand"))
14136 (use (match_operand:XF 1 "general_operand"))
14137 (use (match_operand:XF 2 "general_operand"))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && flag_finite_math_only"
14141 rtx_code_label *label = gen_label_rtx ();
14143 rtx op1 = gen_reg_rtx (XFmode);
14144 rtx op2 = gen_reg_rtx (XFmode);
14146 emit_move_insn (op2, operands[2]);
14147 emit_move_insn (op1, operands[1]);
14149 emit_label (label);
14150 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14151 ix86_emit_fp_unordered_jump (label);
14152 LABEL_NUSES (label) = 1;
14154 emit_move_insn (operands[0], op1);
14158 (define_expand "fmod<mode>3"
14159 [(use (match_operand:MODEF 0 "register_operand"))
14160 (use (match_operand:MODEF 1 "general_operand"))
14161 (use (match_operand:MODEF 2 "general_operand"))]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_finite_math_only"
14165 rtx (*gen_truncxf) (rtx, rtx);
14167 rtx_code_label *label = gen_label_rtx ();
14169 rtx op1 = gen_reg_rtx (XFmode);
14170 rtx op2 = gen_reg_rtx (XFmode);
14172 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14173 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14175 emit_label (label);
14176 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14177 ix86_emit_fp_unordered_jump (label);
14178 LABEL_NUSES (label) = 1;
14180 /* Truncate the result properly for strict SSE math. */
14181 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14182 && !TARGET_MIX_SSE_I387)
14183 gen_truncxf = gen_truncxf<mode>2;
14185 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14187 emit_insn (gen_truncxf (operands[0], op1));
14191 (define_insn "fprem1xf4_i387"
14192 [(set (match_operand:XF 0 "register_operand" "=f")
14193 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14194 (match_operand:XF 3 "register_operand" "1")]
14196 (set (match_operand:XF 1 "register_operand" "=u")
14197 (unspec:XF [(match_dup 2) (match_dup 3)]
14199 (set (reg:CCFP FPSR_REG)
14200 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14202 "TARGET_USE_FANCY_MATH_387
14203 && flag_finite_math_only"
14205 [(set_attr "type" "fpspc")
14206 (set_attr "mode" "XF")])
14208 (define_expand "remainderxf3"
14209 [(use (match_operand:XF 0 "register_operand"))
14210 (use (match_operand:XF 1 "general_operand"))
14211 (use (match_operand:XF 2 "general_operand"))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && flag_finite_math_only"
14215 rtx_code_label *label = gen_label_rtx ();
14217 rtx op1 = gen_reg_rtx (XFmode);
14218 rtx op2 = gen_reg_rtx (XFmode);
14220 emit_move_insn (op2, operands[2]);
14221 emit_move_insn (op1, operands[1]);
14223 emit_label (label);
14224 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14225 ix86_emit_fp_unordered_jump (label);
14226 LABEL_NUSES (label) = 1;
14228 emit_move_insn (operands[0], op1);
14232 (define_expand "remainder<mode>3"
14233 [(use (match_operand:MODEF 0 "register_operand"))
14234 (use (match_operand:MODEF 1 "general_operand"))
14235 (use (match_operand:MODEF 2 "general_operand"))]
14236 "TARGET_USE_FANCY_MATH_387
14237 && flag_finite_math_only"
14239 rtx (*gen_truncxf) (rtx, rtx);
14241 rtx_code_label *label = gen_label_rtx ();
14243 rtx op1 = gen_reg_rtx (XFmode);
14244 rtx op2 = gen_reg_rtx (XFmode);
14246 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14249 emit_label (label);
14251 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14252 ix86_emit_fp_unordered_jump (label);
14253 LABEL_NUSES (label) = 1;
14255 /* Truncate the result properly for strict SSE math. */
14256 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14257 && !TARGET_MIX_SSE_I387)
14258 gen_truncxf = gen_truncxf<mode>2;
14260 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14262 emit_insn (gen_truncxf (operands[0], op1));
14266 (define_int_iterator SINCOS
14270 (define_int_attr sincos
14271 [(UNSPEC_SIN "sin")
14272 (UNSPEC_COS "cos")])
14274 (define_insn "*<sincos>xf2_i387"
14275 [(set (match_operand:XF 0 "register_operand" "=f")
14276 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14278 "TARGET_USE_FANCY_MATH_387
14279 && flag_unsafe_math_optimizations"
14281 [(set_attr "type" "fpspc")
14282 (set_attr "mode" "XF")])
14284 (define_insn "*<sincos>_extend<mode>xf2_i387"
14285 [(set (match_operand:XF 0 "register_operand" "=f")
14286 (unspec:XF [(float_extend:XF
14287 (match_operand:MODEF 1 "register_operand" "0"))]
14289 "TARGET_USE_FANCY_MATH_387
14290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14291 || TARGET_MIX_SSE_I387)
14292 && flag_unsafe_math_optimizations"
14294 [(set_attr "type" "fpspc")
14295 (set_attr "mode" "XF")])
14297 ;; When sincos pattern is defined, sin and cos builtin functions will be
14298 ;; expanded to sincos pattern with one of its outputs left unused.
14299 ;; CSE pass will figure out if two sincos patterns can be combined,
14300 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14301 ;; depending on the unused output.
14303 (define_insn "sincosxf3"
14304 [(set (match_operand:XF 0 "register_operand" "=f")
14305 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14306 UNSPEC_SINCOS_COS))
14307 (set (match_operand:XF 1 "register_operand" "=u")
14308 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14309 "TARGET_USE_FANCY_MATH_387
14310 && flag_unsafe_math_optimizations"
14312 [(set_attr "type" "fpspc")
14313 (set_attr "mode" "XF")])
14316 [(set (match_operand:XF 0 "register_operand")
14317 (unspec:XF [(match_operand:XF 2 "register_operand")]
14318 UNSPEC_SINCOS_COS))
14319 (set (match_operand:XF 1 "register_operand")
14320 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14321 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14322 && can_create_pseudo_p ()"
14323 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14326 [(set (match_operand:XF 0 "register_operand")
14327 (unspec:XF [(match_operand:XF 2 "register_operand")]
14328 UNSPEC_SINCOS_COS))
14329 (set (match_operand:XF 1 "register_operand")
14330 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14331 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14332 && can_create_pseudo_p ()"
14333 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14335 (define_insn "sincos_extend<mode>xf3_i387"
14336 [(set (match_operand:XF 0 "register_operand" "=f")
14337 (unspec:XF [(float_extend:XF
14338 (match_operand:MODEF 2 "register_operand" "0"))]
14339 UNSPEC_SINCOS_COS))
14340 (set (match_operand:XF 1 "register_operand" "=u")
14341 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344 || TARGET_MIX_SSE_I387)
14345 && flag_unsafe_math_optimizations"
14347 [(set_attr "type" "fpspc")
14348 (set_attr "mode" "XF")])
14351 [(set (match_operand:XF 0 "register_operand")
14352 (unspec:XF [(float_extend:XF
14353 (match_operand:MODEF 2 "register_operand"))]
14354 UNSPEC_SINCOS_COS))
14355 (set (match_operand:XF 1 "register_operand")
14356 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14357 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14358 && can_create_pseudo_p ()"
14359 [(set (match_dup 1)
14360 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14363 [(set (match_operand:XF 0 "register_operand")
14364 (unspec:XF [(float_extend:XF
14365 (match_operand:MODEF 2 "register_operand"))]
14366 UNSPEC_SINCOS_COS))
14367 (set (match_operand:XF 1 "register_operand")
14368 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14369 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14370 && can_create_pseudo_p ()"
14371 [(set (match_dup 0)
14372 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14374 (define_expand "sincos<mode>3"
14375 [(use (match_operand:MODEF 0 "register_operand"))
14376 (use (match_operand:MODEF 1 "register_operand"))
14377 (use (match_operand:MODEF 2 "register_operand"))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14383 rtx op0 = gen_reg_rtx (XFmode);
14384 rtx op1 = gen_reg_rtx (XFmode);
14386 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14388 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14392 (define_insn "fptanxf4_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (match_operand:XF 3 "const_double_operand" "F"))
14395 (set (match_operand:XF 1 "register_operand" "=u")
14396 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14398 "TARGET_USE_FANCY_MATH_387
14399 && flag_unsafe_math_optimizations
14400 && standard_80387_constant_p (operands[3]) == 2"
14402 [(set_attr "type" "fpspc")
14403 (set_attr "mode" "XF")])
14405 (define_insn "fptan_extend<mode>xf4_i387"
14406 [(set (match_operand:MODEF 0 "register_operand" "=f")
14407 (match_operand:MODEF 3 "const_double_operand" "F"))
14408 (set (match_operand:XF 1 "register_operand" "=u")
14409 (unspec:XF [(float_extend:XF
14410 (match_operand:MODEF 2 "register_operand" "0"))]
14412 "TARGET_USE_FANCY_MATH_387
14413 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14414 || TARGET_MIX_SSE_I387)
14415 && flag_unsafe_math_optimizations
14416 && standard_80387_constant_p (operands[3]) == 2"
14418 [(set_attr "type" "fpspc")
14419 (set_attr "mode" "XF")])
14421 (define_expand "tanxf2"
14422 [(use (match_operand:XF 0 "register_operand"))
14423 (use (match_operand:XF 1 "register_operand"))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && flag_unsafe_math_optimizations"
14427 rtx one = gen_reg_rtx (XFmode);
14428 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14430 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14434 (define_expand "tan<mode>2"
14435 [(use (match_operand:MODEF 0 "register_operand"))
14436 (use (match_operand:MODEF 1 "register_operand"))]
14437 "TARGET_USE_FANCY_MATH_387
14438 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14439 || TARGET_MIX_SSE_I387)
14440 && flag_unsafe_math_optimizations"
14442 rtx op0 = gen_reg_rtx (XFmode);
14444 rtx one = gen_reg_rtx (<MODE>mode);
14445 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14447 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14448 operands[1], op2));
14449 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14453 (define_insn "*fpatanxf3_i387"
14454 [(set (match_operand:XF 0 "register_operand" "=f")
14455 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14456 (match_operand:XF 2 "register_operand" "u")]
14458 (clobber (match_scratch:XF 3 "=2"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && flag_unsafe_math_optimizations"
14462 [(set_attr "type" "fpspc")
14463 (set_attr "mode" "XF")])
14465 (define_insn "fpatan_extend<mode>xf3_i387"
14466 [(set (match_operand:XF 0 "register_operand" "=f")
14467 (unspec:XF [(float_extend:XF
14468 (match_operand:MODEF 1 "register_operand" "0"))
14470 (match_operand:MODEF 2 "register_operand" "u"))]
14472 (clobber (match_scratch:XF 3 "=2"))]
14473 "TARGET_USE_FANCY_MATH_387
14474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475 || TARGET_MIX_SSE_I387)
14476 && flag_unsafe_math_optimizations"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "XF")])
14481 (define_expand "atan2xf3"
14482 [(parallel [(set (match_operand:XF 0 "register_operand")
14483 (unspec:XF [(match_operand:XF 2 "register_operand")
14484 (match_operand:XF 1 "register_operand")]
14486 (clobber (match_scratch:XF 3))])]
14487 "TARGET_USE_FANCY_MATH_387
14488 && flag_unsafe_math_optimizations")
14490 (define_expand "atan2<mode>3"
14491 [(use (match_operand:MODEF 0 "register_operand"))
14492 (use (match_operand:MODEF 1 "register_operand"))
14493 (use (match_operand:MODEF 2 "register_operand"))]
14494 "TARGET_USE_FANCY_MATH_387
14495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14496 || TARGET_MIX_SSE_I387)
14497 && flag_unsafe_math_optimizations"
14499 rtx op0 = gen_reg_rtx (XFmode);
14501 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14502 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14506 (define_expand "atanxf2"
14507 [(parallel [(set (match_operand:XF 0 "register_operand")
14508 (unspec:XF [(match_dup 2)
14509 (match_operand:XF 1 "register_operand")]
14511 (clobber (match_scratch:XF 3))])]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14515 operands[2] = gen_reg_rtx (XFmode);
14516 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14519 (define_expand "atan<mode>2"
14520 [(use (match_operand:MODEF 0 "register_operand"))
14521 (use (match_operand:MODEF 1 "register_operand"))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14524 || TARGET_MIX_SSE_I387)
14525 && flag_unsafe_math_optimizations"
14527 rtx op0 = gen_reg_rtx (XFmode);
14529 rtx op2 = gen_reg_rtx (<MODE>mode);
14530 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14532 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14533 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14537 (define_expand "asinxf2"
14538 [(set (match_dup 2)
14539 (mult:XF (match_operand:XF 1 "register_operand")
14541 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14542 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14543 (parallel [(set (match_operand:XF 0 "register_operand")
14544 (unspec:XF [(match_dup 5) (match_dup 1)]
14546 (clobber (match_scratch:XF 6))])]
14547 "TARGET_USE_FANCY_MATH_387
14548 && flag_unsafe_math_optimizations"
14552 if (optimize_insn_for_size_p ())
14555 for (i = 2; i < 6; i++)
14556 operands[i] = gen_reg_rtx (XFmode);
14558 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14561 (define_expand "asin<mode>2"
14562 [(use (match_operand:MODEF 0 "register_operand"))
14563 (use (match_operand:MODEF 1 "general_operand"))]
14564 "TARGET_USE_FANCY_MATH_387
14565 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14566 || TARGET_MIX_SSE_I387)
14567 && flag_unsafe_math_optimizations"
14569 rtx op0 = gen_reg_rtx (XFmode);
14570 rtx op1 = gen_reg_rtx (XFmode);
14572 if (optimize_insn_for_size_p ())
14575 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14576 emit_insn (gen_asinxf2 (op0, op1));
14577 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14581 (define_expand "acosxf2"
14582 [(set (match_dup 2)
14583 (mult:XF (match_operand:XF 1 "register_operand")
14585 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14586 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14587 (parallel [(set (match_operand:XF 0 "register_operand")
14588 (unspec:XF [(match_dup 1) (match_dup 5)]
14590 (clobber (match_scratch:XF 6))])]
14591 "TARGET_USE_FANCY_MATH_387
14592 && flag_unsafe_math_optimizations"
14596 if (optimize_insn_for_size_p ())
14599 for (i = 2; i < 6; i++)
14600 operands[i] = gen_reg_rtx (XFmode);
14602 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14605 (define_expand "acos<mode>2"
14606 [(use (match_operand:MODEF 0 "register_operand"))
14607 (use (match_operand:MODEF 1 "general_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14610 || TARGET_MIX_SSE_I387)
14611 && flag_unsafe_math_optimizations"
14613 rtx op0 = gen_reg_rtx (XFmode);
14614 rtx op1 = gen_reg_rtx (XFmode);
14616 if (optimize_insn_for_size_p ())
14619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620 emit_insn (gen_acosxf2 (op0, op1));
14621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14625 (define_insn "fyl2xxf3_i387"
14626 [(set (match_operand:XF 0 "register_operand" "=f")
14627 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14628 (match_operand:XF 2 "register_operand" "u")]
14630 (clobber (match_scratch:XF 3 "=2"))]
14631 "TARGET_USE_FANCY_MATH_387
14632 && flag_unsafe_math_optimizations"
14634 [(set_attr "type" "fpspc")
14635 (set_attr "mode" "XF")])
14637 (define_insn "fyl2x_extend<mode>xf3_i387"
14638 [(set (match_operand:XF 0 "register_operand" "=f")
14639 (unspec:XF [(float_extend:XF
14640 (match_operand:MODEF 1 "register_operand" "0"))
14641 (match_operand:XF 2 "register_operand" "u")]
14643 (clobber (match_scratch:XF 3 "=2"))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14646 || TARGET_MIX_SSE_I387)
14647 && flag_unsafe_math_optimizations"
14649 [(set_attr "type" "fpspc")
14650 (set_attr "mode" "XF")])
14652 (define_expand "logxf2"
14653 [(parallel [(set (match_operand:XF 0 "register_operand")
14654 (unspec:XF [(match_operand:XF 1 "register_operand")
14655 (match_dup 2)] UNSPEC_FYL2X))
14656 (clobber (match_scratch:XF 3))])]
14657 "TARGET_USE_FANCY_MATH_387
14658 && flag_unsafe_math_optimizations"
14660 operands[2] = gen_reg_rtx (XFmode);
14661 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14664 (define_expand "log<mode>2"
14665 [(use (match_operand:MODEF 0 "register_operand"))
14666 (use (match_operand:MODEF 1 "register_operand"))]
14667 "TARGET_USE_FANCY_MATH_387
14668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14669 || TARGET_MIX_SSE_I387)
14670 && flag_unsafe_math_optimizations"
14672 rtx op0 = gen_reg_rtx (XFmode);
14674 rtx op2 = gen_reg_rtx (XFmode);
14675 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14677 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14678 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14682 (define_expand "log10xf2"
14683 [(parallel [(set (match_operand:XF 0 "register_operand")
14684 (unspec:XF [(match_operand:XF 1 "register_operand")
14685 (match_dup 2)] UNSPEC_FYL2X))
14686 (clobber (match_scratch:XF 3))])]
14687 "TARGET_USE_FANCY_MATH_387
14688 && flag_unsafe_math_optimizations"
14690 operands[2] = gen_reg_rtx (XFmode);
14691 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14694 (define_expand "log10<mode>2"
14695 [(use (match_operand:MODEF 0 "register_operand"))
14696 (use (match_operand:MODEF 1 "register_operand"))]
14697 "TARGET_USE_FANCY_MATH_387
14698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14699 || TARGET_MIX_SSE_I387)
14700 && flag_unsafe_math_optimizations"
14702 rtx op0 = gen_reg_rtx (XFmode);
14704 rtx op2 = gen_reg_rtx (XFmode);
14705 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14707 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14708 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14712 (define_expand "log2xf2"
14713 [(parallel [(set (match_operand:XF 0 "register_operand")
14714 (unspec:XF [(match_operand:XF 1 "register_operand")
14715 (match_dup 2)] UNSPEC_FYL2X))
14716 (clobber (match_scratch:XF 3))])]
14717 "TARGET_USE_FANCY_MATH_387
14718 && flag_unsafe_math_optimizations"
14720 operands[2] = gen_reg_rtx (XFmode);
14721 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14724 (define_expand "log2<mode>2"
14725 [(use (match_operand:MODEF 0 "register_operand"))
14726 (use (match_operand:MODEF 1 "register_operand"))]
14727 "TARGET_USE_FANCY_MATH_387
14728 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14729 || TARGET_MIX_SSE_I387)
14730 && flag_unsafe_math_optimizations"
14732 rtx op0 = gen_reg_rtx (XFmode);
14734 rtx op2 = gen_reg_rtx (XFmode);
14735 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14737 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14738 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14742 (define_insn "fyl2xp1xf3_i387"
14743 [(set (match_operand:XF 0 "register_operand" "=f")
14744 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14745 (match_operand:XF 2 "register_operand" "u")]
14747 (clobber (match_scratch:XF 3 "=2"))]
14748 "TARGET_USE_FANCY_MATH_387
14749 && flag_unsafe_math_optimizations"
14751 [(set_attr "type" "fpspc")
14752 (set_attr "mode" "XF")])
14754 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14755 [(set (match_operand:XF 0 "register_operand" "=f")
14756 (unspec:XF [(float_extend:XF
14757 (match_operand:MODEF 1 "register_operand" "0"))
14758 (match_operand:XF 2 "register_operand" "u")]
14760 (clobber (match_scratch:XF 3 "=2"))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14763 || TARGET_MIX_SSE_I387)
14764 && flag_unsafe_math_optimizations"
14766 [(set_attr "type" "fpspc")
14767 (set_attr "mode" "XF")])
14769 (define_expand "log1pxf2"
14770 [(use (match_operand:XF 0 "register_operand"))
14771 (use (match_operand:XF 1 "register_operand"))]
14772 "TARGET_USE_FANCY_MATH_387
14773 && flag_unsafe_math_optimizations"
14775 if (optimize_insn_for_size_p ())
14778 ix86_emit_i387_log1p (operands[0], operands[1]);
14782 (define_expand "log1p<mode>2"
14783 [(use (match_operand:MODEF 0 "register_operand"))
14784 (use (match_operand:MODEF 1 "register_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"
14792 if (optimize_insn_for_size_p ())
14795 op0 = gen_reg_rtx (XFmode);
14797 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14799 ix86_emit_i387_log1p (op0, operands[1]);
14800 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14804 (define_insn "fxtractxf3_i387"
14805 [(set (match_operand:XF 0 "register_operand" "=f")
14806 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14807 UNSPEC_XTRACT_FRACT))
14808 (set (match_operand:XF 1 "register_operand" "=u")
14809 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14810 "TARGET_USE_FANCY_MATH_387
14811 && flag_unsafe_math_optimizations"
14813 [(set_attr "type" "fpspc")
14814 (set_attr "mode" "XF")])
14816 (define_insn "fxtract_extend<mode>xf3_i387"
14817 [(set (match_operand:XF 0 "register_operand" "=f")
14818 (unspec:XF [(float_extend:XF
14819 (match_operand:MODEF 2 "register_operand" "0"))]
14820 UNSPEC_XTRACT_FRACT))
14821 (set (match_operand:XF 1 "register_operand" "=u")
14822 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14823 "TARGET_USE_FANCY_MATH_387
14824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14825 || TARGET_MIX_SSE_I387)
14826 && flag_unsafe_math_optimizations"
14828 [(set_attr "type" "fpspc")
14829 (set_attr "mode" "XF")])
14831 (define_expand "logbxf2"
14832 [(parallel [(set (match_dup 2)
14833 (unspec:XF [(match_operand:XF 1 "register_operand")]
14834 UNSPEC_XTRACT_FRACT))
14835 (set (match_operand:XF 0 "register_operand")
14836 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14837 "TARGET_USE_FANCY_MATH_387
14838 && flag_unsafe_math_optimizations"
14839 "operands[2] = gen_reg_rtx (XFmode);")
14841 (define_expand "logb<mode>2"
14842 [(use (match_operand:MODEF 0 "register_operand"))
14843 (use (match_operand:MODEF 1 "register_operand"))]
14844 "TARGET_USE_FANCY_MATH_387
14845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14846 || TARGET_MIX_SSE_I387)
14847 && flag_unsafe_math_optimizations"
14849 rtx op0 = gen_reg_rtx (XFmode);
14850 rtx op1 = gen_reg_rtx (XFmode);
14852 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14853 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14857 (define_expand "ilogbxf2"
14858 [(use (match_operand:SI 0 "register_operand"))
14859 (use (match_operand:XF 1 "register_operand"))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14865 if (optimize_insn_for_size_p ())
14868 op0 = gen_reg_rtx (XFmode);
14869 op1 = gen_reg_rtx (XFmode);
14871 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14872 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14876 (define_expand "ilogb<mode>2"
14877 [(use (match_operand:SI 0 "register_operand"))
14878 (use (match_operand:MODEF 1 "register_operand"))]
14879 "TARGET_USE_FANCY_MATH_387
14880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14881 || TARGET_MIX_SSE_I387)
14882 && flag_unsafe_math_optimizations"
14886 if (optimize_insn_for_size_p ())
14889 op0 = gen_reg_rtx (XFmode);
14890 op1 = gen_reg_rtx (XFmode);
14892 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14893 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14897 (define_insn "*f2xm1xf2_i387"
14898 [(set (match_operand:XF 0 "register_operand" "=f")
14899 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14901 "TARGET_USE_FANCY_MATH_387
14902 && flag_unsafe_math_optimizations"
14904 [(set_attr "type" "fpspc")
14905 (set_attr "mode" "XF")])
14907 (define_insn "fscalexf4_i387"
14908 [(set (match_operand:XF 0 "register_operand" "=f")
14909 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14910 (match_operand:XF 3 "register_operand" "1")]
14911 UNSPEC_FSCALE_FRACT))
14912 (set (match_operand:XF 1 "register_operand" "=u")
14913 (unspec:XF [(match_dup 2) (match_dup 3)]
14914 UNSPEC_FSCALE_EXP))]
14915 "TARGET_USE_FANCY_MATH_387
14916 && flag_unsafe_math_optimizations"
14918 [(set_attr "type" "fpspc")
14919 (set_attr "mode" "XF")])
14921 (define_expand "expNcorexf3"
14922 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14923 (match_operand:XF 2 "register_operand")))
14924 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14925 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14926 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14927 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14928 (parallel [(set (match_operand:XF 0 "register_operand")
14929 (unspec:XF [(match_dup 8) (match_dup 4)]
14930 UNSPEC_FSCALE_FRACT))
14932 (unspec:XF [(match_dup 8) (match_dup 4)]
14933 UNSPEC_FSCALE_EXP))])]
14934 "TARGET_USE_FANCY_MATH_387
14935 && flag_unsafe_math_optimizations"
14939 if (optimize_insn_for_size_p ())
14942 for (i = 3; i < 10; i++)
14943 operands[i] = gen_reg_rtx (XFmode);
14945 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14948 (define_expand "expxf2"
14949 [(use (match_operand:XF 0 "register_operand"))
14950 (use (match_operand:XF 1 "register_operand"))]
14951 "TARGET_USE_FANCY_MATH_387
14952 && flag_unsafe_math_optimizations"
14956 if (optimize_insn_for_size_p ())
14959 op2 = gen_reg_rtx (XFmode);
14960 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14962 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14966 (define_expand "exp<mode>2"
14967 [(use (match_operand:MODEF 0 "register_operand"))
14968 (use (match_operand:MODEF 1 "general_operand"))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14971 || TARGET_MIX_SSE_I387)
14972 && flag_unsafe_math_optimizations"
14976 if (optimize_insn_for_size_p ())
14979 op0 = gen_reg_rtx (XFmode);
14980 op1 = gen_reg_rtx (XFmode);
14982 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14983 emit_insn (gen_expxf2 (op0, op1));
14984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14988 (define_expand "exp10xf2"
14989 [(use (match_operand:XF 0 "register_operand"))
14990 (use (match_operand:XF 1 "register_operand"))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14996 if (optimize_insn_for_size_p ())
14999 op2 = gen_reg_rtx (XFmode);
15000 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15002 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15006 (define_expand "exp10<mode>2"
15007 [(use (match_operand:MODEF 0 "register_operand"))
15008 (use (match_operand:MODEF 1 "general_operand"))]
15009 "TARGET_USE_FANCY_MATH_387
15010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15011 || TARGET_MIX_SSE_I387)
15012 && flag_unsafe_math_optimizations"
15016 if (optimize_insn_for_size_p ())
15019 op0 = gen_reg_rtx (XFmode);
15020 op1 = gen_reg_rtx (XFmode);
15022 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15023 emit_insn (gen_exp10xf2 (op0, op1));
15024 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15028 (define_expand "exp2xf2"
15029 [(use (match_operand:XF 0 "register_operand"))
15030 (use (match_operand:XF 1 "register_operand"))]
15031 "TARGET_USE_FANCY_MATH_387
15032 && flag_unsafe_math_optimizations"
15036 if (optimize_insn_for_size_p ())
15039 op2 = gen_reg_rtx (XFmode);
15040 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15042 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15046 (define_expand "exp2<mode>2"
15047 [(use (match_operand:MODEF 0 "register_operand"))
15048 (use (match_operand:MODEF 1 "general_operand"))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15051 || TARGET_MIX_SSE_I387)
15052 && flag_unsafe_math_optimizations"
15056 if (optimize_insn_for_size_p ())
15059 op0 = gen_reg_rtx (XFmode);
15060 op1 = gen_reg_rtx (XFmode);
15062 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15063 emit_insn (gen_exp2xf2 (op0, op1));
15064 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15068 (define_expand "expm1xf2"
15069 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15071 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15072 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15073 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15074 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15075 (parallel [(set (match_dup 7)
15076 (unspec:XF [(match_dup 6) (match_dup 4)]
15077 UNSPEC_FSCALE_FRACT))
15079 (unspec:XF [(match_dup 6) (match_dup 4)]
15080 UNSPEC_FSCALE_EXP))])
15081 (parallel [(set (match_dup 10)
15082 (unspec:XF [(match_dup 9) (match_dup 8)]
15083 UNSPEC_FSCALE_FRACT))
15084 (set (match_dup 11)
15085 (unspec:XF [(match_dup 9) (match_dup 8)]
15086 UNSPEC_FSCALE_EXP))])
15087 (set (match_dup 12) (minus:XF (match_dup 10)
15088 (float_extend:XF (match_dup 13))))
15089 (set (match_operand:XF 0 "register_operand")
15090 (plus:XF (match_dup 12) (match_dup 7)))]
15091 "TARGET_USE_FANCY_MATH_387
15092 && flag_unsafe_math_optimizations"
15096 if (optimize_insn_for_size_p ())
15099 for (i = 2; i < 13; i++)
15100 operands[i] = gen_reg_rtx (XFmode);
15103 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15105 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15108 (define_expand "expm1<mode>2"
15109 [(use (match_operand:MODEF 0 "register_operand"))
15110 (use (match_operand:MODEF 1 "general_operand"))]
15111 "TARGET_USE_FANCY_MATH_387
15112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15113 || TARGET_MIX_SSE_I387)
15114 && flag_unsafe_math_optimizations"
15118 if (optimize_insn_for_size_p ())
15121 op0 = gen_reg_rtx (XFmode);
15122 op1 = gen_reg_rtx (XFmode);
15124 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15125 emit_insn (gen_expm1xf2 (op0, op1));
15126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15130 (define_expand "ldexpxf3"
15131 [(match_operand:XF 0 "register_operand")
15132 (match_operand:XF 1 "register_operand")
15133 (match_operand:SI 2 "register_operand")]
15134 "TARGET_USE_FANCY_MATH_387
15135 && flag_unsafe_math_optimizations"
15138 if (optimize_insn_for_size_p ())
15141 tmp1 = gen_reg_rtx (XFmode);
15142 tmp2 = gen_reg_rtx (XFmode);
15144 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15145 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15146 operands[1], tmp1));
15150 (define_expand "ldexp<mode>3"
15151 [(use (match_operand:MODEF 0 "register_operand"))
15152 (use (match_operand:MODEF 1 "general_operand"))
15153 (use (match_operand:SI 2 "register_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_ldexpxf3 (op0, op1, operands[2]));
15169 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15173 (define_expand "scalbxf3"
15174 [(parallel [(set (match_operand:XF 0 " register_operand")
15175 (unspec:XF [(match_operand:XF 1 "register_operand")
15176 (match_operand:XF 2 "register_operand")]
15177 UNSPEC_FSCALE_FRACT))
15179 (unspec:XF [(match_dup 1) (match_dup 2)]
15180 UNSPEC_FSCALE_EXP))])]
15181 "TARGET_USE_FANCY_MATH_387
15182 && flag_unsafe_math_optimizations"
15184 if (optimize_insn_for_size_p ())
15187 operands[3] = gen_reg_rtx (XFmode);
15190 (define_expand "scalb<mode>3"
15191 [(use (match_operand:MODEF 0 "register_operand"))
15192 (use (match_operand:MODEF 1 "general_operand"))
15193 (use (match_operand:MODEF 2 "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);
15206 op2 = gen_reg_rtx (XFmode);
15208 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15209 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15210 emit_insn (gen_scalbxf3 (op0, op1, op2));
15211 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15215 (define_expand "significandxf2"
15216 [(parallel [(set (match_operand:XF 0 "register_operand")
15217 (unspec:XF [(match_operand:XF 1 "register_operand")]
15218 UNSPEC_XTRACT_FRACT))
15220 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15221 "TARGET_USE_FANCY_MATH_387
15222 && flag_unsafe_math_optimizations"
15223 "operands[2] = gen_reg_rtx (XFmode);")
15225 (define_expand "significand<mode>2"
15226 [(use (match_operand:MODEF 0 "register_operand"))
15227 (use (match_operand:MODEF 1 "register_operand"))]
15228 "TARGET_USE_FANCY_MATH_387
15229 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15230 || TARGET_MIX_SSE_I387)
15231 && flag_unsafe_math_optimizations"
15233 rtx op0 = gen_reg_rtx (XFmode);
15234 rtx op1 = gen_reg_rtx (XFmode);
15236 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15237 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15242 (define_insn "sse4_1_round<mode>2"
15243 [(set (match_operand:MODEF 0 "register_operand" "=x")
15244 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15245 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15248 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15249 [(set_attr "type" "ssecvt")
15250 (set_attr "prefix_extra" "1")
15251 (set_attr "prefix" "maybe_vex")
15252 (set_attr "mode" "<MODE>")])
15254 (define_insn "rintxf2"
15255 [(set (match_operand:XF 0 "register_operand" "=f")
15256 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15258 "TARGET_USE_FANCY_MATH_387
15259 && flag_unsafe_math_optimizations"
15261 [(set_attr "type" "fpspc")
15262 (set_attr "mode" "XF")])
15264 (define_expand "rint<mode>2"
15265 [(use (match_operand:MODEF 0 "register_operand"))
15266 (use (match_operand:MODEF 1 "register_operand"))]
15267 "(TARGET_USE_FANCY_MATH_387
15268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15269 || TARGET_MIX_SSE_I387)
15270 && flag_unsafe_math_optimizations)
15271 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15272 && !flag_trapping_math)"
15274 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15275 && !flag_trapping_math)
15278 emit_insn (gen_sse4_1_round<mode>2
15279 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15280 else if (optimize_insn_for_size_p ())
15283 ix86_expand_rint (operands[0], operands[1]);
15287 rtx op0 = gen_reg_rtx (XFmode);
15288 rtx op1 = gen_reg_rtx (XFmode);
15290 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15291 emit_insn (gen_rintxf2 (op0, op1));
15293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15298 (define_expand "round<mode>2"
15299 [(match_operand:X87MODEF 0 "register_operand")
15300 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15301 "(TARGET_USE_FANCY_MATH_387
15302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15303 || TARGET_MIX_SSE_I387)
15304 && flag_unsafe_math_optimizations)
15305 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15306 && !flag_trapping_math && !flag_rounding_math)"
15308 if (optimize_insn_for_size_p ())
15311 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15312 && !flag_trapping_math && !flag_rounding_math)
15316 operands[1] = force_reg (<MODE>mode, operands[1]);
15317 ix86_expand_round_sse4 (operands[0], operands[1]);
15319 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15320 ix86_expand_round (operands[0], operands[1]);
15322 ix86_expand_rounddf_32 (operands[0], operands[1]);
15326 operands[1] = force_reg (<MODE>mode, operands[1]);
15327 ix86_emit_i387_round (operands[0], operands[1]);
15332 (define_insn_and_split "*fistdi2_1"
15333 [(set (match_operand:DI 0 "nonimmediate_operand")
15334 (unspec:DI [(match_operand:XF 1 "register_operand")]
15336 "TARGET_USE_FANCY_MATH_387
15337 && can_create_pseudo_p ()"
15342 if (memory_operand (operands[0], VOIDmode))
15343 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15346 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15347 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15352 [(set_attr "type" "fpspc")
15353 (set_attr "mode" "DI")])
15355 (define_insn "fistdi2"
15356 [(set (match_operand:DI 0 "memory_operand" "=m")
15357 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15359 (clobber (match_scratch:XF 2 "=&1f"))]
15360 "TARGET_USE_FANCY_MATH_387"
15361 "* return output_fix_trunc (insn, operands, false);"
15362 [(set_attr "type" "fpspc")
15363 (set_attr "mode" "DI")])
15365 (define_insn "fistdi2_with_temp"
15366 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15367 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15369 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15370 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15371 "TARGET_USE_FANCY_MATH_387"
15373 [(set_attr "type" "fpspc")
15374 (set_attr "mode" "DI")])
15377 [(set (match_operand:DI 0 "register_operand")
15378 (unspec:DI [(match_operand:XF 1 "register_operand")]
15380 (clobber (match_operand:DI 2 "memory_operand"))
15381 (clobber (match_scratch 3))]
15383 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15384 (clobber (match_dup 3))])
15385 (set (match_dup 0) (match_dup 2))])
15388 [(set (match_operand:DI 0 "memory_operand")
15389 (unspec:DI [(match_operand:XF 1 "register_operand")]
15391 (clobber (match_operand:DI 2 "memory_operand"))
15392 (clobber (match_scratch 3))]
15394 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15395 (clobber (match_dup 3))])])
15397 (define_insn_and_split "*fist<mode>2_1"
15398 [(set (match_operand:SWI24 0 "register_operand")
15399 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15401 "TARGET_USE_FANCY_MATH_387
15402 && can_create_pseudo_p ()"
15407 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15408 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15412 [(set_attr "type" "fpspc")
15413 (set_attr "mode" "<MODE>")])
15415 (define_insn "fist<mode>2"
15416 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15417 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15419 "TARGET_USE_FANCY_MATH_387"
15420 "* return output_fix_trunc (insn, operands, false);"
15421 [(set_attr "type" "fpspc")
15422 (set_attr "mode" "<MODE>")])
15424 (define_insn "fist<mode>2_with_temp"
15425 [(set (match_operand:SWI24 0 "register_operand" "=r")
15426 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15428 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15429 "TARGET_USE_FANCY_MATH_387"
15431 [(set_attr "type" "fpspc")
15432 (set_attr "mode" "<MODE>")])
15435 [(set (match_operand:SWI24 0 "register_operand")
15436 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15438 (clobber (match_operand:SWI24 2 "memory_operand"))]
15440 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15441 (set (match_dup 0) (match_dup 2))])
15444 [(set (match_operand:SWI24 0 "memory_operand")
15445 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15447 (clobber (match_operand:SWI24 2 "memory_operand"))]
15449 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15451 (define_expand "lrintxf<mode>2"
15452 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15453 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15455 "TARGET_USE_FANCY_MATH_387")
15457 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15458 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15459 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15460 UNSPEC_FIX_NOTRUNC))]
15461 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15463 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15464 [(match_operand:SWI248x 0 "nonimmediate_operand")
15465 (match_operand:X87MODEF 1 "register_operand")]
15466 "(TARGET_USE_FANCY_MATH_387
15467 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15468 || TARGET_MIX_SSE_I387)
15469 && flag_unsafe_math_optimizations)
15470 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15471 && <SWI248x:MODE>mode != HImode
15472 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15473 && !flag_trapping_math && !flag_rounding_math)"
15475 if (optimize_insn_for_size_p ())
15478 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15479 && <SWI248x:MODE>mode != HImode
15480 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15481 && !flag_trapping_math && !flag_rounding_math)
15482 ix86_expand_lround (operands[0], operands[1]);
15484 ix86_emit_i387_round (operands[0], operands[1]);
15488 (define_int_iterator FRNDINT_ROUNDING
15489 [UNSPEC_FRNDINT_FLOOR
15490 UNSPEC_FRNDINT_CEIL
15491 UNSPEC_FRNDINT_TRUNC])
15493 (define_int_iterator FIST_ROUNDING
15497 ;; Base name for define_insn
15498 (define_int_attr rounding_insn
15499 [(UNSPEC_FRNDINT_FLOOR "floor")
15500 (UNSPEC_FRNDINT_CEIL "ceil")
15501 (UNSPEC_FRNDINT_TRUNC "btrunc")
15502 (UNSPEC_FIST_FLOOR "floor")
15503 (UNSPEC_FIST_CEIL "ceil")])
15505 (define_int_attr rounding
15506 [(UNSPEC_FRNDINT_FLOOR "floor")
15507 (UNSPEC_FRNDINT_CEIL "ceil")
15508 (UNSPEC_FRNDINT_TRUNC "trunc")
15509 (UNSPEC_FIST_FLOOR "floor")
15510 (UNSPEC_FIST_CEIL "ceil")])
15512 (define_int_attr ROUNDING
15513 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15514 (UNSPEC_FRNDINT_CEIL "CEIL")
15515 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15516 (UNSPEC_FIST_FLOOR "FLOOR")
15517 (UNSPEC_FIST_CEIL "CEIL")])
15519 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15520 (define_insn_and_split "frndintxf2_<rounding>"
15521 [(set (match_operand:XF 0 "register_operand")
15522 (unspec:XF [(match_operand:XF 1 "register_operand")]
15524 (clobber (reg:CC FLAGS_REG))]
15525 "TARGET_USE_FANCY_MATH_387
15526 && flag_unsafe_math_optimizations
15527 && can_create_pseudo_p ()"
15532 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15534 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15535 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15537 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15538 operands[2], operands[3]));
15541 [(set_attr "type" "frndint")
15542 (set_attr "i387_cw" "<rounding>")
15543 (set_attr "mode" "XF")])
15545 (define_insn "frndintxf2_<rounding>_i387"
15546 [(set (match_operand:XF 0 "register_operand" "=f")
15547 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15549 (use (match_operand:HI 2 "memory_operand" "m"))
15550 (use (match_operand:HI 3 "memory_operand" "m"))]
15551 "TARGET_USE_FANCY_MATH_387
15552 && flag_unsafe_math_optimizations"
15553 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15554 [(set_attr "type" "frndint")
15555 (set_attr "i387_cw" "<rounding>")
15556 (set_attr "mode" "XF")])
15558 (define_expand "<rounding_insn>xf2"
15559 [(parallel [(set (match_operand:XF 0 "register_operand")
15560 (unspec:XF [(match_operand:XF 1 "register_operand")]
15562 (clobber (reg:CC FLAGS_REG))])]
15563 "TARGET_USE_FANCY_MATH_387
15564 && flag_unsafe_math_optimizations
15565 && !optimize_insn_for_size_p ()")
15567 (define_expand "<rounding_insn><mode>2"
15568 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15569 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15571 (clobber (reg:CC FLAGS_REG))])]
15572 "(TARGET_USE_FANCY_MATH_387
15573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15574 || TARGET_MIX_SSE_I387)
15575 && flag_unsafe_math_optimizations)
15576 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15577 && !flag_trapping_math)"
15579 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15580 && !flag_trapping_math)
15583 emit_insn (gen_sse4_1_round<mode>2
15584 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15585 else if (optimize_insn_for_size_p ())
15587 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15589 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15590 ix86_expand_floorceil (operands[0], operands[1], true);
15591 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15592 ix86_expand_floorceil (operands[0], operands[1], false);
15593 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15594 ix86_expand_trunc (operands[0], operands[1]);
15596 gcc_unreachable ();
15600 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15601 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15602 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15603 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15604 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15605 ix86_expand_truncdf_32 (operands[0], operands[1]);
15607 gcc_unreachable ();
15614 if (optimize_insn_for_size_p ())
15617 op0 = gen_reg_rtx (XFmode);
15618 op1 = gen_reg_rtx (XFmode);
15619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15620 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15628 (define_insn_and_split "frndintxf2_mask_pm"
15629 [(set (match_operand:XF 0 "register_operand")
15630 (unspec:XF [(match_operand:XF 1 "register_operand")]
15631 UNSPEC_FRNDINT_MASK_PM))
15632 (clobber (reg:CC FLAGS_REG))]
15633 "TARGET_USE_FANCY_MATH_387
15634 && flag_unsafe_math_optimizations
15635 && can_create_pseudo_p ()"
15640 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15642 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15643 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15645 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15646 operands[2], operands[3]));
15649 [(set_attr "type" "frndint")
15650 (set_attr "i387_cw" "mask_pm")
15651 (set_attr "mode" "XF")])
15653 (define_insn "frndintxf2_mask_pm_i387"
15654 [(set (match_operand:XF 0 "register_operand" "=f")
15655 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15656 UNSPEC_FRNDINT_MASK_PM))
15657 (use (match_operand:HI 2 "memory_operand" "m"))
15658 (use (match_operand:HI 3 "memory_operand" "m"))]
15659 "TARGET_USE_FANCY_MATH_387
15660 && flag_unsafe_math_optimizations"
15661 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15662 [(set_attr "type" "frndint")
15663 (set_attr "i387_cw" "mask_pm")
15664 (set_attr "mode" "XF")])
15666 (define_expand "nearbyintxf2"
15667 [(parallel [(set (match_operand:XF 0 "register_operand")
15668 (unspec:XF [(match_operand:XF 1 "register_operand")]
15669 UNSPEC_FRNDINT_MASK_PM))
15670 (clobber (reg:CC FLAGS_REG))])]
15671 "TARGET_USE_FANCY_MATH_387
15672 && flag_unsafe_math_optimizations")
15674 (define_expand "nearbyint<mode>2"
15675 [(use (match_operand:MODEF 0 "register_operand"))
15676 (use (match_operand:MODEF 1 "register_operand"))]
15677 "TARGET_USE_FANCY_MATH_387
15678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15679 || TARGET_MIX_SSE_I387)
15680 && flag_unsafe_math_optimizations"
15682 rtx op0 = gen_reg_rtx (XFmode);
15683 rtx op1 = gen_reg_rtx (XFmode);
15685 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15686 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15688 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15692 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15693 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15694 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15695 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15697 (clobber (reg:CC FLAGS_REG))]
15698 "TARGET_USE_FANCY_MATH_387
15699 && flag_unsafe_math_optimizations
15700 && can_create_pseudo_p ()"
15705 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15707 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15708 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15709 if (memory_operand (operands[0], VOIDmode))
15710 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15711 operands[2], operands[3]));
15714 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15715 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15716 (operands[0], operands[1], operands[2],
15717 operands[3], operands[4]));
15721 [(set_attr "type" "fistp")
15722 (set_attr "i387_cw" "<rounding>")
15723 (set_attr "mode" "<MODE>")])
15725 (define_insn "fistdi2_<rounding>"
15726 [(set (match_operand:DI 0 "memory_operand" "=m")
15727 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15729 (use (match_operand:HI 2 "memory_operand" "m"))
15730 (use (match_operand:HI 3 "memory_operand" "m"))
15731 (clobber (match_scratch:XF 4 "=&1f"))]
15732 "TARGET_USE_FANCY_MATH_387
15733 && flag_unsafe_math_optimizations"
15734 "* return output_fix_trunc (insn, operands, false);"
15735 [(set_attr "type" "fistp")
15736 (set_attr "i387_cw" "<rounding>")
15737 (set_attr "mode" "DI")])
15739 (define_insn "fistdi2_<rounding>_with_temp"
15740 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15741 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15743 (use (match_operand:HI 2 "memory_operand" "m,m"))
15744 (use (match_operand:HI 3 "memory_operand" "m,m"))
15745 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15746 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15747 "TARGET_USE_FANCY_MATH_387
15748 && flag_unsafe_math_optimizations"
15750 [(set_attr "type" "fistp")
15751 (set_attr "i387_cw" "<rounding>")
15752 (set_attr "mode" "DI")])
15755 [(set (match_operand:DI 0 "register_operand")
15756 (unspec:DI [(match_operand:XF 1 "register_operand")]
15758 (use (match_operand:HI 2 "memory_operand"))
15759 (use (match_operand:HI 3 "memory_operand"))
15760 (clobber (match_operand:DI 4 "memory_operand"))
15761 (clobber (match_scratch 5))]
15763 [(parallel [(set (match_dup 4)
15764 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15765 (use (match_dup 2))
15766 (use (match_dup 3))
15767 (clobber (match_dup 5))])
15768 (set (match_dup 0) (match_dup 4))])
15771 [(set (match_operand:DI 0 "memory_operand")
15772 (unspec:DI [(match_operand:XF 1 "register_operand")]
15774 (use (match_operand:HI 2 "memory_operand"))
15775 (use (match_operand:HI 3 "memory_operand"))
15776 (clobber (match_operand:DI 4 "memory_operand"))
15777 (clobber (match_scratch 5))]
15779 [(parallel [(set (match_dup 0)
15780 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15781 (use (match_dup 2))
15782 (use (match_dup 3))
15783 (clobber (match_dup 5))])])
15785 (define_insn "fist<mode>2_<rounding>"
15786 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15787 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15789 (use (match_operand:HI 2 "memory_operand" "m"))
15790 (use (match_operand:HI 3 "memory_operand" "m"))]
15791 "TARGET_USE_FANCY_MATH_387
15792 && flag_unsafe_math_optimizations"
15793 "* return output_fix_trunc (insn, operands, false);"
15794 [(set_attr "type" "fistp")
15795 (set_attr "i387_cw" "<rounding>")
15796 (set_attr "mode" "<MODE>")])
15798 (define_insn "fist<mode>2_<rounding>_with_temp"
15799 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15800 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15802 (use (match_operand:HI 2 "memory_operand" "m,m"))
15803 (use (match_operand:HI 3 "memory_operand" "m,m"))
15804 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15805 "TARGET_USE_FANCY_MATH_387
15806 && flag_unsafe_math_optimizations"
15808 [(set_attr "type" "fistp")
15809 (set_attr "i387_cw" "<rounding>")
15810 (set_attr "mode" "<MODE>")])
15813 [(set (match_operand:SWI24 0 "register_operand")
15814 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15816 (use (match_operand:HI 2 "memory_operand"))
15817 (use (match_operand:HI 3 "memory_operand"))
15818 (clobber (match_operand:SWI24 4 "memory_operand"))]
15820 [(parallel [(set (match_dup 4)
15821 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15822 (use (match_dup 2))
15823 (use (match_dup 3))])
15824 (set (match_dup 0) (match_dup 4))])
15827 [(set (match_operand:SWI24 0 "memory_operand")
15828 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15830 (use (match_operand:HI 2 "memory_operand"))
15831 (use (match_operand:HI 3 "memory_operand"))
15832 (clobber (match_operand:SWI24 4 "memory_operand"))]
15834 [(parallel [(set (match_dup 0)
15835 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15836 (use (match_dup 2))
15837 (use (match_dup 3))])])
15839 (define_expand "l<rounding_insn>xf<mode>2"
15840 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15841 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15843 (clobber (reg:CC FLAGS_REG))])]
15844 "TARGET_USE_FANCY_MATH_387
15845 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15846 && flag_unsafe_math_optimizations")
15848 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15849 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15850 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15852 (clobber (reg:CC FLAGS_REG))])]
15853 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15854 && !flag_trapping_math"
15856 if (TARGET_64BIT && optimize_insn_for_size_p ())
15859 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15860 ix86_expand_lfloorceil (operands[0], operands[1], true);
15861 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15862 ix86_expand_lfloorceil (operands[0], operands[1], false);
15864 gcc_unreachable ();
15869 (define_insn "fxam<mode>2_i387"
15870 [(set (match_operand:HI 0 "register_operand" "=a")
15872 [(match_operand:X87MODEF 1 "register_operand" "f")]
15874 "TARGET_USE_FANCY_MATH_387"
15875 "fxam\n\tfnstsw\t%0"
15876 [(set_attr "type" "multi")
15877 (set_attr "length" "4")
15878 (set_attr "unit" "i387")
15879 (set_attr "mode" "<MODE>")])
15881 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15882 [(set (match_operand:HI 0 "register_operand")
15884 [(match_operand:MODEF 1 "memory_operand")]
15886 "TARGET_USE_FANCY_MATH_387
15887 && can_create_pseudo_p ()"
15890 [(set (match_dup 2)(match_dup 1))
15892 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15894 operands[2] = gen_reg_rtx (<MODE>mode);
15896 MEM_VOLATILE_P (operands[1]) = 1;
15898 [(set_attr "type" "multi")
15899 (set_attr "unit" "i387")
15900 (set_attr "mode" "<MODE>")])
15902 (define_expand "isinfxf2"
15903 [(use (match_operand:SI 0 "register_operand"))
15904 (use (match_operand:XF 1 "register_operand"))]
15905 "TARGET_USE_FANCY_MATH_387
15906 && ix86_libc_has_function (function_c99_misc)"
15908 rtx mask = GEN_INT (0x45);
15909 rtx val = GEN_INT (0x05);
15913 rtx scratch = gen_reg_rtx (HImode);
15914 rtx res = gen_reg_rtx (QImode);
15916 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15918 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15919 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15920 cond = gen_rtx_fmt_ee (EQ, QImode,
15921 gen_rtx_REG (CCmode, FLAGS_REG),
15923 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15924 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15928 (define_expand "isinf<mode>2"
15929 [(use (match_operand:SI 0 "register_operand"))
15930 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15931 "TARGET_USE_FANCY_MATH_387
15932 && ix86_libc_has_function (function_c99_misc)
15933 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15935 rtx mask = GEN_INT (0x45);
15936 rtx val = GEN_INT (0x05);
15940 rtx scratch = gen_reg_rtx (HImode);
15941 rtx res = gen_reg_rtx (QImode);
15943 /* Remove excess precision by forcing value through memory. */
15944 if (memory_operand (operands[1], VOIDmode))
15945 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15948 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15950 emit_move_insn (temp, operands[1]);
15951 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15954 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15955 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15956 cond = gen_rtx_fmt_ee (EQ, QImode,
15957 gen_rtx_REG (CCmode, FLAGS_REG),
15959 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15960 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15964 (define_expand "signbitxf2"
15965 [(use (match_operand:SI 0 "register_operand"))
15966 (use (match_operand:XF 1 "register_operand"))]
15967 "TARGET_USE_FANCY_MATH_387"
15969 rtx scratch = gen_reg_rtx (HImode);
15971 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15972 emit_insn (gen_andsi3 (operands[0],
15973 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15977 (define_insn "movmsk_df"
15978 [(set (match_operand:SI 0 "register_operand" "=r")
15980 [(match_operand:DF 1 "register_operand" "x")]
15982 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15983 "%vmovmskpd\t{%1, %0|%0, %1}"
15984 [(set_attr "type" "ssemov")
15985 (set_attr "prefix" "maybe_vex")
15986 (set_attr "mode" "DF")])
15988 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15989 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15990 (define_expand "signbitdf2"
15991 [(use (match_operand:SI 0 "register_operand"))
15992 (use (match_operand:DF 1 "register_operand"))]
15993 "TARGET_USE_FANCY_MATH_387
15994 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15996 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15998 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15999 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16003 rtx scratch = gen_reg_rtx (HImode);
16005 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16006 emit_insn (gen_andsi3 (operands[0],
16007 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16012 (define_expand "signbitsf2"
16013 [(use (match_operand:SI 0 "register_operand"))
16014 (use (match_operand:SF 1 "register_operand"))]
16015 "TARGET_USE_FANCY_MATH_387
16016 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16018 rtx scratch = gen_reg_rtx (HImode);
16020 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16021 emit_insn (gen_andsi3 (operands[0],
16022 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16026 ;; Block operation instructions
16029 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16032 [(set_attr "length" "1")
16033 (set_attr "length_immediate" "0")
16034 (set_attr "modrm" "0")])
16036 (define_expand "movmem<mode>"
16037 [(use (match_operand:BLK 0 "memory_operand"))
16038 (use (match_operand:BLK 1 "memory_operand"))
16039 (use (match_operand:SWI48 2 "nonmemory_operand"))
16040 (use (match_operand:SWI48 3 "const_int_operand"))
16041 (use (match_operand:SI 4 "const_int_operand"))
16042 (use (match_operand:SI 5 "const_int_operand"))
16043 (use (match_operand:SI 6 ""))
16044 (use (match_operand:SI 7 ""))
16045 (use (match_operand:SI 8 ""))]
16048 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16049 operands[2], NULL, operands[3],
16050 operands[4], operands[5],
16051 operands[6], operands[7],
16052 operands[8], false))
16058 ;; Most CPUs don't like single string operations
16059 ;; Handle this case here to simplify previous expander.
16061 (define_expand "strmov"
16062 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16063 (set (match_operand 1 "memory_operand") (match_dup 4))
16064 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16065 (clobber (reg:CC FLAGS_REG))])
16066 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16067 (clobber (reg:CC FLAGS_REG))])]
16070 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16072 /* If .md ever supports :P for Pmode, these can be directly
16073 in the pattern above. */
16074 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16075 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16077 /* Can't use this if the user has appropriated esi or edi. */
16078 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16079 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16081 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16082 operands[2], operands[3],
16083 operands[5], operands[6]));
16087 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16090 (define_expand "strmov_singleop"
16091 [(parallel [(set (match_operand 1 "memory_operand")
16092 (match_operand 3 "memory_operand"))
16093 (set (match_operand 0 "register_operand")
16095 (set (match_operand 2 "register_operand")
16096 (match_operand 5))])]
16098 "ix86_current_function_needs_cld = 1;")
16100 (define_insn "*strmovdi_rex_1"
16101 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16102 (mem:DI (match_operand:P 3 "register_operand" "1")))
16103 (set (match_operand:P 0 "register_operand" "=D")
16104 (plus:P (match_dup 2)
16106 (set (match_operand:P 1 "register_operand" "=S")
16107 (plus:P (match_dup 3)
16110 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16112 [(set_attr "type" "str")
16113 (set_attr "memory" "both")
16114 (set_attr "mode" "DI")])
16116 (define_insn "*strmovsi_1"
16117 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16118 (mem:SI (match_operand:P 3 "register_operand" "1")))
16119 (set (match_operand:P 0 "register_operand" "=D")
16120 (plus:P (match_dup 2)
16122 (set (match_operand:P 1 "register_operand" "=S")
16123 (plus:P (match_dup 3)
16125 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16127 [(set_attr "type" "str")
16128 (set_attr "memory" "both")
16129 (set_attr "mode" "SI")])
16131 (define_insn "*strmovhi_1"
16132 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16133 (mem:HI (match_operand:P 3 "register_operand" "1")))
16134 (set (match_operand:P 0 "register_operand" "=D")
16135 (plus:P (match_dup 2)
16137 (set (match_operand:P 1 "register_operand" "=S")
16138 (plus:P (match_dup 3)
16140 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16142 [(set_attr "type" "str")
16143 (set_attr "memory" "both")
16144 (set_attr "mode" "HI")])
16146 (define_insn "*strmovqi_1"
16147 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16148 (mem:QI (match_operand:P 3 "register_operand" "1")))
16149 (set (match_operand:P 0 "register_operand" "=D")
16150 (plus:P (match_dup 2)
16152 (set (match_operand:P 1 "register_operand" "=S")
16153 (plus:P (match_dup 3)
16155 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16157 [(set_attr "type" "str")
16158 (set_attr "memory" "both")
16159 (set (attr "prefix_rex")
16161 (match_test "<P:MODE>mode == DImode")
16163 (const_string "*")))
16164 (set_attr "mode" "QI")])
16166 (define_expand "rep_mov"
16167 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16168 (set (match_operand 0 "register_operand")
16170 (set (match_operand 2 "register_operand")
16172 (set (match_operand 1 "memory_operand")
16173 (match_operand 3 "memory_operand"))
16174 (use (match_dup 4))])]
16176 "ix86_current_function_needs_cld = 1;")
16178 (define_insn "*rep_movdi_rex64"
16179 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16180 (set (match_operand:P 0 "register_operand" "=D")
16181 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16183 (match_operand:P 3 "register_operand" "0")))
16184 (set (match_operand:P 1 "register_operand" "=S")
16185 (plus:P (ashift:P (match_dup 5) (const_int 3))
16186 (match_operand:P 4 "register_operand" "1")))
16187 (set (mem:BLK (match_dup 3))
16188 (mem:BLK (match_dup 4)))
16189 (use (match_dup 5))]
16191 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16193 [(set_attr "type" "str")
16194 (set_attr "prefix_rep" "1")
16195 (set_attr "memory" "both")
16196 (set_attr "mode" "DI")])
16198 (define_insn "*rep_movsi"
16199 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16200 (set (match_operand:P 0 "register_operand" "=D")
16201 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16203 (match_operand:P 3 "register_operand" "0")))
16204 (set (match_operand:P 1 "register_operand" "=S")
16205 (plus:P (ashift:P (match_dup 5) (const_int 2))
16206 (match_operand:P 4 "register_operand" "1")))
16207 (set (mem:BLK (match_dup 3))
16208 (mem:BLK (match_dup 4)))
16209 (use (match_dup 5))]
16210 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16211 "%^rep{%;} movs{l|d}"
16212 [(set_attr "type" "str")
16213 (set_attr "prefix_rep" "1")
16214 (set_attr "memory" "both")
16215 (set_attr "mode" "SI")])
16217 (define_insn "*rep_movqi"
16218 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16219 (set (match_operand:P 0 "register_operand" "=D")
16220 (plus:P (match_operand:P 3 "register_operand" "0")
16221 (match_operand:P 5 "register_operand" "2")))
16222 (set (match_operand:P 1 "register_operand" "=S")
16223 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16224 (set (mem:BLK (match_dup 3))
16225 (mem:BLK (match_dup 4)))
16226 (use (match_dup 5))]
16227 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16229 [(set_attr "type" "str")
16230 (set_attr "prefix_rep" "1")
16231 (set_attr "memory" "both")
16232 (set_attr "mode" "QI")])
16234 (define_expand "setmem<mode>"
16235 [(use (match_operand:BLK 0 "memory_operand"))
16236 (use (match_operand:SWI48 1 "nonmemory_operand"))
16237 (use (match_operand:QI 2 "nonmemory_operand"))
16238 (use (match_operand 3 "const_int_operand"))
16239 (use (match_operand:SI 4 "const_int_operand"))
16240 (use (match_operand:SI 5 "const_int_operand"))
16241 (use (match_operand:SI 6 ""))
16242 (use (match_operand:SI 7 ""))
16243 (use (match_operand:SI 8 ""))]
16246 if (ix86_expand_set_or_movmem (operands[0], NULL,
16247 operands[1], operands[2],
16248 operands[3], operands[4],
16249 operands[5], operands[6],
16250 operands[7], operands[8], true))
16256 ;; Most CPUs don't like single string operations
16257 ;; Handle this case here to simplify previous expander.
16259 (define_expand "strset"
16260 [(set (match_operand 1 "memory_operand")
16261 (match_operand 2 "register_operand"))
16262 (parallel [(set (match_operand 0 "register_operand")
16264 (clobber (reg:CC FLAGS_REG))])]
16267 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16268 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16270 /* If .md ever supports :P for Pmode, this can be directly
16271 in the pattern above. */
16272 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16273 GEN_INT (GET_MODE_SIZE (GET_MODE
16275 /* Can't use this if the user has appropriated eax or edi. */
16276 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16277 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16279 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16285 (define_expand "strset_singleop"
16286 [(parallel [(set (match_operand 1 "memory_operand")
16287 (match_operand 2 "register_operand"))
16288 (set (match_operand 0 "register_operand")
16290 (unspec [(const_int 0)] UNSPEC_STOS)])]
16292 "ix86_current_function_needs_cld = 1;")
16294 (define_insn "*strsetdi_rex_1"
16295 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16296 (match_operand:DI 2 "register_operand" "a"))
16297 (set (match_operand:P 0 "register_operand" "=D")
16298 (plus:P (match_dup 1)
16300 (unspec [(const_int 0)] UNSPEC_STOS)]
16302 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16304 [(set_attr "type" "str")
16305 (set_attr "memory" "store")
16306 (set_attr "mode" "DI")])
16308 (define_insn "*strsetsi_1"
16309 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16310 (match_operand:SI 2 "register_operand" "a"))
16311 (set (match_operand:P 0 "register_operand" "=D")
16312 (plus:P (match_dup 1)
16314 (unspec [(const_int 0)] UNSPEC_STOS)]
16315 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16317 [(set_attr "type" "str")
16318 (set_attr "memory" "store")
16319 (set_attr "mode" "SI")])
16321 (define_insn "*strsethi_1"
16322 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16323 (match_operand:HI 2 "register_operand" "a"))
16324 (set (match_operand:P 0 "register_operand" "=D")
16325 (plus:P (match_dup 1)
16327 (unspec [(const_int 0)] UNSPEC_STOS)]
16328 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16330 [(set_attr "type" "str")
16331 (set_attr "memory" "store")
16332 (set_attr "mode" "HI")])
16334 (define_insn "*strsetqi_1"
16335 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16336 (match_operand:QI 2 "register_operand" "a"))
16337 (set (match_operand:P 0 "register_operand" "=D")
16338 (plus:P (match_dup 1)
16340 (unspec [(const_int 0)] UNSPEC_STOS)]
16341 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16343 [(set_attr "type" "str")
16344 (set_attr "memory" "store")
16345 (set (attr "prefix_rex")
16347 (match_test "<P:MODE>mode == DImode")
16349 (const_string "*")))
16350 (set_attr "mode" "QI")])
16352 (define_expand "rep_stos"
16353 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16354 (set (match_operand 0 "register_operand")
16356 (set (match_operand 2 "memory_operand") (const_int 0))
16357 (use (match_operand 3 "register_operand"))
16358 (use (match_dup 1))])]
16360 "ix86_current_function_needs_cld = 1;")
16362 (define_insn "*rep_stosdi_rex64"
16363 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16364 (set (match_operand:P 0 "register_operand" "=D")
16365 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16367 (match_operand:P 3 "register_operand" "0")))
16368 (set (mem:BLK (match_dup 3))
16370 (use (match_operand:DI 2 "register_operand" "a"))
16371 (use (match_dup 4))]
16373 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16375 [(set_attr "type" "str")
16376 (set_attr "prefix_rep" "1")
16377 (set_attr "memory" "store")
16378 (set_attr "mode" "DI")])
16380 (define_insn "*rep_stossi"
16381 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16382 (set (match_operand:P 0 "register_operand" "=D")
16383 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16385 (match_operand:P 3 "register_operand" "0")))
16386 (set (mem:BLK (match_dup 3))
16388 (use (match_operand:SI 2 "register_operand" "a"))
16389 (use (match_dup 4))]
16390 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16391 "%^rep{%;} stos{l|d}"
16392 [(set_attr "type" "str")
16393 (set_attr "prefix_rep" "1")
16394 (set_attr "memory" "store")
16395 (set_attr "mode" "SI")])
16397 (define_insn "*rep_stosqi"
16398 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16399 (set (match_operand:P 0 "register_operand" "=D")
16400 (plus:P (match_operand:P 3 "register_operand" "0")
16401 (match_operand:P 4 "register_operand" "1")))
16402 (set (mem:BLK (match_dup 3))
16404 (use (match_operand:QI 2 "register_operand" "a"))
16405 (use (match_dup 4))]
16406 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16408 [(set_attr "type" "str")
16409 (set_attr "prefix_rep" "1")
16410 (set_attr "memory" "store")
16411 (set (attr "prefix_rex")
16413 (match_test "<P:MODE>mode == DImode")
16415 (const_string "*")))
16416 (set_attr "mode" "QI")])
16418 (define_expand "cmpstrnsi"
16419 [(set (match_operand:SI 0 "register_operand")
16420 (compare:SI (match_operand:BLK 1 "general_operand")
16421 (match_operand:BLK 2 "general_operand")))
16422 (use (match_operand 3 "general_operand"))
16423 (use (match_operand 4 "immediate_operand"))]
16426 rtx addr1, addr2, out, outlow, count, countreg, align;
16428 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16431 /* Can't use this if the user has appropriated ecx, esi or edi. */
16432 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16437 out = gen_reg_rtx (SImode);
16439 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16440 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16441 if (addr1 != XEXP (operands[1], 0))
16442 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16443 if (addr2 != XEXP (operands[2], 0))
16444 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16446 count = operands[3];
16447 countreg = ix86_zero_extend_to_Pmode (count);
16449 /* %%% Iff we are testing strict equality, we can use known alignment
16450 to good advantage. This may be possible with combine, particularly
16451 once cc0 is dead. */
16452 align = operands[4];
16454 if (CONST_INT_P (count))
16456 if (INTVAL (count) == 0)
16458 emit_move_insn (operands[0], const0_rtx);
16461 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16462 operands[1], operands[2]));
16466 rtx (*gen_cmp) (rtx, rtx);
16468 gen_cmp = (TARGET_64BIT
16469 ? gen_cmpdi_1 : gen_cmpsi_1);
16471 emit_insn (gen_cmp (countreg, countreg));
16472 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16473 operands[1], operands[2]));
16476 outlow = gen_lowpart (QImode, out);
16477 emit_insn (gen_cmpintqi (outlow));
16478 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16480 if (operands[0] != out)
16481 emit_move_insn (operands[0], out);
16486 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16488 (define_expand "cmpintqi"
16489 [(set (match_dup 1)
16490 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16492 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16493 (parallel [(set (match_operand:QI 0 "register_operand")
16494 (minus:QI (match_dup 1)
16496 (clobber (reg:CC FLAGS_REG))])]
16499 operands[1] = gen_reg_rtx (QImode);
16500 operands[2] = gen_reg_rtx (QImode);
16503 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16504 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16506 (define_expand "cmpstrnqi_nz_1"
16507 [(parallel [(set (reg:CC FLAGS_REG)
16508 (compare:CC (match_operand 4 "memory_operand")
16509 (match_operand 5 "memory_operand")))
16510 (use (match_operand 2 "register_operand"))
16511 (use (match_operand:SI 3 "immediate_operand"))
16512 (clobber (match_operand 0 "register_operand"))
16513 (clobber (match_operand 1 "register_operand"))
16514 (clobber (match_dup 2))])]
16516 "ix86_current_function_needs_cld = 1;")
16518 (define_insn "*cmpstrnqi_nz_1"
16519 [(set (reg:CC FLAGS_REG)
16520 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16521 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16522 (use (match_operand:P 6 "register_operand" "2"))
16523 (use (match_operand:SI 3 "immediate_operand" "i"))
16524 (clobber (match_operand:P 0 "register_operand" "=S"))
16525 (clobber (match_operand:P 1 "register_operand" "=D"))
16526 (clobber (match_operand:P 2 "register_operand" "=c"))]
16527 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16529 [(set_attr "type" "str")
16530 (set_attr "mode" "QI")
16531 (set (attr "prefix_rex")
16533 (match_test "<P:MODE>mode == DImode")
16535 (const_string "*")))
16536 (set_attr "prefix_rep" "1")])
16538 ;; The same, but the count is not known to not be zero.
16540 (define_expand "cmpstrnqi_1"
16541 [(parallel [(set (reg:CC FLAGS_REG)
16542 (if_then_else:CC (ne (match_operand 2 "register_operand")
16544 (compare:CC (match_operand 4 "memory_operand")
16545 (match_operand 5 "memory_operand"))
16547 (use (match_operand:SI 3 "immediate_operand"))
16548 (use (reg:CC FLAGS_REG))
16549 (clobber (match_operand 0 "register_operand"))
16550 (clobber (match_operand 1 "register_operand"))
16551 (clobber (match_dup 2))])]
16553 "ix86_current_function_needs_cld = 1;")
16555 (define_insn "*cmpstrnqi_1"
16556 [(set (reg:CC FLAGS_REG)
16557 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16559 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16560 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16562 (use (match_operand:SI 3 "immediate_operand" "i"))
16563 (use (reg:CC FLAGS_REG))
16564 (clobber (match_operand:P 0 "register_operand" "=S"))
16565 (clobber (match_operand:P 1 "register_operand" "=D"))
16566 (clobber (match_operand:P 2 "register_operand" "=c"))]
16567 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16569 [(set_attr "type" "str")
16570 (set_attr "mode" "QI")
16571 (set (attr "prefix_rex")
16573 (match_test "<P:MODE>mode == DImode")
16575 (const_string "*")))
16576 (set_attr "prefix_rep" "1")])
16578 (define_expand "strlen<mode>"
16579 [(set (match_operand:P 0 "register_operand")
16580 (unspec:P [(match_operand:BLK 1 "general_operand")
16581 (match_operand:QI 2 "immediate_operand")
16582 (match_operand 3 "immediate_operand")]
16586 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16592 (define_expand "strlenqi_1"
16593 [(parallel [(set (match_operand 0 "register_operand")
16595 (clobber (match_operand 1 "register_operand"))
16596 (clobber (reg:CC FLAGS_REG))])]
16598 "ix86_current_function_needs_cld = 1;")
16600 (define_insn "*strlenqi_1"
16601 [(set (match_operand:P 0 "register_operand" "=&c")
16602 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16603 (match_operand:QI 2 "register_operand" "a")
16604 (match_operand:P 3 "immediate_operand" "i")
16605 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16606 (clobber (match_operand:P 1 "register_operand" "=D"))
16607 (clobber (reg:CC FLAGS_REG))]
16608 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16609 "%^repnz{%;} scasb"
16610 [(set_attr "type" "str")
16611 (set_attr "mode" "QI")
16612 (set (attr "prefix_rex")
16614 (match_test "<P:MODE>mode == DImode")
16616 (const_string "*")))
16617 (set_attr "prefix_rep" "1")])
16619 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16620 ;; handled in combine, but it is not currently up to the task.
16621 ;; When used for their truth value, the cmpstrn* expanders generate
16630 ;; The intermediate three instructions are unnecessary.
16632 ;; This one handles cmpstrn*_nz_1...
16635 (set (reg:CC FLAGS_REG)
16636 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16637 (mem:BLK (match_operand 5 "register_operand"))))
16638 (use (match_operand 6 "register_operand"))
16639 (use (match_operand:SI 3 "immediate_operand"))
16640 (clobber (match_operand 0 "register_operand"))
16641 (clobber (match_operand 1 "register_operand"))
16642 (clobber (match_operand 2 "register_operand"))])
16643 (set (match_operand:QI 7 "register_operand")
16644 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16645 (set (match_operand:QI 8 "register_operand")
16646 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16647 (set (reg FLAGS_REG)
16648 (compare (match_dup 7) (match_dup 8)))
16650 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16652 (set (reg:CC FLAGS_REG)
16653 (compare:CC (mem:BLK (match_dup 4))
16654 (mem:BLK (match_dup 5))))
16655 (use (match_dup 6))
16656 (use (match_dup 3))
16657 (clobber (match_dup 0))
16658 (clobber (match_dup 1))
16659 (clobber (match_dup 2))])])
16661 ;; ...and this one handles cmpstrn*_1.
16664 (set (reg:CC FLAGS_REG)
16665 (if_then_else:CC (ne (match_operand 6 "register_operand")
16667 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16668 (mem:BLK (match_operand 5 "register_operand")))
16670 (use (match_operand:SI 3 "immediate_operand"))
16671 (use (reg:CC FLAGS_REG))
16672 (clobber (match_operand 0 "register_operand"))
16673 (clobber (match_operand 1 "register_operand"))
16674 (clobber (match_operand 2 "register_operand"))])
16675 (set (match_operand:QI 7 "register_operand")
16676 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16677 (set (match_operand:QI 8 "register_operand")
16678 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16679 (set (reg FLAGS_REG)
16680 (compare (match_dup 7) (match_dup 8)))
16682 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16684 (set (reg:CC FLAGS_REG)
16685 (if_then_else:CC (ne (match_dup 6)
16687 (compare:CC (mem:BLK (match_dup 4))
16688 (mem:BLK (match_dup 5)))
16690 (use (match_dup 3))
16691 (use (reg:CC FLAGS_REG))
16692 (clobber (match_dup 0))
16693 (clobber (match_dup 1))
16694 (clobber (match_dup 2))])])
16696 ;; Conditional move instructions.
16698 (define_expand "mov<mode>cc"
16699 [(set (match_operand:SWIM 0 "register_operand")
16700 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16701 (match_operand:SWIM 2 "<general_operand>")
16702 (match_operand:SWIM 3 "<general_operand>")))]
16704 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16706 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16707 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16708 ;; So just document what we're doing explicitly.
16710 (define_expand "x86_mov<mode>cc_0_m1"
16712 [(set (match_operand:SWI48 0 "register_operand")
16713 (if_then_else:SWI48
16714 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16715 [(match_operand 1 "flags_reg_operand")
16719 (clobber (reg:CC FLAGS_REG))])])
16721 (define_insn "*x86_mov<mode>cc_0_m1"
16722 [(set (match_operand:SWI48 0 "register_operand" "=r")
16723 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16724 [(reg FLAGS_REG) (const_int 0)])
16727 (clobber (reg:CC FLAGS_REG))]
16729 "sbb{<imodesuffix>}\t%0, %0"
16730 ; Since we don't have the proper number of operands for an alu insn,
16731 ; fill in all the blanks.
16732 [(set_attr "type" "alu")
16733 (set_attr "use_carry" "1")
16734 (set_attr "pent_pair" "pu")
16735 (set_attr "memory" "none")
16736 (set_attr "imm_disp" "false")
16737 (set_attr "mode" "<MODE>")
16738 (set_attr "length_immediate" "0")])
16740 (define_insn "*x86_mov<mode>cc_0_m1_se"
16741 [(set (match_operand:SWI48 0 "register_operand" "=r")
16742 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16743 [(reg FLAGS_REG) (const_int 0)])
16746 (clobber (reg:CC FLAGS_REG))]
16748 "sbb{<imodesuffix>}\t%0, %0"
16749 [(set_attr "type" "alu")
16750 (set_attr "use_carry" "1")
16751 (set_attr "pent_pair" "pu")
16752 (set_attr "memory" "none")
16753 (set_attr "imm_disp" "false")
16754 (set_attr "mode" "<MODE>")
16755 (set_attr "length_immediate" "0")])
16757 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16758 [(set (match_operand:SWI48 0 "register_operand" "=r")
16759 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16760 [(reg FLAGS_REG) (const_int 0)])))
16761 (clobber (reg:CC FLAGS_REG))]
16763 "sbb{<imodesuffix>}\t%0, %0"
16764 [(set_attr "type" "alu")
16765 (set_attr "use_carry" "1")
16766 (set_attr "pent_pair" "pu")
16767 (set_attr "memory" "none")
16768 (set_attr "imm_disp" "false")
16769 (set_attr "mode" "<MODE>")
16770 (set_attr "length_immediate" "0")])
16772 (define_insn "*mov<mode>cc_noc"
16773 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16774 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16775 [(reg FLAGS_REG) (const_int 0)])
16776 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16777 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16778 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16780 cmov%O2%C1\t{%2, %0|%0, %2}
16781 cmov%O2%c1\t{%3, %0|%0, %3}"
16782 [(set_attr "type" "icmov")
16783 (set_attr "mode" "<MODE>")])
16785 ;; Don't do conditional moves with memory inputs. This splitter helps
16786 ;; register starved x86_32 by forcing inputs into registers before reload.
16788 [(set (match_operand:SWI248 0 "register_operand")
16789 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16790 [(reg FLAGS_REG) (const_int 0)])
16791 (match_operand:SWI248 2 "nonimmediate_operand")
16792 (match_operand:SWI248 3 "nonimmediate_operand")))]
16793 "!TARGET_64BIT && TARGET_CMOVE
16794 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16795 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16796 && can_create_pseudo_p ()
16797 && optimize_insn_for_speed_p ()"
16798 [(set (match_dup 0)
16799 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16801 if (MEM_P (operands[2]))
16802 operands[2] = force_reg (<MODE>mode, operands[2]);
16803 if (MEM_P (operands[3]))
16804 operands[3] = force_reg (<MODE>mode, operands[3]);
16807 (define_insn "*movqicc_noc"
16808 [(set (match_operand:QI 0 "register_operand" "=r,r")
16809 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16810 [(reg FLAGS_REG) (const_int 0)])
16811 (match_operand:QI 2 "register_operand" "r,0")
16812 (match_operand:QI 3 "register_operand" "0,r")))]
16813 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16815 [(set_attr "type" "icmov")
16816 (set_attr "mode" "QI")])
16819 [(set (match_operand:SWI12 0 "register_operand")
16820 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16821 [(reg FLAGS_REG) (const_int 0)])
16822 (match_operand:SWI12 2 "register_operand")
16823 (match_operand:SWI12 3 "register_operand")))]
16824 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16825 && reload_completed"
16826 [(set (match_dup 0)
16827 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16829 operands[0] = gen_lowpart (SImode, operands[0]);
16830 operands[2] = gen_lowpart (SImode, operands[2]);
16831 operands[3] = gen_lowpart (SImode, operands[3]);
16834 ;; Don't do conditional moves with memory inputs
16836 [(match_scratch:SWI248 2 "r")
16837 (set (match_operand:SWI248 0 "register_operand")
16838 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16839 [(reg FLAGS_REG) (const_int 0)])
16841 (match_operand:SWI248 3 "memory_operand")))]
16842 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16843 && optimize_insn_for_speed_p ()"
16844 [(set (match_dup 2) (match_dup 3))
16846 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16849 [(match_scratch:SWI248 2 "r")
16850 (set (match_operand:SWI248 0 "register_operand")
16851 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16852 [(reg FLAGS_REG) (const_int 0)])
16853 (match_operand:SWI248 3 "memory_operand")
16855 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16856 && optimize_insn_for_speed_p ()"
16857 [(set (match_dup 2) (match_dup 3))
16859 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16861 (define_expand "mov<mode>cc"
16862 [(set (match_operand:X87MODEF 0 "register_operand")
16863 (if_then_else:X87MODEF
16864 (match_operand 1 "comparison_operator")
16865 (match_operand:X87MODEF 2 "register_operand")
16866 (match_operand:X87MODEF 3 "register_operand")))]
16867 "(TARGET_80387 && TARGET_CMOVE)
16868 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16869 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16871 (define_insn "*movxfcc_1"
16872 [(set (match_operand:XF 0 "register_operand" "=f,f")
16873 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16874 [(reg FLAGS_REG) (const_int 0)])
16875 (match_operand:XF 2 "register_operand" "f,0")
16876 (match_operand:XF 3 "register_operand" "0,f")))]
16877 "TARGET_80387 && TARGET_CMOVE"
16879 fcmov%F1\t{%2, %0|%0, %2}
16880 fcmov%f1\t{%3, %0|%0, %3}"
16881 [(set_attr "type" "fcmov")
16882 (set_attr "mode" "XF")])
16884 (define_insn "*movdfcc_1"
16885 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16886 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16887 [(reg FLAGS_REG) (const_int 0)])
16888 (match_operand:DF 2 "nonimmediate_operand"
16890 (match_operand:DF 3 "nonimmediate_operand"
16891 "0 ,f,0 ,rm,0, rm")))]
16892 "TARGET_80387 && TARGET_CMOVE
16893 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16895 fcmov%F1\t{%2, %0|%0, %2}
16896 fcmov%f1\t{%3, %0|%0, %3}
16899 cmov%O2%C1\t{%2, %0|%0, %2}
16900 cmov%O2%c1\t{%3, %0|%0, %3}"
16901 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16902 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16903 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16906 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16907 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16908 [(reg FLAGS_REG) (const_int 0)])
16909 (match_operand:DF 2 "nonimmediate_operand")
16910 (match_operand:DF 3 "nonimmediate_operand")))]
16911 "!TARGET_64BIT && reload_completed"
16912 [(set (match_dup 2)
16913 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16915 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16917 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16918 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16921 (define_insn "*movsfcc_1_387"
16922 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16923 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16924 [(reg FLAGS_REG) (const_int 0)])
16925 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16926 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16927 "TARGET_80387 && TARGET_CMOVE
16928 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16930 fcmov%F1\t{%2, %0|%0, %2}
16931 fcmov%f1\t{%3, %0|%0, %3}
16932 cmov%O2%C1\t{%2, %0|%0, %2}
16933 cmov%O2%c1\t{%3, %0|%0, %3}"
16934 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16935 (set_attr "mode" "SF,SF,SI,SI")])
16937 ;; Don't do conditional moves with memory inputs. This splitter helps
16938 ;; register starved x86_32 by forcing inputs into registers before reload.
16940 [(set (match_operand:MODEF 0 "register_operand")
16941 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16942 [(reg FLAGS_REG) (const_int 0)])
16943 (match_operand:MODEF 2 "nonimmediate_operand")
16944 (match_operand:MODEF 3 "nonimmediate_operand")))]
16945 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16946 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16947 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16948 && can_create_pseudo_p ()
16949 && optimize_insn_for_speed_p ()"
16950 [(set (match_dup 0)
16951 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16953 if (MEM_P (operands[2]))
16954 operands[2] = force_reg (<MODE>mode, operands[2]);
16955 if (MEM_P (operands[3]))
16956 operands[3] = force_reg (<MODE>mode, operands[3]);
16959 ;; Don't do conditional moves with memory inputs
16961 [(match_scratch:MODEF 2 "r")
16962 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16963 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16964 [(reg FLAGS_REG) (const_int 0)])
16966 (match_operand:MODEF 3 "memory_operand")))]
16967 "(<MODE>mode != DFmode || TARGET_64BIT)
16968 && TARGET_80387 && TARGET_CMOVE
16969 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16970 && optimize_insn_for_speed_p ()"
16971 [(set (match_dup 2) (match_dup 3))
16973 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16976 [(match_scratch:MODEF 2 "r")
16977 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16978 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16979 [(reg FLAGS_REG) (const_int 0)])
16980 (match_operand:MODEF 3 "memory_operand")
16982 "(<MODE>mode != DFmode || TARGET_64BIT)
16983 && TARGET_80387 && TARGET_CMOVE
16984 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16985 && optimize_insn_for_speed_p ()"
16986 [(set (match_dup 2) (match_dup 3))
16988 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16990 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16991 ;; the scalar versions to have only XMM registers as operands.
16993 ;; XOP conditional move
16994 (define_insn "*xop_pcmov_<mode>"
16995 [(set (match_operand:MODEF 0 "register_operand" "=x")
16996 (if_then_else:MODEF
16997 (match_operand:MODEF 1 "register_operand" "x")
16998 (match_operand:MODEF 2 "register_operand" "x")
16999 (match_operand:MODEF 3 "register_operand" "x")))]
17001 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17002 [(set_attr "type" "sse4arg")])
17004 ;; These versions of the min/max patterns are intentionally ignorant of
17005 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17006 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17007 ;; are undefined in this condition, we're certain this is correct.
17009 (define_insn "<code><mode>3"
17010 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17012 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17013 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17014 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17016 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17017 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17018 [(set_attr "isa" "noavx,avx")
17019 (set_attr "prefix" "orig,vex")
17020 (set_attr "type" "sseadd")
17021 (set_attr "mode" "<MODE>")])
17023 ;; These versions of the min/max patterns implement exactly the operations
17024 ;; min = (op1 < op2 ? op1 : op2)
17025 ;; max = (!(op1 < op2) ? op1 : op2)
17026 ;; Their operands are not commutative, and thus they may be used in the
17027 ;; presence of -0.0 and NaN.
17029 (define_int_iterator IEEE_MAXMIN
17033 (define_int_attr ieee_maxmin
17034 [(UNSPEC_IEEE_MAX "max")
17035 (UNSPEC_IEEE_MIN "min")])
17037 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17038 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17040 [(match_operand:MODEF 1 "register_operand" "0,x")
17041 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
17043 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17045 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17046 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17047 [(set_attr "isa" "noavx,avx")
17048 (set_attr "prefix" "orig,vex")
17049 (set_attr "type" "sseadd")
17050 (set_attr "mode" "<MODE>")])
17052 ;; Make two stack loads independent:
17054 ;; fld %st(0) -> fld bb
17055 ;; fmul bb fmul %st(1), %st
17057 ;; Actually we only match the last two instructions for simplicity.
17059 [(set (match_operand 0 "fp_register_operand")
17060 (match_operand 1 "fp_register_operand"))
17062 (match_operator 2 "binary_fp_operator"
17064 (match_operand 3 "memory_operand")]))]
17065 "REGNO (operands[0]) != REGNO (operands[1])"
17066 [(set (match_dup 0) (match_dup 3))
17067 (set (match_dup 0) (match_dup 4))]
17069 ;; The % modifier is not operational anymore in peephole2's, so we have to
17070 ;; swap the operands manually in the case of addition and multiplication.
17074 if (COMMUTATIVE_ARITH_P (operands[2]))
17075 op0 = operands[0], op1 = operands[1];
17077 op0 = operands[1], op1 = operands[0];
17079 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17080 GET_MODE (operands[2]),
17084 ;; Conditional addition patterns
17085 (define_expand "add<mode>cc"
17086 [(match_operand:SWI 0 "register_operand")
17087 (match_operand 1 "ordered_comparison_operator")
17088 (match_operand:SWI 2 "register_operand")
17089 (match_operand:SWI 3 "const_int_operand")]
17091 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17093 ;; Misc patterns (?)
17095 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17096 ;; Otherwise there will be nothing to keep
17098 ;; [(set (reg ebp) (reg esp))]
17099 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17100 ;; (clobber (eflags)]
17101 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17103 ;; in proper program order.
17105 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17106 [(set (match_operand:P 0 "register_operand" "=r,r")
17107 (plus:P (match_operand:P 1 "register_operand" "0,r")
17108 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17109 (clobber (reg:CC FLAGS_REG))
17110 (clobber (mem:BLK (scratch)))]
17113 switch (get_attr_type (insn))
17116 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17119 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17120 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17121 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17123 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17126 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17127 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17130 [(set (attr "type")
17131 (cond [(and (eq_attr "alternative" "0")
17132 (not (match_test "TARGET_OPT_AGU")))
17133 (const_string "alu")
17134 (match_operand:<MODE> 2 "const0_operand")
17135 (const_string "imov")
17137 (const_string "lea")))
17138 (set (attr "length_immediate")
17139 (cond [(eq_attr "type" "imov")
17141 (and (eq_attr "type" "alu")
17142 (match_operand 2 "const128_operand"))
17145 (const_string "*")))
17146 (set_attr "mode" "<MODE>")])
17148 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17149 [(set (match_operand:P 0 "register_operand" "=r")
17150 (minus:P (match_operand:P 1 "register_operand" "0")
17151 (match_operand:P 2 "register_operand" "r")))
17152 (clobber (reg:CC FLAGS_REG))
17153 (clobber (mem:BLK (scratch)))]
17155 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17156 [(set_attr "type" "alu")
17157 (set_attr "mode" "<MODE>")])
17159 (define_insn "allocate_stack_worker_probe_<mode>"
17160 [(set (match_operand:P 0 "register_operand" "=a")
17161 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17162 UNSPECV_STACK_PROBE))
17163 (clobber (reg:CC FLAGS_REG))]
17164 "ix86_target_stack_probe ()"
17165 "call\t___chkstk_ms"
17166 [(set_attr "type" "multi")
17167 (set_attr "length" "5")])
17169 (define_expand "allocate_stack"
17170 [(match_operand 0 "register_operand")
17171 (match_operand 1 "general_operand")]
17172 "ix86_target_stack_probe ()"
17176 #ifndef CHECK_STACK_LIMIT
17177 #define CHECK_STACK_LIMIT 0
17180 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17181 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17185 rtx (*insn) (rtx, rtx);
17187 x = copy_to_mode_reg (Pmode, operands[1]);
17189 insn = (TARGET_64BIT
17190 ? gen_allocate_stack_worker_probe_di
17191 : gen_allocate_stack_worker_probe_si);
17193 emit_insn (insn (x, x));
17196 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17197 stack_pointer_rtx, 0, OPTAB_DIRECT);
17199 if (x != stack_pointer_rtx)
17200 emit_move_insn (stack_pointer_rtx, x);
17202 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17206 ;; Use IOR for stack probes, this is shorter.
17207 (define_expand "probe_stack"
17208 [(match_operand 0 "memory_operand")]
17211 rtx (*gen_ior3) (rtx, rtx, rtx);
17213 gen_ior3 = (GET_MODE (operands[0]) == DImode
17214 ? gen_iordi3 : gen_iorsi3);
17216 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17220 (define_insn "adjust_stack_and_probe<mode>"
17221 [(set (match_operand:P 0 "register_operand" "=r")
17222 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17223 UNSPECV_PROBE_STACK_RANGE))
17224 (set (reg:P SP_REG)
17225 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17226 (clobber (reg:CC FLAGS_REG))
17227 (clobber (mem:BLK (scratch)))]
17229 "* return output_adjust_stack_and_probe (operands[0]);"
17230 [(set_attr "type" "multi")])
17232 (define_insn "probe_stack_range<mode>"
17233 [(set (match_operand:P 0 "register_operand" "=r")
17234 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17235 (match_operand:P 2 "const_int_operand" "n")]
17236 UNSPECV_PROBE_STACK_RANGE))
17237 (clobber (reg:CC FLAGS_REG))]
17239 "* return output_probe_stack_range (operands[0], operands[2]);"
17240 [(set_attr "type" "multi")])
17242 (define_expand "builtin_setjmp_receiver"
17243 [(label_ref (match_operand 0))]
17244 "!TARGET_64BIT && flag_pic"
17250 rtx_code_label *label_rtx = gen_label_rtx ();
17251 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17252 xops[0] = xops[1] = pic_offset_table_rtx;
17253 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17254 ix86_expand_binary_operator (MINUS, SImode, xops);
17258 emit_insn (gen_set_got (pic_offset_table_rtx));
17262 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17263 ;; Do not split instructions with mask registers.
17265 [(set (match_operand 0 "general_reg_operand")
17266 (match_operator 3 "promotable_binary_operator"
17267 [(match_operand 1 "general_reg_operand")
17268 (match_operand 2 "aligned_operand")]))
17269 (clobber (reg:CC FLAGS_REG))]
17270 "! TARGET_PARTIAL_REG_STALL && reload_completed
17271 && ((GET_MODE (operands[0]) == HImode
17272 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17273 /* ??? next two lines just !satisfies_constraint_K (...) */
17274 || !CONST_INT_P (operands[2])
17275 || satisfies_constraint_K (operands[2])))
17276 || (GET_MODE (operands[0]) == QImode
17277 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17278 [(parallel [(set (match_dup 0)
17279 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17280 (clobber (reg:CC FLAGS_REG))])]
17282 operands[0] = gen_lowpart (SImode, operands[0]);
17283 operands[1] = gen_lowpart (SImode, operands[1]);
17284 if (GET_CODE (operands[3]) != ASHIFT)
17285 operands[2] = gen_lowpart (SImode, operands[2]);
17286 operands[3] = shallow_copy_rtx (operands[3]);
17287 PUT_MODE (operands[3], SImode);
17290 ; Promote the QImode tests, as i386 has encoding of the AND
17291 ; instruction with 32-bit sign-extended immediate and thus the
17292 ; instruction size is unchanged, except in the %eax case for
17293 ; which it is increased by one byte, hence the ! optimize_size.
17295 [(set (match_operand 0 "flags_reg_operand")
17296 (match_operator 2 "compare_operator"
17297 [(and (match_operand 3 "aligned_operand")
17298 (match_operand 4 "const_int_operand"))
17300 (set (match_operand 1 "register_operand")
17301 (and (match_dup 3) (match_dup 4)))]
17302 "! TARGET_PARTIAL_REG_STALL && reload_completed
17303 && optimize_insn_for_speed_p ()
17304 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17305 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17306 /* Ensure that the operand will remain sign-extended immediate. */
17307 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17308 [(parallel [(set (match_dup 0)
17309 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17312 (and:SI (match_dup 3) (match_dup 4)))])]
17315 = gen_int_mode (INTVAL (operands[4])
17316 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17317 operands[1] = gen_lowpart (SImode, operands[1]);
17318 operands[3] = gen_lowpart (SImode, operands[3]);
17321 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17322 ; the TEST instruction with 32-bit sign-extended immediate and thus
17323 ; the instruction size would at least double, which is not what we
17324 ; want even with ! optimize_size.
17326 [(set (match_operand 0 "flags_reg_operand")
17327 (match_operator 1 "compare_operator"
17328 [(and (match_operand:HI 2 "aligned_operand")
17329 (match_operand:HI 3 "const_int_operand"))
17331 "! TARGET_PARTIAL_REG_STALL && reload_completed
17332 && ! TARGET_FAST_PREFIX
17333 && optimize_insn_for_speed_p ()
17334 /* Ensure that the operand will remain sign-extended immediate. */
17335 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17336 [(set (match_dup 0)
17337 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17341 = gen_int_mode (INTVAL (operands[3])
17342 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17343 operands[2] = gen_lowpart (SImode, operands[2]);
17347 [(set (match_operand 0 "register_operand")
17348 (neg (match_operand 1 "register_operand")))
17349 (clobber (reg:CC FLAGS_REG))]
17350 "! TARGET_PARTIAL_REG_STALL && reload_completed
17351 && (GET_MODE (operands[0]) == HImode
17352 || (GET_MODE (operands[0]) == QImode
17353 && (TARGET_PROMOTE_QImode
17354 || optimize_insn_for_size_p ())))"
17355 [(parallel [(set (match_dup 0)
17356 (neg:SI (match_dup 1)))
17357 (clobber (reg:CC FLAGS_REG))])]
17359 operands[0] = gen_lowpart (SImode, operands[0]);
17360 operands[1] = gen_lowpart (SImode, operands[1]);
17363 ;; Do not split instructions with mask regs.
17365 [(set (match_operand 0 "general_reg_operand")
17366 (not (match_operand 1 "general_reg_operand")))]
17367 "! TARGET_PARTIAL_REG_STALL && reload_completed
17368 && (GET_MODE (operands[0]) == HImode
17369 || (GET_MODE (operands[0]) == QImode
17370 && (TARGET_PROMOTE_QImode
17371 || optimize_insn_for_size_p ())))"
17372 [(set (match_dup 0)
17373 (not:SI (match_dup 1)))]
17375 operands[0] = gen_lowpart (SImode, operands[0]);
17376 operands[1] = gen_lowpart (SImode, operands[1]);
17379 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17380 ;; transform a complex memory operation into two memory to register operations.
17382 ;; Don't push memory operands
17384 [(set (match_operand:SWI 0 "push_operand")
17385 (match_operand:SWI 1 "memory_operand"))
17386 (match_scratch:SWI 2 "<r>")]
17387 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17388 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17389 [(set (match_dup 2) (match_dup 1))
17390 (set (match_dup 0) (match_dup 2))])
17392 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17395 [(set (match_operand:SF 0 "push_operand")
17396 (match_operand:SF 1 "memory_operand"))
17397 (match_scratch:SF 2 "r")]
17398 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17399 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17400 [(set (match_dup 2) (match_dup 1))
17401 (set (match_dup 0) (match_dup 2))])
17403 ;; Don't move an immediate directly to memory when the instruction
17404 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17406 [(match_scratch:SWI124 1 "<r>")
17407 (set (match_operand:SWI124 0 "memory_operand")
17409 "optimize_insn_for_speed_p ()
17410 && ((<MODE>mode == HImode
17411 && TARGET_LCP_STALL)
17412 || (!TARGET_USE_MOV0
17413 && TARGET_SPLIT_LONG_MOVES
17414 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17415 && peep2_regno_dead_p (0, FLAGS_REG)"
17416 [(parallel [(set (match_dup 2) (const_int 0))
17417 (clobber (reg:CC FLAGS_REG))])
17418 (set (match_dup 0) (match_dup 1))]
17419 "operands[2] = gen_lowpart (SImode, operands[1]);")
17422 [(match_scratch:SWI124 2 "<r>")
17423 (set (match_operand:SWI124 0 "memory_operand")
17424 (match_operand:SWI124 1 "immediate_operand"))]
17425 "optimize_insn_for_speed_p ()
17426 && ((<MODE>mode == HImode
17427 && TARGET_LCP_STALL)
17428 || (TARGET_SPLIT_LONG_MOVES
17429 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17430 [(set (match_dup 2) (match_dup 1))
17431 (set (match_dup 0) (match_dup 2))])
17433 ;; Don't compare memory with zero, load and use a test instead.
17435 [(set (match_operand 0 "flags_reg_operand")
17436 (match_operator 1 "compare_operator"
17437 [(match_operand:SI 2 "memory_operand")
17439 (match_scratch:SI 3 "r")]
17440 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17441 [(set (match_dup 3) (match_dup 2))
17442 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17444 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17445 ;; Don't split NOTs with a displacement operand, because resulting XOR
17446 ;; will not be pairable anyway.
17448 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17449 ;; represented using a modRM byte. The XOR replacement is long decoded,
17450 ;; so this split helps here as well.
17452 ;; Note: Can't do this as a regular split because we can't get proper
17453 ;; lifetime information then.
17456 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17457 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17458 "optimize_insn_for_speed_p ()
17459 && ((TARGET_NOT_UNPAIRABLE
17460 && (!MEM_P (operands[0])
17461 || !memory_displacement_operand (operands[0], <MODE>mode)))
17462 || (TARGET_NOT_VECTORMODE
17463 && long_memory_operand (operands[0], <MODE>mode)))
17464 && peep2_regno_dead_p (0, FLAGS_REG)"
17465 [(parallel [(set (match_dup 0)
17466 (xor:SWI124 (match_dup 1) (const_int -1)))
17467 (clobber (reg:CC FLAGS_REG))])])
17469 ;; Non pairable "test imm, reg" instructions can be translated to
17470 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17471 ;; byte opcode instead of two, have a short form for byte operands),
17472 ;; so do it for other CPUs as well. Given that the value was dead,
17473 ;; this should not create any new dependencies. Pass on the sub-word
17474 ;; versions if we're concerned about partial register stalls.
17477 [(set (match_operand 0 "flags_reg_operand")
17478 (match_operator 1 "compare_operator"
17479 [(and:SI (match_operand:SI 2 "register_operand")
17480 (match_operand:SI 3 "immediate_operand"))
17482 "ix86_match_ccmode (insn, CCNOmode)
17483 && (true_regnum (operands[2]) != AX_REG
17484 || satisfies_constraint_K (operands[3]))
17485 && peep2_reg_dead_p (1, operands[2])"
17487 [(set (match_dup 0)
17488 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17491 (and:SI (match_dup 2) (match_dup 3)))])])
17493 ;; We don't need to handle HImode case, because it will be promoted to SImode
17494 ;; on ! TARGET_PARTIAL_REG_STALL
17497 [(set (match_operand 0 "flags_reg_operand")
17498 (match_operator 1 "compare_operator"
17499 [(and:QI (match_operand:QI 2 "register_operand")
17500 (match_operand:QI 3 "immediate_operand"))
17502 "! TARGET_PARTIAL_REG_STALL
17503 && ix86_match_ccmode (insn, CCNOmode)
17504 && true_regnum (operands[2]) != AX_REG
17505 && peep2_reg_dead_p (1, operands[2])"
17507 [(set (match_dup 0)
17508 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17511 (and:QI (match_dup 2) (match_dup 3)))])])
17514 [(set (match_operand 0 "flags_reg_operand")
17515 (match_operator 1 "compare_operator"
17518 (match_operand 2 "ext_register_operand")
17521 (match_operand 3 "const_int_operand"))
17523 "! TARGET_PARTIAL_REG_STALL
17524 && ix86_match_ccmode (insn, CCNOmode)
17525 && true_regnum (operands[2]) != AX_REG
17526 && peep2_reg_dead_p (1, operands[2])"
17527 [(parallel [(set (match_dup 0)
17536 (set (zero_extract:SI (match_dup 2)
17544 (match_dup 3)))])])
17546 ;; Don't do logical operations with memory inputs.
17548 [(match_scratch:SI 2 "r")
17549 (parallel [(set (match_operand:SI 0 "register_operand")
17550 (match_operator:SI 3 "arith_or_logical_operator"
17552 (match_operand:SI 1 "memory_operand")]))
17553 (clobber (reg:CC FLAGS_REG))])]
17554 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17555 [(set (match_dup 2) (match_dup 1))
17556 (parallel [(set (match_dup 0)
17557 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17558 (clobber (reg:CC FLAGS_REG))])])
17561 [(match_scratch:SI 2 "r")
17562 (parallel [(set (match_operand:SI 0 "register_operand")
17563 (match_operator:SI 3 "arith_or_logical_operator"
17564 [(match_operand:SI 1 "memory_operand")
17566 (clobber (reg:CC FLAGS_REG))])]
17567 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17568 [(set (match_dup 2) (match_dup 1))
17569 (parallel [(set (match_dup 0)
17570 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17571 (clobber (reg:CC FLAGS_REG))])])
17573 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17574 ;; refers to the destination of the load!
17577 [(set (match_operand:SI 0 "register_operand")
17578 (match_operand:SI 1 "register_operand"))
17579 (parallel [(set (match_dup 0)
17580 (match_operator:SI 3 "commutative_operator"
17582 (match_operand:SI 2 "memory_operand")]))
17583 (clobber (reg:CC FLAGS_REG))])]
17584 "REGNO (operands[0]) != REGNO (operands[1])
17585 && GENERAL_REGNO_P (REGNO (operands[0]))
17586 && GENERAL_REGNO_P (REGNO (operands[1]))"
17587 [(set (match_dup 0) (match_dup 4))
17588 (parallel [(set (match_dup 0)
17589 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17590 (clobber (reg:CC FLAGS_REG))])]
17591 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17594 [(set (match_operand 0 "register_operand")
17595 (match_operand 1 "register_operand"))
17597 (match_operator 3 "commutative_operator"
17599 (match_operand 2 "memory_operand")]))]
17600 "REGNO (operands[0]) != REGNO (operands[1])
17601 && ((MMX_REGNO_P (REGNO (operands[0]))
17602 && MMX_REGNO_P (REGNO (operands[1])))
17603 || (SSE_REGNO_P (REGNO (operands[0]))
17604 && SSE_REGNO_P (REGNO (operands[1]))))"
17605 [(set (match_dup 0) (match_dup 2))
17607 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17609 ; Don't do logical operations with memory outputs
17611 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17612 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17613 ; the same decoder scheduling characteristics as the original.
17616 [(match_scratch:SI 2 "r")
17617 (parallel [(set (match_operand:SI 0 "memory_operand")
17618 (match_operator:SI 3 "arith_or_logical_operator"
17620 (match_operand:SI 1 "nonmemory_operand")]))
17621 (clobber (reg:CC FLAGS_REG))])]
17622 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17623 /* Do not split stack checking probes. */
17624 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17625 [(set (match_dup 2) (match_dup 0))
17626 (parallel [(set (match_dup 2)
17627 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17628 (clobber (reg:CC FLAGS_REG))])
17629 (set (match_dup 0) (match_dup 2))])
17632 [(match_scratch:SI 2 "r")
17633 (parallel [(set (match_operand:SI 0 "memory_operand")
17634 (match_operator:SI 3 "arith_or_logical_operator"
17635 [(match_operand:SI 1 "nonmemory_operand")
17637 (clobber (reg:CC FLAGS_REG))])]
17638 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17639 /* Do not split stack checking probes. */
17640 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17641 [(set (match_dup 2) (match_dup 0))
17642 (parallel [(set (match_dup 2)
17643 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17644 (clobber (reg:CC FLAGS_REG))])
17645 (set (match_dup 0) (match_dup 2))])
17647 ;; Attempt to use arith or logical operations with memory outputs with
17648 ;; setting of flags.
17650 [(set (match_operand:SWI 0 "register_operand")
17651 (match_operand:SWI 1 "memory_operand"))
17652 (parallel [(set (match_dup 0)
17653 (match_operator:SWI 3 "plusminuslogic_operator"
17655 (match_operand:SWI 2 "<nonmemory_operand>")]))
17656 (clobber (reg:CC FLAGS_REG))])
17657 (set (match_dup 1) (match_dup 0))
17658 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17659 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17660 && peep2_reg_dead_p (4, operands[0])
17661 && !reg_overlap_mentioned_p (operands[0], operands[1])
17662 && !reg_overlap_mentioned_p (operands[0], operands[2])
17663 && (<MODE>mode != QImode
17664 || immediate_operand (operands[2], QImode)
17665 || q_regs_operand (operands[2], QImode))
17666 && ix86_match_ccmode (peep2_next_insn (3),
17667 (GET_CODE (operands[3]) == PLUS
17668 || GET_CODE (operands[3]) == MINUS)
17669 ? CCGOCmode : CCNOmode)"
17670 [(parallel [(set (match_dup 4) (match_dup 5))
17671 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17672 (match_dup 2)]))])]
17674 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17675 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17676 copy_rtx (operands[1]),
17677 copy_rtx (operands[2]));
17678 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17679 operands[5], const0_rtx);
17683 [(parallel [(set (match_operand:SWI 0 "register_operand")
17684 (match_operator:SWI 2 "plusminuslogic_operator"
17686 (match_operand:SWI 1 "memory_operand")]))
17687 (clobber (reg:CC FLAGS_REG))])
17688 (set (match_dup 1) (match_dup 0))
17689 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17690 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17691 && GET_CODE (operands[2]) != MINUS
17692 && peep2_reg_dead_p (3, operands[0])
17693 && !reg_overlap_mentioned_p (operands[0], operands[1])
17694 && ix86_match_ccmode (peep2_next_insn (2),
17695 GET_CODE (operands[2]) == PLUS
17696 ? CCGOCmode : CCNOmode)"
17697 [(parallel [(set (match_dup 3) (match_dup 4))
17698 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17699 (match_dup 0)]))])]
17701 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17702 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17703 copy_rtx (operands[1]),
17704 copy_rtx (operands[0]));
17705 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17706 operands[4], const0_rtx);
17710 [(set (match_operand:SWI12 0 "register_operand")
17711 (match_operand:SWI12 1 "memory_operand"))
17712 (parallel [(set (match_operand:SI 4 "register_operand")
17713 (match_operator:SI 3 "plusminuslogic_operator"
17715 (match_operand:SI 2 "nonmemory_operand")]))
17716 (clobber (reg:CC FLAGS_REG))])
17717 (set (match_dup 1) (match_dup 0))
17718 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17719 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17720 && REG_P (operands[0]) && REG_P (operands[4])
17721 && REGNO (operands[0]) == REGNO (operands[4])
17722 && peep2_reg_dead_p (4, operands[0])
17723 && (<MODE>mode != QImode
17724 || immediate_operand (operands[2], SImode)
17725 || q_regs_operand (operands[2], SImode))
17726 && !reg_overlap_mentioned_p (operands[0], operands[1])
17727 && !reg_overlap_mentioned_p (operands[0], operands[2])
17728 && ix86_match_ccmode (peep2_next_insn (3),
17729 (GET_CODE (operands[3]) == PLUS
17730 || GET_CODE (operands[3]) == MINUS)
17731 ? CCGOCmode : CCNOmode)"
17732 [(parallel [(set (match_dup 4) (match_dup 5))
17733 (set (match_dup 1) (match_dup 6))])]
17735 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17736 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17737 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17738 copy_rtx (operands[1]), operands[2]);
17739 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17740 operands[5], const0_rtx);
17741 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17742 copy_rtx (operands[1]),
17743 copy_rtx (operands[2]));
17746 ;; Attempt to always use XOR for zeroing registers.
17748 [(set (match_operand 0 "register_operand")
17749 (match_operand 1 "const0_operand"))]
17750 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17751 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17752 && GENERAL_REGNO_P (REGNO (operands[0]))
17753 && peep2_regno_dead_p (0, FLAGS_REG)"
17754 [(parallel [(set (match_dup 0) (const_int 0))
17755 (clobber (reg:CC FLAGS_REG))])]
17756 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17759 [(set (strict_low_part (match_operand 0 "register_operand"))
17761 "(GET_MODE (operands[0]) == QImode
17762 || GET_MODE (operands[0]) == HImode)
17763 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17764 && peep2_regno_dead_p (0, FLAGS_REG)"
17765 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17766 (clobber (reg:CC FLAGS_REG))])])
17768 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17770 [(set (match_operand:SWI248 0 "register_operand")
17772 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17773 && GENERAL_REGNO_P (REGNO (operands[0]))
17774 && peep2_regno_dead_p (0, FLAGS_REG)"
17775 [(parallel [(set (match_dup 0) (const_int -1))
17776 (clobber (reg:CC FLAGS_REG))])]
17778 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17779 operands[0] = gen_lowpart (SImode, operands[0]);
17782 ;; Attempt to convert simple lea to add/shift.
17783 ;; These can be created by move expanders.
17784 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17785 ;; relevant lea instructions were already split.
17788 [(set (match_operand:SWI48 0 "register_operand")
17789 (plus:SWI48 (match_dup 0)
17790 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17792 && peep2_regno_dead_p (0, FLAGS_REG)"
17793 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17794 (clobber (reg:CC FLAGS_REG))])])
17797 [(set (match_operand:SWI48 0 "register_operand")
17798 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17801 && peep2_regno_dead_p (0, FLAGS_REG)"
17802 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17803 (clobber (reg:CC FLAGS_REG))])])
17806 [(set (match_operand:DI 0 "register_operand")
17808 (plus:SI (match_operand:SI 1 "register_operand")
17809 (match_operand:SI 2 "nonmemory_operand"))))]
17810 "TARGET_64BIT && !TARGET_OPT_AGU
17811 && REGNO (operands[0]) == REGNO (operands[1])
17812 && peep2_regno_dead_p (0, FLAGS_REG)"
17813 [(parallel [(set (match_dup 0)
17814 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17815 (clobber (reg:CC FLAGS_REG))])])
17818 [(set (match_operand:DI 0 "register_operand")
17820 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17821 (match_operand:SI 2 "register_operand"))))]
17822 "TARGET_64BIT && !TARGET_OPT_AGU
17823 && REGNO (operands[0]) == REGNO (operands[2])
17824 && peep2_regno_dead_p (0, FLAGS_REG)"
17825 [(parallel [(set (match_dup 0)
17826 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17827 (clobber (reg:CC FLAGS_REG))])])
17830 [(set (match_operand:SWI48 0 "register_operand")
17831 (mult:SWI48 (match_dup 0)
17832 (match_operand:SWI48 1 "const_int_operand")))]
17833 "exact_log2 (INTVAL (operands[1])) >= 0
17834 && peep2_regno_dead_p (0, FLAGS_REG)"
17835 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17836 (clobber (reg:CC FLAGS_REG))])]
17837 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17840 [(set (match_operand:DI 0 "register_operand")
17842 (mult:SI (match_operand:SI 1 "register_operand")
17843 (match_operand:SI 2 "const_int_operand"))))]
17845 && exact_log2 (INTVAL (operands[2])) >= 0
17846 && REGNO (operands[0]) == REGNO (operands[1])
17847 && peep2_regno_dead_p (0, FLAGS_REG)"
17848 [(parallel [(set (match_dup 0)
17849 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17850 (clobber (reg:CC FLAGS_REG))])]
17851 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17853 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17854 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17855 ;; On many CPUs it is also faster, since special hardware to avoid esp
17856 ;; dependencies is present.
17858 ;; While some of these conversions may be done using splitters, we use
17859 ;; peepholes in order to allow combine_stack_adjustments pass to see
17860 ;; nonobfuscated RTL.
17862 ;; Convert prologue esp subtractions to push.
17863 ;; We need register to push. In order to keep verify_flow_info happy we have
17865 ;; - use scratch and clobber it in order to avoid dependencies
17866 ;; - use already live register
17867 ;; We can't use the second way right now, since there is no reliable way how to
17868 ;; verify that given register is live. First choice will also most likely in
17869 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17870 ;; call clobbered registers are dead. We may want to use base pointer as an
17871 ;; alternative when no register is available later.
17874 [(match_scratch:W 1 "r")
17875 (parallel [(set (reg:P SP_REG)
17876 (plus:P (reg:P SP_REG)
17877 (match_operand:P 0 "const_int_operand")))
17878 (clobber (reg:CC FLAGS_REG))
17879 (clobber (mem:BLK (scratch)))])]
17880 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17881 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17882 [(clobber (match_dup 1))
17883 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17884 (clobber (mem:BLK (scratch)))])])
17887 [(match_scratch:W 1 "r")
17888 (parallel [(set (reg:P SP_REG)
17889 (plus:P (reg:P SP_REG)
17890 (match_operand:P 0 "const_int_operand")))
17891 (clobber (reg:CC FLAGS_REG))
17892 (clobber (mem:BLK (scratch)))])]
17893 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17894 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17895 [(clobber (match_dup 1))
17896 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17897 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17898 (clobber (mem:BLK (scratch)))])])
17900 ;; Convert esp subtractions to push.
17902 [(match_scratch:W 1 "r")
17903 (parallel [(set (reg:P SP_REG)
17904 (plus:P (reg:P SP_REG)
17905 (match_operand:P 0 "const_int_operand")))
17906 (clobber (reg:CC FLAGS_REG))])]
17907 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17908 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17909 [(clobber (match_dup 1))
17910 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17913 [(match_scratch:W 1 "r")
17914 (parallel [(set (reg:P SP_REG)
17915 (plus:P (reg:P SP_REG)
17916 (match_operand:P 0 "const_int_operand")))
17917 (clobber (reg:CC FLAGS_REG))])]
17918 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17919 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17920 [(clobber (match_dup 1))
17921 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17922 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17924 ;; Convert epilogue deallocator to pop.
17926 [(match_scratch:W 1 "r")
17927 (parallel [(set (reg:P SP_REG)
17928 (plus:P (reg:P SP_REG)
17929 (match_operand:P 0 "const_int_operand")))
17930 (clobber (reg:CC FLAGS_REG))
17931 (clobber (mem:BLK (scratch)))])]
17932 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17933 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17934 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17935 (clobber (mem:BLK (scratch)))])])
17937 ;; Two pops case is tricky, since pop causes dependency
17938 ;; on destination register. We use two registers if available.
17940 [(match_scratch:W 1 "r")
17941 (match_scratch:W 2 "r")
17942 (parallel [(set (reg:P SP_REG)
17943 (plus:P (reg:P SP_REG)
17944 (match_operand:P 0 "const_int_operand")))
17945 (clobber (reg:CC FLAGS_REG))
17946 (clobber (mem:BLK (scratch)))])]
17947 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17948 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17949 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17950 (clobber (mem:BLK (scratch)))])
17951 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17954 [(match_scratch:W 1 "r")
17955 (parallel [(set (reg:P SP_REG)
17956 (plus:P (reg:P SP_REG)
17957 (match_operand:P 0 "const_int_operand")))
17958 (clobber (reg:CC FLAGS_REG))
17959 (clobber (mem:BLK (scratch)))])]
17960 "optimize_insn_for_size_p ()
17961 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17962 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17963 (clobber (mem:BLK (scratch)))])
17964 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17966 ;; Convert esp additions to pop.
17968 [(match_scratch:W 1 "r")
17969 (parallel [(set (reg:P SP_REG)
17970 (plus:P (reg:P SP_REG)
17971 (match_operand:P 0 "const_int_operand")))
17972 (clobber (reg:CC FLAGS_REG))])]
17973 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17974 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17976 ;; Two pops case is tricky, since pop causes dependency
17977 ;; on destination register. We use two registers if available.
17979 [(match_scratch:W 1 "r")
17980 (match_scratch:W 2 "r")
17981 (parallel [(set (reg:P SP_REG)
17982 (plus:P (reg:P SP_REG)
17983 (match_operand:P 0 "const_int_operand")))
17984 (clobber (reg:CC FLAGS_REG))])]
17985 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17986 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17987 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17990 [(match_scratch:W 1 "r")
17991 (parallel [(set (reg:P SP_REG)
17992 (plus:P (reg:P SP_REG)
17993 (match_operand:P 0 "const_int_operand")))
17994 (clobber (reg:CC FLAGS_REG))])]
17995 "optimize_insn_for_size_p ()
17996 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17997 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17998 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18000 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18001 ;; required and register dies. Similarly for 128 to -128.
18003 [(set (match_operand 0 "flags_reg_operand")
18004 (match_operator 1 "compare_operator"
18005 [(match_operand 2 "register_operand")
18006 (match_operand 3 "const_int_operand")]))]
18007 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18008 && incdec_operand (operands[3], GET_MODE (operands[3])))
18009 || (!TARGET_FUSE_CMP_AND_BRANCH
18010 && INTVAL (operands[3]) == 128))
18011 && ix86_match_ccmode (insn, CCGCmode)
18012 && peep2_reg_dead_p (1, operands[2])"
18013 [(parallel [(set (match_dup 0)
18014 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18015 (clobber (match_dup 2))])])
18017 ;; Convert imul by three, five and nine into lea
18020 [(set (match_operand:SWI48 0 "register_operand")
18021 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18022 (match_operand:SWI48 2 "const359_operand")))
18023 (clobber (reg:CC FLAGS_REG))])]
18024 "!TARGET_PARTIAL_REG_STALL
18025 || <MODE>mode == SImode
18026 || optimize_function_for_size_p (cfun)"
18027 [(set (match_dup 0)
18028 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18030 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18034 [(set (match_operand:SWI48 0 "register_operand")
18035 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18036 (match_operand:SWI48 2 "const359_operand")))
18037 (clobber (reg:CC FLAGS_REG))])]
18038 "optimize_insn_for_speed_p ()
18039 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18040 [(set (match_dup 0) (match_dup 1))
18042 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18044 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18046 ;; imul $32bit_imm, mem, reg is vector decoded, while
18047 ;; imul $32bit_imm, reg, reg is direct decoded.
18049 [(match_scratch:SWI48 3 "r")
18050 (parallel [(set (match_operand:SWI48 0 "register_operand")
18051 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18052 (match_operand:SWI48 2 "immediate_operand")))
18053 (clobber (reg:CC FLAGS_REG))])]
18054 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18055 && !satisfies_constraint_K (operands[2])"
18056 [(set (match_dup 3) (match_dup 1))
18057 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18058 (clobber (reg:CC FLAGS_REG))])])
18061 [(match_scratch:SI 3 "r")
18062 (parallel [(set (match_operand:DI 0 "register_operand")
18064 (mult:SI (match_operand:SI 1 "memory_operand")
18065 (match_operand:SI 2 "immediate_operand"))))
18066 (clobber (reg:CC FLAGS_REG))])]
18068 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18069 && !satisfies_constraint_K (operands[2])"
18070 [(set (match_dup 3) (match_dup 1))
18071 (parallel [(set (match_dup 0)
18072 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18073 (clobber (reg:CC FLAGS_REG))])])
18075 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18076 ;; Convert it into imul reg, reg
18077 ;; It would be better to force assembler to encode instruction using long
18078 ;; immediate, but there is apparently no way to do so.
18080 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18082 (match_operand:SWI248 1 "nonimmediate_operand")
18083 (match_operand:SWI248 2 "const_int_operand")))
18084 (clobber (reg:CC FLAGS_REG))])
18085 (match_scratch:SWI248 3 "r")]
18086 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18087 && satisfies_constraint_K (operands[2])"
18088 [(set (match_dup 3) (match_dup 2))
18089 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18090 (clobber (reg:CC FLAGS_REG))])]
18092 if (!rtx_equal_p (operands[0], operands[1]))
18093 emit_move_insn (operands[0], operands[1]);
18096 ;; After splitting up read-modify operations, array accesses with memory
18097 ;; operands might end up in form:
18099 ;; movl 4(%esp), %edx
18101 ;; instead of pre-splitting:
18103 ;; addl 4(%esp), %eax
18105 ;; movl 4(%esp), %edx
18106 ;; leal (%edx,%eax,4), %eax
18109 [(match_scratch:W 5 "r")
18110 (parallel [(set (match_operand 0 "register_operand")
18111 (ashift (match_operand 1 "register_operand")
18112 (match_operand 2 "const_int_operand")))
18113 (clobber (reg:CC FLAGS_REG))])
18114 (parallel [(set (match_operand 3 "register_operand")
18115 (plus (match_dup 0)
18116 (match_operand 4 "x86_64_general_operand")))
18117 (clobber (reg:CC FLAGS_REG))])]
18118 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18119 /* Validate MODE for lea. */
18120 && ((!TARGET_PARTIAL_REG_STALL
18121 && (GET_MODE (operands[0]) == QImode
18122 || GET_MODE (operands[0]) == HImode))
18123 || GET_MODE (operands[0]) == SImode
18124 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18125 && (rtx_equal_p (operands[0], operands[3])
18126 || peep2_reg_dead_p (2, operands[0]))
18127 /* We reorder load and the shift. */
18128 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18129 [(set (match_dup 5) (match_dup 4))
18130 (set (match_dup 0) (match_dup 1))]
18132 machine_mode op1mode = GET_MODE (operands[1]);
18133 machine_mode mode = op1mode == DImode ? DImode : SImode;
18134 int scale = 1 << INTVAL (operands[2]);
18135 rtx index = gen_lowpart (word_mode, operands[1]);
18136 rtx base = gen_lowpart (word_mode, operands[5]);
18137 rtx dest = gen_lowpart (mode, operands[3]);
18139 operands[1] = gen_rtx_PLUS (word_mode, base,
18140 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18141 if (mode != word_mode)
18142 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18144 operands[5] = base;
18145 if (op1mode != word_mode)
18146 operands[5] = gen_lowpart (op1mode, operands[5]);
18148 operands[0] = dest;
18151 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18152 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18153 ;; caught for use by garbage collectors and the like. Using an insn that
18154 ;; maps to SIGILL makes it more likely the program will rightfully die.
18155 ;; Keeping with tradition, "6" is in honor of #UD.
18156 (define_insn "trap"
18157 [(trap_if (const_int 1) (const_int 6))]
18160 #ifdef HAVE_AS_IX86_UD2
18163 return ASM_SHORT "0x0b0f";
18166 [(set_attr "length" "2")])
18168 (define_expand "prefetch"
18169 [(prefetch (match_operand 0 "address_operand")
18170 (match_operand:SI 1 "const_int_operand")
18171 (match_operand:SI 2 "const_int_operand"))]
18172 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18174 bool write = INTVAL (operands[1]) != 0;
18175 int locality = INTVAL (operands[2]);
18177 gcc_assert (IN_RANGE (locality, 0, 3));
18179 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18180 supported by SSE counterpart or the SSE prefetch is not available
18181 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18183 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18184 operands[2] = const2_rtx;
18185 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18186 operands[2] = GEN_INT (3);
18188 operands[1] = const0_rtx;
18191 (define_insn "*prefetch_sse"
18192 [(prefetch (match_operand 0 "address_operand" "p")
18194 (match_operand:SI 1 "const_int_operand"))]
18195 "TARGET_PREFETCH_SSE"
18197 static const char * const patterns[4] = {
18198 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18201 int locality = INTVAL (operands[1]);
18202 gcc_assert (IN_RANGE (locality, 0, 3));
18204 return patterns[locality];
18206 [(set_attr "type" "sse")
18207 (set_attr "atom_sse_attr" "prefetch")
18208 (set (attr "length_address")
18209 (symbol_ref "memory_address_length (operands[0], false)"))
18210 (set_attr "memory" "none")])
18212 (define_insn "*prefetch_3dnow"
18213 [(prefetch (match_operand 0 "address_operand" "p")
18214 (match_operand:SI 1 "const_int_operand" "n")
18218 if (INTVAL (operands[1]) == 0)
18219 return "prefetch\t%a0";
18221 return "prefetchw\t%a0";
18223 [(set_attr "type" "mmx")
18224 (set (attr "length_address")
18225 (symbol_ref "memory_address_length (operands[0], false)"))
18226 (set_attr "memory" "none")])
18228 (define_insn "*prefetch_prefetchwt1"
18229 [(prefetch (match_operand 0 "address_operand" "p")
18232 "TARGET_PREFETCHWT1"
18233 "prefetchwt1\t%a0";
18234 [(set_attr "type" "sse")
18235 (set (attr "length_address")
18236 (symbol_ref "memory_address_length (operands[0], false)"))
18237 (set_attr "memory" "none")])
18239 (define_expand "stack_protect_set"
18240 [(match_operand 0 "memory_operand")
18241 (match_operand 1 "memory_operand")]
18242 "TARGET_SSP_TLS_GUARD"
18244 rtx (*insn)(rtx, rtx);
18246 #ifdef TARGET_THREAD_SSP_OFFSET
18247 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18248 insn = (TARGET_LP64
18249 ? gen_stack_tls_protect_set_di
18250 : gen_stack_tls_protect_set_si);
18252 insn = (TARGET_LP64
18253 ? gen_stack_protect_set_di
18254 : gen_stack_protect_set_si);
18257 emit_insn (insn (operands[0], operands[1]));
18261 (define_insn "stack_protect_set_<mode>"
18262 [(set (match_operand:PTR 0 "memory_operand" "=m")
18263 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18265 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18266 (clobber (reg:CC FLAGS_REG))]
18267 "TARGET_SSP_TLS_GUARD"
18268 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18269 [(set_attr "type" "multi")])
18271 (define_insn "stack_tls_protect_set_<mode>"
18272 [(set (match_operand:PTR 0 "memory_operand" "=m")
18273 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18274 UNSPEC_SP_TLS_SET))
18275 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18276 (clobber (reg:CC FLAGS_REG))]
18278 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18279 [(set_attr "type" "multi")])
18281 (define_expand "stack_protect_test"
18282 [(match_operand 0 "memory_operand")
18283 (match_operand 1 "memory_operand")
18285 "TARGET_SSP_TLS_GUARD"
18287 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18289 rtx (*insn)(rtx, rtx, rtx);
18291 #ifdef TARGET_THREAD_SSP_OFFSET
18292 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18293 insn = (TARGET_LP64
18294 ? gen_stack_tls_protect_test_di
18295 : gen_stack_tls_protect_test_si);
18297 insn = (TARGET_LP64
18298 ? gen_stack_protect_test_di
18299 : gen_stack_protect_test_si);
18302 emit_insn (insn (flags, operands[0], operands[1]));
18304 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18305 flags, const0_rtx, operands[2]));
18309 (define_insn "stack_protect_test_<mode>"
18310 [(set (match_operand:CCZ 0 "flags_reg_operand")
18311 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18312 (match_operand:PTR 2 "memory_operand" "m")]
18314 (clobber (match_scratch:PTR 3 "=&r"))]
18315 "TARGET_SSP_TLS_GUARD"
18316 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18317 [(set_attr "type" "multi")])
18319 (define_insn "stack_tls_protect_test_<mode>"
18320 [(set (match_operand:CCZ 0 "flags_reg_operand")
18321 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18322 (match_operand:PTR 2 "const_int_operand" "i")]
18323 UNSPEC_SP_TLS_TEST))
18324 (clobber (match_scratch:PTR 3 "=r"))]
18326 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18327 [(set_attr "type" "multi")])
18329 (define_insn "sse4_2_crc32<mode>"
18330 [(set (match_operand:SI 0 "register_operand" "=r")
18332 [(match_operand:SI 1 "register_operand" "0")
18333 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18335 "TARGET_SSE4_2 || TARGET_CRC32"
18336 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18337 [(set_attr "type" "sselog1")
18338 (set_attr "prefix_rep" "1")
18339 (set_attr "prefix_extra" "1")
18340 (set (attr "prefix_data16")
18341 (if_then_else (match_operand:HI 2)
18343 (const_string "*")))
18344 (set (attr "prefix_rex")
18345 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18347 (const_string "*")))
18348 (set_attr "mode" "SI")])
18350 (define_insn "sse4_2_crc32di"
18351 [(set (match_operand:DI 0 "register_operand" "=r")
18353 [(match_operand:DI 1 "register_operand" "0")
18354 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18356 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18357 "crc32{q}\t{%2, %0|%0, %2}"
18358 [(set_attr "type" "sselog1")
18359 (set_attr "prefix_rep" "1")
18360 (set_attr "prefix_extra" "1")
18361 (set_attr "mode" "DI")])
18363 (define_insn "rdpmc"
18364 [(set (match_operand:DI 0 "register_operand" "=A")
18365 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18369 [(set_attr "type" "other")
18370 (set_attr "length" "2")])
18372 (define_insn "rdpmc_rex64"
18373 [(set (match_operand:DI 0 "register_operand" "=a")
18374 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18376 (set (match_operand:DI 1 "register_operand" "=d")
18377 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18380 [(set_attr "type" "other")
18381 (set_attr "length" "2")])
18383 (define_insn "rdtsc"
18384 [(set (match_operand:DI 0 "register_operand" "=A")
18385 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18388 [(set_attr "type" "other")
18389 (set_attr "length" "2")])
18391 (define_insn "rdtsc_rex64"
18392 [(set (match_operand:DI 0 "register_operand" "=a")
18393 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18394 (set (match_operand:DI 1 "register_operand" "=d")
18395 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18398 [(set_attr "type" "other")
18399 (set_attr "length" "2")])
18401 (define_insn "rdtscp"
18402 [(set (match_operand:DI 0 "register_operand" "=A")
18403 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18404 (set (match_operand:SI 1 "register_operand" "=c")
18405 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18408 [(set_attr "type" "other")
18409 (set_attr "length" "3")])
18411 (define_insn "rdtscp_rex64"
18412 [(set (match_operand:DI 0 "register_operand" "=a")
18413 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18414 (set (match_operand:DI 1 "register_operand" "=d")
18415 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18416 (set (match_operand:SI 2 "register_operand" "=c")
18417 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18420 [(set_attr "type" "other")
18421 (set_attr "length" "3")])
18423 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18425 ;; FXSR, XSAVE and XSAVEOPT instructions
18427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18429 (define_insn "fxsave"
18430 [(set (match_operand:BLK 0 "memory_operand" "=m")
18431 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18434 [(set_attr "type" "other")
18435 (set_attr "memory" "store")
18436 (set (attr "length")
18437 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18439 (define_insn "fxsave64"
18440 [(set (match_operand:BLK 0 "memory_operand" "=m")
18441 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18442 "TARGET_64BIT && TARGET_FXSR"
18444 [(set_attr "type" "other")
18445 (set_attr "memory" "store")
18446 (set (attr "length")
18447 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18449 (define_insn "fxrstor"
18450 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18454 [(set_attr "type" "other")
18455 (set_attr "memory" "load")
18456 (set (attr "length")
18457 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18459 (define_insn "fxrstor64"
18460 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18461 UNSPECV_FXRSTOR64)]
18462 "TARGET_64BIT && TARGET_FXSR"
18464 [(set_attr "type" "other")
18465 (set_attr "memory" "load")
18466 (set (attr "length")
18467 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18469 (define_int_iterator ANY_XSAVE
18471 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18472 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18473 (UNSPECV_XSAVES "TARGET_XSAVES")])
18475 (define_int_iterator ANY_XSAVE64
18477 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18478 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18479 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18481 (define_int_attr xsave
18482 [(UNSPECV_XSAVE "xsave")
18483 (UNSPECV_XSAVE64 "xsave64")
18484 (UNSPECV_XSAVEOPT "xsaveopt")
18485 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18486 (UNSPECV_XSAVEC "xsavec")
18487 (UNSPECV_XSAVEC64 "xsavec64")
18488 (UNSPECV_XSAVES "xsaves")
18489 (UNSPECV_XSAVES64 "xsaves64")])
18491 (define_int_iterator ANY_XRSTOR
18493 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18495 (define_int_iterator ANY_XRSTOR64
18497 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18499 (define_int_attr xrstor
18500 [(UNSPECV_XRSTOR "xrstor")
18501 (UNSPECV_XRSTOR64 "xrstor")
18502 (UNSPECV_XRSTORS "xrstors")
18503 (UNSPECV_XRSTORS64 "xrstors")])
18505 (define_insn "<xsave>"
18506 [(set (match_operand:BLK 0 "memory_operand" "=m")
18507 (unspec_volatile:BLK
18508 [(match_operand:DI 1 "register_operand" "A")]
18510 "!TARGET_64BIT && TARGET_XSAVE"
18512 [(set_attr "type" "other")
18513 (set_attr "memory" "store")
18514 (set (attr "length")
18515 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18517 (define_insn "<xsave>_rex64"
18518 [(set (match_operand:BLK 0 "memory_operand" "=m")
18519 (unspec_volatile:BLK
18520 [(match_operand:SI 1 "register_operand" "a")
18521 (match_operand:SI 2 "register_operand" "d")]
18523 "TARGET_64BIT && TARGET_XSAVE"
18525 [(set_attr "type" "other")
18526 (set_attr "memory" "store")
18527 (set (attr "length")
18528 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18530 (define_insn "<xsave>"
18531 [(set (match_operand:BLK 0 "memory_operand" "=m")
18532 (unspec_volatile:BLK
18533 [(match_operand:SI 1 "register_operand" "a")
18534 (match_operand:SI 2 "register_operand" "d")]
18536 "TARGET_64BIT && TARGET_XSAVE"
18538 [(set_attr "type" "other")
18539 (set_attr "memory" "store")
18540 (set (attr "length")
18541 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18543 (define_insn "<xrstor>"
18544 [(unspec_volatile:BLK
18545 [(match_operand:BLK 0 "memory_operand" "m")
18546 (match_operand:DI 1 "register_operand" "A")]
18548 "!TARGET_64BIT && TARGET_XSAVE"
18550 [(set_attr "type" "other")
18551 (set_attr "memory" "load")
18552 (set (attr "length")
18553 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18555 (define_insn "<xrstor>_rex64"
18556 [(unspec_volatile:BLK
18557 [(match_operand:BLK 0 "memory_operand" "m")
18558 (match_operand:SI 1 "register_operand" "a")
18559 (match_operand:SI 2 "register_operand" "d")]
18561 "TARGET_64BIT && TARGET_XSAVE"
18563 [(set_attr "type" "other")
18564 (set_attr "memory" "load")
18565 (set (attr "length")
18566 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18568 (define_insn "<xrstor>64"
18569 [(unspec_volatile:BLK
18570 [(match_operand:BLK 0 "memory_operand" "m")
18571 (match_operand:SI 1 "register_operand" "a")
18572 (match_operand:SI 2 "register_operand" "d")]
18574 "TARGET_64BIT && TARGET_XSAVE"
18576 [(set_attr "type" "other")
18577 (set_attr "memory" "load")
18578 (set (attr "length")
18579 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18581 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18583 ;; Floating-point instructions for atomic compound assignments
18585 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18587 ; Clobber all floating-point registers on environment save and restore
18588 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18589 (define_insn "fnstenv"
18590 [(set (match_operand:BLK 0 "memory_operand" "=m")
18591 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18592 (clobber (reg:HI FPCR_REG))
18593 (clobber (reg:XF ST0_REG))
18594 (clobber (reg:XF ST1_REG))
18595 (clobber (reg:XF ST2_REG))
18596 (clobber (reg:XF ST3_REG))
18597 (clobber (reg:XF ST4_REG))
18598 (clobber (reg:XF ST5_REG))
18599 (clobber (reg:XF ST6_REG))
18600 (clobber (reg:XF ST7_REG))]
18603 [(set_attr "type" "other")
18604 (set_attr "memory" "store")
18605 (set (attr "length")
18606 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18608 (define_insn "fldenv"
18609 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18611 (clobber (reg:CCFP FPSR_REG))
18612 (clobber (reg:HI FPCR_REG))
18613 (clobber (reg:XF ST0_REG))
18614 (clobber (reg:XF ST1_REG))
18615 (clobber (reg:XF ST2_REG))
18616 (clobber (reg:XF ST3_REG))
18617 (clobber (reg:XF ST4_REG))
18618 (clobber (reg:XF ST5_REG))
18619 (clobber (reg:XF ST6_REG))
18620 (clobber (reg:XF ST7_REG))]
18623 [(set_attr "type" "other")
18624 (set_attr "memory" "load")
18625 (set (attr "length")
18626 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18628 (define_insn "fnstsw"
18629 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18630 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18633 [(set_attr "type" "other,other")
18634 (set_attr "memory" "none,store")
18635 (set (attr "length")
18636 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18638 (define_insn "fnclex"
18639 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18642 [(set_attr "type" "other")
18643 (set_attr "memory" "none")
18644 (set_attr "length" "2")])
18646 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18648 ;; LWP instructions
18650 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18652 (define_expand "lwp_llwpcb"
18653 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18654 UNSPECV_LLWP_INTRINSIC)]
18657 (define_insn "*lwp_llwpcb<mode>1"
18658 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18659 UNSPECV_LLWP_INTRINSIC)]
18662 [(set_attr "type" "lwp")
18663 (set_attr "mode" "<MODE>")
18664 (set_attr "length" "5")])
18666 (define_expand "lwp_slwpcb"
18667 [(set (match_operand 0 "register_operand" "=r")
18668 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18673 insn = (Pmode == DImode
18675 : gen_lwp_slwpcbsi);
18677 emit_insn (insn (operands[0]));
18681 (define_insn "lwp_slwpcb<mode>"
18682 [(set (match_operand:P 0 "register_operand" "=r")
18683 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18686 [(set_attr "type" "lwp")
18687 (set_attr "mode" "<MODE>")
18688 (set_attr "length" "5")])
18690 (define_expand "lwp_lwpval<mode>3"
18691 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18692 (match_operand:SI 2 "nonimmediate_operand" "rm")
18693 (match_operand:SI 3 "const_int_operand" "i")]
18694 UNSPECV_LWPVAL_INTRINSIC)]
18696 ;; Avoid unused variable warning.
18697 "(void) operands[0];")
18699 (define_insn "*lwp_lwpval<mode>3_1"
18700 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18701 (match_operand:SI 1 "nonimmediate_operand" "rm")
18702 (match_operand:SI 2 "const_int_operand" "i")]
18703 UNSPECV_LWPVAL_INTRINSIC)]
18705 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18706 [(set_attr "type" "lwp")
18707 (set_attr "mode" "<MODE>")
18708 (set (attr "length")
18709 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18711 (define_expand "lwp_lwpins<mode>3"
18712 [(set (reg:CCC FLAGS_REG)
18713 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18714 (match_operand:SI 2 "nonimmediate_operand" "rm")
18715 (match_operand:SI 3 "const_int_operand" "i")]
18716 UNSPECV_LWPINS_INTRINSIC))
18717 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18718 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18721 (define_insn "*lwp_lwpins<mode>3_1"
18722 [(set (reg:CCC FLAGS_REG)
18723 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18724 (match_operand:SI 1 "nonimmediate_operand" "rm")
18725 (match_operand:SI 2 "const_int_operand" "i")]
18726 UNSPECV_LWPINS_INTRINSIC))]
18728 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18729 [(set_attr "type" "lwp")
18730 (set_attr "mode" "<MODE>")
18731 (set (attr "length")
18732 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18734 (define_int_iterator RDFSGSBASE
18738 (define_int_iterator WRFSGSBASE
18742 (define_int_attr fsgs
18743 [(UNSPECV_RDFSBASE "fs")
18744 (UNSPECV_RDGSBASE "gs")
18745 (UNSPECV_WRFSBASE "fs")
18746 (UNSPECV_WRGSBASE "gs")])
18748 (define_insn "rd<fsgs>base<mode>"
18749 [(set (match_operand:SWI48 0 "register_operand" "=r")
18750 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18751 "TARGET_64BIT && TARGET_FSGSBASE"
18753 [(set_attr "type" "other")
18754 (set_attr "prefix_extra" "2")])
18756 (define_insn "wr<fsgs>base<mode>"
18757 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18759 "TARGET_64BIT && TARGET_FSGSBASE"
18761 [(set_attr "type" "other")
18762 (set_attr "prefix_extra" "2")])
18764 (define_insn "rdrand<mode>_1"
18765 [(set (match_operand:SWI248 0 "register_operand" "=r")
18766 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18767 (set (reg:CCC FLAGS_REG)
18768 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18771 [(set_attr "type" "other")
18772 (set_attr "prefix_extra" "1")])
18774 (define_insn "rdseed<mode>_1"
18775 [(set (match_operand:SWI248 0 "register_operand" "=r")
18776 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18777 (set (reg:CCC FLAGS_REG)
18778 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18781 [(set_attr "type" "other")
18782 (set_attr "prefix_extra" "1")])
18784 (define_expand "pause"
18785 [(set (match_dup 0)
18786 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18789 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18790 MEM_VOLATILE_P (operands[0]) = 1;
18793 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18794 ;; They have the same encoding.
18795 (define_insn "*pause"
18796 [(set (match_operand:BLK 0)
18797 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18800 [(set_attr "length" "2")
18801 (set_attr "memory" "unknown")])
18803 (define_expand "xbegin"
18804 [(set (match_operand:SI 0 "register_operand")
18805 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18808 rtx_code_label *label = gen_label_rtx ();
18810 /* xbegin is emitted as jump_insn, so reload won't be able
18811 to reload its operand. Force the value into AX hard register. */
18812 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18813 emit_move_insn (ax_reg, constm1_rtx);
18815 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18817 emit_label (label);
18818 LABEL_NUSES (label) = 1;
18820 emit_move_insn (operands[0], ax_reg);
18825 (define_insn "xbegin_1"
18827 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18829 (label_ref (match_operand 1))
18831 (set (match_operand:SI 0 "register_operand" "+a")
18832 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18835 [(set_attr "type" "other")
18836 (set_attr "length" "6")])
18838 (define_insn "xend"
18839 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18842 [(set_attr "type" "other")
18843 (set_attr "length" "3")])
18845 (define_insn "xabort"
18846 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18850 [(set_attr "type" "other")
18851 (set_attr "length" "3")])
18853 (define_expand "xtest"
18854 [(set (match_operand:QI 0 "register_operand")
18855 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18858 emit_insn (gen_xtest_1 ());
18860 ix86_expand_setcc (operands[0], NE,
18861 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18865 (define_insn "xtest_1"
18866 [(set (reg:CCZ FLAGS_REG)
18867 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18870 [(set_attr "type" "other")
18871 (set_attr "length" "3")])
18873 (define_insn "pcommit"
18874 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18877 [(set_attr "type" "other")
18878 (set_attr "length" "4")])
18880 (define_insn "clwb"
18881 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18885 [(set_attr "type" "sse")
18886 (set_attr "atom_sse_attr" "fence")
18887 (set_attr "memory" "unknown")])
18889 (define_insn "clflushopt"
18890 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18891 UNSPECV_CLFLUSHOPT)]
18892 "TARGET_CLFLUSHOPT"
18894 [(set_attr "type" "sse")
18895 (set_attr "atom_sse_attr" "fence")
18896 (set_attr "memory" "unknown")])
18898 ;; MONITORX and MWAITX
18899 (define_insn "mwaitx"
18900 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18901 (match_operand:SI 1 "register_operand" "a")
18902 (match_operand:SI 2 "register_operand" "b")]
18905 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18906 ;; Since 32bit register operands are implicitly zero extended to 64bit,
18907 ;; we only need to set up 32bit registers.
18909 [(set_attr "length" "3")])
18911 (define_insn "monitorx_<mode>"
18912 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18913 (match_operand:SI 1 "register_operand" "c")
18914 (match_operand:SI 2 "register_operand" "d")]
18917 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18918 ;; RCX and RDX are used. Since 32bit register operands are implicitly
18919 ;; zero extended to 64bit, we only need to set up 32bit registers.
18921 [(set (attr "length")
18922 (symbol_ref ("(Pmode != word_mode) + 3")))])
18924 ;; MPX instructions
18926 (define_expand "<mode>_mk"
18927 [(set (match_operand:BND 0 "register_operand")
18931 [(match_operand:<bnd_ptr> 1 "register_operand")
18932 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18936 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18938 UNSPEC_BNDMK_ADDR);
18941 (define_insn "*<mode>_mk"
18942 [(set (match_operand:BND 0 "register_operand" "=w")
18944 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18946 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18947 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18948 UNSPEC_BNDMK_ADDR)])]
18951 "bndmk\t{%3, %0|%0, %3}"
18952 [(set_attr "type" "mpxmk")])
18954 (define_expand "mov<mode>"
18955 [(set (match_operand:BND 0 "general_operand")
18956 (match_operand:BND 1 "general_operand"))]
18959 ix86_expand_move (<MODE>mode, operands);DONE;
18962 (define_insn "*mov<mode>_internal_mpx"
18963 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18964 (match_operand:BND 1 "general_operand" "wm,w"))]
18966 "bndmov\t{%1, %0|%0, %1}"
18967 [(set_attr "type" "mpxmov")])
18969 (define_expand "<mode>_<bndcheck>"
18970 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18971 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18973 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18976 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18977 MEM_VOLATILE_P (operands[2]) = 1;
18980 (define_insn "*<mode>_<bndcheck>"
18981 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18982 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18983 (set (match_operand:BLK 2 "bnd_mem_operator")
18984 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18986 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18987 [(set_attr "type" "mpxchk")])
18989 (define_expand "<mode>_ldx"
18990 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18994 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18995 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18997 (use (mem:BLK (match_dup 1)))])]
19000 /* Avoid registers which connot be used as index. */
19001 if (!index_register_operand (operands[2], Pmode))
19003 rtx temp = gen_reg_rtx (Pmode);
19004 emit_move_insn (temp, operands[2]);
19005 operands[2] = temp;
19008 /* If it was a register originally then it may have
19009 mode other than Pmode. We need to extend in such
19010 case because bndldx may work only with Pmode regs. */
19011 if (GET_MODE (operands[2]) != Pmode)
19012 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
19014 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19016 UNSPEC_BNDLDX_ADDR);
19019 (define_insn "*<mode>_ldx"
19020 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
19022 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19024 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19025 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19026 UNSPEC_BNDLDX_ADDR)])]
19028 (use (mem:BLK (match_dup 1)))])]
19030 "bndldx\t{%3, %0|%0, %3}"
19031 [(set_attr "type" "mpxld")])
19033 (define_expand "<mode>_stx"
19034 [(parallel [(unspec [(mem:<bnd_ptr>
19036 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19037 (match_operand:<bnd_ptr> 1 "register_operand")]))
19038 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
19040 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19043 /* Avoid registers which connot be used as index. */
19044 if (!index_register_operand (operands[1], Pmode))
19046 rtx temp = gen_reg_rtx (Pmode);
19047 emit_move_insn (temp, operands[1]);
19048 operands[1] = temp;
19051 /* If it was a register originally then it may have
19052 mode other than Pmode. We need to extend in such
19053 case because bndstx may work only with Pmode regs. */
19054 if (GET_MODE (operands[1]) != Pmode)
19055 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
19057 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19059 UNSPEC_BNDLDX_ADDR);
19060 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19061 MEM_VOLATILE_P (operands[4]) = 1;
19064 (define_insn "*<mode>_stx"
19065 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19067 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19068 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19069 UNSPEC_BNDLDX_ADDR)])
19070 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
19071 (set (match_operand:BLK 4 "bnd_mem_operator")
19072 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19074 "bndstx\t{%2, %3|%3, %2}"
19075 [(set_attr "type" "mpxst")])
19077 (define_insn "move_size_reloc_<mode>"
19078 [(set (match_operand:SWI48 0 "register_operand" "=r")
19080 [(match_operand:SWI48 1 "symbol_operand")]
19084 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19085 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19087 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19089 [(set_attr "type" "imov")
19090 (set_attr "mode" "<MODE>")])
19094 (include "sync.md")