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_vector_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_vector_move (OImode, operands); DONE;")
1911 (define_expand "movti"
1912 [(set (match_operand:TI 0 "nonimmediate_operand")
1913 (match_operand:TI 1 "general_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" "r,km")]
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, r,m")
2432 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,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: /* FALLTHRU */
2447 case 7: return "kmovw\t{%1, %0|%0, %1}";
2448 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2449 default: gcc_unreachable ();
2453 if (get_attr_mode (insn) == MODE_SI)
2454 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2456 return "mov{w}\t{%1, %0|%0, %1}";
2460 (cond [(eq_attr "alternative" "4,5,6,7")
2461 (const_string "mskmov")
2462 (match_test "optimize_function_for_size_p (cfun)")
2463 (const_string "imov")
2464 (and (eq_attr "alternative" "0")
2465 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2466 (not (match_test "TARGET_HIMODE_MATH"))))
2467 (const_string "imov")
2468 (and (eq_attr "alternative" "1,2")
2469 (match_operand:HI 1 "aligned_operand"))
2470 (const_string "imov")
2471 (and (match_test "TARGET_MOVX")
2472 (eq_attr "alternative" "0,2"))
2473 (const_string "imovx")
2475 (const_string "imov")))
2476 (set (attr "prefix")
2477 (if_then_else (eq_attr "alternative" "4,5,6,7")
2478 (const_string "vex")
2479 (const_string "orig")))
2481 (cond [(eq_attr "type" "imovx")
2483 (and (eq_attr "alternative" "1,2")
2484 (match_operand:HI 1 "aligned_operand"))
2486 (and (eq_attr "alternative" "0")
2487 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2488 (not (match_test "TARGET_HIMODE_MATH"))))
2491 (const_string "HI")))])
2493 ;; Situation is quite tricky about when to choose full sized (SImode) move
2494 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2495 ;; partial register dependency machines (such as AMD Athlon), where QImode
2496 ;; moves issue extra dependency and for partial register stalls machines
2497 ;; that don't use QImode patterns (and QImode move cause stall on the next
2500 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2501 ;; register stall machines with, where we use QImode instructions, since
2502 ;; partial register stall can be caused there. Then we use movzx.
2504 (define_insn "*movqi_internal"
2505 [(set (match_operand:QI 0 "nonimmediate_operand"
2506 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2507 (match_operand:QI 1 "general_operand"
2508 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2511 switch (get_attr_type (insn))
2514 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2515 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2518 switch (which_alternative)
2520 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2521 : "kmovw\t{%k1, %0|%0, %k1}";
2522 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2523 : "kmovw\t{%1, %0|%0, %1}";
2524 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2525 : "kmovw\t{%1, %k0|%k0, %1}";
2528 gcc_assert (TARGET_AVX512DQ);
2529 return "kmovb\t{%1, %0|%0, %1}";
2530 default: gcc_unreachable ();
2534 if (get_attr_mode (insn) == MODE_SI)
2535 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2537 return "mov{b}\t{%1, %0|%0, %1}";
2540 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2542 (cond [(eq_attr "alternative" "7,8,9,10,11")
2543 (const_string "mskmov")
2544 (and (eq_attr "alternative" "5")
2545 (not (match_operand:QI 1 "aligned_operand")))
2546 (const_string "imovx")
2547 (match_test "optimize_function_for_size_p (cfun)")
2548 (const_string "imov")
2549 (and (eq_attr "alternative" "3")
2550 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2551 (not (match_test "TARGET_QIMODE_MATH"))))
2552 (const_string "imov")
2553 (eq_attr "alternative" "3,5")
2554 (const_string "imovx")
2555 (and (match_test "TARGET_MOVX")
2556 (eq_attr "alternative" "2"))
2557 (const_string "imovx")
2559 (const_string "imov")))
2560 (set (attr "prefix")
2561 (if_then_else (eq_attr "alternative" "7,8,9")
2562 (const_string "vex")
2563 (const_string "orig")))
2565 (cond [(eq_attr "alternative" "3,4,5")
2567 (eq_attr "alternative" "6")
2569 (eq_attr "type" "imovx")
2571 (and (eq_attr "type" "imov")
2572 (and (eq_attr "alternative" "0,1")
2573 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2574 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2575 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2577 ;; Avoid partial register stalls when not using QImode arithmetic
2578 (and (eq_attr "type" "imov")
2579 (and (eq_attr "alternative" "0,1")
2580 (and (match_test "TARGET_PARTIAL_REG_STALL")
2581 (not (match_test "TARGET_QIMODE_MATH")))))
2584 (const_string "QI")))])
2586 ;; Stores and loads of ax to arbitrary constant address.
2587 ;; We fake an second form of instruction to force reload to load address
2588 ;; into register when rax is not available
2589 (define_insn "*movabs<mode>_1"
2590 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2591 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2592 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2594 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2595 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2596 [(set_attr "type" "imov")
2597 (set_attr "modrm" "0,*")
2598 (set_attr "length_address" "8,0")
2599 (set_attr "length_immediate" "0,*")
2600 (set_attr "memory" "store")
2601 (set_attr "mode" "<MODE>")])
2603 (define_insn "*movabs<mode>_2"
2604 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2605 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2606 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2608 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2609 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2610 [(set_attr "type" "imov")
2611 (set_attr "modrm" "0,*")
2612 (set_attr "length_address" "8,0")
2613 (set_attr "length_immediate" "0")
2614 (set_attr "memory" "load")
2615 (set_attr "mode" "<MODE>")])
2617 (define_insn "*swap<mode>"
2618 [(set (match_operand:SWI48 0 "register_operand" "+r")
2619 (match_operand:SWI48 1 "register_operand" "+r"))
2623 "xchg{<imodesuffix>}\t%1, %0"
2624 [(set_attr "type" "imov")
2625 (set_attr "mode" "<MODE>")
2626 (set_attr "pent_pair" "np")
2627 (set_attr "athlon_decode" "vector")
2628 (set_attr "amdfam10_decode" "double")
2629 (set_attr "bdver1_decode" "double")])
2631 (define_insn "*swap<mode>_1"
2632 [(set (match_operand:SWI12 0 "register_operand" "+r")
2633 (match_operand:SWI12 1 "register_operand" "+r"))
2636 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2638 [(set_attr "type" "imov")
2639 (set_attr "mode" "SI")
2640 (set_attr "pent_pair" "np")
2641 (set_attr "athlon_decode" "vector")
2642 (set_attr "amdfam10_decode" "double")
2643 (set_attr "bdver1_decode" "double")])
2645 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2646 ;; is disabled for AMDFAM10
2647 (define_insn "*swap<mode>_2"
2648 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2649 (match_operand:SWI12 1 "register_operand" "+<r>"))
2652 "TARGET_PARTIAL_REG_STALL"
2653 "xchg{<imodesuffix>}\t%1, %0"
2654 [(set_attr "type" "imov")
2655 (set_attr "mode" "<MODE>")
2656 (set_attr "pent_pair" "np")
2657 (set_attr "athlon_decode" "vector")])
2659 (define_expand "movstrict<mode>"
2660 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2661 (match_operand:SWI12 1 "general_operand"))]
2664 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2666 if (GET_CODE (operands[0]) == SUBREG
2667 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2669 /* Don't generate memory->memory moves, go through a register */
2670 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2671 operands[1] = force_reg (<MODE>mode, operands[1]);
2674 (define_insn "*movstrict<mode>_1"
2675 [(set (strict_low_part
2676 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2677 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2678 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2679 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2680 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2681 [(set_attr "type" "imov")
2682 (set_attr "mode" "<MODE>")])
2684 (define_insn "*movstrict<mode>_xor"
2685 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2686 (match_operand:SWI12 1 "const0_operand"))
2687 (clobber (reg:CC FLAGS_REG))]
2689 "xor{<imodesuffix>}\t%0, %0"
2690 [(set_attr "type" "alu1")
2691 (set_attr "mode" "<MODE>")
2692 (set_attr "length_immediate" "0")])
2694 (define_insn "*mov<mode>_extv_1"
2695 [(set (match_operand:SWI24 0 "register_operand" "=R")
2696 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2700 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2701 [(set_attr "type" "imovx")
2702 (set_attr "mode" "SI")])
2704 (define_insn "*movqi_extv_1"
2705 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2706 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2711 switch (get_attr_type (insn))
2714 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2716 return "mov{b}\t{%h1, %0|%0, %h1}";
2719 [(set_attr "isa" "*,*,nox64")
2721 (if_then_else (and (match_operand:QI 0 "register_operand")
2722 (ior (not (match_operand:QI 0 "QIreg_operand"))
2723 (match_test "TARGET_MOVX")))
2724 (const_string "imovx")
2725 (const_string "imov")))
2727 (if_then_else (eq_attr "type" "imovx")
2729 (const_string "QI")))])
2731 (define_insn "*mov<mode>_extzv_1"
2732 [(set (match_operand:SWI48 0 "register_operand" "=R")
2733 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2737 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2738 [(set_attr "type" "imovx")
2739 (set_attr "mode" "SI")])
2741 (define_insn "*movqi_extzv_2"
2742 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2744 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2749 switch (get_attr_type (insn))
2752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2754 return "mov{b}\t{%h1, %0|%0, %h1}";
2757 [(set_attr "isa" "*,*,nox64")
2759 (if_then_else (and (match_operand:QI 0 "register_operand")
2760 (ior (not (match_operand:QI 0 "QIreg_operand"))
2761 (match_test "TARGET_MOVX")))
2762 (const_string "imovx")
2763 (const_string "imov")))
2765 (if_then_else (eq_attr "type" "imovx")
2767 (const_string "QI")))])
2769 (define_insn "mov<mode>_insv_1"
2770 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2773 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2776 if (CONST_INT_P (operands[1]))
2777 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2778 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2780 [(set_attr "isa" "*,nox64")
2781 (set_attr "type" "imov")
2782 (set_attr "mode" "QI")])
2784 (define_insn "*movqi_insv_2"
2785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2788 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2791 "mov{b}\t{%h1, %h0|%h0, %h1}"
2792 [(set_attr "type" "imov")
2793 (set_attr "mode" "QI")])
2795 ;; Floating point push instructions.
2797 (define_insn "*pushtf"
2798 [(set (match_operand:TF 0 "push_operand" "=<,<")
2799 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2800 "TARGET_64BIT || TARGET_SSE"
2802 /* This insn should be already split before reg-stack. */
2805 [(set_attr "isa" "*,x64")
2806 (set_attr "type" "multi")
2807 (set_attr "unit" "sse,*")
2808 (set_attr "mode" "TF,DI")])
2810 ;; %%% Kill this when call knows how to work this out.
2812 [(set (match_operand:TF 0 "push_operand")
2813 (match_operand:TF 1 "sse_reg_operand"))]
2814 "TARGET_SSE && reload_completed"
2815 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2816 (set (match_dup 0) (match_dup 1))]
2818 /* Preserve memory attributes. */
2819 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2822 (define_insn "*pushxf"
2823 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2824 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2827 /* This insn should be already split before reg-stack. */
2830 [(set_attr "type" "multi")
2831 (set_attr "unit" "i387,*,*,*")
2833 (cond [(eq_attr "alternative" "1,2,3")
2834 (if_then_else (match_test "TARGET_64BIT")
2836 (const_string "SI"))
2838 (const_string "XF")))
2839 (set (attr "preferred_for_size")
2840 (cond [(eq_attr "alternative" "1")
2841 (symbol_ref "false")]
2842 (symbol_ref "true")))])
2844 ;; %%% Kill this when call knows how to work this out.
2846 [(set (match_operand:XF 0 "push_operand")
2847 (match_operand:XF 1 "fp_register_operand"))]
2849 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2850 (set (match_dup 0) (match_dup 1))]
2852 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2853 /* Preserve memory attributes. */
2854 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2857 (define_insn "*pushdf"
2858 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2859 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2862 /* This insn should be already split before reg-stack. */
2865 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2866 (set_attr "type" "multi")
2867 (set_attr "unit" "i387,*,*,*,*,sse")
2868 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2869 (set (attr "preferred_for_size")
2870 (cond [(eq_attr "alternative" "1")
2871 (symbol_ref "false")]
2872 (symbol_ref "true")))
2873 (set (attr "preferred_for_speed")
2874 (cond [(eq_attr "alternative" "1")
2875 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2876 (symbol_ref "true")))])
2878 ;; %%% Kill this when call knows how to work this out.
2880 [(set (match_operand:DF 0 "push_operand")
2881 (match_operand:DF 1 "any_fp_register_operand"))]
2883 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2884 (set (match_dup 0) (match_dup 1))]
2886 /* Preserve memory attributes. */
2887 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2890 (define_insn "*pushsf_rex64"
2891 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2892 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2895 /* Anything else should be already split before reg-stack. */
2896 gcc_assert (which_alternative == 1);
2897 return "push{q}\t%q1";
2899 [(set_attr "type" "multi,push,multi")
2900 (set_attr "unit" "i387,*,*")
2901 (set_attr "mode" "SF,DI,SF")])
2903 (define_insn "*pushsf"
2904 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2905 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2908 /* Anything else should be already split before reg-stack. */
2909 gcc_assert (which_alternative == 1);
2910 return "push{l}\t%1";
2912 [(set_attr "type" "multi,push,multi")
2913 (set_attr "unit" "i387,*,*")
2914 (set_attr "mode" "SF,SI,SF")])
2916 ;; %%% Kill this when call knows how to work this out.
2918 [(set (match_operand:SF 0 "push_operand")
2919 (match_operand:SF 1 "any_fp_register_operand"))]
2921 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2922 (set (match_dup 0) (match_dup 1))]
2924 rtx op = XEXP (operands[0], 0);
2925 if (GET_CODE (op) == PRE_DEC)
2927 gcc_assert (!TARGET_64BIT);
2932 op = XEXP (XEXP (op, 1), 1);
2933 gcc_assert (CONST_INT_P (op));
2936 /* Preserve memory attributes. */
2937 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2941 [(set (match_operand:SF 0 "push_operand")
2942 (match_operand:SF 1 "memory_operand"))]
2944 && (operands[2] = find_constant_src (insn))"
2945 [(set (match_dup 0) (match_dup 2))])
2948 [(set (match_operand 0 "push_operand")
2949 (match_operand 1 "general_operand"))]
2951 && (GET_MODE (operands[0]) == TFmode
2952 || GET_MODE (operands[0]) == XFmode
2953 || GET_MODE (operands[0]) == DFmode)
2954 && !ANY_FP_REG_P (operands[1])"
2956 "ix86_split_long_move (operands); DONE;")
2958 ;; Floating point move instructions.
2960 (define_expand "movtf"
2961 [(set (match_operand:TF 0 "nonimmediate_operand")
2962 (match_operand:TF 1 "nonimmediate_operand"))]
2963 "TARGET_64BIT || TARGET_SSE"
2964 "ix86_expand_move (TFmode, operands); DONE;")
2966 (define_expand "mov<mode>"
2967 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2968 (match_operand:X87MODEF 1 "general_operand"))]
2970 "ix86_expand_move (<MODE>mode, operands); DONE;")
2972 (define_insn "*movtf_internal"
2973 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2974 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2975 "(TARGET_64BIT || TARGET_SSE)
2976 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2977 && (lra_in_progress || reload_completed
2978 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2979 || GET_CODE (operands[1]) != CONST_DOUBLE
2980 || (optimize_function_for_size_p (cfun)
2981 && standard_sse_constant_p (operands[1])
2982 && !memory_operand (operands[0], TFmode))
2983 || (!TARGET_MEMORY_MISMATCH_STALL
2984 && memory_operand (operands[0], TFmode)))"
2986 switch (get_attr_type (insn))
2989 return standard_sse_constant_opcode (insn, operands[1]);
2992 /* Handle misaligned load/store since we
2993 don't have movmisaligntf pattern. */
2994 if (misaligned_operand (operands[0], TFmode)
2995 || misaligned_operand (operands[1], TFmode))
2997 if (get_attr_mode (insn) == MODE_V4SF)
2998 return "%vmovups\t{%1, %0|%0, %1}";
3000 return "%vmovdqu\t{%1, %0|%0, %1}";
3004 if (get_attr_mode (insn) == MODE_V4SF)
3005 return "%vmovaps\t{%1, %0|%0, %1}";
3007 return "%vmovdqa\t{%1, %0|%0, %1}";
3017 [(set_attr "isa" "*,*,*,x64,x64")
3018 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3019 (set (attr "prefix")
3020 (if_then_else (eq_attr "type" "sselog1,ssemov")
3021 (const_string "maybe_vex")
3022 (const_string "orig")))
3024 (cond [(eq_attr "alternative" "3,4")
3026 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3027 (const_string "V4SF")
3028 (and (eq_attr "alternative" "2")
3029 (match_test "TARGET_SSE_TYPELESS_STORES"))
3030 (const_string "V4SF")
3031 (match_test "TARGET_AVX")
3033 (ior (not (match_test "TARGET_SSE2"))
3034 (match_test "optimize_function_for_size_p (cfun)"))
3035 (const_string "V4SF")
3037 (const_string "TI")))])
3039 ;; Possible store forwarding (partial memory) stall
3040 ;; in alternatives 4, 6, 7 and 8.
3041 (define_insn "*movxf_internal"
3042 [(set (match_operand:XF 0 "nonimmediate_operand"
3043 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3044 (match_operand:XF 1 "general_operand"
3045 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3046 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3047 && (lra_in_progress || reload_completed
3048 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3049 || GET_CODE (operands[1]) != CONST_DOUBLE
3050 || (optimize_function_for_size_p (cfun)
3051 && standard_80387_constant_p (operands[1]) > 0
3052 && !memory_operand (operands[0], XFmode))
3053 || (!TARGET_MEMORY_MISMATCH_STALL
3054 && memory_operand (operands[0], XFmode)))"
3056 switch (get_attr_type (insn))
3059 if (which_alternative == 2)
3060 return standard_80387_constant_opcode (operands[1]);
3061 return output_387_reg_move (insn, operands);
3071 (cond [(eq_attr "alternative" "7")
3072 (const_string "nox64")
3073 (eq_attr "alternative" "8")
3074 (const_string "x64")
3076 (const_string "*")))
3078 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3079 (const_string "multi")
3081 (const_string "fmov")))
3083 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3084 (if_then_else (match_test "TARGET_64BIT")
3086 (const_string "SI"))
3088 (const_string "XF")))
3089 (set (attr "preferred_for_size")
3090 (cond [(eq_attr "alternative" "3,4")
3091 (symbol_ref "false")]
3092 (symbol_ref "true")))])
3094 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3095 (define_insn "*movdf_internal"
3096 [(set (match_operand:DF 0 "nonimmediate_operand"
3097 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3098 (match_operand:DF 1 "general_operand"
3099 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3100 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3101 && (lra_in_progress || reload_completed
3102 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3103 || GET_CODE (operands[1]) != CONST_DOUBLE
3104 || (optimize_function_for_size_p (cfun)
3105 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3106 && standard_80387_constant_p (operands[1]) > 0)
3107 || (TARGET_SSE2 && TARGET_SSE_MATH
3108 && standard_sse_constant_p (operands[1])))
3109 && !memory_operand (operands[0], DFmode))
3110 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3111 && memory_operand (operands[0], DFmode)))"
3113 switch (get_attr_type (insn))
3116 if (which_alternative == 2)
3117 return standard_80387_constant_opcode (operands[1]);
3118 return output_387_reg_move (insn, operands);
3124 if (get_attr_mode (insn) == MODE_SI)
3125 return "mov{l}\t{%1, %k0|%k0, %1}";
3126 else if (which_alternative == 11)
3127 return "movabs{q}\t{%1, %0|%0, %1}";
3129 return "mov{q}\t{%1, %0|%0, %1}";
3132 return standard_sse_constant_opcode (insn, operands[1]);
3135 switch (get_attr_mode (insn))
3138 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3139 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3140 return "%vmovsd\t{%1, %0|%0, %1}";
3143 return "%vmovaps\t{%1, %0|%0, %1}";
3145 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3147 return "%vmovapd\t{%1, %0|%0, %1}";
3150 gcc_assert (!TARGET_AVX);
3151 return "movlps\t{%1, %0|%0, %1}";
3153 gcc_assert (!TARGET_AVX);
3154 return "movlpd\t{%1, %0|%0, %1}";
3157 /* Handle broken assemblers that require movd instead of movq. */
3158 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3159 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3160 return "%vmovd\t{%1, %0|%0, %1}";
3161 return "%vmovq\t{%1, %0|%0, %1}";
3172 (cond [(eq_attr "alternative" "3,4,5,6,7")
3173 (const_string "nox64")
3174 (eq_attr "alternative" "8,9,10,11,20,21")
3175 (const_string "x64")
3176 (eq_attr "alternative" "12,13,14,15")
3177 (const_string "sse2")
3179 (const_string "*")))
3181 (cond [(eq_attr "alternative" "0,1,2")
3182 (const_string "fmov")
3183 (eq_attr "alternative" "3,4,5,6,7")
3184 (const_string "multi")
3185 (eq_attr "alternative" "8,9,10,11")
3186 (const_string "imov")
3187 (eq_attr "alternative" "12,16")
3188 (const_string "sselog1")
3190 (const_string "ssemov")))
3192 (if_then_else (eq_attr "alternative" "11")
3194 (const_string "*")))
3195 (set (attr "length_immediate")
3196 (if_then_else (eq_attr "alternative" "11")
3198 (const_string "*")))
3199 (set (attr "prefix")
3200 (if_then_else (eq_attr "type" "sselog1,ssemov")
3201 (const_string "maybe_vex")
3202 (const_string "orig")))
3203 (set (attr "prefix_data16")
3205 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3206 (eq_attr "mode" "V1DF"))
3208 (const_string "*")))
3210 (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3212 (eq_attr "alternative" "8,9,11,20,21")
3215 /* xorps is one byte shorter for non-AVX targets. */
3216 (eq_attr "alternative" "12,16")
3217 (cond [(not (match_test "TARGET_SSE2"))
3218 (const_string "V4SF")
3219 (match_test "TARGET_AVX512F")
3221 (match_test "TARGET_AVX")
3222 (const_string "V2DF")
3223 (match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3228 (const_string "V2DF"))
3230 /* For architectures resolving dependencies on
3231 whole SSE registers use movapd to break dependency
3232 chains, otherwise use short move to avoid extra work. */
3234 /* movaps is one byte shorter for non-AVX targets. */
3235 (eq_attr "alternative" "13,17")
3236 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3237 (match_operand 1 "ext_sse_reg_operand"))
3238 (const_string "V8DF")
3239 (ior (not (match_test "TARGET_SSE2"))
3240 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3241 (const_string "V4SF")
3242 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3243 (const_string "V2DF")
3244 (match_test "TARGET_AVX")
3246 (match_test "optimize_function_for_size_p (cfun)")
3247 (const_string "V4SF")
3249 (const_string "DF"))
3251 /* For architectures resolving dependencies on register
3252 parts we may avoid extra work to zero out upper part
3254 (eq_attr "alternative" "14,18")
3255 (cond [(not (match_test "TARGET_SSE2"))
3256 (const_string "V2SF")
3257 (match_test "TARGET_AVX")
3259 (match_test "TARGET_SSE_SPLIT_REGS")
3260 (const_string "V1DF")
3262 (const_string "DF"))
3264 (and (eq_attr "alternative" "15,19")
3265 (not (match_test "TARGET_SSE2")))
3266 (const_string "V2SF")
3268 (const_string "DF")))
3269 (set (attr "preferred_for_size")
3270 (cond [(eq_attr "alternative" "3,4")
3271 (symbol_ref "false")]
3272 (symbol_ref "true")))
3273 (set (attr "preferred_for_speed")
3274 (cond [(eq_attr "alternative" "3,4")
3275 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3276 (symbol_ref "true")))])
3278 (define_insn "*movsf_internal"
3279 [(set (match_operand:SF 0 "nonimmediate_operand"
3280 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3281 (match_operand:SF 1 "general_operand"
3282 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3283 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3284 && (lra_in_progress || reload_completed
3285 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3286 || GET_CODE (operands[1]) != CONST_DOUBLE
3287 || (optimize_function_for_size_p (cfun)
3288 && ((!TARGET_SSE_MATH
3289 && standard_80387_constant_p (operands[1]) > 0)
3291 && standard_sse_constant_p (operands[1]))))
3292 || memory_operand (operands[0], SFmode))"
3294 switch (get_attr_type (insn))
3297 if (which_alternative == 2)
3298 return standard_80387_constant_opcode (operands[1]);
3299 return output_387_reg_move (insn, operands);
3302 return "mov{l}\t{%1, %0|%0, %1}";
3305 return standard_sse_constant_opcode (insn, operands[1]);
3308 switch (get_attr_mode (insn))
3311 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3312 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3313 return "%vmovss\t{%1, %0|%0, %1}";
3316 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3318 return "%vmovaps\t{%1, %0|%0, %1}";
3321 return "%vmovd\t{%1, %0|%0, %1}";
3328 switch (get_attr_mode (insn))
3331 return "movq\t{%1, %0|%0, %1}";
3333 return "movd\t{%1, %0|%0, %1}";
3344 (cond [(eq_attr "alternative" "0,1,2")
3345 (const_string "fmov")
3346 (eq_attr "alternative" "3,4")
3347 (const_string "imov")
3348 (eq_attr "alternative" "5")
3349 (const_string "sselog1")
3350 (eq_attr "alternative" "11,12,13,14,15")
3351 (const_string "mmxmov")
3353 (const_string "ssemov")))
3354 (set (attr "prefix")
3355 (if_then_else (eq_attr "type" "sselog1,ssemov")
3356 (const_string "maybe_vex")
3357 (const_string "orig")))
3358 (set (attr "prefix_data16")
3359 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3361 (const_string "*")))
3363 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3365 (eq_attr "alternative" "11")
3367 (eq_attr "alternative" "5")
3368 (cond [(not (match_test "TARGET_SSE2"))
3369 (const_string "V4SF")
3370 (match_test "TARGET_AVX512F")
3371 (const_string "V16SF")
3372 (match_test "TARGET_AVX")
3373 (const_string "V4SF")
3374 (match_test "optimize_function_for_size_p (cfun)")
3375 (const_string "V4SF")
3376 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3379 (const_string "V4SF"))
3381 /* For architectures resolving dependencies on
3382 whole SSE registers use APS move to break dependency
3383 chains, otherwise use short move to avoid extra work.
3385 Do the same for architectures resolving dependencies on
3386 the parts. While in DF mode it is better to always handle
3387 just register parts, the SF mode is different due to lack
3388 of instructions to load just part of the register. It is
3389 better to maintain the whole registers in single format
3390 to avoid problems on using packed logical operations. */
3391 (eq_attr "alternative" "6")
3392 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3393 (match_operand 1 "ext_sse_reg_operand"))
3394 (const_string "V16SF")
3395 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3396 (match_test "TARGET_SSE_SPLIT_REGS"))
3397 (const_string "V4SF")
3399 (const_string "SF"))
3401 (const_string "SF")))])
3404 [(set (match_operand 0 "any_fp_register_operand")
3405 (match_operand 1 "memory_operand"))]
3407 && (GET_MODE (operands[0]) == TFmode
3408 || GET_MODE (operands[0]) == XFmode
3409 || GET_MODE (operands[0]) == DFmode
3410 || GET_MODE (operands[0]) == SFmode)
3411 && (operands[2] = find_constant_src (insn))"
3412 [(set (match_dup 0) (match_dup 2))]
3414 rtx c = operands[2];
3415 int r = REGNO (operands[0]);
3417 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3418 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3423 [(set (match_operand 0 "any_fp_register_operand")
3424 (float_extend (match_operand 1 "memory_operand")))]
3426 && (GET_MODE (operands[0]) == TFmode
3427 || GET_MODE (operands[0]) == XFmode
3428 || GET_MODE (operands[0]) == DFmode)
3429 && (operands[2] = find_constant_src (insn))"
3430 [(set (match_dup 0) (match_dup 2))]
3432 rtx c = operands[2];
3433 int r = REGNO (operands[0]);
3435 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3436 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3440 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3442 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3443 (match_operand:X87MODEF 1 "immediate_operand"))]
3445 && (standard_80387_constant_p (operands[1]) == 8
3446 || standard_80387_constant_p (operands[1]) == 9)"
3447 [(set (match_dup 0)(match_dup 1))
3449 (neg:X87MODEF (match_dup 0)))]
3453 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3454 if (real_isnegzero (&r))
3455 operands[1] = CONST0_RTX (<MODE>mode);
3457 operands[1] = CONST1_RTX (<MODE>mode);
3461 [(set (match_operand 0 "nonimmediate_operand")
3462 (match_operand 1 "general_operand"))]
3464 && (GET_MODE (operands[0]) == TFmode
3465 || GET_MODE (operands[0]) == XFmode
3466 || GET_MODE (operands[0]) == DFmode)
3467 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3469 "ix86_split_long_move (operands); DONE;")
3471 (define_insn "swapxf"
3472 [(set (match_operand:XF 0 "register_operand" "+f")
3473 (match_operand:XF 1 "register_operand" "+f"))
3478 if (STACK_TOP_P (operands[0]))
3483 [(set_attr "type" "fxch")
3484 (set_attr "mode" "XF")])
3486 (define_insn "*swap<mode>"
3487 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3488 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3491 "TARGET_80387 || reload_completed"
3493 if (STACK_TOP_P (operands[0]))
3498 [(set_attr "type" "fxch")
3499 (set_attr "mode" "<MODE>")])
3501 ;; Zero extension instructions
3503 (define_expand "zero_extendsidi2"
3504 [(set (match_operand:DI 0 "nonimmediate_operand")
3505 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3507 (define_insn "*zero_extendsidi2"
3508 [(set (match_operand:DI 0 "nonimmediate_operand"
3509 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3511 (match_operand:SI 1 "x86_64_zext_operand"
3512 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3515 switch (get_attr_type (insn))
3518 if (ix86_use_lea_for_mov (insn, operands))
3519 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3521 return "mov{l}\t{%1, %k0|%k0, %1}";
3527 return "movd\t{%1, %0|%0, %1}";
3530 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3533 if (GENERAL_REG_P (operands[0]))
3534 return "%vmovd\t{%1, %k0|%k0, %1}";
3536 return "%vmovd\t{%1, %0|%0, %1}";
3543 (cond [(eq_attr "alternative" "0,1,2")
3544 (const_string "nox64")
3545 (eq_attr "alternative" "3,7")
3546 (const_string "x64")
3547 (eq_attr "alternative" "8")
3548 (const_string "x64_sse4")
3549 (eq_attr "alternative" "10")
3550 (const_string "sse2")
3552 (const_string "*")))
3554 (cond [(eq_attr "alternative" "0,1,2,4")
3555 (const_string "multi")
3556 (eq_attr "alternative" "5,6")
3557 (const_string "mmxmov")
3558 (eq_attr "alternative" "7,9,10")
3559 (const_string "ssemov")
3560 (eq_attr "alternative" "8")
3561 (const_string "sselog1")
3563 (const_string "imovx")))
3564 (set (attr "prefix_extra")
3565 (if_then_else (eq_attr "alternative" "8")
3567 (const_string "*")))
3568 (set (attr "length_immediate")
3569 (if_then_else (eq_attr "alternative" "8")
3571 (const_string "*")))
3572 (set (attr "prefix")
3573 (if_then_else (eq_attr "type" "ssemov,sselog1")
3574 (const_string "maybe_vex")
3575 (const_string "orig")))
3576 (set (attr "prefix_0f")
3577 (if_then_else (eq_attr "type" "imovx")
3579 (const_string "*")))
3581 (cond [(eq_attr "alternative" "5,6")
3583 (eq_attr "alternative" "7,8,9")
3586 (const_string "SI")))])
3589 [(set (match_operand:DI 0 "memory_operand")
3590 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3592 [(set (match_dup 4) (const_int 0))]
3593 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3596 [(set (match_operand:DI 0 "register_operand")
3597 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3598 "!TARGET_64BIT && reload_completed
3599 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3600 && true_regnum (operands[0]) == true_regnum (operands[1])"
3601 [(set (match_dup 4) (const_int 0))]
3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3605 [(set (match_operand:DI 0 "nonimmediate_operand")
3606 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3607 "!TARGET_64BIT && reload_completed
3608 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3609 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3610 [(set (match_dup 3) (match_dup 1))
3611 (set (match_dup 4) (const_int 0))]
3612 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3614 (define_insn "zero_extend<mode>di2"
3615 [(set (match_operand:DI 0 "register_operand" "=r")
3617 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3619 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3620 [(set_attr "type" "imovx")
3621 (set_attr "mode" "SI")])
3623 (define_expand "zero_extend<mode>si2"
3624 [(set (match_operand:SI 0 "register_operand")
3625 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3628 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3630 operands[1] = force_reg (<MODE>mode, operands[1]);
3631 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3636 (define_insn_and_split "zero_extend<mode>si2_and"
3637 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3639 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3640 (clobber (reg:CC FLAGS_REG))]
3641 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3643 "&& reload_completed"
3644 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3645 (clobber (reg:CC FLAGS_REG))])]
3647 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3649 ix86_expand_clear (operands[0]);
3651 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3652 emit_insn (gen_movstrict<mode>
3653 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3657 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3659 [(set_attr "type" "alu1")
3660 (set_attr "mode" "SI")])
3662 (define_insn "*zero_extend<mode>si2"
3663 [(set (match_operand:SI 0 "register_operand" "=r")
3665 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3666 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3667 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3668 [(set_attr "type" "imovx")
3669 (set_attr "mode" "SI")])
3671 (define_expand "zero_extendqihi2"
3672 [(set (match_operand:HI 0 "register_operand")
3673 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3676 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3678 operands[1] = force_reg (QImode, operands[1]);
3679 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3684 (define_insn_and_split "zero_extendqihi2_and"
3685 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3686 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3687 (clobber (reg:CC FLAGS_REG))]
3688 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3690 "&& reload_completed"
3691 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3692 (clobber (reg:CC FLAGS_REG))])]
3694 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3696 ix86_expand_clear (operands[0]);
3698 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3699 emit_insn (gen_movstrictqi
3700 (gen_lowpart (QImode, operands[0]), operands[1]));
3704 operands[0] = gen_lowpart (SImode, operands[0]);
3706 [(set_attr "type" "alu1")
3707 (set_attr "mode" "SI")])
3709 ; zero extend to SImode to avoid partial register stalls
3710 (define_insn "*zero_extendqihi2"
3711 [(set (match_operand:HI 0 "register_operand" "=r")
3712 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3713 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3714 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3715 [(set_attr "type" "imovx")
3716 (set_attr "mode" "SI")])
3718 ;; Sign extension instructions
3720 (define_expand "extendsidi2"
3721 [(set (match_operand:DI 0 "register_operand")
3722 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3727 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3732 (define_insn "*extendsidi2_rex64"
3733 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3734 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3738 movs{lq|x}\t{%1, %0|%0, %1}"
3739 [(set_attr "type" "imovx")
3740 (set_attr "mode" "DI")
3741 (set_attr "prefix_0f" "0")
3742 (set_attr "modrm" "0,1")])
3744 (define_insn "extendsidi2_1"
3745 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3746 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3747 (clobber (reg:CC FLAGS_REG))
3748 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3752 ;; Split the memory case. If the source register doesn't die, it will stay
3753 ;; this way, if it does die, following peephole2s take care of it.
3755 [(set (match_operand:DI 0 "memory_operand")
3756 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3757 (clobber (reg:CC FLAGS_REG))
3758 (clobber (match_operand:SI 2 "register_operand"))]
3762 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3764 emit_move_insn (operands[3], operands[1]);
3766 /* Generate a cltd if possible and doing so it profitable. */
3767 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3768 && true_regnum (operands[1]) == AX_REG
3769 && true_regnum (operands[2]) == DX_REG)
3771 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3775 emit_move_insn (operands[2], operands[1]);
3776 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3778 emit_move_insn (operands[4], operands[2]);
3782 ;; Peepholes for the case where the source register does die, after
3783 ;; being split with the above splitter.
3785 [(set (match_operand:SI 0 "memory_operand")
3786 (match_operand:SI 1 "register_operand"))
3787 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3788 (parallel [(set (match_dup 2)
3789 (ashiftrt:SI (match_dup 2) (const_int 31)))
3790 (clobber (reg:CC FLAGS_REG))])
3791 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3792 "REGNO (operands[1]) != REGNO (operands[2])
3793 && peep2_reg_dead_p (2, operands[1])
3794 && peep2_reg_dead_p (4, operands[2])
3795 && !reg_mentioned_p (operands[2], operands[3])"
3796 [(set (match_dup 0) (match_dup 1))
3797 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3798 (clobber (reg:CC FLAGS_REG))])
3799 (set (match_dup 3) (match_dup 1))])
3802 [(set (match_operand:SI 0 "memory_operand")
3803 (match_operand:SI 1 "register_operand"))
3804 (parallel [(set (match_operand:SI 2 "register_operand")
3805 (ashiftrt:SI (match_dup 1) (const_int 31)))
3806 (clobber (reg:CC FLAGS_REG))])
3807 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3808 "/* cltd is shorter than sarl $31, %eax */
3809 !optimize_function_for_size_p (cfun)
3810 && true_regnum (operands[1]) == AX_REG
3811 && true_regnum (operands[2]) == DX_REG
3812 && peep2_reg_dead_p (2, operands[1])
3813 && peep2_reg_dead_p (3, operands[2])
3814 && !reg_mentioned_p (operands[2], operands[3])"
3815 [(set (match_dup 0) (match_dup 1))
3816 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3817 (clobber (reg:CC FLAGS_REG))])
3818 (set (match_dup 3) (match_dup 1))])
3820 ;; Extend to register case. Optimize case where source and destination
3821 ;; registers match and cases where we can use cltd.
3823 [(set (match_operand:DI 0 "register_operand")
3824 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3825 (clobber (reg:CC FLAGS_REG))
3826 (clobber (match_scratch:SI 2))]
3830 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3832 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3833 emit_move_insn (operands[3], operands[1]);
3835 /* Generate a cltd if possible and doing so it profitable. */
3836 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3837 && true_regnum (operands[3]) == AX_REG
3838 && true_regnum (operands[4]) == DX_REG)
3840 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3844 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3845 emit_move_insn (operands[4], operands[1]);
3847 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3851 (define_insn "extend<mode>di2"
3852 [(set (match_operand:DI 0 "register_operand" "=r")
3854 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3856 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3857 [(set_attr "type" "imovx")
3858 (set_attr "mode" "DI")])
3860 (define_insn "extendhisi2"
3861 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3862 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3865 switch (get_attr_prefix_0f (insn))
3868 return "{cwtl|cwde}";
3870 return "movs{wl|x}\t{%1, %0|%0, %1}";
3873 [(set_attr "type" "imovx")
3874 (set_attr "mode" "SI")
3875 (set (attr "prefix_0f")
3876 ;; movsx is short decodable while cwtl is vector decoded.
3877 (if_then_else (and (eq_attr "cpu" "!k6")
3878 (eq_attr "alternative" "0"))
3880 (const_string "1")))
3882 (if_then_else (eq_attr "prefix_0f" "0")
3884 (const_string "1")))])
3886 (define_insn "*extendhisi2_zext"
3887 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3890 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3893 switch (get_attr_prefix_0f (insn))
3896 return "{cwtl|cwde}";
3898 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3901 [(set_attr "type" "imovx")
3902 (set_attr "mode" "SI")
3903 (set (attr "prefix_0f")
3904 ;; movsx is short decodable while cwtl is vector decoded.
3905 (if_then_else (and (eq_attr "cpu" "!k6")
3906 (eq_attr "alternative" "0"))
3908 (const_string "1")))
3910 (if_then_else (eq_attr "prefix_0f" "0")
3912 (const_string "1")))])
3914 (define_insn "extendqisi2"
3915 [(set (match_operand:SI 0 "register_operand" "=r")
3916 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3918 "movs{bl|x}\t{%1, %0|%0, %1}"
3919 [(set_attr "type" "imovx")
3920 (set_attr "mode" "SI")])
3922 (define_insn "*extendqisi2_zext"
3923 [(set (match_operand:DI 0 "register_operand" "=r")
3925 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3927 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3928 [(set_attr "type" "imovx")
3929 (set_attr "mode" "SI")])
3931 (define_insn "extendqihi2"
3932 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3933 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3936 switch (get_attr_prefix_0f (insn))
3939 return "{cbtw|cbw}";
3941 return "movs{bw|x}\t{%1, %0|%0, %1}";
3944 [(set_attr "type" "imovx")
3945 (set_attr "mode" "HI")
3946 (set (attr "prefix_0f")
3947 ;; movsx is short decodable while cwtl is vector decoded.
3948 (if_then_else (and (eq_attr "cpu" "!k6")
3949 (eq_attr "alternative" "0"))
3951 (const_string "1")))
3953 (if_then_else (eq_attr "prefix_0f" "0")
3955 (const_string "1")))])
3957 ;; Conversions between float and double.
3959 ;; These are all no-ops in the model used for the 80387.
3960 ;; So just emit moves.
3962 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3964 [(set (match_operand:DF 0 "push_operand")
3965 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3967 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3968 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3971 [(set (match_operand:XF 0 "push_operand")
3972 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3974 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3975 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3976 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3978 (define_expand "extendsfdf2"
3979 [(set (match_operand:DF 0 "nonimmediate_operand")
3980 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3981 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3983 /* ??? Needed for compress_float_constant since all fp constants
3984 are TARGET_LEGITIMATE_CONSTANT_P. */
3985 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3987 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3988 && standard_80387_constant_p (operands[1]) > 0)
3990 operands[1] = simplify_const_unary_operation
3991 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3992 emit_move_insn_1 (operands[0], operands[1]);
3995 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3999 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4001 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4003 We do the conversion post reload to avoid producing of 128bit spills
4004 that might lead to ICE on 32bit target. The sequence unlikely combine
4007 [(set (match_operand:DF 0 "register_operand")
4009 (match_operand:SF 1 "nonimmediate_operand")))]
4010 "TARGET_USE_VECTOR_FP_CONVERTS
4011 && optimize_insn_for_speed_p ()
4012 && reload_completed && SSE_REG_P (operands[0])"
4017 (parallel [(const_int 0) (const_int 1)]))))]
4019 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4020 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4021 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4022 Try to avoid move when unpacking can be done in source. */
4023 if (REG_P (operands[1]))
4025 /* If it is unsafe to overwrite upper half of source, we need
4026 to move to destination and unpack there. */
4027 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4028 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4029 && true_regnum (operands[0]) != true_regnum (operands[1]))
4031 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4032 emit_move_insn (tmp, operands[1]);
4035 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4036 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4040 emit_insn (gen_vec_setv4sf_0 (operands[3],
4041 CONST0_RTX (V4SFmode), operands[1]));
4044 ;; It's more profitable to split and then extend in the same register.
4046 [(set (match_operand:DF 0 "register_operand")
4048 (match_operand:SF 1 "memory_operand")))]
4049 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4050 && optimize_insn_for_speed_p ()
4051 && SSE_REG_P (operands[0])"
4052 [(set (match_dup 2) (match_dup 1))
4053 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4054 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4056 (define_insn "*extendsfdf2_mixed"
4057 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4059 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4060 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4062 switch (which_alternative)
4066 return output_387_reg_move (insn, operands);
4069 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4075 [(set_attr "type" "fmov,fmov,ssecvt")
4076 (set_attr "prefix" "orig,orig,maybe_vex")
4077 (set_attr "mode" "SF,XF,DF")])
4079 (define_insn "*extendsfdf2_sse"
4080 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4081 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4082 "TARGET_SSE2 && TARGET_SSE_MATH"
4083 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4084 [(set_attr "type" "ssecvt")
4085 (set_attr "prefix" "maybe_vex")
4086 (set_attr "mode" "DF")])
4088 (define_insn "*extendsfdf2_i387"
4089 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4090 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4092 "* return output_387_reg_move (insn, operands);"
4093 [(set_attr "type" "fmov")
4094 (set_attr "mode" "SF,XF")])
4096 (define_expand "extend<mode>xf2"
4097 [(set (match_operand:XF 0 "nonimmediate_operand")
4098 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4101 /* ??? Needed for compress_float_constant since all fp constants
4102 are TARGET_LEGITIMATE_CONSTANT_P. */
4103 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4105 if (standard_80387_constant_p (operands[1]) > 0)
4107 operands[1] = simplify_const_unary_operation
4108 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4109 emit_move_insn_1 (operands[0], operands[1]);
4112 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4116 (define_insn "*extend<mode>xf2_i387"
4117 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4119 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4121 "* return output_387_reg_move (insn, operands);"
4122 [(set_attr "type" "fmov")
4123 (set_attr "mode" "<MODE>,XF")])
4125 ;; %%% This seems bad bad news.
4126 ;; This cannot output into an f-reg because there is no way to be sure
4127 ;; of truncating in that case. Otherwise this is just like a simple move
4128 ;; insn. So we pretend we can output to a reg in order to get better
4129 ;; register preferencing, but we really use a stack slot.
4131 ;; Conversion from DFmode to SFmode.
4133 (define_expand "truncdfsf2"
4134 [(set (match_operand:SF 0 "nonimmediate_operand")
4136 (match_operand:DF 1 "nonimmediate_operand")))]
4137 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4139 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4141 else if (flag_unsafe_math_optimizations)
4145 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4146 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4151 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4153 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4155 We do the conversion post reload to avoid producing of 128bit spills
4156 that might lead to ICE on 32bit target. The sequence unlikely combine
4159 [(set (match_operand:SF 0 "register_operand")
4161 (match_operand:DF 1 "nonimmediate_operand")))]
4162 "TARGET_USE_VECTOR_FP_CONVERTS
4163 && optimize_insn_for_speed_p ()
4164 && reload_completed && SSE_REG_P (operands[0])"
4167 (float_truncate:V2SF
4171 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4172 operands[3] = CONST0_RTX (V2SFmode);
4173 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4174 /* Use movsd for loading from memory, unpcklpd for registers.
4175 Try to avoid move when unpacking can be done in source, or SSE3
4176 movddup is available. */
4177 if (REG_P (operands[1]))
4180 && true_regnum (operands[0]) != true_regnum (operands[1])
4181 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4182 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4184 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4185 emit_move_insn (tmp, operands[1]);
4188 else if (!TARGET_SSE3)
4189 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4190 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4193 emit_insn (gen_sse2_loadlpd (operands[4],
4194 CONST0_RTX (V2DFmode), operands[1]));
4197 ;; It's more profitable to split and then extend in the same register.
4199 [(set (match_operand:SF 0 "register_operand")
4201 (match_operand:DF 1 "memory_operand")))]
4202 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4203 && optimize_insn_for_speed_p ()
4204 && SSE_REG_P (operands[0])"
4205 [(set (match_dup 2) (match_dup 1))
4206 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4207 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4209 (define_expand "truncdfsf2_with_temp"
4210 [(parallel [(set (match_operand:SF 0)
4211 (float_truncate:SF (match_operand:DF 1)))
4212 (clobber (match_operand:SF 2))])])
4214 (define_insn "*truncdfsf_fast_mixed"
4215 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4217 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4218 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4220 switch (which_alternative)
4223 return output_387_reg_move (insn, operands);
4225 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4230 [(set_attr "type" "fmov,ssecvt")
4231 (set_attr "prefix" "orig,maybe_vex")
4232 (set_attr "mode" "SF")])
4234 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4235 ;; because nothing we do here is unsafe.
4236 (define_insn "*truncdfsf_fast_sse"
4237 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4239 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4240 "TARGET_SSE2 && TARGET_SSE_MATH"
4241 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4242 [(set_attr "type" "ssecvt")
4243 (set_attr "prefix" "maybe_vex")
4244 (set_attr "mode" "SF")])
4246 (define_insn "*truncdfsf_fast_i387"
4247 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4249 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4250 "TARGET_80387 && flag_unsafe_math_optimizations"
4251 "* return output_387_reg_move (insn, operands);"
4252 [(set_attr "type" "fmov")
4253 (set_attr "mode" "SF")])
4255 (define_insn "*truncdfsf_mixed"
4256 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4258 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4259 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4260 "TARGET_MIX_SSE_I387"
4262 switch (which_alternative)
4265 return output_387_reg_move (insn, operands);
4267 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4273 [(set_attr "isa" "*,sse2,*,*,*")
4274 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4275 (set_attr "unit" "*,*,i387,i387,i387")
4276 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4277 (set_attr "mode" "SF")])
4279 (define_insn "*truncdfsf_i387"
4280 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4282 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4283 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4286 switch (which_alternative)
4289 return output_387_reg_move (insn, operands);
4295 [(set_attr "type" "fmov,multi,multi,multi")
4296 (set_attr "unit" "*,i387,i387,i387")
4297 (set_attr "mode" "SF")])
4299 (define_insn "*truncdfsf2_i387_1"
4300 [(set (match_operand:SF 0 "memory_operand" "=m")
4302 (match_operand:DF 1 "register_operand" "f")))]
4304 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4305 && !TARGET_MIX_SSE_I387"
4306 "* return output_387_reg_move (insn, operands);"
4307 [(set_attr "type" "fmov")
4308 (set_attr "mode" "SF")])
4311 [(set (match_operand:SF 0 "register_operand")
4313 (match_operand:DF 1 "fp_register_operand")))
4314 (clobber (match_operand 2))]
4316 [(set (match_dup 2) (match_dup 1))
4317 (set (match_dup 0) (match_dup 2))]
4318 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4320 ;; Conversion from XFmode to {SF,DF}mode
4322 (define_expand "truncxf<mode>2"
4323 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4324 (float_truncate:MODEF
4325 (match_operand:XF 1 "register_operand")))
4326 (clobber (match_dup 2))])]
4329 if (flag_unsafe_math_optimizations)
4331 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4332 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4333 if (reg != operands[0])
4334 emit_move_insn (operands[0], reg);
4338 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4341 (define_insn "*truncxfsf2_mixed"
4342 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4344 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4345 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4348 gcc_assert (!which_alternative);
4349 return output_387_reg_move (insn, operands);
4351 [(set_attr "type" "fmov,multi,multi,multi")
4352 (set_attr "unit" "*,i387,i387,i387")
4353 (set_attr "mode" "SF")])
4355 (define_insn "*truncxfdf2_mixed"
4356 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4358 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4359 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4362 gcc_assert (!which_alternative);
4363 return output_387_reg_move (insn, operands);
4365 [(set_attr "isa" "*,*,sse2,*")
4366 (set_attr "type" "fmov,multi,multi,multi")
4367 (set_attr "unit" "*,i387,i387,i387")
4368 (set_attr "mode" "DF")])
4370 (define_insn "truncxf<mode>2_i387_noop"
4371 [(set (match_operand:MODEF 0 "register_operand" "=f")
4372 (float_truncate:MODEF
4373 (match_operand:XF 1 "register_operand" "f")))]
4374 "TARGET_80387 && flag_unsafe_math_optimizations"
4375 "* return output_387_reg_move (insn, operands);"
4376 [(set_attr "type" "fmov")
4377 (set_attr "mode" "<MODE>")])
4379 (define_insn "*truncxf<mode>2_i387"
4380 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4381 (float_truncate:MODEF
4382 (match_operand:XF 1 "register_operand" "f")))]
4384 "* return output_387_reg_move (insn, operands);"
4385 [(set_attr "type" "fmov")
4386 (set_attr "mode" "<MODE>")])
4389 [(set (match_operand:MODEF 0 "register_operand")
4390 (float_truncate:MODEF
4391 (match_operand:XF 1 "register_operand")))
4392 (clobber (match_operand:MODEF 2 "memory_operand"))]
4393 "TARGET_80387 && reload_completed"
4394 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4395 (set (match_dup 0) (match_dup 2))])
4398 [(set (match_operand:MODEF 0 "memory_operand")
4399 (float_truncate:MODEF
4400 (match_operand:XF 1 "register_operand")))
4401 (clobber (match_operand:MODEF 2 "memory_operand"))]
4403 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4405 ;; Signed conversion to DImode.
4407 (define_expand "fix_truncxfdi2"
4408 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4409 (fix:DI (match_operand:XF 1 "register_operand")))
4410 (clobber (reg:CC FLAGS_REG))])]
4415 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4420 (define_expand "fix_trunc<mode>di2"
4421 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4422 (fix:DI (match_operand:MODEF 1 "register_operand")))
4423 (clobber (reg:CC FLAGS_REG))])]
4424 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4427 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4429 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4432 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4434 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436 if (out != operands[0])
4437 emit_move_insn (operands[0], out);
4442 ;; Signed conversion to SImode.
4444 (define_expand "fix_truncxfsi2"
4445 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4446 (fix:SI (match_operand:XF 1 "register_operand")))
4447 (clobber (reg:CC FLAGS_REG))])]
4452 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4457 (define_expand "fix_trunc<mode>si2"
4458 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4459 (fix:SI (match_operand:MODEF 1 "register_operand")))
4460 (clobber (reg:CC FLAGS_REG))])]
4461 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4464 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4466 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4469 if (SSE_FLOAT_MODE_P (<MODE>mode))
4471 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473 if (out != operands[0])
4474 emit_move_insn (operands[0], out);
4479 ;; Signed conversion to HImode.
4481 (define_expand "fix_trunc<mode>hi2"
4482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4483 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4484 (clobber (reg:CC FLAGS_REG))])]
4486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4490 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4495 ;; Unsigned conversion to SImode.
4497 (define_expand "fixuns_trunc<mode>si2"
4499 [(set (match_operand:SI 0 "register_operand")
4501 (match_operand:MODEF 1 "nonimmediate_operand")))
4503 (clobber (match_scratch:<ssevecmode> 3))
4504 (clobber (match_scratch:<ssevecmode> 4))])]
4505 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4507 machine_mode mode = <MODE>mode;
4508 machine_mode vecmode = <ssevecmode>mode;
4509 REAL_VALUE_TYPE TWO31r;
4512 if (optimize_insn_for_size_p ())
4515 real_ldexp (&TWO31r, &dconst1, 31);
4516 two31 = const_double_from_real_value (TWO31r, mode);
4517 two31 = ix86_build_const_vector (vecmode, true, two31);
4518 operands[2] = force_reg (vecmode, two31);
4521 (define_insn_and_split "*fixuns_trunc<mode>_1"
4522 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4524 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4525 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4526 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4527 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4528 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4529 && optimize_function_for_speed_p (cfun)"
4531 "&& reload_completed"
4534 ix86_split_convert_uns_si_sse (operands);
4538 ;; Unsigned conversion to HImode.
4539 ;; Without these patterns, we'll try the unsigned SI conversion which
4540 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4542 (define_expand "fixuns_trunc<mode>hi2"
4544 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4545 (set (match_operand:HI 0 "nonimmediate_operand")
4546 (subreg:HI (match_dup 2) 0))]
4547 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4548 "operands[2] = gen_reg_rtx (SImode);")
4550 ;; When SSE is available, it is always faster to use it!
4551 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4552 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4553 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4554 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4555 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4556 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4557 [(set_attr "type" "sseicvt")
4558 (set_attr "prefix" "maybe_vex")
4559 (set (attr "prefix_rex")
4561 (match_test "<SWI48:MODE>mode == DImode")
4563 (const_string "*")))
4564 (set_attr "mode" "<MODEF:MODE>")
4565 (set_attr "athlon_decode" "double,vector")
4566 (set_attr "amdfam10_decode" "double,double")
4567 (set_attr "bdver1_decode" "double,double")])
4569 ;; Avoid vector decoded forms of the instruction.
4571 [(match_scratch:MODEF 2 "x")
4572 (set (match_operand:SWI48 0 "register_operand")
4573 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4574 "TARGET_AVOID_VECTOR_DECODE
4575 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4576 && optimize_insn_for_speed_p ()"
4577 [(set (match_dup 2) (match_dup 1))
4578 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4580 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4581 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4582 (fix:SWI248x (match_operand 1 "register_operand")))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4586 && (TARGET_64BIT || <MODE>mode != DImode))
4588 && can_create_pseudo_p ()"
4593 if (memory_operand (operands[0], VOIDmode))
4594 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4597 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4598 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4604 [(set_attr "type" "fisttp")
4605 (set_attr "mode" "<MODE>")])
4607 (define_insn "fix_trunc<mode>_i387_fisttp"
4608 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4609 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4610 (clobber (match_scratch:XF 2 "=&1f"))]
4611 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && (TARGET_64BIT || <MODE>mode != DImode))
4615 && TARGET_SSE_MATH)"
4616 "* return output_fix_trunc (insn, operands, true);"
4617 [(set_attr "type" "fisttp")
4618 (set_attr "mode" "<MODE>")])
4620 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4621 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4622 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4623 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4624 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4625 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4628 && (TARGET_64BIT || <MODE>mode != DImode))
4629 && TARGET_SSE_MATH)"
4631 [(set_attr "type" "fisttp")
4632 (set_attr "mode" "<MODE>")])
4635 [(set (match_operand:SWI248x 0 "register_operand")
4636 (fix:SWI248x (match_operand 1 "register_operand")))
4637 (clobber (match_operand:SWI248x 2 "memory_operand"))
4638 (clobber (match_scratch 3))]
4640 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4641 (clobber (match_dup 3))])
4642 (set (match_dup 0) (match_dup 2))])
4645 [(set (match_operand:SWI248x 0 "memory_operand")
4646 (fix:SWI248x (match_operand 1 "register_operand")))
4647 (clobber (match_operand:SWI248x 2 "memory_operand"))
4648 (clobber (match_scratch 3))]
4650 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4651 (clobber (match_dup 3))])])
4653 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4654 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4655 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4656 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4657 ;; function in i386.c.
4658 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4659 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4660 (fix:SWI248x (match_operand 1 "register_operand")))
4661 (clobber (reg:CC FLAGS_REG))]
4662 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4664 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4665 && (TARGET_64BIT || <MODE>mode != DImode))
4666 && can_create_pseudo_p ()"
4671 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4673 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4674 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4675 if (memory_operand (operands[0], VOIDmode))
4676 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4677 operands[2], operands[3]));
4680 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4681 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4682 operands[2], operands[3],
4687 [(set_attr "type" "fistp")
4688 (set_attr "i387_cw" "trunc")
4689 (set_attr "mode" "<MODE>")])
4691 (define_insn "fix_truncdi_i387"
4692 [(set (match_operand:DI 0 "memory_operand" "=m")
4693 (fix:DI (match_operand 1 "register_operand" "f")))
4694 (use (match_operand:HI 2 "memory_operand" "m"))
4695 (use (match_operand:HI 3 "memory_operand" "m"))
4696 (clobber (match_scratch:XF 4 "=&1f"))]
4697 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4699 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4700 "* return output_fix_trunc (insn, operands, false);"
4701 [(set_attr "type" "fistp")
4702 (set_attr "i387_cw" "trunc")
4703 (set_attr "mode" "DI")])
4705 (define_insn "fix_truncdi_i387_with_temp"
4706 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4707 (fix:DI (match_operand 1 "register_operand" "f,f")))
4708 (use (match_operand:HI 2 "memory_operand" "m,m"))
4709 (use (match_operand:HI 3 "memory_operand" "m,m"))
4710 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4711 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4712 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4714 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4716 [(set_attr "type" "fistp")
4717 (set_attr "i387_cw" "trunc")
4718 (set_attr "mode" "DI")])
4721 [(set (match_operand:DI 0 "register_operand")
4722 (fix:DI (match_operand 1 "register_operand")))
4723 (use (match_operand:HI 2 "memory_operand"))
4724 (use (match_operand:HI 3 "memory_operand"))
4725 (clobber (match_operand:DI 4 "memory_operand"))
4726 (clobber (match_scratch 5))]
4728 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4731 (clobber (match_dup 5))])
4732 (set (match_dup 0) (match_dup 4))])
4735 [(set (match_operand:DI 0 "memory_operand")
4736 (fix:DI (match_operand 1 "register_operand")))
4737 (use (match_operand:HI 2 "memory_operand"))
4738 (use (match_operand:HI 3 "memory_operand"))
4739 (clobber (match_operand:DI 4 "memory_operand"))
4740 (clobber (match_scratch 5))]
4742 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4745 (clobber (match_dup 5))])])
4747 (define_insn "fix_trunc<mode>_i387"
4748 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4749 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4750 (use (match_operand:HI 2 "memory_operand" "m"))
4751 (use (match_operand:HI 3 "memory_operand" "m"))]
4752 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4754 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4755 "* return output_fix_trunc (insn, operands, false);"
4756 [(set_attr "type" "fistp")
4757 (set_attr "i387_cw" "trunc")
4758 (set_attr "mode" "<MODE>")])
4760 (define_insn "fix_trunc<mode>_i387_with_temp"
4761 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4762 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4763 (use (match_operand:HI 2 "memory_operand" "m,m"))
4764 (use (match_operand:HI 3 "memory_operand" "m,m"))
4765 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4766 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4768 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4770 [(set_attr "type" "fistp")
4771 (set_attr "i387_cw" "trunc")
4772 (set_attr "mode" "<MODE>")])
4775 [(set (match_operand:SWI24 0 "register_operand")
4776 (fix:SWI24 (match_operand 1 "register_operand")))
4777 (use (match_operand:HI 2 "memory_operand"))
4778 (use (match_operand:HI 3 "memory_operand"))
4779 (clobber (match_operand:SWI24 4 "memory_operand"))]
4781 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4783 (use (match_dup 3))])
4784 (set (match_dup 0) (match_dup 4))])
4787 [(set (match_operand:SWI24 0 "memory_operand")
4788 (fix:SWI24 (match_operand 1 "register_operand")))
4789 (use (match_operand:HI 2 "memory_operand"))
4790 (use (match_operand:HI 3 "memory_operand"))
4791 (clobber (match_operand:SWI24 4 "memory_operand"))]
4793 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4795 (use (match_dup 3))])])
4797 (define_insn "x86_fnstcw_1"
4798 [(set (match_operand:HI 0 "memory_operand" "=m")
4799 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4802 [(set (attr "length")
4803 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4804 (set_attr "mode" "HI")
4805 (set_attr "unit" "i387")
4806 (set_attr "bdver1_decode" "vector")])
4808 (define_insn "x86_fldcw_1"
4809 [(set (reg:HI FPCR_REG)
4810 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4813 [(set (attr "length")
4814 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4815 (set_attr "mode" "HI")
4816 (set_attr "unit" "i387")
4817 (set_attr "athlon_decode" "vector")
4818 (set_attr "amdfam10_decode" "vector")
4819 (set_attr "bdver1_decode" "vector")])
4821 ;; Conversion between fixed point and floating point.
4823 ;; Even though we only accept memory inputs, the backend _really_
4824 ;; wants to be able to do this between registers. Thankfully, LRA
4825 ;; will fix this up for us during register allocation.
4827 (define_insn "floathi<mode>2"
4828 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4829 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4832 || TARGET_MIX_SSE_I387)"
4834 [(set_attr "type" "fmov")
4835 (set_attr "mode" "<MODE>")
4836 (set_attr "fp_int_src" "true")])
4838 (define_insn "float<SWI48x:mode>xf2"
4839 [(set (match_operand:XF 0 "register_operand" "=f")
4840 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4843 [(set_attr "type" "fmov")
4844 (set_attr "mode" "XF")
4845 (set_attr "fp_int_src" "true")])
4847 (define_expand "float<SWI48:mode><MODEF:mode>2"
4848 [(set (match_operand:MODEF 0 "register_operand")
4849 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4850 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4852 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4853 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4855 rtx reg = gen_reg_rtx (XFmode);
4856 rtx (*insn)(rtx, rtx);
4858 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4860 if (<MODEF:MODE>mode == SFmode)
4861 insn = gen_truncxfsf2;
4862 else if (<MODEF:MODE>mode == DFmode)
4863 insn = gen_truncxfdf2;
4867 emit_insn (insn (operands[0], reg));
4872 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4873 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4875 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4876 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4879 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4880 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4881 [(set_attr "type" "fmov,sseicvt,sseicvt")
4882 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4883 (set_attr "mode" "<MODEF:MODE>")
4884 (set (attr "prefix_rex")
4886 (and (eq_attr "prefix" "maybe_vex")
4887 (match_test "<SWI48:MODE>mode == DImode"))
4889 (const_string "*")))
4890 (set_attr "unit" "i387,*,*")
4891 (set_attr "athlon_decode" "*,double,direct")
4892 (set_attr "amdfam10_decode" "*,vector,double")
4893 (set_attr "bdver1_decode" "*,double,direct")
4894 (set_attr "fp_int_src" "true")
4895 (set (attr "enabled")
4896 (cond [(eq_attr "alternative" "0")
4897 (symbol_ref "TARGET_MIX_SSE_I387
4898 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4901 (symbol_ref "true")))
4902 (set (attr "preferred_for_speed")
4903 (cond [(eq_attr "alternative" "1")
4904 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4905 (symbol_ref "true")))])
4907 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4908 [(set (match_operand:MODEF 0 "register_operand" "=f")
4909 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4910 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4912 [(set_attr "type" "fmov")
4913 (set_attr "mode" "<MODEF:MODE>")
4914 (set_attr "fp_int_src" "true")])
4916 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4917 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4918 ;; alternative in sse2_loadld.
4920 [(set (match_operand:MODEF 0 "register_operand")
4921 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4922 "TARGET_SSE2 && TARGET_SSE_MATH
4923 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4924 && reload_completed && SSE_REG_P (operands[0])
4925 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4928 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4930 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4932 emit_insn (gen_sse2_loadld (operands[4],
4933 CONST0_RTX (V4SImode), operands[1]));
4935 if (<ssevecmode>mode == V4SFmode)
4936 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4938 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4942 ;; Avoid partial SSE register dependency stalls
4944 [(set (match_operand:MODEF 0 "register_operand")
4945 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4946 "TARGET_SSE2 && TARGET_SSE_MATH
4947 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4948 && optimize_function_for_speed_p (cfun)
4949 && reload_completed && SSE_REG_P (operands[0])"
4952 const machine_mode vmode = <MODEF:ssevecmode>mode;
4953 const machine_mode mode = <MODEF:MODE>mode;
4954 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4956 emit_move_insn (op0, CONST0_RTX (vmode));
4958 t = gen_rtx_FLOAT (mode, operands[1]);
4959 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4960 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4961 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4965 ;; Break partial reg stall for cvtsd2ss.
4968 [(set (match_operand:SF 0 "register_operand")
4970 (match_operand:DF 1 "nonimmediate_operand")))]
4971 "TARGET_SSE2 && TARGET_SSE_MATH
4972 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4973 && optimize_function_for_speed_p (cfun)
4974 && SSE_REG_P (operands[0])
4975 && (!SSE_REG_P (operands[1])
4976 || REGNO (operands[0]) != REGNO (operands[1]))"
4980 (float_truncate:V2SF
4985 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4987 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4989 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4992 ;; Break partial reg stall for cvtss2sd.
4995 [(set (match_operand:DF 0 "register_operand")
4997 (match_operand:SF 1 "nonimmediate_operand")))]
4998 "TARGET_SSE2 && TARGET_SSE_MATH
4999 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5000 && optimize_function_for_speed_p (cfun)
5001 && SSE_REG_P (operands[0])
5002 && (!SSE_REG_P (operands[1])
5003 || REGNO (operands[0]) != REGNO (operands[1]))"
5009 (parallel [(const_int 0) (const_int 1)])))
5013 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5015 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5017 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5020 ;; Avoid store forwarding (partial memory) stall penalty
5021 ;; by passing DImode value through XMM registers. */
5023 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5024 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5026 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5027 (clobber (match_scratch:V4SI 3 "=X,x"))
5028 (clobber (match_scratch:V4SI 4 "=X,x"))
5029 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5030 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5031 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5032 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5034 [(set_attr "type" "multi")
5035 (set_attr "mode" "<X87MODEF:MODE>")
5036 (set_attr "unit" "i387")
5037 (set_attr "fp_int_src" "true")])
5040 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5041 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5042 (clobber (match_scratch:V4SI 3))
5043 (clobber (match_scratch:V4SI 4))
5044 (clobber (match_operand:DI 2 "memory_operand"))]
5045 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5046 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5047 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5048 && reload_completed"
5049 [(set (match_dup 2) (match_dup 3))
5050 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5052 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5053 Assemble the 64-bit DImode value in an xmm register. */
5054 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5055 gen_lowpart (SImode, operands[1])));
5056 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5057 gen_highpart (SImode, operands[1])));
5058 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5061 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5065 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5066 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5067 (clobber (match_scratch:V4SI 3))
5068 (clobber (match_scratch:V4SI 4))
5069 (clobber (match_operand:DI 2 "memory_operand"))]
5070 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5071 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5072 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5073 && reload_completed"
5074 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5076 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5077 [(set (match_operand:MODEF 0 "register_operand")
5078 (unsigned_float:MODEF
5079 (match_operand:SWI12 1 "nonimmediate_operand")))]
5081 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5083 operands[1] = convert_to_mode (SImode, operands[1], 1);
5084 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5088 ;; Avoid store forwarding (partial memory) stall penalty by extending
5089 ;; SImode value to DImode through XMM register instead of pushing two
5090 ;; SImode values to stack. Also note that fild loads from memory only.
5092 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5093 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5094 (unsigned_float:X87MODEF
5095 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5096 (clobber (match_scratch:DI 3 "=x"))
5097 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5099 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5100 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5102 "&& reload_completed"
5103 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5104 (set (match_dup 2) (match_dup 3))
5106 (float:X87MODEF (match_dup 2)))]
5108 [(set_attr "type" "multi")
5109 (set_attr "mode" "<MODE>")])
5111 (define_expand "floatunssi<mode>2"
5113 [(set (match_operand:X87MODEF 0 "register_operand")
5114 (unsigned_float:X87MODEF
5115 (match_operand:SI 1 "nonimmediate_operand")))
5116 (clobber (match_scratch:DI 3))
5117 (clobber (match_dup 2))])]
5119 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5120 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5121 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5123 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5125 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5129 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5132 (define_expand "floatunsdisf2"
5133 [(use (match_operand:SF 0 "register_operand"))
5134 (use (match_operand:DI 1 "nonimmediate_operand"))]
5135 "TARGET_64BIT && TARGET_SSE_MATH"
5136 "x86_emit_floatuns (operands); DONE;")
5138 (define_expand "floatunsdidf2"
5139 [(use (match_operand:DF 0 "register_operand"))
5140 (use (match_operand:DI 1 "nonimmediate_operand"))]
5141 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5142 && TARGET_SSE2 && TARGET_SSE_MATH"
5145 x86_emit_floatuns (operands);
5147 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5151 ;; Load effective address instructions
5153 (define_insn_and_split "*lea<mode>"
5154 [(set (match_operand:SWI48 0 "register_operand" "=r")
5155 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5158 if (SImode_address_operand (operands[1], VOIDmode))
5160 gcc_assert (TARGET_64BIT);
5161 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5164 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5166 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5169 machine_mode mode = <MODE>mode;
5172 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5173 change operands[] array behind our back. */
5174 pat = PATTERN (curr_insn);
5176 operands[0] = SET_DEST (pat);
5177 operands[1] = SET_SRC (pat);
5179 /* Emit all operations in SImode for zero-extended addresses. */
5180 if (SImode_address_operand (operands[1], VOIDmode))
5183 ix86_split_lea_for_addr (curr_insn, operands, mode);
5185 /* Zero-extend return register to DImode for zero-extended addresses. */
5186 if (mode != <MODE>mode)
5187 emit_insn (gen_zero_extendsidi2
5188 (operands[0], gen_lowpart (mode, operands[0])));
5192 [(set_attr "type" "lea")
5195 (match_operand 1 "SImode_address_operand")
5197 (const_string "<MODE>")))])
5201 (define_expand "add<mode>3"
5202 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5203 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5204 (match_operand:SDWIM 2 "<general_operand>")))]
5206 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5208 (define_insn_and_split "*add<dwi>3_doubleword"
5209 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5211 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5212 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5213 (clobber (reg:CC FLAGS_REG))]
5214 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5217 [(parallel [(set (reg:CCC FLAGS_REG)
5219 (plus:DWIH (match_dup 1) (match_dup 2))
5222 (plus:DWIH (match_dup 1) (match_dup 2)))])
5223 (parallel [(set (match_dup 3)
5226 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5229 (clobber (reg:CC FLAGS_REG))])]
5230 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5232 (define_insn "*add<mode>_1"
5233 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5235 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5236 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5237 (clobber (reg:CC FLAGS_REG))]
5238 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5240 switch (get_attr_type (insn))
5246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247 if (operands[2] == const1_rtx)
5248 return "inc{<imodesuffix>}\t%0";
5251 gcc_assert (operands[2] == constm1_rtx);
5252 return "dec{<imodesuffix>}\t%0";
5256 /* For most processors, ADD is faster than LEA. This alternative
5257 was added to use ADD as much as possible. */
5258 if (which_alternative == 2)
5259 std::swap (operands[1], operands[2]);
5261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5263 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5265 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5269 (cond [(eq_attr "alternative" "3")
5270 (const_string "lea")
5271 (match_operand:SWI48 2 "incdec_operand")
5272 (const_string "incdec")
5274 (const_string "alu")))
5275 (set (attr "length_immediate")
5277 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5279 (const_string "*")))
5280 (set_attr "mode" "<MODE>")])
5282 ;; It may seem that nonimmediate operand is proper one for operand 1.
5283 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5284 ;; we take care in ix86_binary_operator_ok to not allow two memory
5285 ;; operands so proper swapping will be done in reload. This allow
5286 ;; patterns constructed from addsi_1 to match.
5288 (define_insn "addsi_1_zext"
5289 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5291 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5292 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5293 (clobber (reg:CC FLAGS_REG))]
5294 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5296 switch (get_attr_type (insn))
5302 if (operands[2] == const1_rtx)
5303 return "inc{l}\t%k0";
5306 gcc_assert (operands[2] == constm1_rtx);
5307 return "dec{l}\t%k0";
5311 /* For most processors, ADD is faster than LEA. This alternative
5312 was added to use ADD as much as possible. */
5313 if (which_alternative == 1)
5314 std::swap (operands[1], operands[2]);
5316 if (x86_maybe_negate_const_int (&operands[2], SImode))
5317 return "sub{l}\t{%2, %k0|%k0, %2}";
5319 return "add{l}\t{%2, %k0|%k0, %2}";
5323 (cond [(eq_attr "alternative" "2")
5324 (const_string "lea")
5325 (match_operand:SI 2 "incdec_operand")
5326 (const_string "incdec")
5328 (const_string "alu")))
5329 (set (attr "length_immediate")
5331 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5333 (const_string "*")))
5334 (set_attr "mode" "SI")])
5336 (define_insn "*addhi_1"
5337 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5338 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5339 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5340 (clobber (reg:CC FLAGS_REG))]
5341 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5343 switch (get_attr_type (insn))
5349 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5350 if (operands[2] == const1_rtx)
5351 return "inc{w}\t%0";
5354 gcc_assert (operands[2] == constm1_rtx);
5355 return "dec{w}\t%0";
5359 /* For most processors, ADD is faster than LEA. This alternative
5360 was added to use ADD as much as possible. */
5361 if (which_alternative == 2)
5362 std::swap (operands[1], operands[2]);
5364 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5365 if (x86_maybe_negate_const_int (&operands[2], HImode))
5366 return "sub{w}\t{%2, %0|%0, %2}";
5368 return "add{w}\t{%2, %0|%0, %2}";
5372 (cond [(eq_attr "alternative" "3")
5373 (const_string "lea")
5374 (match_operand:HI 2 "incdec_operand")
5375 (const_string "incdec")
5377 (const_string "alu")))
5378 (set (attr "length_immediate")
5380 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5382 (const_string "*")))
5383 (set_attr "mode" "HI,HI,HI,SI")])
5385 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5386 (define_insn "*addqi_1"
5387 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5388 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5389 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5390 (clobber (reg:CC FLAGS_REG))]
5391 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5393 bool widen = (which_alternative == 3 || which_alternative == 4);
5395 switch (get_attr_type (insn))
5401 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402 if (operands[2] == const1_rtx)
5403 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5406 gcc_assert (operands[2] == constm1_rtx);
5407 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5411 /* For most processors, ADD is faster than LEA. These alternatives
5412 were added to use ADD as much as possible. */
5413 if (which_alternative == 2 || which_alternative == 4)
5414 std::swap (operands[1], operands[2]);
5416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417 if (x86_maybe_negate_const_int (&operands[2], QImode))
5420 return "sub{l}\t{%2, %k0|%k0, %2}";
5422 return "sub{b}\t{%2, %0|%0, %2}";
5425 return "add{l}\t{%k2, %k0|%k0, %k2}";
5427 return "add{b}\t{%2, %0|%0, %2}";
5431 (cond [(eq_attr "alternative" "5")
5432 (const_string "lea")
5433 (match_operand:QI 2 "incdec_operand")
5434 (const_string "incdec")
5436 (const_string "alu")))
5437 (set (attr "length_immediate")
5439 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5441 (const_string "*")))
5442 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5444 (define_insn "*addqi_1_slp"
5445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5446 (plus:QI (match_dup 0)
5447 (match_operand:QI 1 "general_operand" "qn,qm")))
5448 (clobber (reg:CC FLAGS_REG))]
5449 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5452 switch (get_attr_type (insn))
5455 if (operands[1] == const1_rtx)
5456 return "inc{b}\t%0";
5459 gcc_assert (operands[1] == constm1_rtx);
5460 return "dec{b}\t%0";
5464 if (x86_maybe_negate_const_int (&operands[1], QImode))
5465 return "sub{b}\t{%1, %0|%0, %1}";
5467 return "add{b}\t{%1, %0|%0, %1}";
5471 (if_then_else (match_operand:QI 1 "incdec_operand")
5472 (const_string "incdec")
5473 (const_string "alu1")))
5474 (set (attr "memory")
5475 (if_then_else (match_operand 1 "memory_operand")
5476 (const_string "load")
5477 (const_string "none")))
5478 (set_attr "mode" "QI")])
5480 ;; Split non destructive adds if we cannot use lea.
5482 [(set (match_operand:SWI48 0 "register_operand")
5483 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5484 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5485 (clobber (reg:CC FLAGS_REG))]
5486 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5487 [(set (match_dup 0) (match_dup 1))
5488 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5489 (clobber (reg:CC FLAGS_REG))])])
5491 ;; Convert add to the lea pattern to avoid flags dependency.
5493 [(set (match_operand:SWI 0 "register_operand")
5494 (plus:SWI (match_operand:SWI 1 "register_operand")
5495 (match_operand:SWI 2 "<nonmemory_operand>")))
5496 (clobber (reg:CC FLAGS_REG))]
5497 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5500 machine_mode mode = <MODE>mode;
5503 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5506 operands[0] = gen_lowpart (mode, operands[0]);
5507 operands[1] = gen_lowpart (mode, operands[1]);
5508 operands[2] = gen_lowpart (mode, operands[2]);
5511 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5513 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5517 ;; Split non destructive adds if we cannot use lea.
5519 [(set (match_operand:DI 0 "register_operand")
5521 (plus:SI (match_operand:SI 1 "register_operand")
5522 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5523 (clobber (reg:CC FLAGS_REG))]
5525 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5526 [(set (match_dup 3) (match_dup 1))
5527 (parallel [(set (match_dup 0)
5528 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5529 (clobber (reg:CC FLAGS_REG))])]
5530 "operands[3] = gen_lowpart (SImode, operands[0]);")
5532 ;; Convert add to the lea pattern to avoid flags dependency.
5534 [(set (match_operand:DI 0 "register_operand")
5536 (plus:SI (match_operand:SI 1 "register_operand")
5537 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5538 (clobber (reg:CC FLAGS_REG))]
5539 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5541 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5543 (define_insn "*add<mode>_2"
5544 [(set (reg FLAGS_REG)
5547 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5548 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5550 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5551 (plus:SWI (match_dup 1) (match_dup 2)))]
5552 "ix86_match_ccmode (insn, CCGOCmode)
5553 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5555 switch (get_attr_type (insn))
5558 if (operands[2] == const1_rtx)
5559 return "inc{<imodesuffix>}\t%0";
5562 gcc_assert (operands[2] == constm1_rtx);
5563 return "dec{<imodesuffix>}\t%0";
5567 if (which_alternative == 2)
5568 std::swap (operands[1], operands[2]);
5570 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5571 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5572 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5574 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5578 (if_then_else (match_operand:SWI 2 "incdec_operand")
5579 (const_string "incdec")
5580 (const_string "alu")))
5581 (set (attr "length_immediate")
5583 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5585 (const_string "*")))
5586 (set_attr "mode" "<MODE>")])
5588 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5589 (define_insn "*addsi_2_zext"
5590 [(set (reg FLAGS_REG)
5592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5593 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5595 (set (match_operand:DI 0 "register_operand" "=r,r")
5596 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5598 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5600 switch (get_attr_type (insn))
5603 if (operands[2] == const1_rtx)
5604 return "inc{l}\t%k0";
5607 gcc_assert (operands[2] == constm1_rtx);
5608 return "dec{l}\t%k0";
5612 if (which_alternative == 1)
5613 std::swap (operands[1], operands[2]);
5615 if (x86_maybe_negate_const_int (&operands[2], SImode))
5616 return "sub{l}\t{%2, %k0|%k0, %2}";
5618 return "add{l}\t{%2, %k0|%k0, %2}";
5622 (if_then_else (match_operand:SI 2 "incdec_operand")
5623 (const_string "incdec")
5624 (const_string "alu")))
5625 (set (attr "length_immediate")
5627 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5629 (const_string "*")))
5630 (set_attr "mode" "SI")])
5632 (define_insn "*add<mode>_3"
5633 [(set (reg FLAGS_REG)
5635 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5636 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5637 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5638 "ix86_match_ccmode (insn, CCZmode)
5639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5641 switch (get_attr_type (insn))
5644 if (operands[2] == const1_rtx)
5645 return "inc{<imodesuffix>}\t%0";
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{<imodesuffix>}\t%0";
5653 if (which_alternative == 1)
5654 std::swap (operands[1], operands[2]);
5656 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5658 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5660 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5664 (if_then_else (match_operand:SWI 2 "incdec_operand")
5665 (const_string "incdec")
5666 (const_string "alu")))
5667 (set (attr "length_immediate")
5669 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5671 (const_string "*")))
5672 (set_attr "mode" "<MODE>")])
5674 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5675 (define_insn "*addsi_3_zext"
5676 [(set (reg FLAGS_REG)
5678 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5679 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5680 (set (match_operand:DI 0 "register_operand" "=r,r")
5681 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5682 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5683 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5685 switch (get_attr_type (insn))
5688 if (operands[2] == const1_rtx)
5689 return "inc{l}\t%k0";
5692 gcc_assert (operands[2] == constm1_rtx);
5693 return "dec{l}\t%k0";
5697 if (which_alternative == 1)
5698 std::swap (operands[1], operands[2]);
5700 if (x86_maybe_negate_const_int (&operands[2], SImode))
5701 return "sub{l}\t{%2, %k0|%k0, %2}";
5703 return "add{l}\t{%2, %k0|%k0, %2}";
5707 (if_then_else (match_operand:SI 2 "incdec_operand")
5708 (const_string "incdec")
5709 (const_string "alu")))
5710 (set (attr "length_immediate")
5712 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5714 (const_string "*")))
5715 (set_attr "mode" "SI")])
5717 ; For comparisons against 1, -1 and 128, we may generate better code
5718 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5719 ; is matched then. We can't accept general immediate, because for
5720 ; case of overflows, the result is messed up.
5721 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5722 ; only for comparisons not depending on it.
5724 (define_insn "*adddi_4"
5725 [(set (reg FLAGS_REG)
5727 (match_operand:DI 1 "nonimmediate_operand" "0")
5728 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5729 (clobber (match_scratch:DI 0 "=rm"))]
5731 && ix86_match_ccmode (insn, CCGCmode)"
5733 switch (get_attr_type (insn))
5736 if (operands[2] == constm1_rtx)
5737 return "inc{q}\t%0";
5740 gcc_assert (operands[2] == const1_rtx);
5741 return "dec{q}\t%0";
5745 if (x86_maybe_negate_const_int (&operands[2], DImode))
5746 return "add{q}\t{%2, %0|%0, %2}";
5748 return "sub{q}\t{%2, %0|%0, %2}";
5752 (if_then_else (match_operand:DI 2 "incdec_operand")
5753 (const_string "incdec")
5754 (const_string "alu")))
5755 (set (attr "length_immediate")
5757 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5759 (const_string "*")))
5760 (set_attr "mode" "DI")])
5762 ; For comparisons against 1, -1 and 128, we may generate better code
5763 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5764 ; is matched then. We can't accept general immediate, because for
5765 ; case of overflows, the result is messed up.
5766 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5767 ; only for comparisons not depending on it.
5769 (define_insn "*add<mode>_4"
5770 [(set (reg FLAGS_REG)
5772 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5773 (match_operand:SWI124 2 "const_int_operand" "n")))
5774 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5775 "ix86_match_ccmode (insn, CCGCmode)"
5777 switch (get_attr_type (insn))
5780 if (operands[2] == constm1_rtx)
5781 return "inc{<imodesuffix>}\t%0";
5784 gcc_assert (operands[2] == const1_rtx);
5785 return "dec{<imodesuffix>}\t%0";
5789 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5790 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5792 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5796 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5797 (const_string "incdec")
5798 (const_string "alu")))
5799 (set (attr "length_immediate")
5801 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5803 (const_string "*")))
5804 (set_attr "mode" "<MODE>")])
5806 (define_insn "*add<mode>_5"
5807 [(set (reg FLAGS_REG)
5810 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5811 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5813 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5814 "ix86_match_ccmode (insn, CCGOCmode)
5815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5817 switch (get_attr_type (insn))
5820 if (operands[2] == const1_rtx)
5821 return "inc{<imodesuffix>}\t%0";
5824 gcc_assert (operands[2] == constm1_rtx);
5825 return "dec{<imodesuffix>}\t%0";
5829 if (which_alternative == 1)
5830 std::swap (operands[1], operands[2]);
5832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5834 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5836 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5840 (if_then_else (match_operand:SWI 2 "incdec_operand")
5841 (const_string "incdec")
5842 (const_string "alu")))
5843 (set (attr "length_immediate")
5845 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5847 (const_string "*")))
5848 (set_attr "mode" "<MODE>")])
5850 (define_insn "addqi_ext_1"
5851 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5856 (match_operand 1 "ext_register_operand" "0,0")
5859 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5860 (clobber (reg:CC FLAGS_REG))]
5863 switch (get_attr_type (insn))
5866 if (operands[2] == const1_rtx)
5867 return "inc{b}\t%h0";
5870 gcc_assert (operands[2] == constm1_rtx);
5871 return "dec{b}\t%h0";
5875 return "add{b}\t{%2, %h0|%h0, %2}";
5878 [(set_attr "isa" "*,nox64")
5880 (if_then_else (match_operand:QI 2 "incdec_operand")
5881 (const_string "incdec")
5882 (const_string "alu")))
5883 (set_attr "modrm" "1")
5884 (set_attr "mode" "QI")])
5886 (define_insn "*addqi_ext_2"
5887 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5892 (match_operand 1 "ext_register_operand" "%0")
5896 (match_operand 2 "ext_register_operand" "Q")
5899 (clobber (reg:CC FLAGS_REG))]
5901 "add{b}\t{%h2, %h0|%h0, %h2}"
5902 [(set_attr "type" "alu")
5903 (set_attr "mode" "QI")])
5905 ;; Add with jump on overflow.
5906 (define_expand "addv<mode>4"
5907 [(parallel [(set (reg:CCO FLAGS_REG)
5910 (match_operand:SWI 1 "nonimmediate_operand"))
5913 (plus:SWI (match_dup 1)
5914 (match_operand:SWI 2
5915 "<general_operand>")))))
5916 (set (match_operand:SWI 0 "register_operand")
5917 (plus:SWI (match_dup 1) (match_dup 2)))])
5918 (set (pc) (if_then_else
5919 (eq (reg:CCO FLAGS_REG) (const_int 0))
5920 (label_ref (match_operand 3))
5924 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5925 if (CONST_INT_P (operands[2]))
5926 operands[4] = operands[2];
5928 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5931 (define_insn "*addv<mode>4"
5932 [(set (reg:CCO FLAGS_REG)
5935 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5937 (match_operand:SWI 2 "<general_sext_operand>"
5940 (plus:SWI (match_dup 1) (match_dup 2)))))
5941 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5942 (plus:SWI (match_dup 1) (match_dup 2)))]
5943 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5944 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5945 [(set_attr "type" "alu")
5946 (set_attr "mode" "<MODE>")])
5948 (define_insn "*addv<mode>4_1"
5949 [(set (reg:CCO FLAGS_REG)
5952 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5953 (match_operand:<DWI> 3 "const_int_operand" "i"))
5955 (plus:SWI (match_dup 1)
5956 (match_operand:SWI 2 "x86_64_immediate_operand"
5958 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5959 (plus:SWI (match_dup 1) (match_dup 2)))]
5960 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5961 && CONST_INT_P (operands[2])
5962 && INTVAL (operands[2]) == INTVAL (operands[3])"
5963 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5964 [(set_attr "type" "alu")
5965 (set_attr "mode" "<MODE>")
5966 (set (attr "length_immediate")
5967 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5969 (match_test "<MODE_SIZE> == 8")
5971 (const_string "<MODE_SIZE>")))])
5973 ;; The lea patterns for modes less than 32 bits need to be matched by
5974 ;; several insns converted to real lea by splitters.
5976 (define_insn_and_split "*lea_general_1"
5977 [(set (match_operand 0 "register_operand" "=r")
5978 (plus (plus (match_operand 1 "index_register_operand" "l")
5979 (match_operand 2 "register_operand" "r"))
5980 (match_operand 3 "immediate_operand" "i")))]
5981 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5982 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5983 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5984 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5985 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5986 || GET_MODE (operands[3]) == VOIDmode)"
5988 "&& reload_completed"
5991 machine_mode mode = SImode;
5994 operands[0] = gen_lowpart (mode, operands[0]);
5995 operands[1] = gen_lowpart (mode, operands[1]);
5996 operands[2] = gen_lowpart (mode, operands[2]);
5997 operands[3] = gen_lowpart (mode, operands[3]);
5999 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6002 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6005 [(set_attr "type" "lea")
6006 (set_attr "mode" "SI")])
6008 (define_insn_and_split "*lea_general_2"
6009 [(set (match_operand 0 "register_operand" "=r")
6010 (plus (mult (match_operand 1 "index_register_operand" "l")
6011 (match_operand 2 "const248_operand" "n"))
6012 (match_operand 3 "nonmemory_operand" "ri")))]
6013 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6014 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6015 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6016 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6017 || GET_MODE (operands[3]) == VOIDmode)"
6019 "&& reload_completed"
6022 machine_mode mode = SImode;
6025 operands[0] = gen_lowpart (mode, operands[0]);
6026 operands[1] = gen_lowpart (mode, operands[1]);
6027 operands[3] = gen_lowpart (mode, operands[3]);
6029 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6032 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6035 [(set_attr "type" "lea")
6036 (set_attr "mode" "SI")])
6038 (define_insn_and_split "*lea_general_3"
6039 [(set (match_operand 0 "register_operand" "=r")
6040 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6041 (match_operand 2 "const248_operand" "n"))
6042 (match_operand 3 "register_operand" "r"))
6043 (match_operand 4 "immediate_operand" "i")))]
6044 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6045 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6046 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6047 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6049 "&& reload_completed"
6052 machine_mode mode = SImode;
6055 operands[0] = gen_lowpart (mode, operands[0]);
6056 operands[1] = gen_lowpart (mode, operands[1]);
6057 operands[3] = gen_lowpart (mode, operands[3]);
6058 operands[4] = gen_lowpart (mode, operands[4]);
6060 pat = gen_rtx_PLUS (mode,
6062 gen_rtx_MULT (mode, operands[1],
6067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6070 [(set_attr "type" "lea")
6071 (set_attr "mode" "SI")])
6073 (define_insn_and_split "*lea_general_4"
6074 [(set (match_operand 0 "register_operand" "=r")
6076 (match_operand 1 "index_register_operand" "l")
6077 (match_operand 2 "const_int_operand" "n"))
6078 (match_operand 3 "const_int_operand" "n")))]
6079 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6080 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6081 || GET_MODE (operands[0]) == SImode
6082 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6083 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6084 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6085 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6086 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6088 "&& reload_completed"
6091 machine_mode mode = GET_MODE (operands[0]);
6094 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6097 operands[0] = gen_lowpart (mode, operands[0]);
6098 operands[1] = gen_lowpart (mode, operands[1]);
6101 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6103 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6104 INTVAL (operands[3]));
6106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6109 [(set_attr "type" "lea")
6111 (if_then_else (match_operand:DI 0)
6113 (const_string "SI")))])
6115 ;; Subtract instructions
6117 (define_expand "sub<mode>3"
6118 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6119 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6120 (match_operand:SDWIM 2 "<general_operand>")))]
6122 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6124 (define_insn_and_split "*sub<dwi>3_doubleword"
6125 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6127 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6128 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6129 (clobber (reg:CC FLAGS_REG))]
6130 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6133 [(parallel [(set (reg:CC FLAGS_REG)
6134 (compare:CC (match_dup 1) (match_dup 2)))
6136 (minus:DWIH (match_dup 1) (match_dup 2)))])
6137 (parallel [(set (match_dup 3)
6141 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6143 (clobber (reg:CC FLAGS_REG))])]
6144 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6146 (define_insn "*sub<mode>_1"
6147 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6149 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6150 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6151 (clobber (reg:CC FLAGS_REG))]
6152 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6153 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6154 [(set_attr "type" "alu")
6155 (set_attr "mode" "<MODE>")])
6157 (define_insn "*subsi_1_zext"
6158 [(set (match_operand:DI 0 "register_operand" "=r")
6160 (minus:SI (match_operand:SI 1 "register_operand" "0")
6161 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6162 (clobber (reg:CC FLAGS_REG))]
6163 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6164 "sub{l}\t{%2, %k0|%k0, %2}"
6165 [(set_attr "type" "alu")
6166 (set_attr "mode" "SI")])
6168 (define_insn "*subqi_1_slp"
6169 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6170 (minus:QI (match_dup 0)
6171 (match_operand:QI 1 "general_operand" "qn,qm")))
6172 (clobber (reg:CC FLAGS_REG))]
6173 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6175 "sub{b}\t{%1, %0|%0, %1}"
6176 [(set_attr "type" "alu1")
6177 (set_attr "mode" "QI")])
6179 (define_insn "*sub<mode>_2"
6180 [(set (reg FLAGS_REG)
6183 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6184 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6186 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6187 (minus:SWI (match_dup 1) (match_dup 2)))]
6188 "ix86_match_ccmode (insn, CCGOCmode)
6189 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6190 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6191 [(set_attr "type" "alu")
6192 (set_attr "mode" "<MODE>")])
6194 (define_insn "*subsi_2_zext"
6195 [(set (reg FLAGS_REG)
6197 (minus:SI (match_operand:SI 1 "register_operand" "0")
6198 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6200 (set (match_operand:DI 0 "register_operand" "=r")
6202 (minus:SI (match_dup 1)
6204 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6205 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6206 "sub{l}\t{%2, %k0|%k0, %2}"
6207 [(set_attr "type" "alu")
6208 (set_attr "mode" "SI")])
6210 ;; Subtract with jump on overflow.
6211 (define_expand "subv<mode>4"
6212 [(parallel [(set (reg:CCO FLAGS_REG)
6213 (eq:CCO (minus:<DWI>
6215 (match_operand:SWI 1 "nonimmediate_operand"))
6218 (minus:SWI (match_dup 1)
6219 (match_operand:SWI 2
6220 "<general_operand>")))))
6221 (set (match_operand:SWI 0 "register_operand")
6222 (minus:SWI (match_dup 1) (match_dup 2)))])
6223 (set (pc) (if_then_else
6224 (eq (reg:CCO FLAGS_REG) (const_int 0))
6225 (label_ref (match_operand 3))
6229 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6230 if (CONST_INT_P (operands[2]))
6231 operands[4] = operands[2];
6233 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6236 (define_insn "*subv<mode>4"
6237 [(set (reg:CCO FLAGS_REG)
6238 (eq:CCO (minus:<DWI>
6240 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6242 (match_operand:SWI 2 "<general_sext_operand>"
6245 (minus:SWI (match_dup 1) (match_dup 2)))))
6246 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6247 (minus:SWI (match_dup 1) (match_dup 2)))]
6248 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6249 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6250 [(set_attr "type" "alu")
6251 (set_attr "mode" "<MODE>")])
6253 (define_insn "*subv<mode>4_1"
6254 [(set (reg:CCO FLAGS_REG)
6255 (eq:CCO (minus:<DWI>
6257 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6258 (match_operand:<DWI> 3 "const_int_operand" "i"))
6260 (minus:SWI (match_dup 1)
6261 (match_operand:SWI 2 "x86_64_immediate_operand"
6263 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6264 (minus:SWI (match_dup 1) (match_dup 2)))]
6265 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6266 && CONST_INT_P (operands[2])
6267 && INTVAL (operands[2]) == INTVAL (operands[3])"
6268 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6269 [(set_attr "type" "alu")
6270 (set_attr "mode" "<MODE>")
6271 (set (attr "length_immediate")
6272 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6274 (match_test "<MODE_SIZE> == 8")
6276 (const_string "<MODE_SIZE>")))])
6278 (define_insn "*sub<mode>_3"
6279 [(set (reg FLAGS_REG)
6280 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6281 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6282 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6283 (minus:SWI (match_dup 1) (match_dup 2)))]
6284 "ix86_match_ccmode (insn, CCmode)
6285 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6286 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6287 [(set_attr "type" "alu")
6288 (set_attr "mode" "<MODE>")])
6290 (define_insn "*subsi_3_zext"
6291 [(set (reg FLAGS_REG)
6292 (compare (match_operand:SI 1 "register_operand" "0")
6293 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6294 (set (match_operand:DI 0 "register_operand" "=r")
6296 (minus:SI (match_dup 1)
6298 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6299 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6300 "sub{l}\t{%2, %1|%1, %2}"
6301 [(set_attr "type" "alu")
6302 (set_attr "mode" "SI")])
6304 ;; Add with carry and subtract with borrow
6306 (define_insn "add<mode>3_carry"
6307 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6310 (match_operator:SWI 4 "ix86_carry_flag_operator"
6311 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6312 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6313 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6314 (clobber (reg:CC FLAGS_REG))]
6315 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6316 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6317 [(set_attr "type" "alu")
6318 (set_attr "use_carry" "1")
6319 (set_attr "pent_pair" "pu")
6320 (set_attr "mode" "<MODE>")])
6322 (define_insn "*addsi3_carry_zext"
6323 [(set (match_operand:DI 0 "register_operand" "=r")
6326 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6327 [(reg FLAGS_REG) (const_int 0)])
6328 (match_operand:SI 1 "register_operand" "%0"))
6329 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6330 (clobber (reg:CC FLAGS_REG))]
6331 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6332 "adc{l}\t{%2, %k0|%k0, %2}"
6333 [(set_attr "type" "alu")
6334 (set_attr "use_carry" "1")
6335 (set_attr "pent_pair" "pu")
6336 (set_attr "mode" "SI")])
6338 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6340 (define_insn "addcarry<mode>"
6341 [(set (reg:CCC FLAGS_REG)
6345 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6346 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6347 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6348 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6350 (set (match_operand:SWI48 0 "register_operand" "=r")
6351 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6352 [(match_dup 3) (const_int 0)])
6355 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6356 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6357 [(set_attr "type" "alu")
6358 (set_attr "use_carry" "1")
6359 (set_attr "pent_pair" "pu")
6360 (set_attr "mode" "<MODE>")])
6362 (define_insn "sub<mode>3_carry"
6363 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6366 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6367 (match_operator:SWI 4 "ix86_carry_flag_operator"
6368 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6369 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6370 (clobber (reg:CC FLAGS_REG))]
6371 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6372 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6373 [(set_attr "type" "alu")
6374 (set_attr "use_carry" "1")
6375 (set_attr "pent_pair" "pu")
6376 (set_attr "mode" "<MODE>")])
6378 (define_insn "*subsi3_carry_zext"
6379 [(set (match_operand:DI 0 "register_operand" "=r")
6383 (match_operand:SI 1 "register_operand" "0")
6384 (match_operator:SI 3 "ix86_carry_flag_operator"
6385 [(reg FLAGS_REG) (const_int 0)]))
6386 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6387 (clobber (reg:CC FLAGS_REG))]
6388 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6389 "sbb{l}\t{%2, %k0|%k0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "use_carry" "1")
6392 (set_attr "pent_pair" "pu")
6393 (set_attr "mode" "SI")])
6395 (define_insn "subborrow<mode>"
6396 [(set (reg:CCC FLAGS_REG)
6398 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6400 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6401 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6402 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6403 (set (match_operand:SWI48 0 "register_operand" "=r")
6404 (minus:SWI48 (minus:SWI48 (match_dup 1)
6406 [(match_dup 3) (const_int 0)]))
6408 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6409 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6410 [(set_attr "type" "alu")
6411 (set_attr "use_carry" "1")
6412 (set_attr "pent_pair" "pu")
6413 (set_attr "mode" "<MODE>")])
6415 ;; Overflow setting add instructions
6417 (define_expand "addqi3_cconly_overflow"
6419 [(set (reg:CCC FLAGS_REG)
6422 (match_operand:QI 0 "nonimmediate_operand")
6423 (match_operand:QI 1 "general_operand"))
6425 (clobber (match_scratch:QI 2))])]
6426 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6428 (define_insn "*add<mode>3_cconly_overflow"
6429 [(set (reg:CCC FLAGS_REG)
6432 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6433 (match_operand:SWI 2 "<general_operand>" "<g>"))
6435 (clobber (match_scratch:SWI 0 "=<r>"))]
6436 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6437 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6438 [(set_attr "type" "alu")
6439 (set_attr "mode" "<MODE>")])
6441 (define_insn "*add<mode>3_cc_overflow"
6442 [(set (reg:CCC FLAGS_REG)
6445 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6446 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (plus:SWI (match_dup 1) (match_dup 2)))]
6450 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6451 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6452 [(set_attr "type" "alu")
6453 (set_attr "mode" "<MODE>")])
6455 (define_insn "*addsi3_zext_cc_overflow"
6456 [(set (reg:CCC FLAGS_REG)
6459 (match_operand:SI 1 "nonimmediate_operand" "%0")
6460 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6462 (set (match_operand:DI 0 "register_operand" "=r")
6463 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6464 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6465 "add{l}\t{%2, %k0|%k0, %2}"
6466 [(set_attr "type" "alu")
6467 (set_attr "mode" "SI")])
6469 ;; The patterns that match these are at the end of this file.
6471 (define_expand "<plusminus_insn>xf3"
6472 [(set (match_operand:XF 0 "register_operand")
6474 (match_operand:XF 1 "register_operand")
6475 (match_operand:XF 2 "register_operand")))]
6478 (define_expand "<plusminus_insn><mode>3"
6479 [(set (match_operand:MODEF 0 "register_operand")
6481 (match_operand:MODEF 1 "register_operand")
6482 (match_operand:MODEF 2 "nonimmediate_operand")))]
6483 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6484 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6486 ;; Multiply instructions
6488 (define_expand "mul<mode>3"
6489 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6491 (match_operand:SWIM248 1 "register_operand")
6492 (match_operand:SWIM248 2 "<general_operand>")))
6493 (clobber (reg:CC FLAGS_REG))])])
6495 (define_expand "mulqi3"
6496 [(parallel [(set (match_operand:QI 0 "register_operand")
6498 (match_operand:QI 1 "register_operand")
6499 (match_operand:QI 2 "nonimmediate_operand")))
6500 (clobber (reg:CC FLAGS_REG))])]
6501 "TARGET_QIMODE_MATH")
6504 ;; IMUL reg32/64, reg32/64, imm8 Direct
6505 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6506 ;; IMUL reg32/64, reg32/64, imm32 Direct
6507 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6508 ;; IMUL reg32/64, reg32/64 Direct
6509 ;; IMUL reg32/64, mem32/64 Direct
6511 ;; On BDVER1, all above IMULs use DirectPath
6513 (define_insn "*mul<mode>3_1"
6514 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6516 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6517 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6521 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6522 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6523 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6524 [(set_attr "type" "imul")
6525 (set_attr "prefix_0f" "0,0,1")
6526 (set (attr "athlon_decode")
6527 (cond [(eq_attr "cpu" "athlon")
6528 (const_string "vector")
6529 (eq_attr "alternative" "1")
6530 (const_string "vector")
6531 (and (eq_attr "alternative" "2")
6532 (match_operand 1 "memory_operand"))
6533 (const_string "vector")]
6534 (const_string "direct")))
6535 (set (attr "amdfam10_decode")
6536 (cond [(and (eq_attr "alternative" "0,1")
6537 (match_operand 1 "memory_operand"))
6538 (const_string "vector")]
6539 (const_string "direct")))
6540 (set_attr "bdver1_decode" "direct")
6541 (set_attr "mode" "<MODE>")])
6543 (define_insn "*mulsi3_1_zext"
6544 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6546 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6547 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6548 (clobber (reg:CC FLAGS_REG))]
6550 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6552 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6553 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6554 imul{l}\t{%2, %k0|%k0, %2}"
6555 [(set_attr "type" "imul")
6556 (set_attr "prefix_0f" "0,0,1")
6557 (set (attr "athlon_decode")
6558 (cond [(eq_attr "cpu" "athlon")
6559 (const_string "vector")
6560 (eq_attr "alternative" "1")
6561 (const_string "vector")
6562 (and (eq_attr "alternative" "2")
6563 (match_operand 1 "memory_operand"))
6564 (const_string "vector")]
6565 (const_string "direct")))
6566 (set (attr "amdfam10_decode")
6567 (cond [(and (eq_attr "alternative" "0,1")
6568 (match_operand 1 "memory_operand"))
6569 (const_string "vector")]
6570 (const_string "direct")))
6571 (set_attr "bdver1_decode" "direct")
6572 (set_attr "mode" "SI")])
6575 ;; IMUL reg16, reg16, imm8 VectorPath
6576 ;; IMUL reg16, mem16, imm8 VectorPath
6577 ;; IMUL reg16, reg16, imm16 VectorPath
6578 ;; IMUL reg16, mem16, imm16 VectorPath
6579 ;; IMUL reg16, reg16 Direct
6580 ;; IMUL reg16, mem16 Direct
6582 ;; On BDVER1, all HI MULs use DoublePath
6584 (define_insn "*mulhi3_1"
6585 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6586 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6587 (match_operand:HI 2 "general_operand" "K,n,mr")))
6588 (clobber (reg:CC FLAGS_REG))]
6590 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6592 imul{w}\t{%2, %1, %0|%0, %1, %2}
6593 imul{w}\t{%2, %1, %0|%0, %1, %2}
6594 imul{w}\t{%2, %0|%0, %2}"
6595 [(set_attr "type" "imul")
6596 (set_attr "prefix_0f" "0,0,1")
6597 (set (attr "athlon_decode")
6598 (cond [(eq_attr "cpu" "athlon")
6599 (const_string "vector")
6600 (eq_attr "alternative" "1,2")
6601 (const_string "vector")]
6602 (const_string "direct")))
6603 (set (attr "amdfam10_decode")
6604 (cond [(eq_attr "alternative" "0,1")
6605 (const_string "vector")]
6606 (const_string "direct")))
6607 (set_attr "bdver1_decode" "double")
6608 (set_attr "mode" "HI")])
6610 ;;On AMDFAM10 and BDVER1
6614 (define_insn "*mulqi3_1"
6615 [(set (match_operand:QI 0 "register_operand" "=a")
6616 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6617 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6618 (clobber (reg:CC FLAGS_REG))]
6620 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6622 [(set_attr "type" "imul")
6623 (set_attr "length_immediate" "0")
6624 (set (attr "athlon_decode")
6625 (if_then_else (eq_attr "cpu" "athlon")
6626 (const_string "vector")
6627 (const_string "direct")))
6628 (set_attr "amdfam10_decode" "direct")
6629 (set_attr "bdver1_decode" "direct")
6630 (set_attr "mode" "QI")])
6632 ;; Multiply with jump on overflow.
6633 (define_expand "mulv<mode>4"
6634 [(parallel [(set (reg:CCO FLAGS_REG)
6637 (match_operand:SWI48 1 "register_operand"))
6640 (mult:SWI48 (match_dup 1)
6641 (match_operand:SWI48 2
6642 "<general_operand>")))))
6643 (set (match_operand:SWI48 0 "register_operand")
6644 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6645 (set (pc) (if_then_else
6646 (eq (reg:CCO FLAGS_REG) (const_int 0))
6647 (label_ref (match_operand 3))
6651 if (CONST_INT_P (operands[2]))
6652 operands[4] = operands[2];
6654 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6657 (define_insn "*mulv<mode>4"
6658 [(set (reg:CCO FLAGS_REG)
6661 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6663 (match_operand:SWI48 2 "<general_sext_operand>"
6666 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6667 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6668 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6669 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6671 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6672 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6673 [(set_attr "type" "imul")
6674 (set_attr "prefix_0f" "0,1")
6675 (set (attr "athlon_decode")
6676 (cond [(eq_attr "cpu" "athlon")
6677 (const_string "vector")
6678 (eq_attr "alternative" "0")
6679 (const_string "vector")
6680 (and (eq_attr "alternative" "1")
6681 (match_operand 1 "memory_operand"))
6682 (const_string "vector")]
6683 (const_string "direct")))
6684 (set (attr "amdfam10_decode")
6685 (cond [(and (eq_attr "alternative" "1")
6686 (match_operand 1 "memory_operand"))
6687 (const_string "vector")]
6688 (const_string "direct")))
6689 (set_attr "bdver1_decode" "direct")
6690 (set_attr "mode" "<MODE>")])
6692 (define_insn "*mulv<mode>4_1"
6693 [(set (reg:CCO FLAGS_REG)
6696 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6697 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6699 (mult:SWI48 (match_dup 1)
6700 (match_operand:SWI 2 "x86_64_immediate_operand"
6702 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6703 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6704 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6705 && CONST_INT_P (operands[2])
6706 && INTVAL (operands[2]) == INTVAL (operands[3])"
6708 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6709 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6710 [(set_attr "type" "imul")
6711 (set (attr "athlon_decode")
6712 (cond [(eq_attr "cpu" "athlon")
6713 (const_string "vector")
6714 (eq_attr "alternative" "1")
6715 (const_string "vector")]
6716 (const_string "direct")))
6717 (set (attr "amdfam10_decode")
6718 (cond [(match_operand 1 "memory_operand")
6719 (const_string "vector")]
6720 (const_string "direct")))
6721 (set_attr "bdver1_decode" "direct")
6722 (set_attr "mode" "<MODE>")
6723 (set (attr "length_immediate")
6724 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6726 (match_test "<MODE_SIZE> == 8")
6728 (const_string "<MODE_SIZE>")))])
6730 (define_expand "umulv<mode>4"
6731 [(parallel [(set (reg:CCO FLAGS_REG)
6734 (match_operand:SWI48 1
6735 "nonimmediate_operand"))
6737 (match_operand:SWI48 2
6738 "nonimmediate_operand")))
6740 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6741 (set (match_operand:SWI48 0 "register_operand")
6742 (mult:SWI48 (match_dup 1) (match_dup 2)))
6743 (clobber (match_scratch:SWI48 4))])
6744 (set (pc) (if_then_else
6745 (eq (reg:CCO FLAGS_REG) (const_int 0))
6746 (label_ref (match_operand 3))
6750 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6751 operands[1] = force_reg (<MODE>mode, operands[1]);
6754 (define_insn "*umulv<mode>4"
6755 [(set (reg:CCO FLAGS_REG)
6758 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6760 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6762 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6763 (set (match_operand:SWI48 0 "register_operand" "=a")
6764 (mult:SWI48 (match_dup 1) (match_dup 2)))
6765 (clobber (match_scratch:SWI48 3 "=d"))]
6766 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6767 "mul{<imodesuffix>}\t%2"
6768 [(set_attr "type" "imul")
6769 (set_attr "length_immediate" "0")
6770 (set (attr "athlon_decode")
6771 (if_then_else (eq_attr "cpu" "athlon")
6772 (const_string "vector")
6773 (const_string "double")))
6774 (set_attr "amdfam10_decode" "double")
6775 (set_attr "bdver1_decode" "direct")
6776 (set_attr "mode" "<MODE>")])
6778 (define_expand "<u>mulvqi4"
6779 [(parallel [(set (reg:CCO FLAGS_REG)
6782 (match_operand:QI 1 "nonimmediate_operand"))
6784 (match_operand:QI 2 "nonimmediate_operand")))
6786 (mult:QI (match_dup 1) (match_dup 2)))))
6787 (set (match_operand:QI 0 "register_operand")
6788 (mult:QI (match_dup 1) (match_dup 2)))])
6789 (set (pc) (if_then_else
6790 (eq (reg:CCO FLAGS_REG) (const_int 0))
6791 (label_ref (match_operand 3))
6793 "TARGET_QIMODE_MATH"
6795 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6796 operands[1] = force_reg (QImode, operands[1]);
6799 (define_insn "*<u>mulvqi4"
6800 [(set (reg:CCO FLAGS_REG)
6803 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6805 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6807 (mult:QI (match_dup 1) (match_dup 2)))))
6808 (set (match_operand:QI 0 "register_operand" "=a")
6809 (mult:QI (match_dup 1) (match_dup 2)))]
6811 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812 "<sgnprefix>mul{b}\t%2"
6813 [(set_attr "type" "imul")
6814 (set_attr "length_immediate" "0")
6815 (set (attr "athlon_decode")
6816 (if_then_else (eq_attr "cpu" "athlon")
6817 (const_string "vector")
6818 (const_string "direct")))
6819 (set_attr "amdfam10_decode" "direct")
6820 (set_attr "bdver1_decode" "direct")
6821 (set_attr "mode" "QI")])
6823 (define_expand "<u>mul<mode><dwi>3"
6824 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6827 (match_operand:DWIH 1 "nonimmediate_operand"))
6829 (match_operand:DWIH 2 "register_operand"))))
6830 (clobber (reg:CC FLAGS_REG))])])
6832 (define_expand "<u>mulqihi3"
6833 [(parallel [(set (match_operand:HI 0 "register_operand")
6836 (match_operand:QI 1 "nonimmediate_operand"))
6838 (match_operand:QI 2 "register_operand"))))
6839 (clobber (reg:CC FLAGS_REG))])]
6840 "TARGET_QIMODE_MATH")
6842 (define_insn "*bmi2_umulditi3_1"
6843 [(set (match_operand:DI 0 "register_operand" "=r")
6845 (match_operand:DI 2 "nonimmediate_operand" "%d")
6846 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6847 (set (match_operand:DI 1 "register_operand" "=r")
6850 (mult:TI (zero_extend:TI (match_dup 2))
6851 (zero_extend:TI (match_dup 3)))
6853 "TARGET_64BIT && TARGET_BMI2
6854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 "mulx\t{%3, %0, %1|%1, %0, %3}"
6856 [(set_attr "type" "imulx")
6857 (set_attr "prefix" "vex")
6858 (set_attr "mode" "DI")])
6860 (define_insn "*bmi2_umulsidi3_1"
6861 [(set (match_operand:SI 0 "register_operand" "=r")
6863 (match_operand:SI 2 "nonimmediate_operand" "%d")
6864 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6865 (set (match_operand:SI 1 "register_operand" "=r")
6868 (mult:DI (zero_extend:DI (match_dup 2))
6869 (zero_extend:DI (match_dup 3)))
6871 "!TARGET_64BIT && TARGET_BMI2
6872 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6873 "mulx\t{%3, %0, %1|%1, %0, %3}"
6874 [(set_attr "type" "imulx")
6875 (set_attr "prefix" "vex")
6876 (set_attr "mode" "SI")])
6878 (define_insn "*umul<mode><dwi>3_1"
6879 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6882 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6884 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6885 (clobber (reg:CC FLAGS_REG))]
6886 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 mul{<imodesuffix>}\t%2"
6890 [(set_attr "isa" "bmi2,*")
6891 (set_attr "type" "imulx,imul")
6892 (set_attr "length_immediate" "*,0")
6893 (set (attr "athlon_decode")
6894 (cond [(eq_attr "alternative" "1")
6895 (if_then_else (eq_attr "cpu" "athlon")
6896 (const_string "vector")
6897 (const_string "double"))]
6898 (const_string "*")))
6899 (set_attr "amdfam10_decode" "*,double")
6900 (set_attr "bdver1_decode" "*,direct")
6901 (set_attr "prefix" "vex,orig")
6902 (set_attr "mode" "<MODE>")])
6904 ;; Convert mul to the mulx pattern to avoid flags dependency.
6906 [(set (match_operand:<DWI> 0 "register_operand")
6909 (match_operand:DWIH 1 "register_operand"))
6911 (match_operand:DWIH 2 "nonimmediate_operand"))))
6912 (clobber (reg:CC FLAGS_REG))]
6913 "TARGET_BMI2 && reload_completed
6914 && true_regnum (operands[1]) == DX_REG"
6915 [(parallel [(set (match_dup 3)
6916 (mult:DWIH (match_dup 1) (match_dup 2)))
6920 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6921 (zero_extend:<DWI> (match_dup 2)))
6924 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6926 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6929 (define_insn "*mul<mode><dwi>3_1"
6930 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6933 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6935 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6936 (clobber (reg:CC FLAGS_REG))]
6937 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938 "imul{<imodesuffix>}\t%2"
6939 [(set_attr "type" "imul")
6940 (set_attr "length_immediate" "0")
6941 (set (attr "athlon_decode")
6942 (if_then_else (eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (const_string "double")))
6945 (set_attr "amdfam10_decode" "double")
6946 (set_attr "bdver1_decode" "direct")
6947 (set_attr "mode" "<MODE>")])
6949 (define_insn "*<u>mulqihi3_1"
6950 [(set (match_operand:HI 0 "register_operand" "=a")
6953 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6955 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6956 (clobber (reg:CC FLAGS_REG))]
6958 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6959 "<sgnprefix>mul{b}\t%2"
6960 [(set_attr "type" "imul")
6961 (set_attr "length_immediate" "0")
6962 (set (attr "athlon_decode")
6963 (if_then_else (eq_attr "cpu" "athlon")
6964 (const_string "vector")
6965 (const_string "direct")))
6966 (set_attr "amdfam10_decode" "direct")
6967 (set_attr "bdver1_decode" "direct")
6968 (set_attr "mode" "QI")])
6970 (define_expand "<s>mul<mode>3_highpart"
6971 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6976 (match_operand:SWI48 1 "nonimmediate_operand"))
6978 (match_operand:SWI48 2 "register_operand")))
6980 (clobber (match_scratch:SWI48 3))
6981 (clobber (reg:CC FLAGS_REG))])]
6983 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6985 (define_insn "*<s>muldi3_highpart_1"
6986 [(set (match_operand:DI 0 "register_operand" "=d")
6991 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6993 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6995 (clobber (match_scratch:DI 3 "=1"))
6996 (clobber (reg:CC FLAGS_REG))]
6998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 "<sgnprefix>mul{q}\t%2"
7000 [(set_attr "type" "imul")
7001 (set_attr "length_immediate" "0")
7002 (set (attr "athlon_decode")
7003 (if_then_else (eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (const_string "double")))
7006 (set_attr "amdfam10_decode" "double")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "DI")])
7010 (define_insn "*<s>mulsi3_highpart_1"
7011 [(set (match_operand:SI 0 "register_operand" "=d")
7016 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7018 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7020 (clobber (match_scratch:SI 3 "=1"))
7021 (clobber (reg:CC FLAGS_REG))]
7022 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7023 "<sgnprefix>mul{l}\t%2"
7024 [(set_attr "type" "imul")
7025 (set_attr "length_immediate" "0")
7026 (set (attr "athlon_decode")
7027 (if_then_else (eq_attr "cpu" "athlon")
7028 (const_string "vector")
7029 (const_string "double")))
7030 (set_attr "amdfam10_decode" "double")
7031 (set_attr "bdver1_decode" "direct")
7032 (set_attr "mode" "SI")])
7034 (define_insn "*<s>mulsi3_highpart_zext"
7035 [(set (match_operand:DI 0 "register_operand" "=d")
7036 (zero_extend:DI (truncate:SI
7038 (mult:DI (any_extend:DI
7039 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7041 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7043 (clobber (match_scratch:SI 3 "=1"))
7044 (clobber (reg:CC FLAGS_REG))]
7046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7047 "<sgnprefix>mul{l}\t%2"
7048 [(set_attr "type" "imul")
7049 (set_attr "length_immediate" "0")
7050 (set (attr "athlon_decode")
7051 (if_then_else (eq_attr "cpu" "athlon")
7052 (const_string "vector")
7053 (const_string "double")))
7054 (set_attr "amdfam10_decode" "double")
7055 (set_attr "bdver1_decode" "direct")
7056 (set_attr "mode" "SI")])
7058 ;; The patterns that match these are at the end of this file.
7060 (define_expand "mulxf3"
7061 [(set (match_operand:XF 0 "register_operand")
7062 (mult:XF (match_operand:XF 1 "register_operand")
7063 (match_operand:XF 2 "register_operand")))]
7066 (define_expand "mul<mode>3"
7067 [(set (match_operand:MODEF 0 "register_operand")
7068 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7069 (match_operand:MODEF 2 "nonimmediate_operand")))]
7070 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7071 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7073 ;; Divide instructions
7075 ;; The patterns that match these are at the end of this file.
7077 (define_expand "divxf3"
7078 [(set (match_operand:XF 0 "register_operand")
7079 (div:XF (match_operand:XF 1 "register_operand")
7080 (match_operand:XF 2 "register_operand")))]
7083 (define_expand "divdf3"
7084 [(set (match_operand:DF 0 "register_operand")
7085 (div:DF (match_operand:DF 1 "register_operand")
7086 (match_operand:DF 2 "nonimmediate_operand")))]
7087 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7088 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7090 (define_expand "divsf3"
7091 [(set (match_operand:SF 0 "register_operand")
7092 (div:SF (match_operand:SF 1 "register_operand")
7093 (match_operand:SF 2 "nonimmediate_operand")))]
7094 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7099 && optimize_insn_for_speed_p ()
7100 && flag_finite_math_only && !flag_trapping_math
7101 && flag_unsafe_math_optimizations)
7103 ix86_emit_swdivsf (operands[0], operands[1],
7104 operands[2], SFmode);
7109 ;; Divmod instructions.
7111 (define_expand "divmod<mode>4"
7112 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7114 (match_operand:SWIM248 1 "register_operand")
7115 (match_operand:SWIM248 2 "nonimmediate_operand")))
7116 (set (match_operand:SWIM248 3 "register_operand")
7117 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7118 (clobber (reg:CC FLAGS_REG))])])
7120 ;; Split with 8bit unsigned divide:
7121 ;; if (dividend an divisor are in [0-255])
7122 ;; use 8bit unsigned integer divide
7124 ;; use original integer divide
7126 [(set (match_operand:SWI48 0 "register_operand")
7127 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7128 (match_operand:SWI48 3 "nonimmediate_operand")))
7129 (set (match_operand:SWI48 1 "register_operand")
7130 (mod:SWI48 (match_dup 2) (match_dup 3)))
7131 (clobber (reg:CC FLAGS_REG))]
7132 "TARGET_USE_8BIT_IDIV
7133 && TARGET_QIMODE_MATH
7134 && can_create_pseudo_p ()
7135 && !optimize_insn_for_size_p ()"
7137 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7139 (define_insn_and_split "divmod<mode>4_1"
7140 [(set (match_operand:SWI48 0 "register_operand" "=a")
7141 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7142 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7143 (set (match_operand:SWI48 1 "register_operand" "=&d")
7144 (mod:SWI48 (match_dup 2) (match_dup 3)))
7145 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7146 (clobber (reg:CC FLAGS_REG))]
7150 [(parallel [(set (match_dup 1)
7151 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7152 (clobber (reg:CC FLAGS_REG))])
7153 (parallel [(set (match_dup 0)
7154 (div:SWI48 (match_dup 2) (match_dup 3)))
7156 (mod:SWI48 (match_dup 2) (match_dup 3)))
7158 (clobber (reg:CC FLAGS_REG))])]
7160 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7162 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7163 operands[4] = operands[2];
7166 /* Avoid use of cltd in favor of a mov+shift. */
7167 emit_move_insn (operands[1], operands[2]);
7168 operands[4] = operands[1];
7171 [(set_attr "type" "multi")
7172 (set_attr "mode" "<MODE>")])
7174 (define_insn_and_split "*divmod<mode>4"
7175 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7176 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7177 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7178 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7179 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7180 (clobber (reg:CC FLAGS_REG))]
7184 [(parallel [(set (match_dup 1)
7185 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7186 (clobber (reg:CC FLAGS_REG))])
7187 (parallel [(set (match_dup 0)
7188 (div:SWIM248 (match_dup 2) (match_dup 3)))
7190 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7192 (clobber (reg:CC FLAGS_REG))])]
7194 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7196 if (<MODE>mode != HImode
7197 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7198 operands[4] = operands[2];
7201 /* Avoid use of cltd in favor of a mov+shift. */
7202 emit_move_insn (operands[1], operands[2]);
7203 operands[4] = operands[1];
7206 [(set_attr "type" "multi")
7207 (set_attr "mode" "<MODE>")])
7209 (define_insn "*divmod<mode>4_noext"
7210 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7211 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7212 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7213 (set (match_operand:SWIM248 1 "register_operand" "=d")
7214 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7215 (use (match_operand:SWIM248 4 "register_operand" "1"))
7216 (clobber (reg:CC FLAGS_REG))]
7218 "idiv{<imodesuffix>}\t%3"
7219 [(set_attr "type" "idiv")
7220 (set_attr "mode" "<MODE>")])
7222 (define_expand "divmodqi4"
7223 [(parallel [(set (match_operand:QI 0 "register_operand")
7225 (match_operand:QI 1 "register_operand")
7226 (match_operand:QI 2 "nonimmediate_operand")))
7227 (set (match_operand:QI 3 "register_operand")
7228 (mod:QI (match_dup 1) (match_dup 2)))
7229 (clobber (reg:CC FLAGS_REG))])]
7230 "TARGET_QIMODE_MATH"
7235 tmp0 = gen_reg_rtx (HImode);
7236 tmp1 = gen_reg_rtx (HImode);
7238 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7240 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7241 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7243 /* Extract remainder from AH. */
7244 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7245 insn = emit_move_insn (operands[3], tmp1);
7247 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7248 set_unique_reg_note (insn, REG_EQUAL, mod);
7250 /* Extract quotient from AL. */
7251 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7253 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7254 set_unique_reg_note (insn, REG_EQUAL, div);
7259 ;; Divide AX by r/m8, with result stored in
7262 ;; Change div/mod to HImode and extend the second argument to HImode
7263 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7264 ;; combine may fail.
7265 (define_insn "divmodhiqi3"
7266 [(set (match_operand:HI 0 "register_operand" "=a")
7271 (mod:HI (match_operand:HI 1 "register_operand" "0")
7273 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7277 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7278 (clobber (reg:CC FLAGS_REG))]
7279 "TARGET_QIMODE_MATH"
7281 [(set_attr "type" "idiv")
7282 (set_attr "mode" "QI")])
7284 (define_expand "udivmod<mode>4"
7285 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7287 (match_operand:SWIM248 1 "register_operand")
7288 (match_operand:SWIM248 2 "nonimmediate_operand")))
7289 (set (match_operand:SWIM248 3 "register_operand")
7290 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7291 (clobber (reg:CC FLAGS_REG))])])
7293 ;; Split with 8bit unsigned divide:
7294 ;; if (dividend an divisor are in [0-255])
7295 ;; use 8bit unsigned integer divide
7297 ;; use original integer divide
7299 [(set (match_operand:SWI48 0 "register_operand")
7300 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7301 (match_operand:SWI48 3 "nonimmediate_operand")))
7302 (set (match_operand:SWI48 1 "register_operand")
7303 (umod:SWI48 (match_dup 2) (match_dup 3)))
7304 (clobber (reg:CC FLAGS_REG))]
7305 "TARGET_USE_8BIT_IDIV
7306 && TARGET_QIMODE_MATH
7307 && can_create_pseudo_p ()
7308 && !optimize_insn_for_size_p ()"
7310 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7312 (define_insn_and_split "udivmod<mode>4_1"
7313 [(set (match_operand:SWI48 0 "register_operand" "=a")
7314 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7315 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7316 (set (match_operand:SWI48 1 "register_operand" "=&d")
7317 (umod:SWI48 (match_dup 2) (match_dup 3)))
7318 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7319 (clobber (reg:CC FLAGS_REG))]
7323 [(set (match_dup 1) (const_int 0))
7324 (parallel [(set (match_dup 0)
7325 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7327 (umod:SWI48 (match_dup 2) (match_dup 3)))
7329 (clobber (reg:CC FLAGS_REG))])]
7331 [(set_attr "type" "multi")
7332 (set_attr "mode" "<MODE>")])
7334 (define_insn_and_split "*udivmod<mode>4"
7335 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7336 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7337 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7338 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7339 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7340 (clobber (reg:CC FLAGS_REG))]
7344 [(set (match_dup 1) (const_int 0))
7345 (parallel [(set (match_dup 0)
7346 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7348 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7350 (clobber (reg:CC FLAGS_REG))])]
7352 [(set_attr "type" "multi")
7353 (set_attr "mode" "<MODE>")])
7355 ;; Optimize division or modulo by constant power of 2, if the constant
7356 ;; materializes only after expansion.
7357 (define_insn_and_split "*udivmod<mode>4_pow2"
7358 [(set (match_operand:SWI48 0 "register_operand" "=r")
7359 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7360 (match_operand:SWI48 3 "const_int_operand" "n")))
7361 (set (match_operand:SWI48 1 "register_operand" "=r")
7362 (umod:SWI48 (match_dup 2) (match_dup 3)))
7363 (clobber (reg:CC FLAGS_REG))]
7364 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7365 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7368 [(set (match_dup 1) (match_dup 2))
7369 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7370 (clobber (reg:CC FLAGS_REG))])
7371 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7372 (clobber (reg:CC FLAGS_REG))])]
7374 int v = exact_log2 (UINTVAL (operands[3]));
7375 operands[4] = GEN_INT (v);
7376 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7378 [(set_attr "type" "multi")
7379 (set_attr "mode" "<MODE>")])
7381 (define_insn "*udivmod<mode>4_noext"
7382 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7383 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7384 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7385 (set (match_operand:SWIM248 1 "register_operand" "=d")
7386 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7387 (use (match_operand:SWIM248 4 "register_operand" "1"))
7388 (clobber (reg:CC FLAGS_REG))]
7390 "div{<imodesuffix>}\t%3"
7391 [(set_attr "type" "idiv")
7392 (set_attr "mode" "<MODE>")])
7394 (define_expand "udivmodqi4"
7395 [(parallel [(set (match_operand:QI 0 "register_operand")
7397 (match_operand:QI 1 "register_operand")
7398 (match_operand:QI 2 "nonimmediate_operand")))
7399 (set (match_operand:QI 3 "register_operand")
7400 (umod:QI (match_dup 1) (match_dup 2)))
7401 (clobber (reg:CC FLAGS_REG))])]
7402 "TARGET_QIMODE_MATH"
7407 tmp0 = gen_reg_rtx (HImode);
7408 tmp1 = gen_reg_rtx (HImode);
7410 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7412 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7413 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7415 /* Extract remainder from AH. */
7416 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7417 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7418 insn = emit_move_insn (operands[3], tmp1);
7420 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7421 set_unique_reg_note (insn, REG_EQUAL, mod);
7423 /* Extract quotient from AL. */
7424 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7426 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7427 set_unique_reg_note (insn, REG_EQUAL, div);
7432 (define_insn "udivmodhiqi3"
7433 [(set (match_operand:HI 0 "register_operand" "=a")
7438 (mod:HI (match_operand:HI 1 "register_operand" "0")
7440 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7444 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7445 (clobber (reg:CC FLAGS_REG))]
7446 "TARGET_QIMODE_MATH"
7448 [(set_attr "type" "idiv")
7449 (set_attr "mode" "QI")])
7451 ;; We cannot use div/idiv for double division, because it causes
7452 ;; "division by zero" on the overflow and that's not what we expect
7453 ;; from truncate. Because true (non truncating) double division is
7454 ;; never generated, we can't create this insn anyway.
7457 ; [(set (match_operand:SI 0 "register_operand" "=a")
7459 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7461 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7462 ; (set (match_operand:SI 3 "register_operand" "=d")
7464 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7465 ; (clobber (reg:CC FLAGS_REG))]
7467 ; "div{l}\t{%2, %0|%0, %2}"
7468 ; [(set_attr "type" "idiv")])
7470 ;;- Logical AND instructions
7472 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7473 ;; Note that this excludes ah.
7475 (define_expand "testsi_ccno_1"
7476 [(set (reg:CCNO FLAGS_REG)
7478 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7479 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7482 (define_expand "testqi_ccz_1"
7483 [(set (reg:CCZ FLAGS_REG)
7484 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7485 (match_operand:QI 1 "nonmemory_operand"))
7488 (define_expand "testdi_ccno_1"
7489 [(set (reg:CCNO FLAGS_REG)
7491 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7492 (match_operand:DI 1 "x86_64_szext_general_operand"))
7494 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7496 (define_insn "*testdi_1"
7497 [(set (reg FLAGS_REG)
7500 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7501 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7503 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7506 test{l}\t{%k1, %k0|%k0, %k1}
7507 test{l}\t{%k1, %k0|%k0, %k1}
7508 test{q}\t{%1, %0|%0, %1}
7509 test{q}\t{%1, %0|%0, %1}
7510 test{q}\t{%1, %0|%0, %1}"
7511 [(set_attr "type" "test")
7512 (set_attr "modrm" "0,1,0,1,1")
7513 (set_attr "mode" "SI,SI,DI,DI,DI")])
7515 (define_insn "*testqi_1_maybe_si"
7516 [(set (reg FLAGS_REG)
7519 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7520 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7522 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7523 && ix86_match_ccmode (insn,
7524 CONST_INT_P (operands[1])
7525 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7527 if (which_alternative == 3)
7529 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7530 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7531 return "test{l}\t{%1, %k0|%k0, %1}";
7533 return "test{b}\t{%1, %0|%0, %1}";
7535 [(set_attr "type" "test")
7536 (set_attr "modrm" "0,1,1,1")
7537 (set_attr "mode" "QI,QI,QI,SI")
7538 (set_attr "pent_pair" "uv,np,uv,np")])
7540 (define_insn "*test<mode>_1"
7541 [(set (reg FLAGS_REG)
7544 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7545 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7547 "ix86_match_ccmode (insn, CCNOmode)
7548 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7549 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7550 [(set_attr "type" "test")
7551 (set_attr "modrm" "0,1,1")
7552 (set_attr "mode" "<MODE>")
7553 (set_attr "pent_pair" "uv,np,uv")])
7555 (define_expand "testqi_ext_ccno_0"
7556 [(set (reg:CCNO FLAGS_REG)
7560 (match_operand 0 "ext_register_operand")
7563 (match_operand 1 "const_int_operand"))
7566 (define_insn "*testqi_ext_0"
7567 [(set (reg FLAGS_REG)
7571 (match_operand 0 "ext_register_operand" "Q")
7574 (match_operand 1 "const_int_operand" "n"))
7576 "ix86_match_ccmode (insn, CCNOmode)"
7577 "test{b}\t{%1, %h0|%h0, %1}"
7578 [(set_attr "type" "test")
7579 (set_attr "mode" "QI")
7580 (set_attr "length_immediate" "1")
7581 (set_attr "modrm" "1")
7582 (set_attr "pent_pair" "np")])
7584 (define_insn "*testqi_ext_1"
7585 [(set (reg FLAGS_REG)
7589 (match_operand 0 "ext_register_operand" "Q,Q")
7593 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7595 "ix86_match_ccmode (insn, CCNOmode)"
7596 "test{b}\t{%1, %h0|%h0, %1}"
7597 [(set_attr "isa" "*,nox64")
7598 (set_attr "type" "test")
7599 (set_attr "mode" "QI")])
7601 (define_insn "*testqi_ext_2"
7602 [(set (reg FLAGS_REG)
7606 (match_operand 0 "ext_register_operand" "Q")
7610 (match_operand 1 "ext_register_operand" "Q")
7614 "ix86_match_ccmode (insn, CCNOmode)"
7615 "test{b}\t{%h1, %h0|%h0, %h1}"
7616 [(set_attr "type" "test")
7617 (set_attr "mode" "QI")])
7619 ;; Combine likes to form bit extractions for some tests. Humor it.
7620 (define_insn "*testqi_ext_3"
7621 [(set (reg FLAGS_REG)
7622 (compare (zero_extract:SWI48
7623 (match_operand 0 "nonimmediate_operand" "rm")
7624 (match_operand:SWI48 1 "const_int_operand")
7625 (match_operand:SWI48 2 "const_int_operand"))
7627 "ix86_match_ccmode (insn, CCNOmode)
7628 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7629 || GET_MODE (operands[0]) == SImode
7630 || GET_MODE (operands[0]) == HImode
7631 || GET_MODE (operands[0]) == QImode)
7632 /* Ensure that resulting mask is zero or sign extended operand. */
7633 && INTVAL (operands[2]) >= 0
7634 && ((INTVAL (operands[1]) > 0
7635 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7636 || (<MODE>mode == DImode
7637 && INTVAL (operands[1]) > 32
7638 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7642 [(set (match_operand 0 "flags_reg_operand")
7643 (match_operator 1 "compare_operator"
7645 (match_operand 2 "nonimmediate_operand")
7646 (match_operand 3 "const_int_operand")
7647 (match_operand 4 "const_int_operand"))
7649 "ix86_match_ccmode (insn, CCNOmode)"
7650 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7652 rtx val = operands[2];
7653 HOST_WIDE_INT len = INTVAL (operands[3]);
7654 HOST_WIDE_INT pos = INTVAL (operands[4]);
7656 machine_mode mode, submode;
7658 mode = GET_MODE (val);
7661 /* ??? Combine likes to put non-volatile mem extractions in QImode
7662 no matter the size of the test. So find a mode that works. */
7663 if (! MEM_VOLATILE_P (val))
7665 mode = smallest_mode_for_size (pos + len, MODE_INT);
7666 val = adjust_address (val, mode, 0);
7669 else if (GET_CODE (val) == SUBREG
7670 && (submode = GET_MODE (SUBREG_REG (val)),
7671 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7672 && pos + len <= GET_MODE_BITSIZE (submode)
7673 && GET_MODE_CLASS (submode) == MODE_INT)
7675 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7677 val = SUBREG_REG (val);
7679 else if (mode == HImode && pos + len <= 8)
7681 /* Small HImode tests can be converted to QImode. */
7683 val = gen_lowpart (QImode, val);
7686 if (len == HOST_BITS_PER_WIDE_INT)
7689 mask = ((HOST_WIDE_INT)1 << len) - 1;
7692 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7695 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7696 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7697 ;; this is relatively important trick.
7698 ;; Do the conversion only post-reload to avoid limiting of the register class
7701 [(set (match_operand 0 "flags_reg_operand")
7702 (match_operator 1 "compare_operator"
7703 [(and (match_operand 2 "register_operand")
7704 (match_operand 3 "const_int_operand"))
7707 && QI_REG_P (operands[2])
7708 && GET_MODE (operands[2]) != QImode
7709 && ((ix86_match_ccmode (insn, CCZmode)
7710 && !(INTVAL (operands[3]) & ~(255 << 8)))
7711 || (ix86_match_ccmode (insn, CCNOmode)
7712 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7715 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7719 operands[2] = gen_lowpart (SImode, operands[2]);
7720 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7724 [(set (match_operand 0 "flags_reg_operand")
7725 (match_operator 1 "compare_operator"
7726 [(and (match_operand 2 "nonimmediate_operand")
7727 (match_operand 3 "const_int_operand"))
7730 && GET_MODE (operands[2]) != QImode
7731 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7732 && ((ix86_match_ccmode (insn, CCZmode)
7733 && !(INTVAL (operands[3]) & ~255))
7734 || (ix86_match_ccmode (insn, CCNOmode)
7735 && !(INTVAL (operands[3]) & ~127)))"
7737 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7740 operands[2] = gen_lowpart (QImode, operands[2]);
7741 operands[3] = gen_lowpart (QImode, operands[3]);
7745 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7746 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7747 (match_operand:SWI1248x 2 "mask_reg_operand")))
7748 (clobber (reg:CC FLAGS_REG))]
7749 "TARGET_AVX512F && reload_completed"
7751 (any_logic:SWI1248x (match_dup 1)
7754 (define_insn "*k<logic><mode>"
7755 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7756 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7757 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7760 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7761 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7763 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7765 [(set_attr "mode" "<MODE>")
7766 (set_attr "type" "msklog")
7767 (set_attr "prefix" "vex")])
7769 ;; %%% This used to optimize known byte-wide and operations to memory,
7770 ;; and sometimes to QImode registers. If this is considered useful,
7771 ;; it should be done with splitters.
7773 (define_expand "and<mode>3"
7774 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7775 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7776 (match_operand:SWIM 2 "<general_szext_operand>")))]
7779 machine_mode mode = <MODE>mode;
7780 rtx (*insn) (rtx, rtx);
7782 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7784 HOST_WIDE_INT ival = INTVAL (operands[2]);
7786 if (ival == (HOST_WIDE_INT) 0xffffffff)
7788 else if (ival == 0xffff)
7790 else if (ival == 0xff)
7794 if (mode == <MODE>mode)
7796 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7800 if (<MODE>mode == DImode)
7801 insn = (mode == SImode)
7802 ? gen_zero_extendsidi2
7804 ? gen_zero_extendhidi2
7805 : gen_zero_extendqidi2;
7806 else if (<MODE>mode == SImode)
7807 insn = (mode == HImode)
7808 ? gen_zero_extendhisi2
7809 : gen_zero_extendqisi2;
7810 else if (<MODE>mode == HImode)
7811 insn = gen_zero_extendqihi2;
7815 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7819 (define_insn "*anddi_1"
7820 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7822 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7823 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7827 switch (get_attr_type (insn))
7833 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7837 if (get_attr_mode (insn) == MODE_SI)
7838 return "and{l}\t{%k2, %k0|%k0, %k2}";
7840 return "and{q}\t{%2, %0|%0, %2}";
7843 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7844 (set_attr "length_immediate" "*,*,*,0,0")
7845 (set (attr "prefix_rex")
7847 (and (eq_attr "type" "imovx")
7848 (and (match_test "INTVAL (operands[2]) == 0xff")
7849 (match_operand 1 "ext_QIreg_operand")))
7851 (const_string "*")))
7852 (set_attr "mode" "SI,DI,DI,SI,DI")])
7854 (define_insn "*andsi_1"
7855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7856 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7857 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "ix86_binary_operator_ok (AND, SImode, operands)"
7861 switch (get_attr_type (insn))
7867 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7870 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7871 return "and{l}\t{%2, %0|%0, %2}";
7874 [(set_attr "type" "alu,alu,imovx,msklog")
7875 (set (attr "prefix_rex")
7877 (and (eq_attr "type" "imovx")
7878 (and (match_test "INTVAL (operands[2]) == 0xff")
7879 (match_operand 1 "ext_QIreg_operand")))
7881 (const_string "*")))
7882 (set_attr "length_immediate" "*,*,0,0")
7883 (set_attr "mode" "SI")])
7885 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7886 (define_insn "*andsi_1_zext"
7887 [(set (match_operand:DI 0 "register_operand" "=r")
7889 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7890 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7891 (clobber (reg:CC FLAGS_REG))]
7892 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7893 "and{l}\t{%2, %k0|%k0, %2}"
7894 [(set_attr "type" "alu")
7895 (set_attr "mode" "SI")])
7897 (define_insn "*andhi_1"
7898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7899 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7900 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "ix86_binary_operator_ok (AND, HImode, operands)"
7904 switch (get_attr_type (insn))
7910 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7913 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7914 return "and{w}\t{%2, %0|%0, %2}";
7917 [(set_attr "type" "alu,alu,imovx,msklog")
7918 (set_attr "length_immediate" "*,*,0,*")
7919 (set (attr "prefix_rex")
7921 (and (eq_attr "type" "imovx")
7922 (match_operand 1 "ext_QIreg_operand"))
7924 (const_string "*")))
7925 (set_attr "mode" "HI,HI,SI,HI")])
7927 ;; %%% Potential partial reg stall on alternative 2. What to do?
7928 (define_insn "*andqi_1"
7929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7930 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7931 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "ix86_binary_operator_ok (AND, QImode, operands)"
7935 switch (which_alternative)
7939 return "and{b}\t{%2, %0|%0, %2}";
7941 return "and{l}\t{%k2, %k0|%k0, %k2}";
7943 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7944 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7949 [(set_attr "type" "alu,alu,alu,msklog")
7950 (set_attr "mode" "QI,QI,SI,HI")])
7952 (define_insn "*andqi_1_slp"
7953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7954 (and:QI (match_dup 0)
7955 (match_operand:QI 1 "general_operand" "qn,qmn")))
7956 (clobber (reg:CC FLAGS_REG))]
7957 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7958 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7959 "and{b}\t{%1, %0|%0, %1}"
7960 [(set_attr "type" "alu1")
7961 (set_attr "mode" "QI")])
7963 (define_insn "kandn<mode>"
7964 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7967 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7968 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7969 (clobber (reg:CC FLAGS_REG))]
7972 switch (which_alternative)
7975 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7979 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7980 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7982 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7987 [(set_attr "isa" "bmi,*,avx512f")
7988 (set_attr "type" "bitmanip,*,msklog")
7989 (set_attr "prefix" "*,*,vex")
7990 (set_attr "btver2_decode" "direct,*,*")
7991 (set_attr "mode" "<MODE>")])
7994 [(set (match_operand:SWI12 0 "general_reg_operand")
7998 (match_operand:SWI12 1 "general_reg_operand")))
7999 (clobber (reg:CC FLAGS_REG))]
8000 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8002 (not:SWI12 (match_dup 0)))
8003 (parallel [(set (match_dup 0)
8004 (and:SWI12 (match_dup 0)
8006 (clobber (reg:CC FLAGS_REG))])])
8008 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8010 [(set (match_operand:DI 0 "register_operand")
8011 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8012 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8013 (clobber (reg:CC FLAGS_REG))]
8015 [(parallel [(set (match_dup 0)
8016 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8017 (clobber (reg:CC FLAGS_REG))])]
8018 "operands[2] = gen_lowpart (SImode, operands[2]);")
8021 [(set (match_operand:SWI248 0 "register_operand")
8022 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8023 (match_operand:SWI248 2 "const_int_operand")))
8024 (clobber (reg:CC FLAGS_REG))]
8026 && true_regnum (operands[0]) != true_regnum (operands[1])"
8029 HOST_WIDE_INT ival = INTVAL (operands[2]);
8031 rtx (*insn) (rtx, rtx);
8033 if (ival == (HOST_WIDE_INT) 0xffffffff)
8035 else if (ival == 0xffff)
8039 gcc_assert (ival == 0xff);
8043 if (<MODE>mode == DImode)
8044 insn = (mode == SImode)
8045 ? gen_zero_extendsidi2
8047 ? gen_zero_extendhidi2
8048 : gen_zero_extendqidi2;
8051 if (<MODE>mode != SImode)
8052 /* Zero extend to SImode to avoid partial register stalls. */
8053 operands[0] = gen_lowpart (SImode, operands[0]);
8055 insn = (mode == HImode)
8056 ? gen_zero_extendhisi2
8057 : gen_zero_extendqisi2;
8059 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8064 [(set (match_operand 0 "register_operand")
8066 (const_int -65536)))
8067 (clobber (reg:CC FLAGS_REG))]
8068 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8069 || optimize_function_for_size_p (cfun)"
8070 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8071 "operands[1] = gen_lowpart (HImode, operands[0]);")
8074 [(set (match_operand 0 "ext_register_operand")
8077 (clobber (reg:CC FLAGS_REG))]
8078 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8079 && reload_completed"
8080 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8081 "operands[1] = gen_lowpart (QImode, operands[0]);")
8084 [(set (match_operand 0 "ext_register_operand")
8086 (const_int -65281)))
8087 (clobber (reg:CC FLAGS_REG))]
8088 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8089 && reload_completed"
8090 [(parallel [(set (zero_extract:SI (match_dup 0)
8094 (zero_extract:SI (match_dup 0)
8097 (zero_extract:SI (match_dup 0)
8100 (clobber (reg:CC FLAGS_REG))])]
8101 "operands[0] = gen_lowpart (SImode, operands[0]);")
8103 (define_insn "*anddi_2"
8104 [(set (reg FLAGS_REG)
8107 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8108 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8110 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8111 (and:DI (match_dup 1) (match_dup 2)))]
8113 && ix86_match_ccmode
8115 /* If we are going to emit andl instead of andq, and the operands[2]
8116 constant might have the SImode sign bit set, make sure the sign
8117 flag isn't tested, because the instruction will set the sign flag
8118 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8119 conservatively assume it might have bit 31 set. */
8120 (satisfies_constraint_Z (operands[2])
8121 && (!CONST_INT_P (operands[2])
8122 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8123 ? CCZmode : CCNOmode)
8124 && ix86_binary_operator_ok (AND, DImode, operands)"
8126 and{l}\t{%k2, %k0|%k0, %k2}
8127 and{q}\t{%2, %0|%0, %2}
8128 and{q}\t{%2, %0|%0, %2}"
8129 [(set_attr "type" "alu")
8130 (set_attr "mode" "SI,DI,DI")])
8132 (define_insn "*andqi_2_maybe_si"
8133 [(set (reg FLAGS_REG)
8135 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8136 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8138 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8139 (and:QI (match_dup 1) (match_dup 2)))]
8140 "ix86_binary_operator_ok (AND, QImode, operands)
8141 && ix86_match_ccmode (insn,
8142 CONST_INT_P (operands[2])
8143 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8145 if (which_alternative == 2)
8147 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8148 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8149 return "and{l}\t{%2, %k0|%k0, %2}";
8151 return "and{b}\t{%2, %0|%0, %2}";
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "QI,QI,SI")])
8156 (define_insn "*and<mode>_2"
8157 [(set (reg FLAGS_REG)
8158 (compare (and:SWI124
8159 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8160 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8162 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8163 (and:SWI124 (match_dup 1) (match_dup 2)))]
8164 "ix86_match_ccmode (insn, CCNOmode)
8165 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8166 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "<MODE>")])
8170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171 (define_insn "*andsi_2_zext"
8172 [(set (reg FLAGS_REG)
8174 (match_operand:SI 1 "nonimmediate_operand" "%0")
8175 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8177 (set (match_operand:DI 0 "register_operand" "=r")
8178 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8179 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8180 && ix86_binary_operator_ok (AND, SImode, operands)"
8181 "and{l}\t{%2, %k0|%k0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "mode" "SI")])
8185 (define_insn "*andqi_2_slp"
8186 [(set (reg FLAGS_REG)
8188 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8189 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8191 (set (strict_low_part (match_dup 0))
8192 (and:QI (match_dup 0) (match_dup 1)))]
8193 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8194 && ix86_match_ccmode (insn, CCNOmode)
8195 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8196 "and{b}\t{%1, %0|%0, %1}"
8197 [(set_attr "type" "alu1")
8198 (set_attr "mode" "QI")])
8200 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8201 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8202 ;; for a QImode operand, which of course failed.
8203 (define_insn "andqi_ext_0"
8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8209 (match_operand 1 "ext_register_operand" "0")
8212 (match_operand 2 "const_int_operand" "n")))
8213 (clobber (reg:CC FLAGS_REG))]
8215 "and{b}\t{%2, %h0|%h0, %2}"
8216 [(set_attr "type" "alu")
8217 (set_attr "length_immediate" "1")
8218 (set_attr "modrm" "1")
8219 (set_attr "mode" "QI")])
8221 ;; Generated by peephole translating test to and. This shows up
8222 ;; often in fp comparisons.
8223 (define_insn "*andqi_ext_0_cc"
8224 [(set (reg FLAGS_REG)
8228 (match_operand 1 "ext_register_operand" "0")
8231 (match_operand 2 "const_int_operand" "n"))
8233 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242 "ix86_match_ccmode (insn, CCNOmode)"
8243 "and{b}\t{%2, %h0|%h0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "length_immediate" "1")
8246 (set_attr "modrm" "1")
8247 (set_attr "mode" "QI")])
8249 (define_insn "*andqi_ext_1"
8250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8255 (match_operand 1 "ext_register_operand" "0,0")
8259 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8260 (clobber (reg:CC FLAGS_REG))]
8262 "and{b}\t{%2, %h0|%h0, %2}"
8263 [(set_attr "isa" "*,nox64")
8264 (set_attr "type" "alu")
8265 (set_attr "length_immediate" "0")
8266 (set_attr "mode" "QI")])
8268 (define_insn "*andqi_ext_2"
8269 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8274 (match_operand 1 "ext_register_operand" "%0")
8278 (match_operand 2 "ext_register_operand" "Q")
8281 (clobber (reg:CC FLAGS_REG))]
8283 "and{b}\t{%h2, %h0|%h0, %h2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "QI")])
8288 ;; Convert wide AND instructions with immediate operand to shorter QImode
8289 ;; equivalents when possible.
8290 ;; Don't do the splitting with memory operands, since it introduces risk
8291 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8292 ;; for size, but that can (should?) be handled by generic code instead.
8294 [(set (match_operand 0 "register_operand")
8295 (and (match_operand 1 "register_operand")
8296 (match_operand 2 "const_int_operand")))
8297 (clobber (reg:CC FLAGS_REG))]
8299 && QI_REG_P (operands[0])
8300 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8301 && !(~INTVAL (operands[2]) & ~(255 << 8))
8302 && GET_MODE (operands[0]) != QImode"
8303 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8304 (and:SI (zero_extract:SI (match_dup 1)
8305 (const_int 8) (const_int 8))
8307 (clobber (reg:CC FLAGS_REG))])]
8309 operands[0] = gen_lowpart (SImode, operands[0]);
8310 operands[1] = gen_lowpart (SImode, operands[1]);
8311 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8314 ;; Since AND can be encoded with sign extended immediate, this is only
8315 ;; profitable when 7th bit is not set.
8317 [(set (match_operand 0 "register_operand")
8318 (and (match_operand 1 "general_operand")
8319 (match_operand 2 "const_int_operand")))
8320 (clobber (reg:CC FLAGS_REG))]
8322 && ANY_QI_REG_P (operands[0])
8323 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8324 && !(~INTVAL (operands[2]) & ~255)
8325 && !(INTVAL (operands[2]) & 128)
8326 && GET_MODE (operands[0]) != QImode"
8327 [(parallel [(set (strict_low_part (match_dup 0))
8328 (and:QI (match_dup 1)
8330 (clobber (reg:CC FLAGS_REG))])]
8332 operands[0] = gen_lowpart (QImode, operands[0]);
8333 operands[1] = gen_lowpart (QImode, operands[1]);
8334 operands[2] = gen_lowpart (QImode, operands[2]);
8337 ;; Logical inclusive and exclusive OR instructions
8339 ;; %%% This used to optimize known byte-wide and operations to memory.
8340 ;; If this is considered useful, it should be done with splitters.
8342 (define_expand "<code><mode>3"
8343 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8344 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8345 (match_operand:SWIM 2 "<general_operand>")))]
8347 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8349 (define_insn "*<code><mode>_1"
8350 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8352 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8353 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8354 (clobber (reg:CC FLAGS_REG))]
8355 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8357 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8358 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8359 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8360 [(set_attr "type" "alu,alu,msklog")
8361 (set_attr "mode" "<MODE>")])
8363 (define_insn "*<code>hi_1"
8364 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8366 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8367 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8368 (clobber (reg:CC FLAGS_REG))]
8369 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8371 <logic>{w}\t{%2, %0|%0, %2}
8372 <logic>{w}\t{%2, %0|%0, %2}
8373 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8374 [(set_attr "type" "alu,alu,msklog")
8375 (set_attr "mode" "HI")])
8377 ;; %%% Potential partial reg stall on alternative 2. What to do?
8378 (define_insn "*<code>qi_1"
8379 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8380 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8381 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8382 (clobber (reg:CC FLAGS_REG))]
8383 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8385 <logic>{b}\t{%2, %0|%0, %2}
8386 <logic>{b}\t{%2, %0|%0, %2}
8387 <logic>{l}\t{%k2, %k0|%k0, %k2}
8388 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8389 [(set_attr "type" "alu,alu,alu,msklog")
8390 (set_attr "mode" "QI,QI,SI,HI")])
8392 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8393 (define_insn "*<code>si_1_zext"
8394 [(set (match_operand:DI 0 "register_operand" "=r")
8396 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8397 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8398 (clobber (reg:CC FLAGS_REG))]
8399 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8400 "<logic>{l}\t{%2, %k0|%k0, %2}"
8401 [(set_attr "type" "alu")
8402 (set_attr "mode" "SI")])
8404 (define_insn "*<code>si_1_zext_imm"
8405 [(set (match_operand:DI 0 "register_operand" "=r")
8407 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8408 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8409 (clobber (reg:CC FLAGS_REG))]
8410 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8411 "<logic>{l}\t{%2, %k0|%k0, %2}"
8412 [(set_attr "type" "alu")
8413 (set_attr "mode" "SI")])
8415 (define_insn "*<code>qi_1_slp"
8416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8417 (any_or:QI (match_dup 0)
8418 (match_operand:QI 1 "general_operand" "qmn,qn")))
8419 (clobber (reg:CC FLAGS_REG))]
8420 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8422 "<logic>{b}\t{%1, %0|%0, %1}"
8423 [(set_attr "type" "alu1")
8424 (set_attr "mode" "QI")])
8426 (define_insn "*<code><mode>_2"
8427 [(set (reg FLAGS_REG)
8428 (compare (any_or:SWI
8429 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8430 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8432 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8433 (any_or:SWI (match_dup 1) (match_dup 2)))]
8434 "ix86_match_ccmode (insn, CCNOmode)
8435 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8436 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8437 [(set_attr "type" "alu")
8438 (set_attr "mode" "<MODE>")])
8440 (define_insn "kxnor<mode>"
8441 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8444 (match_operand:SWI12 1 "register_operand" "0,k")
8445 (match_operand:SWI12 2 "register_operand" "r,k"))))
8446 (clobber (reg:CC FLAGS_REG))]
8449 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8450 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8451 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8453 [(set_attr "type" "*,msklog")
8454 (set_attr "prefix" "*,vex")
8455 (set_attr "mode" "<MODE>")])
8457 (define_insn "kxnor<mode>"
8458 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8461 (match_operand:SWI48x 1 "register_operand" "0,k")
8462 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8463 (clobber (reg:CC FLAGS_REG))]
8467 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8468 [(set_attr "type" "*,msklog")
8469 (set_attr "prefix" "*,vex")
8470 (set_attr "mode" "<MODE>")])
8473 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8477 (match_operand:SWI1248x 1 "general_reg_operand"))))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "TARGET_AVX512F && reload_completed"
8480 [(parallel [(set (match_dup 0)
8481 (xor:SWI1248x (match_dup 0)
8483 (clobber (reg:CC FLAGS_REG))])
8485 (not:SWI1248x (match_dup 0)))])
8487 ;;There are kortrest[bdq] but no intrinsics for them.
8488 ;;We probably don't need to implement them.
8489 (define_insn "kortestzhi"
8490 [(set (reg:CCZ FLAGS_REG)
8493 (match_operand:HI 0 "register_operand" "k")
8494 (match_operand:HI 1 "register_operand" "k"))
8496 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8497 "kortestw\t{%1, %0|%0, %1}"
8498 [(set_attr "mode" "HI")
8499 (set_attr "type" "msklog")
8500 (set_attr "prefix" "vex")])
8502 (define_insn "kortestchi"
8503 [(set (reg:CCC FLAGS_REG)
8506 (match_operand:HI 0 "register_operand" "k")
8507 (match_operand:HI 1 "register_operand" "k"))
8509 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8510 "kortestw\t{%1, %0|%0, %1}"
8511 [(set_attr "mode" "HI")
8512 (set_attr "type" "msklog")
8513 (set_attr "prefix" "vex")])
8515 (define_insn "kunpckhi"
8516 [(set (match_operand:HI 0 "register_operand" "=k")
8519 (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8521 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8523 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8524 [(set_attr "mode" "HI")
8525 (set_attr "type" "msklog")
8526 (set_attr "prefix" "vex")])
8528 (define_insn "kunpcksi"
8529 [(set (match_operand:SI 0 "register_operand" "=k")
8532 (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8534 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8536 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8537 [(set_attr "mode" "SI")])
8539 (define_insn "kunpckdi"
8540 [(set (match_operand:DI 0 "register_operand" "=k")
8543 (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8545 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8547 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8548 [(set_attr "mode" "DI")])
8550 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8551 ;; ??? Special case for immediate operand is missing - it is tricky.
8552 (define_insn "*<code>si_2_zext"
8553 [(set (reg FLAGS_REG)
8554 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8555 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8557 (set (match_operand:DI 0 "register_operand" "=r")
8558 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8560 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8561 "<logic>{l}\t{%2, %k0|%k0, %2}"
8562 [(set_attr "type" "alu")
8563 (set_attr "mode" "SI")])
8565 (define_insn "*<code>si_2_zext_imm"
8566 [(set (reg FLAGS_REG)
8568 (match_operand:SI 1 "nonimmediate_operand" "%0")
8569 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8571 (set (match_operand:DI 0 "register_operand" "=r")
8572 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8574 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8575 "<logic>{l}\t{%2, %k0|%k0, %2}"
8576 [(set_attr "type" "alu")
8577 (set_attr "mode" "SI")])
8579 (define_insn "*<code>qi_2_slp"
8580 [(set (reg FLAGS_REG)
8581 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8582 (match_operand:QI 1 "general_operand" "qmn,qn"))
8584 (set (strict_low_part (match_dup 0))
8585 (any_or:QI (match_dup 0) (match_dup 1)))]
8586 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8587 && ix86_match_ccmode (insn, CCNOmode)
8588 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8589 "<logic>{b}\t{%1, %0|%0, %1}"
8590 [(set_attr "type" "alu1")
8591 (set_attr "mode" "QI")])
8593 (define_insn "*<code><mode>_3"
8594 [(set (reg FLAGS_REG)
8595 (compare (any_or:SWI
8596 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8597 (match_operand:SWI 2 "<general_operand>" "<g>"))
8599 (clobber (match_scratch:SWI 0 "=<r>"))]
8600 "ix86_match_ccmode (insn, CCNOmode)
8601 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8602 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "<MODE>")])
8606 (define_insn "*<code>qi_ext_0"
8607 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8612 (match_operand 1 "ext_register_operand" "0")
8615 (match_operand 2 "const_int_operand" "n")))
8616 (clobber (reg:CC FLAGS_REG))]
8617 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8618 "<logic>{b}\t{%2, %h0|%h0, %2}"
8619 [(set_attr "type" "alu")
8620 (set_attr "length_immediate" "1")
8621 (set_attr "modrm" "1")
8622 (set_attr "mode" "QI")])
8624 (define_insn "*<code>qi_ext_1"
8625 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8630 (match_operand 1 "ext_register_operand" "0,0")
8634 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8637 "<logic>{b}\t{%2, %h0|%h0, %2}"
8638 [(set_attr "isa" "*,nox64")
8639 (set_attr "type" "alu")
8640 (set_attr "length_immediate" "0")
8641 (set_attr "mode" "QI")])
8643 (define_insn "*<code>qi_ext_2"
8644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8648 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8651 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8654 (clobber (reg:CC FLAGS_REG))]
8655 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8656 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8657 [(set_attr "type" "alu")
8658 (set_attr "length_immediate" "0")
8659 (set_attr "mode" "QI")])
8662 [(set (match_operand 0 "register_operand")
8663 (any_or (match_operand 1 "register_operand")
8664 (match_operand 2 "const_int_operand")))
8665 (clobber (reg:CC FLAGS_REG))]
8667 && QI_REG_P (operands[0])
8668 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8669 && !(INTVAL (operands[2]) & ~(255 << 8))
8670 && GET_MODE (operands[0]) != QImode"
8671 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8672 (any_or:SI (zero_extract:SI (match_dup 1)
8673 (const_int 8) (const_int 8))
8675 (clobber (reg:CC FLAGS_REG))])]
8677 operands[0] = gen_lowpart (SImode, operands[0]);
8678 operands[1] = gen_lowpart (SImode, operands[1]);
8679 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8682 ;; Since OR can be encoded with sign extended immediate, this is only
8683 ;; profitable when 7th bit is set.
8685 [(set (match_operand 0 "register_operand")
8686 (any_or (match_operand 1 "general_operand")
8687 (match_operand 2 "const_int_operand")))
8688 (clobber (reg:CC FLAGS_REG))]
8690 && ANY_QI_REG_P (operands[0])
8691 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8692 && !(INTVAL (operands[2]) & ~255)
8693 && (INTVAL (operands[2]) & 128)
8694 && GET_MODE (operands[0]) != QImode"
8695 [(parallel [(set (strict_low_part (match_dup 0))
8696 (any_or:QI (match_dup 1)
8698 (clobber (reg:CC FLAGS_REG))])]
8700 operands[0] = gen_lowpart (QImode, operands[0]);
8701 operands[1] = gen_lowpart (QImode, operands[1]);
8702 operands[2] = gen_lowpart (QImode, operands[2]);
8705 (define_expand "xorqi_cc_ext_1"
8707 (set (reg:CCNO FLAGS_REG)
8711 (match_operand 1 "ext_register_operand")
8714 (match_operand:QI 2 "const_int_operand"))
8716 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8726 (define_insn "*xorqi_cc_ext_1"
8727 [(set (reg FLAGS_REG)
8731 (match_operand 1 "ext_register_operand" "0,0")
8734 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8736 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8745 "ix86_match_ccmode (insn, CCNOmode)"
8746 "xor{b}\t{%2, %h0|%h0, %2}"
8747 [(set_attr "isa" "*,nox64")
8748 (set_attr "type" "alu")
8749 (set_attr "modrm" "1")
8750 (set_attr "mode" "QI")])
8752 ;; Negation instructions
8754 (define_expand "neg<mode>2"
8755 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8756 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8758 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8760 (define_insn_and_split "*neg<dwi>2_doubleword"
8761 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8762 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8763 (clobber (reg:CC FLAGS_REG))]
8764 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8768 [(set (reg:CCZ FLAGS_REG)
8769 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8770 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8773 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8776 (clobber (reg:CC FLAGS_REG))])
8779 (neg:DWIH (match_dup 2)))
8780 (clobber (reg:CC FLAGS_REG))])]
8781 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8783 (define_insn "*neg<mode>2_1"
8784 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8785 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8786 (clobber (reg:CC FLAGS_REG))]
8787 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8788 "neg{<imodesuffix>}\t%0"
8789 [(set_attr "type" "negnot")
8790 (set_attr "mode" "<MODE>")])
8792 ;; Combine is quite creative about this pattern.
8793 (define_insn "*negsi2_1_zext"
8794 [(set (match_operand:DI 0 "register_operand" "=r")
8796 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8799 (clobber (reg:CC FLAGS_REG))]
8800 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8802 [(set_attr "type" "negnot")
8803 (set_attr "mode" "SI")])
8805 ;; The problem with neg is that it does not perform (compare x 0),
8806 ;; it really performs (compare 0 x), which leaves us with the zero
8807 ;; flag being the only useful item.
8809 (define_insn "*neg<mode>2_cmpz"
8810 [(set (reg:CCZ FLAGS_REG)
8812 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8814 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8815 (neg:SWI (match_dup 1)))]
8816 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8817 "neg{<imodesuffix>}\t%0"
8818 [(set_attr "type" "negnot")
8819 (set_attr "mode" "<MODE>")])
8821 (define_insn "*negsi2_cmpz_zext"
8822 [(set (reg:CCZ FLAGS_REG)
8826 (match_operand:DI 1 "register_operand" "0")
8830 (set (match_operand:DI 0 "register_operand" "=r")
8831 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8834 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8836 [(set_attr "type" "negnot")
8837 (set_attr "mode" "SI")])
8839 ;; Negate with jump on overflow.
8840 (define_expand "negv<mode>3"
8841 [(parallel [(set (reg:CCO FLAGS_REG)
8842 (ne:CCO (match_operand:SWI 1 "register_operand")
8844 (set (match_operand:SWI 0 "register_operand")
8845 (neg:SWI (match_dup 1)))])
8846 (set (pc) (if_then_else
8847 (eq (reg:CCO FLAGS_REG) (const_int 0))
8848 (label_ref (match_operand 2))
8853 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8857 (define_insn "*negv<mode>3"
8858 [(set (reg:CCO FLAGS_REG)
8859 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8860 (match_operand:SWI 2 "const_int_operand")))
8861 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8862 (neg:SWI (match_dup 1)))]
8863 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8864 && mode_signbit_p (<MODE>mode, operands[2])"
8865 "neg{<imodesuffix>}\t%0"
8866 [(set_attr "type" "negnot")
8867 (set_attr "mode" "<MODE>")])
8869 ;; Changing of sign for FP values is doable using integer unit too.
8871 (define_expand "<code><mode>2"
8872 [(set (match_operand:X87MODEF 0 "register_operand")
8873 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8874 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8875 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8877 (define_insn "*absneg<mode>2_mixed"
8878 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8879 (match_operator:MODEF 3 "absneg_operator"
8880 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8881 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8882 (clobber (reg:CC FLAGS_REG))]
8883 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8886 (define_insn "*absneg<mode>2_sse"
8887 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8888 (match_operator:MODEF 3 "absneg_operator"
8889 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8890 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8895 (define_insn "*absneg<mode>2_i387"
8896 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8897 (match_operator:X87MODEF 3 "absneg_operator"
8898 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8899 (use (match_operand 2))
8900 (clobber (reg:CC FLAGS_REG))]
8901 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8904 (define_expand "<code>tf2"
8905 [(set (match_operand:TF 0 "register_operand")
8906 (absneg:TF (match_operand:TF 1 "register_operand")))]
8908 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8910 (define_insn "*absnegtf2_sse"
8911 [(set (match_operand:TF 0 "register_operand" "=x,x")
8912 (match_operator:TF 3 "absneg_operator"
8913 [(match_operand:TF 1 "register_operand" "0,x")]))
8914 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8915 (clobber (reg:CC FLAGS_REG))]
8919 ;; Splitters for fp abs and neg.
8922 [(set (match_operand 0 "fp_register_operand")
8923 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8924 (use (match_operand 2))
8925 (clobber (reg:CC FLAGS_REG))]
8927 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8930 [(set (match_operand 0 "register_operand")
8931 (match_operator 3 "absneg_operator"
8932 [(match_operand 1 "register_operand")]))
8933 (use (match_operand 2 "nonimmediate_operand"))
8934 (clobber (reg:CC FLAGS_REG))]
8935 "reload_completed && SSE_REG_P (operands[0])"
8936 [(set (match_dup 0) (match_dup 3))]
8938 machine_mode mode = GET_MODE (operands[0]);
8939 machine_mode vmode = GET_MODE (operands[2]);
8942 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8943 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8944 if (operands_match_p (operands[0], operands[2]))
8945 std::swap (operands[1], operands[2]);
8946 if (GET_CODE (operands[3]) == ABS)
8947 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8949 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8954 [(set (match_operand:SF 0 "register_operand")
8955 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8956 (use (match_operand:V4SF 2))
8957 (clobber (reg:CC FLAGS_REG))]
8959 [(parallel [(set (match_dup 0) (match_dup 1))
8960 (clobber (reg:CC FLAGS_REG))])]
8963 operands[0] = gen_lowpart (SImode, operands[0]);
8964 if (GET_CODE (operands[1]) == ABS)
8966 tmp = gen_int_mode (0x7fffffff, SImode);
8967 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8971 tmp = gen_int_mode (0x80000000, SImode);
8972 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8978 [(set (match_operand:DF 0 "register_operand")
8979 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8980 (use (match_operand 2))
8981 (clobber (reg:CC FLAGS_REG))]
8983 [(parallel [(set (match_dup 0) (match_dup 1))
8984 (clobber (reg:CC FLAGS_REG))])]
8989 tmp = gen_lowpart (DImode, operands[0]);
8990 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8993 if (GET_CODE (operands[1]) == ABS)
8996 tmp = gen_rtx_NOT (DImode, tmp);
9000 operands[0] = gen_highpart (SImode, operands[0]);
9001 if (GET_CODE (operands[1]) == ABS)
9003 tmp = gen_int_mode (0x7fffffff, SImode);
9004 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9008 tmp = gen_int_mode (0x80000000, SImode);
9009 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9016 [(set (match_operand:XF 0 "register_operand")
9017 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9018 (use (match_operand 2))
9019 (clobber (reg:CC FLAGS_REG))]
9021 [(parallel [(set (match_dup 0) (match_dup 1))
9022 (clobber (reg:CC FLAGS_REG))])]
9025 operands[0] = gen_rtx_REG (SImode,
9026 true_regnum (operands[0])
9027 + (TARGET_64BIT ? 1 : 2));
9028 if (GET_CODE (operands[1]) == ABS)
9030 tmp = GEN_INT (0x7fff);
9031 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9035 tmp = GEN_INT (0x8000);
9036 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9041 ;; Conditionalize these after reload. If they match before reload, we
9042 ;; lose the clobber and ability to use integer instructions.
9044 (define_insn "*<code><mode>2_1"
9045 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9046 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9048 && (reload_completed
9049 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9050 "f<absneg_mnemonic>"
9051 [(set_attr "type" "fsgn")
9052 (set_attr "mode" "<MODE>")])
9054 (define_insn "*<code>extendsfdf2"
9055 [(set (match_operand:DF 0 "register_operand" "=f")
9056 (absneg:DF (float_extend:DF
9057 (match_operand:SF 1 "register_operand" "0"))))]
9058 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9059 "f<absneg_mnemonic>"
9060 [(set_attr "type" "fsgn")
9061 (set_attr "mode" "DF")])
9063 (define_insn "*<code>extendsfxf2"
9064 [(set (match_operand:XF 0 "register_operand" "=f")
9065 (absneg:XF (float_extend:XF
9066 (match_operand:SF 1 "register_operand" "0"))))]
9068 "f<absneg_mnemonic>"
9069 [(set_attr "type" "fsgn")
9070 (set_attr "mode" "XF")])
9072 (define_insn "*<code>extenddfxf2"
9073 [(set (match_operand:XF 0 "register_operand" "=f")
9074 (absneg:XF (float_extend:XF
9075 (match_operand:DF 1 "register_operand" "0"))))]
9077 "f<absneg_mnemonic>"
9078 [(set_attr "type" "fsgn")
9079 (set_attr "mode" "XF")])
9081 ;; Copysign instructions
9083 (define_mode_iterator CSGNMODE [SF DF TF])
9084 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9086 (define_expand "copysign<mode>3"
9087 [(match_operand:CSGNMODE 0 "register_operand")
9088 (match_operand:CSGNMODE 1 "nonmemory_operand")
9089 (match_operand:CSGNMODE 2 "register_operand")]
9090 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9091 || (TARGET_SSE && (<MODE>mode == TFmode))"
9092 "ix86_expand_copysign (operands); DONE;")
9094 (define_insn_and_split "copysign<mode>3_const"
9095 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9097 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9098 (match_operand:CSGNMODE 2 "register_operand" "0")
9099 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9101 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9102 || (TARGET_SSE && (<MODE>mode == TFmode))"
9104 "&& reload_completed"
9106 "ix86_split_copysign_const (operands); DONE;")
9108 (define_insn "copysign<mode>3_var"
9109 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9111 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9112 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9113 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9114 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9116 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9117 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9118 || (TARGET_SSE && (<MODE>mode == TFmode))"
9122 [(set (match_operand:CSGNMODE 0 "register_operand")
9124 [(match_operand:CSGNMODE 2 "register_operand")
9125 (match_operand:CSGNMODE 3 "register_operand")
9126 (match_operand:<CSGNVMODE> 4)
9127 (match_operand:<CSGNVMODE> 5)]
9129 (clobber (match_scratch:<CSGNVMODE> 1))]
9130 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9131 || (TARGET_SSE && (<MODE>mode == TFmode)))
9132 && reload_completed"
9134 "ix86_split_copysign_var (operands); DONE;")
9136 ;; One complement instructions
9138 (define_expand "one_cmpl<mode>2"
9139 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9140 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9142 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9144 (define_insn "*one_cmpl<mode>2_1"
9145 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9146 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9147 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9149 not{<imodesuffix>}\t%0
9150 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9151 [(set_attr "isa" "*,avx512bw")
9152 (set_attr "type" "negnot,msklog")
9153 (set_attr "prefix" "*,vex")
9154 (set_attr "mode" "<MODE>")])
9156 (define_insn "*one_cmplhi2_1"
9157 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9158 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9159 "ix86_unary_operator_ok (NOT, HImode, operands)"
9162 knotw\t{%1, %0|%0, %1}"
9163 [(set_attr "isa" "*,avx512f")
9164 (set_attr "type" "negnot,msklog")
9165 (set_attr "prefix" "*,vex")
9166 (set_attr "mode" "HI")])
9168 ;; %%% Potential partial reg stall on alternative 1. What to do?
9169 (define_insn "*one_cmplqi2_1"
9170 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9171 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9172 "ix86_unary_operator_ok (NOT, QImode, operands)"
9174 switch (which_alternative)
9177 return "not{b}\t%0";
9179 return "not{l}\t%k0";
9181 if (TARGET_AVX512DQ)
9182 return "knotb\t{%1, %0|%0, %1}";
9183 return "knotw\t{%1, %0|%0, %1}";
9188 [(set_attr "isa" "*,*,avx512f")
9189 (set_attr "type" "negnot,negnot,msklog")
9190 (set_attr "prefix" "*,*,vex")
9191 (set_attr "mode" "QI,SI,QI")])
9193 ;; ??? Currently never generated - xor is used instead.
9194 (define_insn "*one_cmplsi2_1_zext"
9195 [(set (match_operand:DI 0 "register_operand" "=r")
9197 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9198 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9200 [(set_attr "type" "negnot")
9201 (set_attr "mode" "SI")])
9203 (define_insn "*one_cmpl<mode>2_2"
9204 [(set (reg FLAGS_REG)
9205 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9207 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9208 (not:SWI (match_dup 1)))]
9209 "ix86_match_ccmode (insn, CCNOmode)
9210 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9212 [(set_attr "type" "alu1")
9213 (set_attr "mode" "<MODE>")])
9216 [(set (match_operand 0 "flags_reg_operand")
9217 (match_operator 2 "compare_operator"
9218 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9220 (set (match_operand:SWI 1 "nonimmediate_operand")
9221 (not:SWI (match_dup 3)))]
9222 "ix86_match_ccmode (insn, CCNOmode)"
9223 [(parallel [(set (match_dup 0)
9224 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9227 (xor:SWI (match_dup 3) (const_int -1)))])])
9229 ;; ??? Currently never generated - xor is used instead.
9230 (define_insn "*one_cmplsi2_2_zext"
9231 [(set (reg FLAGS_REG)
9232 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9234 (set (match_operand:DI 0 "register_operand" "=r")
9235 (zero_extend:DI (not:SI (match_dup 1))))]
9236 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9237 && ix86_unary_operator_ok (NOT, SImode, operands)"
9239 [(set_attr "type" "alu1")
9240 (set_attr "mode" "SI")])
9243 [(set (match_operand 0 "flags_reg_operand")
9244 (match_operator 2 "compare_operator"
9245 [(not:SI (match_operand:SI 3 "register_operand"))
9247 (set (match_operand:DI 1 "register_operand")
9248 (zero_extend:DI (not:SI (match_dup 3))))]
9249 "ix86_match_ccmode (insn, CCNOmode)"
9250 [(parallel [(set (match_dup 0)
9251 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9254 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9256 ;; Shift instructions
9258 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9259 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9260 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9261 ;; from the assembler input.
9263 ;; This instruction shifts the target reg/mem as usual, but instead of
9264 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9265 ;; is a left shift double, bits are taken from the high order bits of
9266 ;; reg, else if the insn is a shift right double, bits are taken from the
9267 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9268 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9270 ;; Since sh[lr]d does not change the `reg' operand, that is done
9271 ;; separately, making all shifts emit pairs of shift double and normal
9272 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9273 ;; support a 63 bit shift, each shift where the count is in a reg expands
9274 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9276 ;; If the shift count is a constant, we need never emit more than one
9277 ;; shift pair, instead using moves and sign extension for counts greater
9280 (define_expand "ashl<mode>3"
9281 [(set (match_operand:SDWIM 0 "<shift_operand>")
9282 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9283 (match_operand:QI 2 "nonmemory_operand")))]
9285 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9287 (define_insn "*ashl<mode>3_doubleword"
9288 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9289 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9290 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9291 (clobber (reg:CC FLAGS_REG))]
9294 [(set_attr "type" "multi")])
9297 [(set (match_operand:DWI 0 "register_operand")
9298 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9299 (match_operand:QI 2 "nonmemory_operand")))
9300 (clobber (reg:CC FLAGS_REG))]
9301 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9303 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9305 ;; By default we don't ask for a scratch register, because when DWImode
9306 ;; values are manipulated, registers are already at a premium. But if
9307 ;; we have one handy, we won't turn it away.
9310 [(match_scratch:DWIH 3 "r")
9311 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9313 (match_operand:<DWI> 1 "nonmemory_operand")
9314 (match_operand:QI 2 "nonmemory_operand")))
9315 (clobber (reg:CC FLAGS_REG))])
9319 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9321 (define_insn "x86_64_shld"
9322 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9323 (ior:DI (ashift:DI (match_dup 0)
9324 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9325 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9326 (minus:QI (const_int 64) (match_dup 2)))))
9327 (clobber (reg:CC FLAGS_REG))]
9329 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9330 [(set_attr "type" "ishift")
9331 (set_attr "prefix_0f" "1")
9332 (set_attr "mode" "DI")
9333 (set_attr "athlon_decode" "vector")
9334 (set_attr "amdfam10_decode" "vector")
9335 (set_attr "bdver1_decode" "vector")])
9337 (define_insn "x86_shld"
9338 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9339 (ior:SI (ashift:SI (match_dup 0)
9340 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9341 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9342 (minus:QI (const_int 32) (match_dup 2)))))
9343 (clobber (reg:CC FLAGS_REG))]
9345 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9346 [(set_attr "type" "ishift")
9347 (set_attr "prefix_0f" "1")
9348 (set_attr "mode" "SI")
9349 (set_attr "pent_pair" "np")
9350 (set_attr "athlon_decode" "vector")
9351 (set_attr "amdfam10_decode" "vector")
9352 (set_attr "bdver1_decode" "vector")])
9354 (define_expand "x86_shift<mode>_adj_1"
9355 [(set (reg:CCZ FLAGS_REG)
9356 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9359 (set (match_operand:SWI48 0 "register_operand")
9360 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9361 (match_operand:SWI48 1 "register_operand")
9364 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9365 (match_operand:SWI48 3 "register_operand")
9368 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9370 (define_expand "x86_shift<mode>_adj_2"
9371 [(use (match_operand:SWI48 0 "register_operand"))
9372 (use (match_operand:SWI48 1 "register_operand"))
9373 (use (match_operand:QI 2 "register_operand"))]
9376 rtx_code_label *label = gen_label_rtx ();
9379 emit_insn (gen_testqi_ccz_1 (operands[2],
9380 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9382 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9383 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9384 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9385 gen_rtx_LABEL_REF (VOIDmode, label),
9387 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9388 JUMP_LABEL (tmp) = label;
9390 emit_move_insn (operands[0], operands[1]);
9391 ix86_expand_clear (operands[1]);
9394 LABEL_NUSES (label) = 1;
9399 ;; Avoid useless masking of count operand.
9400 (define_insn "*ashl<mode>3_mask"
9401 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9403 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9406 (match_operand:SI 2 "register_operand" "c")
9407 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9410 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9411 == GET_MODE_BITSIZE (<MODE>mode)-1"
9413 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9415 [(set_attr "type" "ishift")
9416 (set_attr "mode" "<MODE>")])
9418 (define_insn "*bmi2_ashl<mode>3_1"
9419 [(set (match_operand:SWI48 0 "register_operand" "=r")
9420 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9421 (match_operand:SWI48 2 "register_operand" "r")))]
9423 "shlx\t{%2, %1, %0|%0, %1, %2}"
9424 [(set_attr "type" "ishiftx")
9425 (set_attr "mode" "<MODE>")])
9427 (define_insn "*ashl<mode>3_1"
9428 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9429 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9430 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9434 switch (get_attr_type (insn))
9441 gcc_assert (operands[2] == const1_rtx);
9442 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9443 return "add{<imodesuffix>}\t%0, %0";
9446 if (operands[2] == const1_rtx
9447 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9448 return "sal{<imodesuffix>}\t%0";
9450 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9453 [(set_attr "isa" "*,*,bmi2")
9455 (cond [(eq_attr "alternative" "1")
9456 (const_string "lea")
9457 (eq_attr "alternative" "2")
9458 (const_string "ishiftx")
9459 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460 (match_operand 0 "register_operand"))
9461 (match_operand 2 "const1_operand"))
9462 (const_string "alu")
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9473 (const_string "*")))
9474 (set_attr "mode" "<MODE>")])
9476 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9478 [(set (match_operand:SWI48 0 "register_operand")
9479 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9480 (match_operand:QI 2 "register_operand")))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "TARGET_BMI2 && reload_completed"
9484 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9485 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9487 (define_insn "*bmi2_ashlsi3_1_zext"
9488 [(set (match_operand:DI 0 "register_operand" "=r")
9490 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9491 (match_operand:SI 2 "register_operand" "r"))))]
9492 "TARGET_64BIT && TARGET_BMI2"
9493 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9494 [(set_attr "type" "ishiftx")
9495 (set_attr "mode" "SI")])
9497 (define_insn "*ashlsi3_1_zext"
9498 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9500 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9501 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9505 switch (get_attr_type (insn))
9512 gcc_assert (operands[2] == const1_rtx);
9513 return "add{l}\t%k0, %k0";
9516 if (operands[2] == const1_rtx
9517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9518 return "sal{l}\t%k0";
9520 return "sal{l}\t{%2, %k0|%k0, %2}";
9523 [(set_attr "isa" "*,*,bmi2")
9525 (cond [(eq_attr "alternative" "1")
9526 (const_string "lea")
9527 (eq_attr "alternative" "2")
9528 (const_string "ishiftx")
9529 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9530 (match_operand 2 "const1_operand"))
9531 (const_string "alu")
9533 (const_string "ishift")))
9534 (set (attr "length_immediate")
9536 (ior (eq_attr "type" "alu")
9537 (and (eq_attr "type" "ishift")
9538 (and (match_operand 2 "const1_operand")
9539 (ior (match_test "TARGET_SHIFT1")
9540 (match_test "optimize_function_for_size_p (cfun)")))))
9542 (const_string "*")))
9543 (set_attr "mode" "SI")])
9545 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9547 [(set (match_operand:DI 0 "register_operand")
9549 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9550 (match_operand:QI 2 "register_operand"))))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9554 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9555 "operands[2] = gen_lowpart (SImode, operands[2]);")
9557 (define_insn "*ashlhi3_1"
9558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9559 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9560 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9561 (clobber (reg:CC FLAGS_REG))]
9562 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9564 switch (get_attr_type (insn))
9570 gcc_assert (operands[2] == const1_rtx);
9571 return "add{w}\t%0, %0";
9574 if (operands[2] == const1_rtx
9575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9576 return "sal{w}\t%0";
9578 return "sal{w}\t{%2, %0|%0, %2}";
9582 (cond [(eq_attr "alternative" "1")
9583 (const_string "lea")
9584 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9585 (match_operand 0 "register_operand"))
9586 (match_operand 2 "const1_operand"))
9587 (const_string "alu")
9589 (const_string "ishift")))
9590 (set (attr "length_immediate")
9592 (ior (eq_attr "type" "alu")
9593 (and (eq_attr "type" "ishift")
9594 (and (match_operand 2 "const1_operand")
9595 (ior (match_test "TARGET_SHIFT1")
9596 (match_test "optimize_function_for_size_p (cfun)")))))
9598 (const_string "*")))
9599 (set_attr "mode" "HI,SI")])
9601 ;; %%% Potential partial reg stall on alternative 1. What to do?
9602 (define_insn "*ashlqi3_1"
9603 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9604 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9605 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9606 (clobber (reg:CC FLAGS_REG))]
9607 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9609 switch (get_attr_type (insn))
9615 gcc_assert (operands[2] == const1_rtx);
9616 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9617 return "add{l}\t%k0, %k0";
9619 return "add{b}\t%0, %0";
9622 if (operands[2] == const1_rtx
9623 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9625 if (get_attr_mode (insn) == MODE_SI)
9626 return "sal{l}\t%k0";
9628 return "sal{b}\t%0";
9632 if (get_attr_mode (insn) == MODE_SI)
9633 return "sal{l}\t{%2, %k0|%k0, %2}";
9635 return "sal{b}\t{%2, %0|%0, %2}";
9640 (cond [(eq_attr "alternative" "2")
9641 (const_string "lea")
9642 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9643 (match_operand 0 "register_operand"))
9644 (match_operand 2 "const1_operand"))
9645 (const_string "alu")
9647 (const_string "ishift")))
9648 (set (attr "length_immediate")
9650 (ior (eq_attr "type" "alu")
9651 (and (eq_attr "type" "ishift")
9652 (and (match_operand 2 "const1_operand")
9653 (ior (match_test "TARGET_SHIFT1")
9654 (match_test "optimize_function_for_size_p (cfun)")))))
9656 (const_string "*")))
9657 (set_attr "mode" "QI,SI,SI")])
9659 (define_insn "*ashlqi3_1_slp"
9660 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9661 (ashift:QI (match_dup 0)
9662 (match_operand:QI 1 "nonmemory_operand" "cI")))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "(optimize_function_for_size_p (cfun)
9665 || !TARGET_PARTIAL_FLAG_REG_STALL
9666 || (operands[1] == const1_rtx
9668 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9670 switch (get_attr_type (insn))
9673 gcc_assert (operands[1] == const1_rtx);
9674 return "add{b}\t%0, %0";
9677 if (operands[1] == const1_rtx
9678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9679 return "sal{b}\t%0";
9681 return "sal{b}\t{%1, %0|%0, %1}";
9685 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9686 (match_operand 0 "register_operand"))
9687 (match_operand 1 "const1_operand"))
9688 (const_string "alu")
9690 (const_string "ishift1")))
9691 (set (attr "length_immediate")
9693 (ior (eq_attr "type" "alu")
9694 (and (eq_attr "type" "ishift1")
9695 (and (match_operand 1 "const1_operand")
9696 (ior (match_test "TARGET_SHIFT1")
9697 (match_test "optimize_function_for_size_p (cfun)")))))
9699 (const_string "*")))
9700 (set_attr "mode" "QI")])
9702 ;; Convert ashift to the lea pattern to avoid flags dependency.
9704 [(set (match_operand 0 "register_operand")
9705 (ashift (match_operand 1 "index_register_operand")
9706 (match_operand:QI 2 "const_int_operand")))
9707 (clobber (reg:CC FLAGS_REG))]
9708 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9710 && true_regnum (operands[0]) != true_regnum (operands[1])"
9713 machine_mode mode = GET_MODE (operands[0]);
9716 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9719 operands[0] = gen_lowpart (mode, operands[0]);
9720 operands[1] = gen_lowpart (mode, operands[1]);
9723 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9725 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9727 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9731 ;; Convert ashift to the lea pattern to avoid flags dependency.
9733 [(set (match_operand:DI 0 "register_operand")
9735 (ashift:SI (match_operand:SI 1 "index_register_operand")
9736 (match_operand:QI 2 "const_int_operand"))))
9737 (clobber (reg:CC FLAGS_REG))]
9738 "TARGET_64BIT && reload_completed
9739 && true_regnum (operands[0]) != true_regnum (operands[1])"
9741 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9743 operands[1] = gen_lowpart (SImode, operands[1]);
9744 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9747 ;; This pattern can't accept a variable shift count, since shifts by
9748 ;; zero don't affect the flags. We assume that shifts by constant
9749 ;; zero are optimized away.
9750 (define_insn "*ashl<mode>3_cmp"
9751 [(set (reg FLAGS_REG)
9753 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9754 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9756 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9757 (ashift:SWI (match_dup 1) (match_dup 2)))]
9758 "(optimize_function_for_size_p (cfun)
9759 || !TARGET_PARTIAL_FLAG_REG_STALL
9760 || (operands[2] == const1_rtx
9762 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9763 && ix86_match_ccmode (insn, CCGOCmode)
9764 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9766 switch (get_attr_type (insn))
9769 gcc_assert (operands[2] == const1_rtx);
9770 return "add{<imodesuffix>}\t%0, %0";
9773 if (operands[2] == const1_rtx
9774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9775 return "sal{<imodesuffix>}\t%0";
9777 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9781 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9782 (match_operand 0 "register_operand"))
9783 (match_operand 2 "const1_operand"))
9784 (const_string "alu")
9786 (const_string "ishift")))
9787 (set (attr "length_immediate")
9789 (ior (eq_attr "type" "alu")
9790 (and (eq_attr "type" "ishift")
9791 (and (match_operand 2 "const1_operand")
9792 (ior (match_test "TARGET_SHIFT1")
9793 (match_test "optimize_function_for_size_p (cfun)")))))
9795 (const_string "*")))
9796 (set_attr "mode" "<MODE>")])
9798 (define_insn "*ashlsi3_cmp_zext"
9799 [(set (reg FLAGS_REG)
9801 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9802 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9804 (set (match_operand:DI 0 "register_operand" "=r")
9805 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9807 && (optimize_function_for_size_p (cfun)
9808 || !TARGET_PARTIAL_FLAG_REG_STALL
9809 || (operands[2] == const1_rtx
9811 || TARGET_DOUBLE_WITH_ADD)))
9812 && ix86_match_ccmode (insn, CCGOCmode)
9813 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9815 switch (get_attr_type (insn))
9818 gcc_assert (operands[2] == const1_rtx);
9819 return "add{l}\t%k0, %k0";
9822 if (operands[2] == const1_rtx
9823 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9824 return "sal{l}\t%k0";
9826 return "sal{l}\t{%2, %k0|%k0, %2}";
9830 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9831 (match_operand 2 "const1_operand"))
9832 (const_string "alu")
9834 (const_string "ishift")))
9835 (set (attr "length_immediate")
9837 (ior (eq_attr "type" "alu")
9838 (and (eq_attr "type" "ishift")
9839 (and (match_operand 2 "const1_operand")
9840 (ior (match_test "TARGET_SHIFT1")
9841 (match_test "optimize_function_for_size_p (cfun)")))))
9843 (const_string "*")))
9844 (set_attr "mode" "SI")])
9846 (define_insn "*ashl<mode>3_cconly"
9847 [(set (reg FLAGS_REG)
9849 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9850 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9852 (clobber (match_scratch:SWI 0 "=<r>"))]
9853 "(optimize_function_for_size_p (cfun)
9854 || !TARGET_PARTIAL_FLAG_REG_STALL
9855 || (operands[2] == const1_rtx
9857 || TARGET_DOUBLE_WITH_ADD)))
9858 && ix86_match_ccmode (insn, CCGOCmode)"
9860 switch (get_attr_type (insn))
9863 gcc_assert (operands[2] == const1_rtx);
9864 return "add{<imodesuffix>}\t%0, %0";
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "sal{<imodesuffix>}\t%0";
9871 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9875 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9876 (match_operand 0 "register_operand"))
9877 (match_operand 2 "const1_operand"))
9878 (const_string "alu")
9880 (const_string "ishift")))
9881 (set (attr "length_immediate")
9883 (ior (eq_attr "type" "alu")
9884 (and (eq_attr "type" "ishift")
9885 (and (match_operand 2 "const1_operand")
9886 (ior (match_test "TARGET_SHIFT1")
9887 (match_test "optimize_function_for_size_p (cfun)")))))
9889 (const_string "*")))
9890 (set_attr "mode" "<MODE>")])
9892 ;; See comment above `ashl<mode>3' about how this works.
9894 (define_expand "<shift_insn><mode>3"
9895 [(set (match_operand:SDWIM 0 "<shift_operand>")
9896 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9897 (match_operand:QI 2 "nonmemory_operand")))]
9899 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9901 ;; Avoid useless masking of count operand.
9902 (define_insn "*<shift_insn><mode>3_mask"
9903 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9905 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9908 (match_operand:SI 2 "register_operand" "c")
9909 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9912 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9913 == GET_MODE_BITSIZE (<MODE>mode)-1"
9915 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9917 [(set_attr "type" "ishift")
9918 (set_attr "mode" "<MODE>")])
9920 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9921 [(set (match_operand:DWI 0 "register_operand" "=r")
9922 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9923 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9924 (clobber (reg:CC FLAGS_REG))]
9927 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9929 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9930 [(set_attr "type" "multi")])
9932 ;; By default we don't ask for a scratch register, because when DWImode
9933 ;; values are manipulated, registers are already at a premium. But if
9934 ;; we have one handy, we won't turn it away.
9937 [(match_scratch:DWIH 3 "r")
9938 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9940 (match_operand:<DWI> 1 "register_operand")
9941 (match_operand:QI 2 "nonmemory_operand")))
9942 (clobber (reg:CC FLAGS_REG))])
9946 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9948 (define_insn "x86_64_shrd"
9949 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9950 (ior:DI (lshiftrt:DI (match_dup 0)
9951 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9952 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9953 (minus:QI (const_int 64) (match_dup 2)))))
9954 (clobber (reg:CC FLAGS_REG))]
9956 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9957 [(set_attr "type" "ishift")
9958 (set_attr "prefix_0f" "1")
9959 (set_attr "mode" "DI")
9960 (set_attr "athlon_decode" "vector")
9961 (set_attr "amdfam10_decode" "vector")
9962 (set_attr "bdver1_decode" "vector")])
9964 (define_insn "x86_shrd"
9965 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9966 (ior:SI (lshiftrt:SI (match_dup 0)
9967 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9968 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9969 (minus:QI (const_int 32) (match_dup 2)))))
9970 (clobber (reg:CC FLAGS_REG))]
9972 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9973 [(set_attr "type" "ishift")
9974 (set_attr "prefix_0f" "1")
9975 (set_attr "mode" "SI")
9976 (set_attr "pent_pair" "np")
9977 (set_attr "athlon_decode" "vector")
9978 (set_attr "amdfam10_decode" "vector")
9979 (set_attr "bdver1_decode" "vector")])
9981 (define_insn "ashrdi3_cvt"
9982 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9983 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9984 (match_operand:QI 2 "const_int_operand")))
9985 (clobber (reg:CC FLAGS_REG))]
9986 "TARGET_64BIT && INTVAL (operands[2]) == 63
9987 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9988 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9991 sar{q}\t{%2, %0|%0, %2}"
9992 [(set_attr "type" "imovx,ishift")
9993 (set_attr "prefix_0f" "0,*")
9994 (set_attr "length_immediate" "0,*")
9995 (set_attr "modrm" "0,1")
9996 (set_attr "mode" "DI")])
9998 (define_insn "ashrsi3_cvt"
9999 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10000 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10001 (match_operand:QI 2 "const_int_operand")))
10002 (clobber (reg:CC FLAGS_REG))]
10003 "INTVAL (operands[2]) == 31
10004 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10005 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10008 sar{l}\t{%2, %0|%0, %2}"
10009 [(set_attr "type" "imovx,ishift")
10010 (set_attr "prefix_0f" "0,*")
10011 (set_attr "length_immediate" "0,*")
10012 (set_attr "modrm" "0,1")
10013 (set_attr "mode" "SI")])
10015 (define_insn "*ashrsi3_cvt_zext"
10016 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10018 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10019 (match_operand:QI 2 "const_int_operand"))))
10020 (clobber (reg:CC FLAGS_REG))]
10021 "TARGET_64BIT && INTVAL (operands[2]) == 31
10022 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10026 sar{l}\t{%2, %k0|%k0, %2}"
10027 [(set_attr "type" "imovx,ishift")
10028 (set_attr "prefix_0f" "0,*")
10029 (set_attr "length_immediate" "0,*")
10030 (set_attr "modrm" "0,1")
10031 (set_attr "mode" "SI")])
10033 (define_expand "x86_shift<mode>_adj_3"
10034 [(use (match_operand:SWI48 0 "register_operand"))
10035 (use (match_operand:SWI48 1 "register_operand"))
10036 (use (match_operand:QI 2 "register_operand"))]
10039 rtx_code_label *label = gen_label_rtx ();
10042 emit_insn (gen_testqi_ccz_1 (operands[2],
10043 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10045 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10046 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10047 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10048 gen_rtx_LABEL_REF (VOIDmode, label),
10050 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10051 JUMP_LABEL (tmp) = label;
10053 emit_move_insn (operands[0], operands[1]);
10054 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10055 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10056 emit_label (label);
10057 LABEL_NUSES (label) = 1;
10062 (define_insn "*bmi2_<shift_insn><mode>3_1"
10063 [(set (match_operand:SWI48 0 "register_operand" "=r")
10064 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10065 (match_operand:SWI48 2 "register_operand" "r")))]
10067 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10068 [(set_attr "type" "ishiftx")
10069 (set_attr "mode" "<MODE>")])
10071 (define_insn "*<shift_insn><mode>3_1"
10072 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10074 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10075 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10076 (clobber (reg:CC FLAGS_REG))]
10077 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10079 switch (get_attr_type (insn))
10085 if (operands[2] == const1_rtx
10086 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10087 return "<shift>{<imodesuffix>}\t%0";
10089 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10092 [(set_attr "isa" "*,bmi2")
10093 (set_attr "type" "ishift,ishiftx")
10094 (set (attr "length_immediate")
10096 (and (match_operand 2 "const1_operand")
10097 (ior (match_test "TARGET_SHIFT1")
10098 (match_test "optimize_function_for_size_p (cfun)")))
10100 (const_string "*")))
10101 (set_attr "mode" "<MODE>")])
10103 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10105 [(set (match_operand:SWI48 0 "register_operand")
10106 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10107 (match_operand:QI 2 "register_operand")))
10108 (clobber (reg:CC FLAGS_REG))]
10109 "TARGET_BMI2 && reload_completed"
10110 [(set (match_dup 0)
10111 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10112 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10114 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10115 [(set (match_operand:DI 0 "register_operand" "=r")
10117 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10118 (match_operand:SI 2 "register_operand" "r"))))]
10119 "TARGET_64BIT && TARGET_BMI2"
10120 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10121 [(set_attr "type" "ishiftx")
10122 (set_attr "mode" "SI")])
10124 (define_insn "*<shift_insn>si3_1_zext"
10125 [(set (match_operand:DI 0 "register_operand" "=r,r")
10127 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10128 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10129 (clobber (reg:CC FLAGS_REG))]
10130 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10132 switch (get_attr_type (insn))
10138 if (operands[2] == const1_rtx
10139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10140 return "<shift>{l}\t%k0";
10142 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10145 [(set_attr "isa" "*,bmi2")
10146 (set_attr "type" "ishift,ishiftx")
10147 (set (attr "length_immediate")
10149 (and (match_operand 2 "const1_operand")
10150 (ior (match_test "TARGET_SHIFT1")
10151 (match_test "optimize_function_for_size_p (cfun)")))
10153 (const_string "*")))
10154 (set_attr "mode" "SI")])
10156 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10158 [(set (match_operand:DI 0 "register_operand")
10160 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10161 (match_operand:QI 2 "register_operand"))))
10162 (clobber (reg:CC FLAGS_REG))]
10163 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10164 [(set (match_dup 0)
10165 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10166 "operands[2] = gen_lowpart (SImode, operands[2]);")
10168 (define_insn "*<shift_insn><mode>3_1"
10169 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10171 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10172 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10173 (clobber (reg:CC FLAGS_REG))]
10174 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10176 if (operands[2] == const1_rtx
10177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10178 return "<shift>{<imodesuffix>}\t%0";
10180 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10182 [(set_attr "type" "ishift")
10183 (set (attr "length_immediate")
10185 (and (match_operand 2 "const1_operand")
10186 (ior (match_test "TARGET_SHIFT1")
10187 (match_test "optimize_function_for_size_p (cfun)")))
10189 (const_string "*")))
10190 (set_attr "mode" "<MODE>")])
10192 (define_insn "*<shift_insn>qi3_1_slp"
10193 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10194 (any_shiftrt:QI (match_dup 0)
10195 (match_operand:QI 1 "nonmemory_operand" "cI")))
10196 (clobber (reg:CC FLAGS_REG))]
10197 "(optimize_function_for_size_p (cfun)
10198 || !TARGET_PARTIAL_REG_STALL
10199 || (operands[1] == const1_rtx
10200 && TARGET_SHIFT1))"
10202 if (operands[1] == const1_rtx
10203 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10204 return "<shift>{b}\t%0";
10206 return "<shift>{b}\t{%1, %0|%0, %1}";
10208 [(set_attr "type" "ishift1")
10209 (set (attr "length_immediate")
10211 (and (match_operand 1 "const1_operand")
10212 (ior (match_test "TARGET_SHIFT1")
10213 (match_test "optimize_function_for_size_p (cfun)")))
10215 (const_string "*")))
10216 (set_attr "mode" "QI")])
10218 ;; This pattern can't accept a variable shift count, since shifts by
10219 ;; zero don't affect the flags. We assume that shifts by constant
10220 ;; zero are optimized away.
10221 (define_insn "*<shift_insn><mode>3_cmp"
10222 [(set (reg FLAGS_REG)
10225 (match_operand:SWI 1 "nonimmediate_operand" "0")
10226 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10228 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10229 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10230 "(optimize_function_for_size_p (cfun)
10231 || !TARGET_PARTIAL_FLAG_REG_STALL
10232 || (operands[2] == const1_rtx
10234 && ix86_match_ccmode (insn, CCGOCmode)
10235 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10237 if (operands[2] == const1_rtx
10238 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10239 return "<shift>{<imodesuffix>}\t%0";
10241 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10243 [(set_attr "type" "ishift")
10244 (set (attr "length_immediate")
10246 (and (match_operand 2 "const1_operand")
10247 (ior (match_test "TARGET_SHIFT1")
10248 (match_test "optimize_function_for_size_p (cfun)")))
10250 (const_string "*")))
10251 (set_attr "mode" "<MODE>")])
10253 (define_insn "*<shift_insn>si3_cmp_zext"
10254 [(set (reg FLAGS_REG)
10256 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10257 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10259 (set (match_operand:DI 0 "register_operand" "=r")
10260 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10262 && (optimize_function_for_size_p (cfun)
10263 || !TARGET_PARTIAL_FLAG_REG_STALL
10264 || (operands[2] == const1_rtx
10266 && ix86_match_ccmode (insn, CCGOCmode)
10267 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10269 if (operands[2] == const1_rtx
10270 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10271 return "<shift>{l}\t%k0";
10273 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10275 [(set_attr "type" "ishift")
10276 (set (attr "length_immediate")
10278 (and (match_operand 2 "const1_operand")
10279 (ior (match_test "TARGET_SHIFT1")
10280 (match_test "optimize_function_for_size_p (cfun)")))
10282 (const_string "*")))
10283 (set_attr "mode" "SI")])
10285 (define_insn "*<shift_insn><mode>3_cconly"
10286 [(set (reg FLAGS_REG)
10289 (match_operand:SWI 1 "register_operand" "0")
10290 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10292 (clobber (match_scratch:SWI 0 "=<r>"))]
10293 "(optimize_function_for_size_p (cfun)
10294 || !TARGET_PARTIAL_FLAG_REG_STALL
10295 || (operands[2] == const1_rtx
10297 && ix86_match_ccmode (insn, CCGOCmode)"
10299 if (operands[2] == const1_rtx
10300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10301 return "<shift>{<imodesuffix>}\t%0";
10303 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10305 [(set_attr "type" "ishift")
10306 (set (attr "length_immediate")
10308 (and (match_operand 2 "const1_operand")
10309 (ior (match_test "TARGET_SHIFT1")
10310 (match_test "optimize_function_for_size_p (cfun)")))
10312 (const_string "*")))
10313 (set_attr "mode" "<MODE>")])
10315 ;; Rotate instructions
10317 (define_expand "<rotate_insn>ti3"
10318 [(set (match_operand:TI 0 "register_operand")
10319 (any_rotate:TI (match_operand:TI 1 "register_operand")
10320 (match_operand:QI 2 "nonmemory_operand")))]
10323 if (const_1_to_63_operand (operands[2], VOIDmode))
10324 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10325 (operands[0], operands[1], operands[2]));
10332 (define_expand "<rotate_insn>di3"
10333 [(set (match_operand:DI 0 "shiftdi_operand")
10334 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10335 (match_operand:QI 2 "nonmemory_operand")))]
10339 ix86_expand_binary_operator (<CODE>, DImode, operands);
10340 else if (const_1_to_31_operand (operands[2], VOIDmode))
10341 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10342 (operands[0], operands[1], operands[2]));
10349 (define_expand "<rotate_insn><mode>3"
10350 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10351 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10352 (match_operand:QI 2 "nonmemory_operand")))]
10354 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10356 ;; Avoid useless masking of count operand.
10357 (define_insn "*<rotate_insn><mode>3_mask"
10358 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10360 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10363 (match_operand:SI 2 "register_operand" "c")
10364 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10367 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10368 == GET_MODE_BITSIZE (<MODE>mode)-1"
10370 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10372 [(set_attr "type" "rotate")
10373 (set_attr "mode" "<MODE>")])
10375 ;; Implement rotation using two double-precision
10376 ;; shift instructions and a scratch register.
10378 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10379 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10380 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10381 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10382 (clobber (reg:CC FLAGS_REG))
10383 (clobber (match_scratch:DWIH 3 "=&r"))]
10387 [(set (match_dup 3) (match_dup 4))
10389 [(set (match_dup 4)
10390 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10391 (lshiftrt:DWIH (match_dup 5)
10392 (minus:QI (match_dup 6) (match_dup 2)))))
10393 (clobber (reg:CC FLAGS_REG))])
10395 [(set (match_dup 5)
10396 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10397 (lshiftrt:DWIH (match_dup 3)
10398 (minus:QI (match_dup 6) (match_dup 2)))))
10399 (clobber (reg:CC FLAGS_REG))])]
10401 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10403 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10406 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10407 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10408 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10409 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10410 (clobber (reg:CC FLAGS_REG))
10411 (clobber (match_scratch:DWIH 3 "=&r"))]
10415 [(set (match_dup 3) (match_dup 4))
10417 [(set (match_dup 4)
10418 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10419 (ashift:DWIH (match_dup 5)
10420 (minus:QI (match_dup 6) (match_dup 2)))))
10421 (clobber (reg:CC FLAGS_REG))])
10423 [(set (match_dup 5)
10424 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10425 (ashift:DWIH (match_dup 3)
10426 (minus:QI (match_dup 6) (match_dup 2)))))
10427 (clobber (reg:CC FLAGS_REG))])]
10429 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10431 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10434 (define_insn "*bmi2_rorx<mode>3_1"
10435 [(set (match_operand:SWI48 0 "register_operand" "=r")
10436 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10437 (match_operand:QI 2 "immediate_operand" "<S>")))]
10439 "rorx\t{%2, %1, %0|%0, %1, %2}"
10440 [(set_attr "type" "rotatex")
10441 (set_attr "mode" "<MODE>")])
10443 (define_insn "*<rotate_insn><mode>3_1"
10444 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10446 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10447 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10448 (clobber (reg:CC FLAGS_REG))]
10449 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10451 switch (get_attr_type (insn))
10457 if (operands[2] == const1_rtx
10458 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10459 return "<rotate>{<imodesuffix>}\t%0";
10461 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10464 [(set_attr "isa" "*,bmi2")
10465 (set_attr "type" "rotate,rotatex")
10466 (set (attr "length_immediate")
10468 (and (eq_attr "type" "rotate")
10469 (and (match_operand 2 "const1_operand")
10470 (ior (match_test "TARGET_SHIFT1")
10471 (match_test "optimize_function_for_size_p (cfun)"))))
10473 (const_string "*")))
10474 (set_attr "mode" "<MODE>")])
10476 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10478 [(set (match_operand:SWI48 0 "register_operand")
10479 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10480 (match_operand:QI 2 "immediate_operand")))
10481 (clobber (reg:CC FLAGS_REG))]
10482 "TARGET_BMI2 && reload_completed"
10483 [(set (match_dup 0)
10484 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10487 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10491 [(set (match_operand:SWI48 0 "register_operand")
10492 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10493 (match_operand:QI 2 "immediate_operand")))
10494 (clobber (reg:CC FLAGS_REG))]
10495 "TARGET_BMI2 && reload_completed"
10496 [(set (match_dup 0)
10497 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10499 (define_insn "*bmi2_rorxsi3_1_zext"
10500 [(set (match_operand:DI 0 "register_operand" "=r")
10502 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10503 (match_operand:QI 2 "immediate_operand" "I"))))]
10504 "TARGET_64BIT && TARGET_BMI2"
10505 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10506 [(set_attr "type" "rotatex")
10507 (set_attr "mode" "SI")])
10509 (define_insn "*<rotate_insn>si3_1_zext"
10510 [(set (match_operand:DI 0 "register_operand" "=r,r")
10512 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10513 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10514 (clobber (reg:CC FLAGS_REG))]
10515 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10517 switch (get_attr_type (insn))
10523 if (operands[2] == const1_rtx
10524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10525 return "<rotate>{l}\t%k0";
10527 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10530 [(set_attr "isa" "*,bmi2")
10531 (set_attr "type" "rotate,rotatex")
10532 (set (attr "length_immediate")
10534 (and (eq_attr "type" "rotate")
10535 (and (match_operand 2 "const1_operand")
10536 (ior (match_test "TARGET_SHIFT1")
10537 (match_test "optimize_function_for_size_p (cfun)"))))
10539 (const_string "*")))
10540 (set_attr "mode" "SI")])
10542 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10544 [(set (match_operand:DI 0 "register_operand")
10546 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10547 (match_operand:QI 2 "immediate_operand"))))
10548 (clobber (reg:CC FLAGS_REG))]
10549 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10550 [(set (match_dup 0)
10551 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10554 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10558 [(set (match_operand:DI 0 "register_operand")
10560 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10561 (match_operand:QI 2 "immediate_operand"))))
10562 (clobber (reg:CC FLAGS_REG))]
10563 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10564 [(set (match_dup 0)
10565 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10567 (define_insn "*<rotate_insn><mode>3_1"
10568 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10569 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10570 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10571 (clobber (reg:CC FLAGS_REG))]
10572 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10574 if (operands[2] == const1_rtx
10575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10576 return "<rotate>{<imodesuffix>}\t%0";
10578 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10580 [(set_attr "type" "rotate")
10581 (set (attr "length_immediate")
10583 (and (match_operand 2 "const1_operand")
10584 (ior (match_test "TARGET_SHIFT1")
10585 (match_test "optimize_function_for_size_p (cfun)")))
10587 (const_string "*")))
10588 (set_attr "mode" "<MODE>")])
10590 (define_insn "*<rotate_insn>qi3_1_slp"
10591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10592 (any_rotate:QI (match_dup 0)
10593 (match_operand:QI 1 "nonmemory_operand" "cI")))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "(optimize_function_for_size_p (cfun)
10596 || !TARGET_PARTIAL_REG_STALL
10597 || (operands[1] == const1_rtx
10598 && TARGET_SHIFT1))"
10600 if (operands[1] == const1_rtx
10601 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10602 return "<rotate>{b}\t%0";
10604 return "<rotate>{b}\t{%1, %0|%0, %1}";
10606 [(set_attr "type" "rotate1")
10607 (set (attr "length_immediate")
10609 (and (match_operand 1 "const1_operand")
10610 (ior (match_test "TARGET_SHIFT1")
10611 (match_test "optimize_function_for_size_p (cfun)")))
10613 (const_string "*")))
10614 (set_attr "mode" "QI")])
10617 [(set (match_operand:HI 0 "register_operand")
10618 (any_rotate:HI (match_dup 0) (const_int 8)))
10619 (clobber (reg:CC FLAGS_REG))]
10621 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10622 [(parallel [(set (strict_low_part (match_dup 0))
10623 (bswap:HI (match_dup 0)))
10624 (clobber (reg:CC FLAGS_REG))])])
10626 ;; Bit set / bit test instructions
10628 (define_expand "extv"
10629 [(set (match_operand:SI 0 "register_operand")
10630 (sign_extract:SI (match_operand:SI 1 "register_operand")
10631 (match_operand:SI 2 "const8_operand")
10632 (match_operand:SI 3 "const8_operand")))]
10635 /* Handle extractions from %ah et al. */
10636 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10639 /* From mips.md: extract_bit_field doesn't verify that our source
10640 matches the predicate, so check it again here. */
10641 if (! ext_register_operand (operands[1], VOIDmode))
10645 (define_expand "extzv"
10646 [(set (match_operand:SI 0 "register_operand")
10647 (zero_extract:SI (match_operand 1 "ext_register_operand")
10648 (match_operand:SI 2 "const8_operand")
10649 (match_operand:SI 3 "const8_operand")))]
10652 /* Handle extractions from %ah et al. */
10653 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10656 /* From mips.md: extract_bit_field doesn't verify that our source
10657 matches the predicate, so check it again here. */
10658 if (! ext_register_operand (operands[1], VOIDmode))
10662 (define_expand "insv"
10663 [(set (zero_extract (match_operand 0 "register_operand")
10664 (match_operand 1 "const_int_operand")
10665 (match_operand 2 "const_int_operand"))
10666 (match_operand 3 "register_operand"))]
10669 rtx (*gen_mov_insv_1) (rtx, rtx);
10671 if (ix86_expand_pinsr (operands))
10674 /* Handle insertions to %ah et al. */
10675 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10678 /* From mips.md: insert_bit_field doesn't verify that our source
10679 matches the predicate, so check it again here. */
10680 if (! ext_register_operand (operands[0], VOIDmode))
10683 gen_mov_insv_1 = (TARGET_64BIT
10684 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10686 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10690 ;; %%% bts, btr, btc, bt.
10691 ;; In general these instructions are *slow* when applied to memory,
10692 ;; since they enforce atomic operation. When applied to registers,
10693 ;; it depends on the cpu implementation. They're never faster than
10694 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10695 ;; no point. But in 64-bit, we can't hold the relevant immediates
10696 ;; within the instruction itself, so operating on bits in the high
10697 ;; 32-bits of a register becomes easier.
10699 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10700 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10701 ;; negdf respectively, so they can never be disabled entirely.
10703 (define_insn "*btsq"
10704 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10706 (match_operand:DI 1 "const_0_to_63_operand"))
10708 (clobber (reg:CC FLAGS_REG))]
10709 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10710 "bts{q}\t{%1, %0|%0, %1}"
10711 [(set_attr "type" "alu1")
10712 (set_attr "prefix_0f" "1")
10713 (set_attr "mode" "DI")])
10715 (define_insn "*btrq"
10716 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10718 (match_operand:DI 1 "const_0_to_63_operand"))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10722 "btr{q}\t{%1, %0|%0, %1}"
10723 [(set_attr "type" "alu1")
10724 (set_attr "prefix_0f" "1")
10725 (set_attr "mode" "DI")])
10727 (define_insn "*btcq"
10728 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10730 (match_operand:DI 1 "const_0_to_63_operand"))
10731 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10732 (clobber (reg:CC FLAGS_REG))]
10733 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10734 "btc{q}\t{%1, %0|%0, %1}"
10735 [(set_attr "type" "alu1")
10736 (set_attr "prefix_0f" "1")
10737 (set_attr "mode" "DI")])
10739 ;; Allow Nocona to avoid these instructions if a register is available.
10742 [(match_scratch:DI 2 "r")
10743 (parallel [(set (zero_extract:DI
10744 (match_operand:DI 0 "register_operand")
10746 (match_operand:DI 1 "const_0_to_63_operand"))
10748 (clobber (reg:CC FLAGS_REG))])]
10749 "TARGET_64BIT && !TARGET_USE_BT"
10752 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10755 if (HOST_BITS_PER_WIDE_INT >= 64)
10756 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10757 else if (i < HOST_BITS_PER_WIDE_INT)
10758 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10760 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10762 op1 = immed_double_const (lo, hi, DImode);
10765 emit_move_insn (operands[2], op1);
10769 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10774 [(match_scratch:DI 2 "r")
10775 (parallel [(set (zero_extract:DI
10776 (match_operand:DI 0 "register_operand")
10778 (match_operand:DI 1 "const_0_to_63_operand"))
10780 (clobber (reg:CC FLAGS_REG))])]
10781 "TARGET_64BIT && !TARGET_USE_BT"
10784 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10787 if (HOST_BITS_PER_WIDE_INT >= 64)
10788 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10789 else if (i < HOST_BITS_PER_WIDE_INT)
10790 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10792 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10794 op1 = immed_double_const (~lo, ~hi, DImode);
10797 emit_move_insn (operands[2], op1);
10801 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10806 [(match_scratch:DI 2 "r")
10807 (parallel [(set (zero_extract:DI
10808 (match_operand:DI 0 "register_operand")
10810 (match_operand:DI 1 "const_0_to_63_operand"))
10811 (not:DI (zero_extract:DI
10812 (match_dup 0) (const_int 1) (match_dup 1))))
10813 (clobber (reg:CC FLAGS_REG))])]
10814 "TARGET_64BIT && !TARGET_USE_BT"
10817 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10820 if (HOST_BITS_PER_WIDE_INT >= 64)
10821 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10822 else if (i < HOST_BITS_PER_WIDE_INT)
10823 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10825 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10827 op1 = immed_double_const (lo, hi, DImode);
10830 emit_move_insn (operands[2], op1);
10834 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10838 (define_insn "*bt<mode>"
10839 [(set (reg:CCC FLAGS_REG)
10841 (zero_extract:SWI48
10842 (match_operand:SWI48 0 "register_operand" "r")
10844 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10846 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10847 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10848 [(set_attr "type" "alu1")
10849 (set_attr "prefix_0f" "1")
10850 (set_attr "mode" "<MODE>")])
10852 ;; Store-flag instructions.
10854 ;; For all sCOND expanders, also expand the compare or test insn that
10855 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10857 (define_insn_and_split "*setcc_di_1"
10858 [(set (match_operand:DI 0 "register_operand" "=q")
10859 (match_operator:DI 1 "ix86_comparison_operator"
10860 [(reg FLAGS_REG) (const_int 0)]))]
10861 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10863 "&& reload_completed"
10864 [(set (match_dup 2) (match_dup 1))
10865 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10867 operands[1] = shallow_copy_rtx (operands[1]);
10868 PUT_MODE (operands[1], QImode);
10869 operands[2] = gen_lowpart (QImode, operands[0]);
10872 (define_insn_and_split "*setcc_si_1_and"
10873 [(set (match_operand:SI 0 "register_operand" "=q")
10874 (match_operator:SI 1 "ix86_comparison_operator"
10875 [(reg FLAGS_REG) (const_int 0)]))
10876 (clobber (reg:CC FLAGS_REG))]
10877 "!TARGET_PARTIAL_REG_STALL
10878 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10880 "&& reload_completed"
10881 [(set (match_dup 2) (match_dup 1))
10882 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10883 (clobber (reg:CC FLAGS_REG))])]
10885 operands[1] = shallow_copy_rtx (operands[1]);
10886 PUT_MODE (operands[1], QImode);
10887 operands[2] = gen_lowpart (QImode, operands[0]);
10890 (define_insn_and_split "*setcc_si_1_movzbl"
10891 [(set (match_operand:SI 0 "register_operand" "=q")
10892 (match_operator:SI 1 "ix86_comparison_operator"
10893 [(reg FLAGS_REG) (const_int 0)]))]
10894 "!TARGET_PARTIAL_REG_STALL
10895 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10897 "&& reload_completed"
10898 [(set (match_dup 2) (match_dup 1))
10899 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10901 operands[1] = shallow_copy_rtx (operands[1]);
10902 PUT_MODE (operands[1], QImode);
10903 operands[2] = gen_lowpart (QImode, operands[0]);
10906 (define_insn "*setcc_qi"
10907 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10908 (match_operator:QI 1 "ix86_comparison_operator"
10909 [(reg FLAGS_REG) (const_int 0)]))]
10912 [(set_attr "type" "setcc")
10913 (set_attr "mode" "QI")])
10915 (define_insn "*setcc_qi_slp"
10916 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10917 (match_operator:QI 1 "ix86_comparison_operator"
10918 [(reg FLAGS_REG) (const_int 0)]))]
10921 [(set_attr "type" "setcc")
10922 (set_attr "mode" "QI")])
10924 ;; In general it is not safe to assume too much about CCmode registers,
10925 ;; so simplify-rtx stops when it sees a second one. Under certain
10926 ;; conditions this is safe on x86, so help combine not create
10933 [(set (match_operand:QI 0 "nonimmediate_operand")
10934 (ne:QI (match_operator 1 "ix86_comparison_operator"
10935 [(reg FLAGS_REG) (const_int 0)])
10938 [(set (match_dup 0) (match_dup 1))]
10940 operands[1] = shallow_copy_rtx (operands[1]);
10941 PUT_MODE (operands[1], QImode);
10945 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10946 (ne:QI (match_operator 1 "ix86_comparison_operator"
10947 [(reg FLAGS_REG) (const_int 0)])
10950 [(set (match_dup 0) (match_dup 1))]
10952 operands[1] = shallow_copy_rtx (operands[1]);
10953 PUT_MODE (operands[1], QImode);
10957 [(set (match_operand:QI 0 "nonimmediate_operand")
10958 (eq:QI (match_operator 1 "ix86_comparison_operator"
10959 [(reg FLAGS_REG) (const_int 0)])
10962 [(set (match_dup 0) (match_dup 1))]
10964 operands[1] = shallow_copy_rtx (operands[1]);
10965 PUT_MODE (operands[1], QImode);
10966 PUT_CODE (operands[1],
10967 ix86_reverse_condition (GET_CODE (operands[1]),
10968 GET_MODE (XEXP (operands[1], 0))));
10970 /* Make sure that (a) the CCmode we have for the flags is strong
10971 enough for the reversed compare or (b) we have a valid FP compare. */
10972 if (! ix86_comparison_operator (operands[1], VOIDmode))
10977 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10978 (eq:QI (match_operator 1 "ix86_comparison_operator"
10979 [(reg FLAGS_REG) (const_int 0)])
10982 [(set (match_dup 0) (match_dup 1))]
10984 operands[1] = shallow_copy_rtx (operands[1]);
10985 PUT_MODE (operands[1], QImode);
10986 PUT_CODE (operands[1],
10987 ix86_reverse_condition (GET_CODE (operands[1]),
10988 GET_MODE (XEXP (operands[1], 0))));
10990 /* Make sure that (a) the CCmode we have for the flags is strong
10991 enough for the reversed compare or (b) we have a valid FP compare. */
10992 if (! ix86_comparison_operator (operands[1], VOIDmode))
10996 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10997 ;; subsequent logical operations are used to imitate conditional moves.
10998 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11001 (define_insn "setcc_<mode>_sse"
11002 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11003 (match_operator:MODEF 3 "sse_comparison_operator"
11004 [(match_operand:MODEF 1 "register_operand" "0,x")
11005 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11006 "SSE_FLOAT_MODE_P (<MODE>mode)"
11008 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11009 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11010 [(set_attr "isa" "noavx,avx")
11011 (set_attr "type" "ssecmp")
11012 (set_attr "length_immediate" "1")
11013 (set_attr "prefix" "orig,vex")
11014 (set_attr "mode" "<MODE>")])
11016 ;; Basic conditional jump instructions.
11017 ;; We ignore the overflow flag for signed branch instructions.
11019 (define_insn "*jcc_1_bnd"
11021 (if_then_else (match_operator 1 "ix86_comparison_operator"
11022 [(reg FLAGS_REG) (const_int 0)])
11023 (label_ref (match_operand 0))
11025 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11027 [(set_attr "type" "ibr")
11028 (set_attr "modrm" "0")
11029 (set (attr "length")
11030 (if_then_else (and (ge (minus (match_dup 0) (pc))
11032 (lt (minus (match_dup 0) (pc))
11037 (define_insn "*jcc_1"
11039 (if_then_else (match_operator 1 "ix86_comparison_operator"
11040 [(reg FLAGS_REG) (const_int 0)])
11041 (label_ref (match_operand 0))
11045 [(set_attr "type" "ibr")
11046 (set_attr "modrm" "0")
11047 (set (attr "length")
11048 (if_then_else (and (ge (minus (match_dup 0) (pc))
11050 (lt (minus (match_dup 0) (pc))
11055 (define_insn "*jcc_2_bnd"
11057 (if_then_else (match_operator 1 "ix86_comparison_operator"
11058 [(reg FLAGS_REG) (const_int 0)])
11060 (label_ref (match_operand 0))))]
11061 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11063 [(set_attr "type" "ibr")
11064 (set_attr "modrm" "0")
11065 (set (attr "length")
11066 (if_then_else (and (ge (minus (match_dup 0) (pc))
11068 (lt (minus (match_dup 0) (pc))
11073 (define_insn "*jcc_2"
11075 (if_then_else (match_operator 1 "ix86_comparison_operator"
11076 [(reg FLAGS_REG) (const_int 0)])
11078 (label_ref (match_operand 0))))]
11081 [(set_attr "type" "ibr")
11082 (set_attr "modrm" "0")
11083 (set (attr "length")
11084 (if_then_else (and (ge (minus (match_dup 0) (pc))
11086 (lt (minus (match_dup 0) (pc))
11091 ;; In general it is not safe to assume too much about CCmode registers,
11092 ;; so simplify-rtx stops when it sees a second one. Under certain
11093 ;; conditions this is safe on x86, so help combine not create
11101 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11102 [(reg FLAGS_REG) (const_int 0)])
11104 (label_ref (match_operand 1))
11108 (if_then_else (match_dup 0)
11109 (label_ref (match_dup 1))
11112 operands[0] = shallow_copy_rtx (operands[0]);
11113 PUT_MODE (operands[0], VOIDmode);
11118 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11119 [(reg FLAGS_REG) (const_int 0)])
11121 (label_ref (match_operand 1))
11125 (if_then_else (match_dup 0)
11126 (label_ref (match_dup 1))
11129 operands[0] = shallow_copy_rtx (operands[0]);
11130 PUT_MODE (operands[0], VOIDmode);
11131 PUT_CODE (operands[0],
11132 ix86_reverse_condition (GET_CODE (operands[0]),
11133 GET_MODE (XEXP (operands[0], 0))));
11135 /* Make sure that (a) the CCmode we have for the flags is strong
11136 enough for the reversed compare or (b) we have a valid FP compare. */
11137 if (! ix86_comparison_operator (operands[0], VOIDmode))
11141 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11142 ;; pass generates from shift insn with QImode operand. Actually, the mode
11143 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11144 ;; appropriate modulo of the bit offset value.
11146 (define_insn_and_split "*jcc_bt<mode>"
11148 (if_then_else (match_operator 0 "bt_comparison_operator"
11149 [(zero_extract:SWI48
11150 (match_operand:SWI48 1 "register_operand" "r")
11153 (match_operand:QI 2 "register_operand" "r")))
11155 (label_ref (match_operand 3))
11157 (clobber (reg:CC FLAGS_REG))]
11158 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11161 [(set (reg:CCC FLAGS_REG)
11163 (zero_extract:SWI48
11169 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11170 (label_ref (match_dup 3))
11173 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11174 operands[0] = shallow_copy_rtx (operands[0]);
11175 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11178 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11179 ;; zero extended to SImode.
11180 (define_insn_and_split "*jcc_bt<mode>_1"
11182 (if_then_else (match_operator 0 "bt_comparison_operator"
11183 [(zero_extract:SWI48
11184 (match_operand:SWI48 1 "register_operand" "r")
11186 (match_operand:SI 2 "register_operand" "r"))
11188 (label_ref (match_operand 3))
11190 (clobber (reg:CC FLAGS_REG))]
11191 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11194 [(set (reg:CCC FLAGS_REG)
11196 (zero_extract:SWI48
11202 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11203 (label_ref (match_dup 3))
11206 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11207 operands[0] = shallow_copy_rtx (operands[0]);
11208 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11211 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11212 ;; also for DImode, this is what combine produces.
11213 (define_insn_and_split "*jcc_bt<mode>_mask"
11215 (if_then_else (match_operator 0 "bt_comparison_operator"
11216 [(zero_extract:SWI48
11217 (match_operand:SWI48 1 "register_operand" "r")
11220 (match_operand:SI 2 "register_operand" "r")
11221 (match_operand:SI 3 "const_int_operand" "n")))])
11222 (label_ref (match_operand 4))
11224 (clobber (reg:CC FLAGS_REG))]
11225 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11226 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11227 == GET_MODE_BITSIZE (<MODE>mode)-1"
11230 [(set (reg:CCC FLAGS_REG)
11232 (zero_extract:SWI48
11238 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11239 (label_ref (match_dup 4))
11242 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11243 operands[0] = shallow_copy_rtx (operands[0]);
11244 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11247 (define_insn_and_split "*jcc_btsi_1"
11249 (if_then_else (match_operator 0 "bt_comparison_operator"
11252 (match_operand:SI 1 "register_operand" "r")
11253 (match_operand:QI 2 "register_operand" "r"))
11256 (label_ref (match_operand 3))
11258 (clobber (reg:CC FLAGS_REG))]
11259 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11262 [(set (reg:CCC FLAGS_REG)
11270 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11271 (label_ref (match_dup 3))
11274 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11275 operands[0] = shallow_copy_rtx (operands[0]);
11276 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11279 ;; avoid useless masking of bit offset operand
11280 (define_insn_and_split "*jcc_btsi_mask_1"
11283 (match_operator 0 "bt_comparison_operator"
11286 (match_operand:SI 1 "register_operand" "r")
11289 (match_operand:SI 2 "register_operand" "r")
11290 (match_operand:SI 3 "const_int_operand" "n")) 0))
11293 (label_ref (match_operand 4))
11295 (clobber (reg:CC FLAGS_REG))]
11296 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11297 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11300 [(set (reg:CCC FLAGS_REG)
11308 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11309 (label_ref (match_dup 4))
11312 operands[0] = shallow_copy_rtx (operands[0]);
11313 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11316 ;; Define combination compare-and-branch fp compare instructions to help
11319 (define_insn "*jcc<mode>_0_i387"
11321 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11322 [(match_operand:X87MODEF 1 "register_operand" "f")
11323 (match_operand:X87MODEF 2 "const0_operand")])
11324 (label_ref (match_operand 3))
11326 (clobber (reg:CCFP FPSR_REG))
11327 (clobber (reg:CCFP FLAGS_REG))
11328 (clobber (match_scratch:HI 4 "=a"))]
11329 "TARGET_80387 && !TARGET_CMOVE"
11332 (define_insn "*jcc<mode>_0_r_i387"
11334 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11335 [(match_operand:X87MODEF 1 "register_operand" "f")
11336 (match_operand:X87MODEF 2 "const0_operand")])
11338 (label_ref (match_operand 3))))
11339 (clobber (reg:CCFP FPSR_REG))
11340 (clobber (reg:CCFP FLAGS_REG))
11341 (clobber (match_scratch:HI 4 "=a"))]
11342 "TARGET_80387 && !TARGET_CMOVE"
11345 (define_insn "*jccxf_i387"
11347 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11348 [(match_operand:XF 1 "register_operand" "f")
11349 (match_operand:XF 2 "register_operand" "f")])
11350 (label_ref (match_operand 3))
11352 (clobber (reg:CCFP FPSR_REG))
11353 (clobber (reg:CCFP FLAGS_REG))
11354 (clobber (match_scratch:HI 4 "=a"))]
11355 "TARGET_80387 && !TARGET_CMOVE"
11358 (define_insn "*jccxf_r_i387"
11360 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11361 [(match_operand:XF 1 "register_operand" "f")
11362 (match_operand:XF 2 "register_operand" "f")])
11364 (label_ref (match_operand 3))))
11365 (clobber (reg:CCFP FPSR_REG))
11366 (clobber (reg:CCFP FLAGS_REG))
11367 (clobber (match_scratch:HI 4 "=a"))]
11368 "TARGET_80387 && !TARGET_CMOVE"
11371 (define_insn "*jcc<mode>_i387"
11373 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11374 [(match_operand:MODEF 1 "register_operand" "f")
11375 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11376 (label_ref (match_operand 3))
11378 (clobber (reg:CCFP FPSR_REG))
11379 (clobber (reg:CCFP FLAGS_REG))
11380 (clobber (match_scratch:HI 4 "=a"))]
11381 "TARGET_80387 && !TARGET_CMOVE"
11384 (define_insn "*jcc<mode>_r_i387"
11386 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11387 [(match_operand:MODEF 1 "register_operand" "f")
11388 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11390 (label_ref (match_operand 3))))
11391 (clobber (reg:CCFP FPSR_REG))
11392 (clobber (reg:CCFP FLAGS_REG))
11393 (clobber (match_scratch:HI 4 "=a"))]
11394 "TARGET_80387 && !TARGET_CMOVE"
11397 (define_insn "*jccu<mode>_i387"
11399 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11400 [(match_operand:X87MODEF 1 "register_operand" "f")
11401 (match_operand:X87MODEF 2 "register_operand" "f")])
11402 (label_ref (match_operand 3))
11404 (clobber (reg:CCFP FPSR_REG))
11405 (clobber (reg:CCFP FLAGS_REG))
11406 (clobber (match_scratch:HI 4 "=a"))]
11407 "TARGET_80387 && !TARGET_CMOVE"
11410 (define_insn "*jccu<mode>_r_i387"
11412 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11413 [(match_operand:X87MODEF 1 "register_operand" "f")
11414 (match_operand:X87MODEF 2 "register_operand" "f")])
11416 (label_ref (match_operand 3))))
11417 (clobber (reg:CCFP FPSR_REG))
11418 (clobber (reg:CCFP FLAGS_REG))
11419 (clobber (match_scratch:HI 4 "=a"))]
11420 "TARGET_80387 && !TARGET_CMOVE"
11425 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11426 [(match_operand:X87MODEF 1 "register_operand")
11427 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11429 (match_operand 4)))
11430 (clobber (reg:CCFP FPSR_REG))
11431 (clobber (reg:CCFP FLAGS_REG))]
11432 "TARGET_80387 && !TARGET_CMOVE
11433 && reload_completed"
11436 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11437 operands[3], operands[4], NULL_RTX);
11443 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11444 [(match_operand:X87MODEF 1 "register_operand")
11445 (match_operand:X87MODEF 2 "general_operand")])
11447 (match_operand 4)))
11448 (clobber (reg:CCFP FPSR_REG))
11449 (clobber (reg:CCFP FLAGS_REG))
11450 (clobber (match_scratch:HI 5))]
11451 "TARGET_80387 && !TARGET_CMOVE
11452 && reload_completed"
11455 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11456 operands[3], operands[4], operands[5]);
11460 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11461 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11462 ;; with a precedence over other operators and is always put in the first
11463 ;; place. Swap condition and operands to match ficom instruction.
11465 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11468 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11469 [(match_operator:X87MODEF 1 "float_operator"
11470 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11471 (match_operand:X87MODEF 3 "register_operand" "f")])
11472 (label_ref (match_operand 4))
11474 (clobber (reg:CCFP FPSR_REG))
11475 (clobber (reg:CCFP FLAGS_REG))
11476 (clobber (match_scratch:HI 5 "=a"))]
11477 "TARGET_80387 && !TARGET_CMOVE
11478 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11479 || optimize_function_for_size_p (cfun))"
11482 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11485 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11486 [(match_operator:X87MODEF 1 "float_operator"
11487 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11488 (match_operand:X87MODEF 3 "register_operand" "f")])
11490 (label_ref (match_operand 4))))
11491 (clobber (reg:CCFP FPSR_REG))
11492 (clobber (reg:CCFP FLAGS_REG))
11493 (clobber (match_scratch:HI 5 "=a"))]
11494 "TARGET_80387 && !TARGET_CMOVE
11495 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11496 || optimize_function_for_size_p (cfun))"
11502 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11503 [(match_operator:X87MODEF 1 "float_operator"
11504 [(match_operand:SWI24 2 "memory_operand")])
11505 (match_operand:X87MODEF 3 "register_operand")])
11507 (match_operand 5)))
11508 (clobber (reg:CCFP FPSR_REG))
11509 (clobber (reg:CCFP FLAGS_REG))
11510 (clobber (match_scratch:HI 6))]
11511 "TARGET_80387 && !TARGET_CMOVE
11512 && reload_completed"
11515 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11516 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11517 operands[4], operands[5], operands[6]);
11521 ;; Unconditional and other jump instructions
11523 (define_insn "jump_bnd"
11525 (label_ref (match_operand 0)))]
11526 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11528 [(set_attr "type" "ibr")
11529 (set (attr "length")
11530 (if_then_else (and (ge (minus (match_dup 0) (pc))
11532 (lt (minus (match_dup 0) (pc))
11536 (set_attr "modrm" "0")])
11538 (define_insn "jump"
11540 (label_ref (match_operand 0)))]
11543 [(set_attr "type" "ibr")
11544 (set (attr "length")
11545 (if_then_else (and (ge (minus (match_dup 0) (pc))
11547 (lt (minus (match_dup 0) (pc))
11551 (set_attr "modrm" "0")])
11553 (define_expand "indirect_jump"
11554 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11558 operands[0] = convert_memory_address (word_mode, operands[0]);
11561 (define_insn "*indirect_jump"
11562 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11565 [(set_attr "type" "ibr")
11566 (set_attr "length_immediate" "0")])
11568 (define_expand "tablejump"
11569 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11570 (use (label_ref (match_operand 1)))])]
11573 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11574 relative. Convert the relative address to an absolute address. */
11578 enum rtx_code code;
11580 /* We can't use @GOTOFF for text labels on VxWorks;
11581 see gotoff_operand. */
11582 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11586 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11588 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11592 op1 = pic_offset_table_rtx;
11597 op0 = pic_offset_table_rtx;
11601 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11606 operands[0] = convert_memory_address (word_mode, operands[0]);
11609 (define_insn "*tablejump_1"
11610 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11611 (use (label_ref (match_operand 1)))]
11614 [(set_attr "type" "ibr")
11615 (set_attr "length_immediate" "0")])
11617 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11620 [(set (reg FLAGS_REG) (match_operand 0))
11621 (set (match_operand:QI 1 "register_operand")
11622 (match_operator:QI 2 "ix86_comparison_operator"
11623 [(reg FLAGS_REG) (const_int 0)]))
11624 (set (match_operand 3 "q_regs_operand")
11625 (zero_extend (match_dup 1)))]
11626 "(peep2_reg_dead_p (3, operands[1])
11627 || operands_match_p (operands[1], operands[3]))
11628 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11629 [(set (match_dup 4) (match_dup 0))
11630 (set (strict_low_part (match_dup 5))
11633 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11634 operands[5] = gen_lowpart (QImode, operands[3]);
11635 ix86_expand_clear (operands[3]);
11639 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11640 (match_operand 4)])
11641 (set (match_operand:QI 1 "register_operand")
11642 (match_operator:QI 2 "ix86_comparison_operator"
11643 [(reg FLAGS_REG) (const_int 0)]))
11644 (set (match_operand 3 "q_regs_operand")
11645 (zero_extend (match_dup 1)))]
11646 "(peep2_reg_dead_p (3, operands[1])
11647 || operands_match_p (operands[1], operands[3]))
11648 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11649 && ! reg_set_p (operands[3], operands[4])"
11650 [(parallel [(set (match_dup 5) (match_dup 0))
11652 (set (strict_low_part (match_dup 6))
11655 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11656 operands[6] = gen_lowpart (QImode, operands[3]);
11657 ix86_expand_clear (operands[3]);
11660 ;; Similar, but match zero extend with andsi3.
11663 [(set (reg FLAGS_REG) (match_operand 0))
11664 (set (match_operand:QI 1 "register_operand")
11665 (match_operator:QI 2 "ix86_comparison_operator"
11666 [(reg FLAGS_REG) (const_int 0)]))
11667 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11668 (and:SI (match_dup 3) (const_int 255)))
11669 (clobber (reg:CC FLAGS_REG))])]
11670 "REGNO (operands[1]) == REGNO (operands[3])
11671 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11672 [(set (match_dup 4) (match_dup 0))
11673 (set (strict_low_part (match_dup 5))
11676 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11677 operands[5] = gen_lowpart (QImode, operands[3]);
11678 ix86_expand_clear (operands[3]);
11682 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11683 (match_operand 4)])
11684 (set (match_operand:QI 1 "register_operand")
11685 (match_operator:QI 2 "ix86_comparison_operator"
11686 [(reg FLAGS_REG) (const_int 0)]))
11687 (parallel [(set (match_operand 3 "q_regs_operand")
11688 (zero_extend (match_dup 1)))
11689 (clobber (reg:CC FLAGS_REG))])]
11690 "(peep2_reg_dead_p (3, operands[1])
11691 || operands_match_p (operands[1], operands[3]))
11692 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11693 && ! reg_set_p (operands[3], operands[4])"
11694 [(parallel [(set (match_dup 5) (match_dup 0))
11696 (set (strict_low_part (match_dup 6))
11699 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11700 operands[6] = gen_lowpart (QImode, operands[3]);
11701 ix86_expand_clear (operands[3]);
11704 ;; Call instructions.
11706 ;; The predicates normally associated with named expanders are not properly
11707 ;; checked for calls. This is a bug in the generic code, but it isn't that
11708 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11710 ;; P6 processors will jump to the address after the decrement when %esp
11711 ;; is used as a call operand, so they will execute return address as a code.
11712 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11714 ;; Register constraint for call instruction.
11715 (define_mode_attr c [(SI "l") (DI "r")])
11717 ;; Call subroutine returning no value.
11719 (define_expand "call"
11720 [(call (match_operand:QI 0)
11722 (use (match_operand 2))]
11725 ix86_expand_call (NULL, operands[0], operands[1],
11726 operands[2], NULL, false);
11730 (define_expand "sibcall"
11731 [(call (match_operand:QI 0)
11733 (use (match_operand 2))]
11736 ix86_expand_call (NULL, operands[0], operands[1],
11737 operands[2], NULL, true);
11741 (define_insn "*call"
11742 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11743 (match_operand 1))]
11744 "!SIBLING_CALL_P (insn)"
11745 "* return ix86_output_call_insn (insn, operands[0]);"
11746 [(set_attr "type" "call")])
11748 (define_insn "*sibcall"
11749 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11750 (match_operand 1))]
11751 "SIBLING_CALL_P (insn)"
11752 "* return ix86_output_call_insn (insn, operands[0]);"
11753 [(set_attr "type" "call")])
11755 (define_insn "*sibcall_memory"
11756 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11758 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11760 "* return ix86_output_call_insn (insn, operands[0]);"
11761 [(set_attr "type" "call")])
11764 [(set (match_operand:W 0 "register_operand")
11765 (match_operand:W 1 "memory_operand"))
11766 (call (mem:QI (match_dup 0))
11767 (match_operand 3))]
11768 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11769 && peep2_reg_dead_p (2, operands[0])"
11770 [(parallel [(call (mem:QI (match_dup 1))
11772 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11775 [(set (match_operand:W 0 "register_operand")
11776 (match_operand:W 1 "memory_operand"))
11777 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11778 (call (mem:QI (match_dup 0))
11779 (match_operand 3))]
11780 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11781 && peep2_reg_dead_p (3, operands[0])"
11782 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11783 (parallel [(call (mem:QI (match_dup 1))
11785 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11787 (define_expand "call_pop"
11788 [(parallel [(call (match_operand:QI 0)
11789 (match_operand:SI 1))
11790 (set (reg:SI SP_REG)
11791 (plus:SI (reg:SI SP_REG)
11792 (match_operand:SI 3)))])]
11795 ix86_expand_call (NULL, operands[0], operands[1],
11796 operands[2], operands[3], false);
11800 (define_insn "*call_pop"
11801 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11803 (set (reg:SI SP_REG)
11804 (plus:SI (reg:SI SP_REG)
11805 (match_operand:SI 2 "immediate_operand" "i")))]
11806 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11807 "* return ix86_output_call_insn (insn, operands[0]);"
11808 [(set_attr "type" "call")])
11810 (define_insn "*sibcall_pop"
11811 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11813 (set (reg:SI SP_REG)
11814 (plus:SI (reg:SI SP_REG)
11815 (match_operand:SI 2 "immediate_operand" "i")))]
11816 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11817 "* return ix86_output_call_insn (insn, operands[0]);"
11818 [(set_attr "type" "call")])
11820 (define_insn "*sibcall_pop_memory"
11821 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11823 (set (reg:SI SP_REG)
11824 (plus:SI (reg:SI SP_REG)
11825 (match_operand:SI 2 "immediate_operand" "i")))
11826 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11828 "* return ix86_output_call_insn (insn, operands[0]);"
11829 [(set_attr "type" "call")])
11832 [(set (match_operand:SI 0 "register_operand")
11833 (match_operand:SI 1 "memory_operand"))
11834 (parallel [(call (mem:QI (match_dup 0))
11836 (set (reg:SI SP_REG)
11837 (plus:SI (reg:SI SP_REG)
11838 (match_operand:SI 4 "immediate_operand")))])]
11839 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11840 && peep2_reg_dead_p (2, operands[0])"
11841 [(parallel [(call (mem:QI (match_dup 1))
11843 (set (reg:SI SP_REG)
11844 (plus:SI (reg:SI SP_REG)
11846 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11849 [(set (match_operand:SI 0 "register_operand")
11850 (match_operand:SI 1 "memory_operand"))
11851 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11852 (parallel [(call (mem:QI (match_dup 0))
11854 (set (reg:SI SP_REG)
11855 (plus:SI (reg:SI SP_REG)
11856 (match_operand:SI 4 "immediate_operand")))])]
11857 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11858 && peep2_reg_dead_p (3, operands[0])"
11859 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11860 (parallel [(call (mem:QI (match_dup 1))
11862 (set (reg:SI SP_REG)
11863 (plus:SI (reg:SI SP_REG)
11865 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11867 ;; Combining simple memory jump instruction
11870 [(set (match_operand:W 0 "register_operand")
11871 (match_operand:W 1 "memory_operand"))
11872 (set (pc) (match_dup 0))]
11873 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11874 [(set (pc) (match_dup 1))])
11876 ;; Call subroutine, returning value in operand 0
11878 (define_expand "call_value"
11879 [(set (match_operand 0)
11880 (call (match_operand:QI 1)
11881 (match_operand 2)))
11882 (use (match_operand 3))]
11885 ix86_expand_call (operands[0], operands[1], operands[2],
11886 operands[3], NULL, false);
11890 (define_expand "sibcall_value"
11891 [(set (match_operand 0)
11892 (call (match_operand:QI 1)
11893 (match_operand 2)))
11894 (use (match_operand 3))]
11897 ix86_expand_call (operands[0], operands[1], operands[2],
11898 operands[3], NULL, true);
11902 (define_insn "*call_value"
11903 [(set (match_operand 0)
11904 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11905 (match_operand 2)))]
11906 "!SIBLING_CALL_P (insn)"
11907 "* return ix86_output_call_insn (insn, operands[1]);"
11908 [(set_attr "type" "callv")])
11910 (define_insn "*sibcall_value"
11911 [(set (match_operand 0)
11912 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11913 (match_operand 2)))]
11914 "SIBLING_CALL_P (insn)"
11915 "* return ix86_output_call_insn (insn, operands[1]);"
11916 [(set_attr "type" "callv")])
11918 (define_insn "*sibcall_value_memory"
11919 [(set (match_operand 0)
11920 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11921 (match_operand 2)))
11922 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11924 "* return ix86_output_call_insn (insn, operands[1]);"
11925 [(set_attr "type" "callv")])
11928 [(set (match_operand:W 0 "register_operand")
11929 (match_operand:W 1 "memory_operand"))
11930 (set (match_operand 2)
11931 (call (mem:QI (match_dup 0))
11932 (match_operand 3)))]
11933 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11934 && peep2_reg_dead_p (2, operands[0])"
11935 [(parallel [(set (match_dup 2)
11936 (call (mem:QI (match_dup 1))
11938 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11941 [(set (match_operand:W 0 "register_operand")
11942 (match_operand:W 1 "memory_operand"))
11943 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11944 (set (match_operand 2)
11945 (call (mem:QI (match_dup 0))
11946 (match_operand 3)))]
11947 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11948 && peep2_reg_dead_p (3, operands[0])"
11949 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11950 (parallel [(set (match_dup 2)
11951 (call (mem:QI (match_dup 1))
11953 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11955 (define_expand "call_value_pop"
11956 [(parallel [(set (match_operand 0)
11957 (call (match_operand:QI 1)
11958 (match_operand:SI 2)))
11959 (set (reg:SI SP_REG)
11960 (plus:SI (reg:SI SP_REG)
11961 (match_operand:SI 4)))])]
11964 ix86_expand_call (operands[0], operands[1], operands[2],
11965 operands[3], operands[4], false);
11969 (define_insn "*call_value_pop"
11970 [(set (match_operand 0)
11971 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11972 (match_operand 2)))
11973 (set (reg:SI SP_REG)
11974 (plus:SI (reg:SI SP_REG)
11975 (match_operand:SI 3 "immediate_operand" "i")))]
11976 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11977 "* return ix86_output_call_insn (insn, operands[1]);"
11978 [(set_attr "type" "callv")])
11980 (define_insn "*sibcall_value_pop"
11981 [(set (match_operand 0)
11982 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11983 (match_operand 2)))
11984 (set (reg:SI SP_REG)
11985 (plus:SI (reg:SI SP_REG)
11986 (match_operand:SI 3 "immediate_operand" "i")))]
11987 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11988 "* return ix86_output_call_insn (insn, operands[1]);"
11989 [(set_attr "type" "callv")])
11991 (define_insn "*sibcall_value_pop_memory"
11992 [(set (match_operand 0)
11993 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11994 (match_operand 2)))
11995 (set (reg:SI SP_REG)
11996 (plus:SI (reg:SI SP_REG)
11997 (match_operand:SI 3 "immediate_operand" "i")))
11998 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12000 "* return ix86_output_call_insn (insn, operands[1]);"
12001 [(set_attr "type" "callv")])
12004 [(set (match_operand:SI 0 "register_operand")
12005 (match_operand:SI 1 "memory_operand"))
12006 (parallel [(set (match_operand 2)
12007 (call (mem:QI (match_dup 0))
12008 (match_operand 3)))
12009 (set (reg:SI SP_REG)
12010 (plus:SI (reg:SI SP_REG)
12011 (match_operand:SI 4 "immediate_operand")))])]
12012 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12013 && peep2_reg_dead_p (2, operands[0])"
12014 [(parallel [(set (match_dup 2)
12015 (call (mem:QI (match_dup 1))
12017 (set (reg:SI SP_REG)
12018 (plus:SI (reg:SI SP_REG)
12020 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12023 [(set (match_operand:SI 0 "register_operand")
12024 (match_operand:SI 1 "memory_operand"))
12025 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12026 (parallel [(set (match_operand 2)
12027 (call (mem:QI (match_dup 0))
12028 (match_operand 3)))
12029 (set (reg:SI SP_REG)
12030 (plus:SI (reg:SI SP_REG)
12031 (match_operand:SI 4 "immediate_operand")))])]
12032 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12033 && peep2_reg_dead_p (3, operands[0])"
12034 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12035 (parallel [(set (match_dup 2)
12036 (call (mem:QI (match_dup 1))
12038 (set (reg:SI SP_REG)
12039 (plus:SI (reg:SI SP_REG)
12041 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12043 ;; Call subroutine returning any type.
12045 (define_expand "untyped_call"
12046 [(parallel [(call (match_operand 0)
12049 (match_operand 2)])]
12054 /* In order to give reg-stack an easier job in validating two
12055 coprocessor registers as containing a possible return value,
12056 simply pretend the untyped call returns a complex long double
12059 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12060 and should have the default ABI. */
12062 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12063 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12064 operands[0], const0_rtx,
12065 GEN_INT ((TARGET_64BIT
12066 ? (ix86_abi == SYSV_ABI
12067 ? X86_64_SSE_REGPARM_MAX
12068 : X86_64_MS_SSE_REGPARM_MAX)
12069 : X86_32_SSE_REGPARM_MAX)
12073 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12075 rtx set = XVECEXP (operands[2], 0, i);
12076 emit_move_insn (SET_DEST (set), SET_SRC (set));
12079 /* The optimizer does not know that the call sets the function value
12080 registers we stored in the result block. We avoid problems by
12081 claiming that all hard registers are used and clobbered at this
12083 emit_insn (gen_blockage ());
12088 ;; Prologue and epilogue instructions
12090 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12091 ;; all of memory. This blocks insns from being moved across this point.
12093 (define_insn "blockage"
12094 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12097 [(set_attr "length" "0")])
12099 ;; Do not schedule instructions accessing memory across this point.
12101 (define_expand "memory_blockage"
12102 [(set (match_dup 0)
12103 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12106 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12107 MEM_VOLATILE_P (operands[0]) = 1;
12110 (define_insn "*memory_blockage"
12111 [(set (match_operand:BLK 0)
12112 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12115 [(set_attr "length" "0")])
12117 ;; As USE insns aren't meaningful after reload, this is used instead
12118 ;; to prevent deleting instructions setting registers for PIC code
12119 (define_insn "prologue_use"
12120 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12123 [(set_attr "length" "0")])
12125 ;; Insn emitted into the body of a function to return from a function.
12126 ;; This is only done if the function's epilogue is known to be simple.
12127 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12129 (define_expand "return"
12131 "ix86_can_use_return_insn_p ()"
12133 if (crtl->args.pops_args)
12135 rtx popc = GEN_INT (crtl->args.pops_args);
12136 emit_jump_insn (gen_simple_return_pop_internal (popc));
12141 ;; We need to disable this for TARGET_SEH, as otherwise
12142 ;; shrink-wrapped prologue gets enabled too. This might exceed
12143 ;; the maximum size of prologue in unwind information.
12144 ;; Also disallow shrink-wrapping if using stack slot to pass the
12145 ;; static chain pointer - the first instruction has to be pushl %esi
12146 ;; and it can't be moved around, as we use alternate entry points
12149 (define_expand "simple_return"
12151 "!TARGET_SEH && !ix86_static_chain_on_stack"
12153 if (crtl->args.pops_args)
12155 rtx popc = GEN_INT (crtl->args.pops_args);
12156 emit_jump_insn (gen_simple_return_pop_internal (popc));
12161 (define_insn "simple_return_internal"
12165 [(set_attr "length_nobnd" "1")
12166 (set_attr "atom_unit" "jeu")
12167 (set_attr "length_immediate" "0")
12168 (set_attr "modrm" "0")])
12170 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12171 ;; instruction Athlon and K8 have.
12173 (define_insn "simple_return_internal_long"
12175 (unspec [(const_int 0)] UNSPEC_REP)]
12178 if (ix86_bnd_prefixed_insn_p (insn))
12181 return "rep%; ret";
12183 [(set_attr "length" "2")
12184 (set_attr "atom_unit" "jeu")
12185 (set_attr "length_immediate" "0")
12186 (set_attr "prefix_rep" "1")
12187 (set_attr "modrm" "0")])
12189 (define_insn "simple_return_pop_internal"
12191 (use (match_operand:SI 0 "const_int_operand"))]
12194 [(set_attr "length_nobnd" "3")
12195 (set_attr "atom_unit" "jeu")
12196 (set_attr "length_immediate" "2")
12197 (set_attr "modrm" "0")])
12199 (define_insn "simple_return_indirect_internal"
12201 (use (match_operand:SI 0 "register_operand" "r"))]
12204 [(set_attr "type" "ibr")
12205 (set_attr "length_immediate" "0")])
12211 [(set_attr "length" "1")
12212 (set_attr "length_immediate" "0")
12213 (set_attr "modrm" "0")])
12215 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12216 (define_insn "nops"
12217 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12221 int num = INTVAL (operands[0]);
12223 gcc_assert (IN_RANGE (num, 1, 8));
12226 fputs ("\tnop\n", asm_out_file);
12230 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12231 (set_attr "length_immediate" "0")
12232 (set_attr "modrm" "0")])
12234 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12235 ;; branch prediction penalty for the third jump in a 16-byte
12239 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12242 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12243 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12245 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12246 The align insn is used to avoid 3 jump instructions in the row to improve
12247 branch prediction and the benefits hardly outweigh the cost of extra 8
12248 nops on the average inserted by full alignment pseudo operation. */
12252 [(set_attr "length" "16")])
12254 (define_expand "prologue"
12257 "ix86_expand_prologue (); DONE;")
12259 (define_insn "set_got"
12260 [(set (match_operand:SI 0 "register_operand" "=r")
12261 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12262 (clobber (reg:CC FLAGS_REG))]
12264 "* return output_set_got (operands[0], NULL_RTX);"
12265 [(set_attr "type" "multi")
12266 (set_attr "length" "12")])
12268 (define_insn "set_got_labelled"
12269 [(set (match_operand:SI 0 "register_operand" "=r")
12270 (unspec:SI [(label_ref (match_operand 1))]
12272 (clobber (reg:CC FLAGS_REG))]
12274 "* return output_set_got (operands[0], operands[1]);"
12275 [(set_attr "type" "multi")
12276 (set_attr "length" "12")])
12278 (define_insn "set_got_rex64"
12279 [(set (match_operand:DI 0 "register_operand" "=r")
12280 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12282 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12283 [(set_attr "type" "lea")
12284 (set_attr "length_address" "4")
12285 (set_attr "mode" "DI")])
12287 (define_insn "set_rip_rex64"
12288 [(set (match_operand:DI 0 "register_operand" "=r")
12289 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12291 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12292 [(set_attr "type" "lea")
12293 (set_attr "length_address" "4")
12294 (set_attr "mode" "DI")])
12296 (define_insn "set_got_offset_rex64"
12297 [(set (match_operand:DI 0 "register_operand" "=r")
12299 [(label_ref (match_operand 1))]
12300 UNSPEC_SET_GOT_OFFSET))]
12302 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12303 [(set_attr "type" "imov")
12304 (set_attr "length_immediate" "0")
12305 (set_attr "length_address" "8")
12306 (set_attr "mode" "DI")])
12308 (define_expand "epilogue"
12311 "ix86_expand_epilogue (1); DONE;")
12313 (define_expand "sibcall_epilogue"
12316 "ix86_expand_epilogue (0); DONE;")
12318 (define_expand "eh_return"
12319 [(use (match_operand 0 "register_operand"))]
12322 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12324 /* Tricky bit: we write the address of the handler to which we will
12325 be returning into someone else's stack frame, one word below the
12326 stack address we wish to restore. */
12327 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12328 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12329 tmp = gen_rtx_MEM (Pmode, tmp);
12330 emit_move_insn (tmp, ra);
12332 emit_jump_insn (gen_eh_return_internal ());
12337 (define_insn_and_split "eh_return_internal"
12341 "epilogue_completed"
12343 "ix86_expand_epilogue (2); DONE;")
12345 (define_insn "leave"
12346 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12347 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12348 (clobber (mem:BLK (scratch)))]
12351 [(set_attr "type" "leave")])
12353 (define_insn "leave_rex64"
12354 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12355 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12356 (clobber (mem:BLK (scratch)))]
12359 [(set_attr "type" "leave")])
12361 ;; Handle -fsplit-stack.
12363 (define_expand "split_stack_prologue"
12367 ix86_expand_split_stack_prologue ();
12371 ;; In order to support the call/return predictor, we use a return
12372 ;; instruction which the middle-end doesn't see.
12373 (define_insn "split_stack_return"
12374 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12375 UNSPECV_SPLIT_STACK_RETURN)]
12378 if (operands[0] == const0_rtx)
12383 [(set_attr "atom_unit" "jeu")
12384 (set_attr "modrm" "0")
12385 (set (attr "length")
12386 (if_then_else (match_operand:SI 0 "const0_operand")
12389 (set (attr "length_immediate")
12390 (if_then_else (match_operand:SI 0 "const0_operand")
12394 ;; If there are operand 0 bytes available on the stack, jump to
12397 (define_expand "split_stack_space_check"
12398 [(set (pc) (if_then_else
12399 (ltu (minus (reg SP_REG)
12400 (match_operand 0 "register_operand"))
12401 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12402 (label_ref (match_operand 1))
12406 rtx reg, size, limit;
12408 reg = gen_reg_rtx (Pmode);
12409 size = force_reg (Pmode, operands[0]);
12410 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12411 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12412 UNSPEC_STACK_CHECK);
12413 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12414 ix86_expand_branch (GEU, reg, limit, operands[1]);
12419 ;; Bit manipulation instructions.
12421 (define_expand "ffs<mode>2"
12422 [(set (match_dup 2) (const_int -1))
12423 (parallel [(set (match_dup 3) (match_dup 4))
12424 (set (match_operand:SWI48 0 "register_operand")
12426 (match_operand:SWI48 1 "nonimmediate_operand")))])
12427 (set (match_dup 0) (if_then_else:SWI48
12428 (eq (match_dup 3) (const_int 0))
12431 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12432 (clobber (reg:CC FLAGS_REG))])]
12435 machine_mode flags_mode;
12437 if (<MODE>mode == SImode && !TARGET_CMOVE)
12439 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12444 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12446 operands[2] = gen_reg_rtx (<MODE>mode);
12447 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12448 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12451 (define_insn_and_split "ffssi2_no_cmove"
12452 [(set (match_operand:SI 0 "register_operand" "=r")
12453 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12454 (clobber (match_scratch:SI 2 "=&q"))
12455 (clobber (reg:CC FLAGS_REG))]
12458 "&& reload_completed"
12459 [(parallel [(set (match_dup 4) (match_dup 5))
12460 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12461 (set (strict_low_part (match_dup 3))
12462 (eq:QI (match_dup 4) (const_int 0)))
12463 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12464 (clobber (reg:CC FLAGS_REG))])
12465 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12466 (clobber (reg:CC FLAGS_REG))])
12467 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12468 (clobber (reg:CC FLAGS_REG))])]
12470 machine_mode flags_mode
12471 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12473 operands[3] = gen_lowpart (QImode, operands[2]);
12474 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12475 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12477 ix86_expand_clear (operands[2]);
12480 (define_insn "*tzcnt<mode>_1"
12481 [(set (reg:CCC FLAGS_REG)
12482 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12484 (set (match_operand:SWI48 0 "register_operand" "=r")
12485 (ctz:SWI48 (match_dup 1)))]
12486 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12487 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12488 [(set_attr "type" "alu1")
12489 (set_attr "prefix_0f" "1")
12490 (set_attr "prefix_rep" "1")
12491 (set_attr "btver2_decode" "double")
12492 (set_attr "mode" "<MODE>")])
12494 (define_insn "*bsf<mode>_1"
12495 [(set (reg:CCZ FLAGS_REG)
12496 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12498 (set (match_operand:SWI48 0 "register_operand" "=r")
12499 (ctz:SWI48 (match_dup 1)))]
12501 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12502 [(set_attr "type" "alu1")
12503 (set_attr "prefix_0f" "1")
12504 (set_attr "btver2_decode" "double")
12505 (set_attr "mode" "<MODE>")])
12507 (define_expand "ctz<mode>2"
12509 [(set (match_operand:SWI248 0 "register_operand")
12511 (match_operand:SWI248 1 "nonimmediate_operand")))
12512 (clobber (reg:CC FLAGS_REG))])])
12514 ; False dependency happens when destination is only updated by tzcnt,
12515 ; lzcnt or popcnt. There is no false dependency when destination is
12516 ; also used in source.
12517 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12518 [(set (match_operand:SWI48 0 "register_operand" "=r")
12520 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12521 (clobber (reg:CC FLAGS_REG))]
12522 "(TARGET_BMI || TARGET_GENERIC)
12523 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12525 "&& reload_completed"
12527 [(set (match_dup 0)
12528 (ctz:SWI48 (match_dup 1)))
12529 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12530 (clobber (reg:CC FLAGS_REG))])]
12532 if (!reg_mentioned_p (operands[0], operands[1]))
12533 ix86_expand_clear (operands[0]);
12536 (define_insn "*ctz<mode>2_falsedep"
12537 [(set (match_operand:SWI48 0 "register_operand" "=r")
12539 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12540 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12541 UNSPEC_INSN_FALSE_DEP)
12542 (clobber (reg:CC FLAGS_REG))]
12546 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12547 else if (TARGET_GENERIC)
12548 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12549 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12551 gcc_unreachable ();
12553 [(set_attr "type" "alu1")
12554 (set_attr "prefix_0f" "1")
12555 (set_attr "prefix_rep" "1")
12556 (set_attr "mode" "<MODE>")])
12558 (define_insn "*ctz<mode>2"
12559 [(set (match_operand:SWI248 0 "register_operand" "=r")
12560 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12561 (clobber (reg:CC FLAGS_REG))]
12565 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12566 else if (optimize_function_for_size_p (cfun))
12568 else if (TARGET_GENERIC)
12569 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12570 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12572 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12574 [(set_attr "type" "alu1")
12575 (set_attr "prefix_0f" "1")
12576 (set (attr "prefix_rep")
12578 (ior (match_test "TARGET_BMI")
12579 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12580 (match_test "TARGET_GENERIC")))
12582 (const_string "0")))
12583 (set_attr "mode" "<MODE>")])
12585 (define_expand "clz<mode>2"
12587 [(set (match_operand:SWI248 0 "register_operand")
12590 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12591 (clobber (reg:CC FLAGS_REG))])
12593 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12594 (clobber (reg:CC FLAGS_REG))])]
12599 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12602 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12605 (define_expand "clz<mode>2_lzcnt"
12607 [(set (match_operand:SWI248 0 "register_operand")
12609 (match_operand:SWI248 1 "nonimmediate_operand")))
12610 (clobber (reg:CC FLAGS_REG))])]
12613 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12614 [(set (match_operand:SWI48 0 "register_operand" "=r")
12616 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12617 (clobber (reg:CC FLAGS_REG))]
12619 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12621 "&& reload_completed"
12623 [(set (match_dup 0)
12624 (clz:SWI48 (match_dup 1)))
12625 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12626 (clobber (reg:CC FLAGS_REG))])]
12628 if (!reg_mentioned_p (operands[0], operands[1]))
12629 ix86_expand_clear (operands[0]);
12632 (define_insn "*clz<mode>2_lzcnt_falsedep"
12633 [(set (match_operand:SWI48 0 "register_operand" "=r")
12635 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12636 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12637 UNSPEC_INSN_FALSE_DEP)
12638 (clobber (reg:CC FLAGS_REG))]
12640 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12641 [(set_attr "prefix_rep" "1")
12642 (set_attr "type" "bitmanip")
12643 (set_attr "mode" "<MODE>")])
12645 (define_insn "*clz<mode>2_lzcnt"
12646 [(set (match_operand:SWI248 0 "register_operand" "=r")
12647 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12648 (clobber (reg:CC FLAGS_REG))]
12650 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12651 [(set_attr "prefix_rep" "1")
12652 (set_attr "type" "bitmanip")
12653 (set_attr "mode" "<MODE>")])
12655 ;; BMI instructions.
12656 (define_insn "*bmi_andn_<mode>"
12657 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12660 (match_operand:SWI48 1 "register_operand" "r,r"))
12661 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12662 (clobber (reg:CC FLAGS_REG))]
12664 "andn\t{%2, %1, %0|%0, %1, %2}"
12665 [(set_attr "type" "bitmanip")
12666 (set_attr "btver2_decode" "direct, double")
12667 (set_attr "mode" "<MODE>")])
12669 (define_insn "bmi_bextr_<mode>"
12670 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12671 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12672 (match_operand:SWI48 2 "register_operand" "r,r")]
12674 (clobber (reg:CC FLAGS_REG))]
12676 "bextr\t{%2, %1, %0|%0, %1, %2}"
12677 [(set_attr "type" "bitmanip")
12678 (set_attr "btver2_decode" "direct, double")
12679 (set_attr "mode" "<MODE>")])
12681 (define_insn "*bmi_blsi_<mode>"
12682 [(set (match_operand:SWI48 0 "register_operand" "=r")
12685 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12687 (clobber (reg:CC FLAGS_REG))]
12689 "blsi\t{%1, %0|%0, %1}"
12690 [(set_attr "type" "bitmanip")
12691 (set_attr "btver2_decode" "double")
12692 (set_attr "mode" "<MODE>")])
12694 (define_insn "*bmi_blsmsk_<mode>"
12695 [(set (match_operand:SWI48 0 "register_operand" "=r")
12698 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12701 (clobber (reg:CC FLAGS_REG))]
12703 "blsmsk\t{%1, %0|%0, %1}"
12704 [(set_attr "type" "bitmanip")
12705 (set_attr "btver2_decode" "double")
12706 (set_attr "mode" "<MODE>")])
12708 (define_insn "*bmi_blsr_<mode>"
12709 [(set (match_operand:SWI48 0 "register_operand" "=r")
12712 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12715 (clobber (reg:CC FLAGS_REG))]
12717 "blsr\t{%1, %0|%0, %1}"
12718 [(set_attr "type" "bitmanip")
12719 (set_attr "btver2_decode" "double")
12720 (set_attr "mode" "<MODE>")])
12722 ;; BMI2 instructions.
12723 (define_expand "bmi2_bzhi_<mode>3"
12725 [(set (match_operand:SWI48 0 "register_operand")
12726 (zero_extract:SWI48
12727 (match_operand:SWI48 1 "nonimmediate_operand")
12729 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12733 (clobber (reg:CC FLAGS_REG))])]
12735 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12737 (define_insn "*bmi2_bzhi_<mode>3"
12738 [(set (match_operand:SWI48 0 "register_operand" "=r")
12739 (zero_extract:SWI48
12740 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12742 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12744 (match_operand:SWI48 3 "const_int_operand" "n"))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12748 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12749 [(set_attr "type" "bitmanip")
12750 (set_attr "prefix" "vex")
12751 (set_attr "mode" "<MODE>")])
12753 (define_mode_attr k [(SI "k") (DI "q")])
12754 (define_insn "*bmi2_bzhi_<mode>3_1"
12755 [(set (match_operand:SWI48 0 "register_operand" "=r")
12756 (zero_extract:SWI48
12757 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12759 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12760 (match_operand:SWI48 3 "const_int_operand" "n"))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12764 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12765 [(set_attr "type" "bitmanip")
12766 (set_attr "prefix" "vex")
12767 (set_attr "mode" "<MODE>")])
12769 (define_insn "bmi2_pdep_<mode>3"
12770 [(set (match_operand:SWI48 0 "register_operand" "=r")
12771 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12772 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12775 "pdep\t{%2, %1, %0|%0, %1, %2}"
12776 [(set_attr "type" "bitmanip")
12777 (set_attr "prefix" "vex")
12778 (set_attr "mode" "<MODE>")])
12780 (define_insn "bmi2_pext_<mode>3"
12781 [(set (match_operand:SWI48 0 "register_operand" "=r")
12782 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12783 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12786 "pext\t{%2, %1, %0|%0, %1, %2}"
12787 [(set_attr "type" "bitmanip")
12788 (set_attr "prefix" "vex")
12789 (set_attr "mode" "<MODE>")])
12791 ;; TBM instructions.
12792 (define_insn "tbm_bextri_<mode>"
12793 [(set (match_operand:SWI48 0 "register_operand" "=r")
12794 (zero_extract:SWI48
12795 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12796 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12797 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12798 (clobber (reg:CC FLAGS_REG))]
12801 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12802 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12804 [(set_attr "type" "bitmanip")
12805 (set_attr "mode" "<MODE>")])
12807 (define_insn "*tbm_blcfill_<mode>"
12808 [(set (match_operand:SWI48 0 "register_operand" "=r")
12811 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12814 (clobber (reg:CC FLAGS_REG))]
12816 "blcfill\t{%1, %0|%0, %1}"
12817 [(set_attr "type" "bitmanip")
12818 (set_attr "mode" "<MODE>")])
12820 (define_insn "*tbm_blci_<mode>"
12821 [(set (match_operand:SWI48 0 "register_operand" "=r")
12825 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12828 (clobber (reg:CC FLAGS_REG))]
12830 "blci\t{%1, %0|%0, %1}"
12831 [(set_attr "type" "bitmanip")
12832 (set_attr "mode" "<MODE>")])
12834 (define_insn "*tbm_blcic_<mode>"
12835 [(set (match_operand:SWI48 0 "register_operand" "=r")
12838 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12842 (clobber (reg:CC FLAGS_REG))]
12844 "blcic\t{%1, %0|%0, %1}"
12845 [(set_attr "type" "bitmanip")
12846 (set_attr "mode" "<MODE>")])
12848 (define_insn "*tbm_blcmsk_<mode>"
12849 [(set (match_operand:SWI48 0 "register_operand" "=r")
12852 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12855 (clobber (reg:CC FLAGS_REG))]
12857 "blcmsk\t{%1, %0|%0, %1}"
12858 [(set_attr "type" "bitmanip")
12859 (set_attr "mode" "<MODE>")])
12861 (define_insn "*tbm_blcs_<mode>"
12862 [(set (match_operand:SWI48 0 "register_operand" "=r")
12865 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12868 (clobber (reg:CC FLAGS_REG))]
12870 "blcs\t{%1, %0|%0, %1}"
12871 [(set_attr "type" "bitmanip")
12872 (set_attr "mode" "<MODE>")])
12874 (define_insn "*tbm_blsfill_<mode>"
12875 [(set (match_operand:SWI48 0 "register_operand" "=r")
12878 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12881 (clobber (reg:CC FLAGS_REG))]
12883 "blsfill\t{%1, %0|%0, %1}"
12884 [(set_attr "type" "bitmanip")
12885 (set_attr "mode" "<MODE>")])
12887 (define_insn "*tbm_blsic_<mode>"
12888 [(set (match_operand:SWI48 0 "register_operand" "=r")
12891 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12895 (clobber (reg:CC FLAGS_REG))]
12897 "blsic\t{%1, %0|%0, %1}"
12898 [(set_attr "type" "bitmanip")
12899 (set_attr "mode" "<MODE>")])
12901 (define_insn "*tbm_t1mskc_<mode>"
12902 [(set (match_operand:SWI48 0 "register_operand" "=r")
12905 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12909 (clobber (reg:CC FLAGS_REG))]
12911 "t1mskc\t{%1, %0|%0, %1}"
12912 [(set_attr "type" "bitmanip")
12913 (set_attr "mode" "<MODE>")])
12915 (define_insn "*tbm_tzmsk_<mode>"
12916 [(set (match_operand:SWI48 0 "register_operand" "=r")
12919 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12923 (clobber (reg:CC FLAGS_REG))]
12925 "tzmsk\t{%1, %0|%0, %1}"
12926 [(set_attr "type" "bitmanip")
12927 (set_attr "mode" "<MODE>")])
12929 (define_insn "bsr_rex64"
12930 [(set (match_operand:DI 0 "register_operand" "=r")
12931 (minus:DI (const_int 63)
12932 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12933 (clobber (reg:CC FLAGS_REG))]
12935 "bsr{q}\t{%1, %0|%0, %1}"
12936 [(set_attr "type" "alu1")
12937 (set_attr "prefix_0f" "1")
12938 (set_attr "mode" "DI")])
12941 [(set (match_operand:SI 0 "register_operand" "=r")
12942 (minus:SI (const_int 31)
12943 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12944 (clobber (reg:CC FLAGS_REG))]
12946 "bsr{l}\t{%1, %0|%0, %1}"
12947 [(set_attr "type" "alu1")
12948 (set_attr "prefix_0f" "1")
12949 (set_attr "mode" "SI")])
12951 (define_insn "*bsrhi"
12952 [(set (match_operand:HI 0 "register_operand" "=r")
12953 (minus:HI (const_int 15)
12954 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12955 (clobber (reg:CC FLAGS_REG))]
12957 "bsr{w}\t{%1, %0|%0, %1}"
12958 [(set_attr "type" "alu1")
12959 (set_attr "prefix_0f" "1")
12960 (set_attr "mode" "HI")])
12962 (define_expand "popcount<mode>2"
12964 [(set (match_operand:SWI248 0 "register_operand")
12966 (match_operand:SWI248 1 "nonimmediate_operand")))
12967 (clobber (reg:CC FLAGS_REG))])]
12970 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12971 [(set (match_operand:SWI48 0 "register_operand" "=r")
12973 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12974 (clobber (reg:CC FLAGS_REG))]
12976 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12978 "&& reload_completed"
12980 [(set (match_dup 0)
12981 (popcount:SWI48 (match_dup 1)))
12982 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12983 (clobber (reg:CC FLAGS_REG))])]
12985 if (!reg_mentioned_p (operands[0], operands[1]))
12986 ix86_expand_clear (operands[0]);
12989 (define_insn "*popcount<mode>2_falsedep"
12990 [(set (match_operand:SWI48 0 "register_operand" "=r")
12992 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12993 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12994 UNSPEC_INSN_FALSE_DEP)
12995 (clobber (reg:CC FLAGS_REG))]
12999 return "popcnt\t{%1, %0|%0, %1}";
13001 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13004 [(set_attr "prefix_rep" "1")
13005 (set_attr "type" "bitmanip")
13006 (set_attr "mode" "<MODE>")])
13008 (define_insn "*popcount<mode>2"
13009 [(set (match_operand:SWI248 0 "register_operand" "=r")
13011 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13012 (clobber (reg:CC FLAGS_REG))]
13016 return "popcnt\t{%1, %0|%0, %1}";
13018 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13021 [(set_attr "prefix_rep" "1")
13022 (set_attr "type" "bitmanip")
13023 (set_attr "mode" "<MODE>")])
13025 (define_expand "bswapdi2"
13026 [(set (match_operand:DI 0 "register_operand")
13027 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13031 operands[1] = force_reg (DImode, operands[1]);
13034 (define_expand "bswapsi2"
13035 [(set (match_operand:SI 0 "register_operand")
13036 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13041 else if (TARGET_BSWAP)
13042 operands[1] = force_reg (SImode, operands[1]);
13045 rtx x = operands[0];
13047 emit_move_insn (x, operands[1]);
13048 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13049 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13050 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13055 (define_insn "*bswap<mode>2_movbe"
13056 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13057 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13059 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13062 movbe\t{%1, %0|%0, %1}
13063 movbe\t{%1, %0|%0, %1}"
13064 [(set_attr "type" "bitmanip,imov,imov")
13065 (set_attr "modrm" "0,1,1")
13066 (set_attr "prefix_0f" "*,1,1")
13067 (set_attr "prefix_extra" "*,1,1")
13068 (set_attr "mode" "<MODE>")])
13070 (define_insn "*bswap<mode>2"
13071 [(set (match_operand:SWI48 0 "register_operand" "=r")
13072 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13075 [(set_attr "type" "bitmanip")
13076 (set_attr "modrm" "0")
13077 (set_attr "mode" "<MODE>")])
13079 (define_insn "*bswaphi_lowpart_1"
13080 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13081 (bswap:HI (match_dup 0)))
13082 (clobber (reg:CC FLAGS_REG))]
13083 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13085 xchg{b}\t{%h0, %b0|%b0, %h0}
13086 rol{w}\t{$8, %0|%0, 8}"
13087 [(set_attr "length" "2,4")
13088 (set_attr "mode" "QI,HI")])
13090 (define_insn "bswaphi_lowpart"
13091 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13092 (bswap:HI (match_dup 0)))
13093 (clobber (reg:CC FLAGS_REG))]
13095 "rol{w}\t{$8, %0|%0, 8}"
13096 [(set_attr "length" "4")
13097 (set_attr "mode" "HI")])
13099 (define_expand "paritydi2"
13100 [(set (match_operand:DI 0 "register_operand")
13101 (parity:DI (match_operand:DI 1 "register_operand")))]
13104 rtx scratch = gen_reg_rtx (QImode);
13107 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13108 NULL_RTX, operands[1]));
13110 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13111 gen_rtx_REG (CCmode, FLAGS_REG),
13113 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13116 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13119 rtx tmp = gen_reg_rtx (SImode);
13121 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13122 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13127 (define_expand "paritysi2"
13128 [(set (match_operand:SI 0 "register_operand")
13129 (parity:SI (match_operand:SI 1 "register_operand")))]
13132 rtx scratch = gen_reg_rtx (QImode);
13135 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13137 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13138 gen_rtx_REG (CCmode, FLAGS_REG),
13140 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13142 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13146 (define_insn_and_split "paritydi2_cmp"
13147 [(set (reg:CC FLAGS_REG)
13148 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13150 (clobber (match_scratch:DI 0 "=r"))
13151 (clobber (match_scratch:SI 1 "=&r"))
13152 (clobber (match_scratch:HI 2 "=Q"))]
13155 "&& reload_completed"
13157 [(set (match_dup 1)
13158 (xor:SI (match_dup 1) (match_dup 4)))
13159 (clobber (reg:CC FLAGS_REG))])
13161 [(set (reg:CC FLAGS_REG)
13162 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13163 (clobber (match_dup 1))
13164 (clobber (match_dup 2))])]
13166 operands[4] = gen_lowpart (SImode, operands[3]);
13170 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13171 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13174 operands[1] = gen_highpart (SImode, operands[3]);
13177 (define_insn_and_split "paritysi2_cmp"
13178 [(set (reg:CC FLAGS_REG)
13179 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13181 (clobber (match_scratch:SI 0 "=r"))
13182 (clobber (match_scratch:HI 1 "=&Q"))]
13185 "&& reload_completed"
13187 [(set (match_dup 1)
13188 (xor:HI (match_dup 1) (match_dup 3)))
13189 (clobber (reg:CC FLAGS_REG))])
13191 [(set (reg:CC FLAGS_REG)
13192 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13193 (clobber (match_dup 1))])]
13195 operands[3] = gen_lowpart (HImode, operands[2]);
13197 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13198 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13201 (define_insn "*parityhi2_cmp"
13202 [(set (reg:CC FLAGS_REG)
13203 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13205 (clobber (match_scratch:HI 0 "=Q"))]
13207 "xor{b}\t{%h0, %b0|%b0, %h0}"
13208 [(set_attr "length" "2")
13209 (set_attr "mode" "HI")])
13212 ;; Thread-local storage patterns for ELF.
13214 ;; Note that these code sequences must appear exactly as shown
13215 ;; in order to allow linker relaxation.
13217 (define_insn "*tls_global_dynamic_32_gnu"
13218 [(set (match_operand:SI 0 "register_operand" "=a")
13220 [(match_operand:SI 1 "register_operand" "b")
13221 (match_operand 2 "tls_symbolic_operand")
13222 (match_operand 3 "constant_call_address_operand" "Bz")
13225 (clobber (match_scratch:SI 4 "=d"))
13226 (clobber (match_scratch:SI 5 "=c"))
13227 (clobber (reg:CC FLAGS_REG))]
13228 "!TARGET_64BIT && TARGET_GNU_TLS"
13231 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13232 if (TARGET_SUN_TLS)
13233 #ifdef HAVE_AS_IX86_TLSGDPLT
13234 return "call\t%a2@tlsgdplt";
13236 return "call\t%p3@plt";
13238 return "call\t%P3";
13240 [(set_attr "type" "multi")
13241 (set_attr "length" "12")])
13243 (define_expand "tls_global_dynamic_32"
13245 [(set (match_operand:SI 0 "register_operand")
13246 (unspec:SI [(match_operand:SI 2 "register_operand")
13247 (match_operand 1 "tls_symbolic_operand")
13248 (match_operand 3 "constant_call_address_operand")
13251 (clobber (match_scratch:SI 4))
13252 (clobber (match_scratch:SI 5))
13253 (clobber (reg:CC FLAGS_REG))])]
13255 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13257 (define_insn "*tls_global_dynamic_64_<mode>"
13258 [(set (match_operand:P 0 "register_operand" "=a")
13260 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13261 (match_operand 3)))
13262 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13268 fputs (ASM_BYTE "0x66\n", asm_out_file);
13270 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13271 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13272 fputs ("\trex64\n", asm_out_file);
13273 if (TARGET_SUN_TLS)
13274 return "call\t%p2@plt";
13275 return "call\t%P2";
13277 [(set_attr "type" "multi")
13278 (set (attr "length")
13279 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13281 (define_insn "*tls_global_dynamic_64_largepic"
13282 [(set (match_operand:DI 0 "register_operand" "=a")
13284 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13285 (match_operand:DI 3 "immediate_operand" "i")))
13286 (match_operand 4)))
13287 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13290 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13291 && GET_CODE (operands[3]) == CONST
13292 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13293 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13296 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13297 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13298 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13299 return "call\t{*%%rax|rax}";
13301 [(set_attr "type" "multi")
13302 (set_attr "length" "22")])
13304 (define_expand "tls_global_dynamic_64_<mode>"
13306 [(set (match_operand:P 0 "register_operand")
13308 (mem:QI (match_operand 2))
13310 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13314 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13316 (define_insn "*tls_local_dynamic_base_32_gnu"
13317 [(set (match_operand:SI 0 "register_operand" "=a")
13319 [(match_operand:SI 1 "register_operand" "b")
13320 (match_operand 2 "constant_call_address_operand" "Bz")
13322 UNSPEC_TLS_LD_BASE))
13323 (clobber (match_scratch:SI 3 "=d"))
13324 (clobber (match_scratch:SI 4 "=c"))
13325 (clobber (reg:CC FLAGS_REG))]
13326 "!TARGET_64BIT && TARGET_GNU_TLS"
13329 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13330 if (TARGET_SUN_TLS)
13332 if (HAVE_AS_IX86_TLSLDMPLT)
13333 return "call\t%&@tlsldmplt";
13335 return "call\t%p2@plt";
13337 return "call\t%P2";
13339 [(set_attr "type" "multi")
13340 (set_attr "length" "11")])
13342 (define_expand "tls_local_dynamic_base_32"
13344 [(set (match_operand:SI 0 "register_operand")
13346 [(match_operand:SI 1 "register_operand")
13347 (match_operand 2 "constant_call_address_operand")
13349 UNSPEC_TLS_LD_BASE))
13350 (clobber (match_scratch:SI 3))
13351 (clobber (match_scratch:SI 4))
13352 (clobber (reg:CC FLAGS_REG))])]
13354 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13356 (define_insn "*tls_local_dynamic_base_64_<mode>"
13357 [(set (match_operand:P 0 "register_operand" "=a")
13359 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13360 (match_operand 2)))
13361 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13365 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13366 if (TARGET_SUN_TLS)
13367 return "call\t%p1@plt";
13368 return "call\t%P1";
13370 [(set_attr "type" "multi")
13371 (set_attr "length" "12")])
13373 (define_insn "*tls_local_dynamic_base_64_largepic"
13374 [(set (match_operand:DI 0 "register_operand" "=a")
13376 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13377 (match_operand:DI 2 "immediate_operand" "i")))
13378 (match_operand 3)))
13379 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13380 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13381 && GET_CODE (operands[2]) == CONST
13382 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13383 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13386 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13387 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13388 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13389 return "call\t{*%%rax|rax}";
13391 [(set_attr "type" "multi")
13392 (set_attr "length" "22")])
13394 (define_expand "tls_local_dynamic_base_64_<mode>"
13396 [(set (match_operand:P 0 "register_operand")
13398 (mem:QI (match_operand 1))
13400 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13402 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13404 ;; Local dynamic of a single variable is a lose. Show combine how
13405 ;; to convert that back to global dynamic.
13407 (define_insn_and_split "*tls_local_dynamic_32_once"
13408 [(set (match_operand:SI 0 "register_operand" "=a")
13410 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13411 (match_operand 2 "constant_call_address_operand" "Bz")
13413 UNSPEC_TLS_LD_BASE)
13414 (const:SI (unspec:SI
13415 [(match_operand 3 "tls_symbolic_operand")]
13417 (clobber (match_scratch:SI 4 "=d"))
13418 (clobber (match_scratch:SI 5 "=c"))
13419 (clobber (reg:CC FLAGS_REG))]
13424 [(set (match_dup 0)
13425 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13428 (clobber (match_dup 4))
13429 (clobber (match_dup 5))
13430 (clobber (reg:CC FLAGS_REG))])])
13432 ;; Segment register for the thread base ptr load
13433 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13435 ;; Load and add the thread base pointer from %<tp_seg>:0.
13436 (define_insn "*load_tp_x32"
13437 [(set (match_operand:SI 0 "register_operand" "=r")
13438 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13440 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13441 [(set_attr "type" "imov")
13442 (set_attr "modrm" "0")
13443 (set_attr "length" "7")
13444 (set_attr "memory" "load")
13445 (set_attr "imm_disp" "false")])
13447 (define_insn "*load_tp_x32_zext"
13448 [(set (match_operand:DI 0 "register_operand" "=r")
13449 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13451 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13452 [(set_attr "type" "imov")
13453 (set_attr "modrm" "0")
13454 (set_attr "length" "7")
13455 (set_attr "memory" "load")
13456 (set_attr "imm_disp" "false")])
13458 (define_insn "*load_tp_<mode>"
13459 [(set (match_operand:P 0 "register_operand" "=r")
13460 (unspec:P [(const_int 0)] UNSPEC_TP))]
13462 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13463 [(set_attr "type" "imov")
13464 (set_attr "modrm" "0")
13465 (set_attr "length" "7")
13466 (set_attr "memory" "load")
13467 (set_attr "imm_disp" "false")])
13469 (define_insn "*add_tp_x32"
13470 [(set (match_operand:SI 0 "register_operand" "=r")
13471 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13472 (match_operand:SI 1 "register_operand" "0")))
13473 (clobber (reg:CC FLAGS_REG))]
13475 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13476 [(set_attr "type" "alu")
13477 (set_attr "modrm" "0")
13478 (set_attr "length" "7")
13479 (set_attr "memory" "load")
13480 (set_attr "imm_disp" "false")])
13482 (define_insn "*add_tp_x32_zext"
13483 [(set (match_operand:DI 0 "register_operand" "=r")
13485 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13486 (match_operand:SI 1 "register_operand" "0"))))
13487 (clobber (reg:CC FLAGS_REG))]
13489 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13490 [(set_attr "type" "alu")
13491 (set_attr "modrm" "0")
13492 (set_attr "length" "7")
13493 (set_attr "memory" "load")
13494 (set_attr "imm_disp" "false")])
13496 (define_insn "*add_tp_<mode>"
13497 [(set (match_operand:P 0 "register_operand" "=r")
13498 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13499 (match_operand:P 1 "register_operand" "0")))
13500 (clobber (reg:CC FLAGS_REG))]
13502 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13503 [(set_attr "type" "alu")
13504 (set_attr "modrm" "0")
13505 (set_attr "length" "7")
13506 (set_attr "memory" "load")
13507 (set_attr "imm_disp" "false")])
13509 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13510 ;; %rax as destination of the initial executable code sequence.
13511 (define_insn "tls_initial_exec_64_sun"
13512 [(set (match_operand:DI 0 "register_operand" "=a")
13514 [(match_operand 1 "tls_symbolic_operand")]
13515 UNSPEC_TLS_IE_SUN))
13516 (clobber (reg:CC FLAGS_REG))]
13517 "TARGET_64BIT && TARGET_SUN_TLS"
13520 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13521 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13523 [(set_attr "type" "multi")])
13525 ;; GNU2 TLS patterns can be split.
13527 (define_expand "tls_dynamic_gnu2_32"
13528 [(set (match_dup 3)
13529 (plus:SI (match_operand:SI 2 "register_operand")
13531 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13534 [(set (match_operand:SI 0 "register_operand")
13535 (unspec:SI [(match_dup 1) (match_dup 3)
13536 (match_dup 2) (reg:SI SP_REG)]
13538 (clobber (reg:CC FLAGS_REG))])]
13539 "!TARGET_64BIT && TARGET_GNU2_TLS"
13541 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13542 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13545 (define_insn "*tls_dynamic_gnu2_lea_32"
13546 [(set (match_operand:SI 0 "register_operand" "=r")
13547 (plus:SI (match_operand:SI 1 "register_operand" "b")
13549 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13550 UNSPEC_TLSDESC))))]
13551 "!TARGET_64BIT && TARGET_GNU2_TLS"
13552 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13553 [(set_attr "type" "lea")
13554 (set_attr "mode" "SI")
13555 (set_attr "length" "6")
13556 (set_attr "length_address" "4")])
13558 (define_insn "*tls_dynamic_gnu2_call_32"
13559 [(set (match_operand:SI 0 "register_operand" "=a")
13560 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13561 (match_operand:SI 2 "register_operand" "0")
13562 ;; we have to make sure %ebx still points to the GOT
13563 (match_operand:SI 3 "register_operand" "b")
13566 (clobber (reg:CC FLAGS_REG))]
13567 "!TARGET_64BIT && TARGET_GNU2_TLS"
13568 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13569 [(set_attr "type" "call")
13570 (set_attr "length" "2")
13571 (set_attr "length_address" "0")])
13573 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13574 [(set (match_operand:SI 0 "register_operand" "=&a")
13576 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13577 (match_operand:SI 4)
13578 (match_operand:SI 2 "register_operand" "b")
13581 (const:SI (unspec:SI
13582 [(match_operand 1 "tls_symbolic_operand")]
13584 (clobber (reg:CC FLAGS_REG))]
13585 "!TARGET_64BIT && TARGET_GNU2_TLS"
13588 [(set (match_dup 0) (match_dup 5))]
13590 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13591 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13594 (define_expand "tls_dynamic_gnu2_64"
13595 [(set (match_dup 2)
13596 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13599 [(set (match_operand:DI 0 "register_operand")
13600 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13602 (clobber (reg:CC FLAGS_REG))])]
13603 "TARGET_64BIT && TARGET_GNU2_TLS"
13605 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13606 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13609 (define_insn "*tls_dynamic_gnu2_lea_64"
13610 [(set (match_operand:DI 0 "register_operand" "=r")
13611 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13613 "TARGET_64BIT && TARGET_GNU2_TLS"
13614 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13615 [(set_attr "type" "lea")
13616 (set_attr "mode" "DI")
13617 (set_attr "length" "7")
13618 (set_attr "length_address" "4")])
13620 (define_insn "*tls_dynamic_gnu2_call_64"
13621 [(set (match_operand:DI 0 "register_operand" "=a")
13622 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13623 (match_operand:DI 2 "register_operand" "0")
13626 (clobber (reg:CC FLAGS_REG))]
13627 "TARGET_64BIT && TARGET_GNU2_TLS"
13628 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13629 [(set_attr "type" "call")
13630 (set_attr "length" "2")
13631 (set_attr "length_address" "0")])
13633 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13634 [(set (match_operand:DI 0 "register_operand" "=&a")
13636 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13637 (match_operand:DI 3)
13640 (const:DI (unspec:DI
13641 [(match_operand 1 "tls_symbolic_operand")]
13643 (clobber (reg:CC FLAGS_REG))]
13644 "TARGET_64BIT && TARGET_GNU2_TLS"
13647 [(set (match_dup 0) (match_dup 4))]
13649 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13650 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13653 ;; These patterns match the binary 387 instructions for addM3, subM3,
13654 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13655 ;; SFmode. The first is the normal insn, the second the same insn but
13656 ;; with one operand a conversion, and the third the same insn but with
13657 ;; the other operand a conversion. The conversion may be SFmode or
13658 ;; SImode if the target mode DFmode, but only SImode if the target mode
13661 ;; Gcc is slightly more smart about handling normal two address instructions
13662 ;; so use special patterns for add and mull.
13664 (define_insn "*fop_<mode>_comm_mixed"
13665 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13666 (match_operator:MODEF 3 "binary_fp_operator"
13667 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13668 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13669 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13670 && COMMUTATIVE_ARITH_P (operands[3])
13671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13672 "* return output_387_binary_op (insn, operands);"
13673 [(set (attr "type")
13674 (if_then_else (eq_attr "alternative" "1,2")
13675 (if_then_else (match_operand:MODEF 3 "mult_operator")
13676 (const_string "ssemul")
13677 (const_string "sseadd"))
13678 (if_then_else (match_operand:MODEF 3 "mult_operator")
13679 (const_string "fmul")
13680 (const_string "fop"))))
13681 (set_attr "isa" "*,noavx,avx")
13682 (set_attr "prefix" "orig,orig,vex")
13683 (set_attr "mode" "<MODE>")])
13685 (define_insn "*fop_<mode>_comm_sse"
13686 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13687 (match_operator:MODEF 3 "binary_fp_operator"
13688 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13689 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13690 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13691 && COMMUTATIVE_ARITH_P (operands[3])
13692 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13693 "* return output_387_binary_op (insn, operands);"
13694 [(set (attr "type")
13695 (if_then_else (match_operand:MODEF 3 "mult_operator")
13696 (const_string "ssemul")
13697 (const_string "sseadd")))
13698 (set_attr "isa" "noavx,avx")
13699 (set_attr "prefix" "orig,vex")
13700 (set_attr "mode" "<MODE>")])
13702 (define_insn "*fop_<mode>_comm_i387"
13703 [(set (match_operand:MODEF 0 "register_operand" "=f")
13704 (match_operator:MODEF 3 "binary_fp_operator"
13705 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13706 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13707 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13708 && COMMUTATIVE_ARITH_P (operands[3])
13709 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13710 "* return output_387_binary_op (insn, operands);"
13711 [(set (attr "type")
13712 (if_then_else (match_operand:MODEF 3 "mult_operator")
13713 (const_string "fmul")
13714 (const_string "fop")))
13715 (set_attr "mode" "<MODE>")])
13717 (define_insn "*fop_<mode>_1_mixed"
13718 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13719 (match_operator:MODEF 3 "binary_fp_operator"
13720 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13721 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13722 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13723 && !COMMUTATIVE_ARITH_P (operands[3])
13724 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13725 "* return output_387_binary_op (insn, operands);"
13726 [(set (attr "type")
13727 (cond [(and (eq_attr "alternative" "2,3")
13728 (match_operand:MODEF 3 "mult_operator"))
13729 (const_string "ssemul")
13730 (and (eq_attr "alternative" "2,3")
13731 (match_operand:MODEF 3 "div_operator"))
13732 (const_string "ssediv")
13733 (eq_attr "alternative" "2,3")
13734 (const_string "sseadd")
13735 (match_operand:MODEF 3 "mult_operator")
13736 (const_string "fmul")
13737 (match_operand:MODEF 3 "div_operator")
13738 (const_string "fdiv")
13740 (const_string "fop")))
13741 (set_attr "isa" "*,*,noavx,avx")
13742 (set_attr "prefix" "orig,orig,orig,vex")
13743 (set_attr "mode" "<MODE>")])
13745 (define_insn "*rcpsf2_sse"
13746 [(set (match_operand:SF 0 "register_operand" "=x")
13747 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13750 "%vrcpss\t{%1, %d0|%d0, %1}"
13751 [(set_attr "type" "sse")
13752 (set_attr "atom_sse_attr" "rcp")
13753 (set_attr "btver2_sse_attr" "rcp")
13754 (set_attr "prefix" "maybe_vex")
13755 (set_attr "mode" "SF")])
13757 (define_insn "*fop_<mode>_1_sse"
13758 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13759 (match_operator:MODEF 3 "binary_fp_operator"
13760 [(match_operand:MODEF 1 "register_operand" "0,x")
13761 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13762 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13763 && !COMMUTATIVE_ARITH_P (operands[3])"
13764 "* return output_387_binary_op (insn, operands);"
13765 [(set (attr "type")
13766 (cond [(match_operand:MODEF 3 "mult_operator")
13767 (const_string "ssemul")
13768 (match_operand:MODEF 3 "div_operator")
13769 (const_string "ssediv")
13771 (const_string "sseadd")))
13772 (set_attr "isa" "noavx,avx")
13773 (set_attr "prefix" "orig,vex")
13774 (set_attr "mode" "<MODE>")])
13776 ;; This pattern is not fully shadowed by the pattern above.
13777 (define_insn "*fop_<mode>_1_i387"
13778 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13779 (match_operator:MODEF 3 "binary_fp_operator"
13780 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13781 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13782 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13783 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784 && !COMMUTATIVE_ARITH_P (operands[3])
13785 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13786 "* return output_387_binary_op (insn, operands);"
13787 [(set (attr "type")
13788 (cond [(match_operand:MODEF 3 "mult_operator")
13789 (const_string "fmul")
13790 (match_operand:MODEF 3 "div_operator")
13791 (const_string "fdiv")
13793 (const_string "fop")))
13794 (set_attr "mode" "<MODE>")])
13796 ;; ??? Add SSE splitters for these!
13797 (define_insn "*fop_<MODEF:mode>_2_i387"
13798 [(set (match_operand:MODEF 0 "register_operand" "=f")
13799 (match_operator:MODEF 3 "binary_fp_operator"
13801 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13802 (match_operand:MODEF 2 "register_operand" "0")]))]
13803 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13804 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13805 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13806 || optimize_function_for_size_p (cfun))"
13807 { return output_387_binary_op (insn, operands); }
13808 [(set (attr "type")
13809 (cond [(match_operand:MODEF 3 "mult_operator")
13810 (const_string "fmul")
13811 (match_operand:MODEF 3 "div_operator")
13812 (const_string "fdiv")
13814 (const_string "fop")))
13815 (set_attr "fp_int_src" "true")
13816 (set_attr "mode" "<SWI24:MODE>")])
13818 (define_insn "*fop_<MODEF:mode>_3_i387"
13819 [(set (match_operand:MODEF 0 "register_operand" "=f")
13820 (match_operator:MODEF 3 "binary_fp_operator"
13821 [(match_operand:MODEF 1 "register_operand" "0")
13823 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13824 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13825 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13826 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13827 || optimize_function_for_size_p (cfun))"
13828 { return output_387_binary_op (insn, operands); }
13829 [(set (attr "type")
13830 (cond [(match_operand:MODEF 3 "mult_operator")
13831 (const_string "fmul")
13832 (match_operand:MODEF 3 "div_operator")
13833 (const_string "fdiv")
13835 (const_string "fop")))
13836 (set_attr "fp_int_src" "true")
13837 (set_attr "mode" "<MODE>")])
13839 (define_insn "*fop_df_4_i387"
13840 [(set (match_operand:DF 0 "register_operand" "=f,f")
13841 (match_operator:DF 3 "binary_fp_operator"
13843 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13844 (match_operand:DF 2 "register_operand" "0,f")]))]
13845 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13846 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13847 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13848 "* return output_387_binary_op (insn, operands);"
13849 [(set (attr "type")
13850 (cond [(match_operand:DF 3 "mult_operator")
13851 (const_string "fmul")
13852 (match_operand:DF 3 "div_operator")
13853 (const_string "fdiv")
13855 (const_string "fop")))
13856 (set_attr "mode" "SF")])
13858 (define_insn "*fop_df_5_i387"
13859 [(set (match_operand:DF 0 "register_operand" "=f,f")
13860 (match_operator:DF 3 "binary_fp_operator"
13861 [(match_operand:DF 1 "register_operand" "0,f")
13863 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13864 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13865 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13866 "* return output_387_binary_op (insn, operands);"
13867 [(set (attr "type")
13868 (cond [(match_operand:DF 3 "mult_operator")
13869 (const_string "fmul")
13870 (match_operand:DF 3 "div_operator")
13871 (const_string "fdiv")
13873 (const_string "fop")))
13874 (set_attr "mode" "SF")])
13876 (define_insn "*fop_df_6_i387"
13877 [(set (match_operand:DF 0 "register_operand" "=f,f")
13878 (match_operator:DF 3 "binary_fp_operator"
13880 (match_operand:SF 1 "register_operand" "0,f"))
13882 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13883 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13884 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13885 "* return output_387_binary_op (insn, operands);"
13886 [(set (attr "type")
13887 (cond [(match_operand:DF 3 "mult_operator")
13888 (const_string "fmul")
13889 (match_operand:DF 3 "div_operator")
13890 (const_string "fdiv")
13892 (const_string "fop")))
13893 (set_attr "mode" "SF")])
13895 (define_insn "*fop_xf_comm_i387"
13896 [(set (match_operand:XF 0 "register_operand" "=f")
13897 (match_operator:XF 3 "binary_fp_operator"
13898 [(match_operand:XF 1 "register_operand" "%0")
13899 (match_operand:XF 2 "register_operand" "f")]))]
13901 && COMMUTATIVE_ARITH_P (operands[3])"
13902 "* return output_387_binary_op (insn, operands);"
13903 [(set (attr "type")
13904 (if_then_else (match_operand:XF 3 "mult_operator")
13905 (const_string "fmul")
13906 (const_string "fop")))
13907 (set_attr "mode" "XF")])
13909 (define_insn "*fop_xf_1_i387"
13910 [(set (match_operand:XF 0 "register_operand" "=f,f")
13911 (match_operator:XF 3 "binary_fp_operator"
13912 [(match_operand:XF 1 "register_operand" "0,f")
13913 (match_operand:XF 2 "register_operand" "f,0")]))]
13915 && !COMMUTATIVE_ARITH_P (operands[3])"
13916 "* return output_387_binary_op (insn, operands);"
13917 [(set (attr "type")
13918 (cond [(match_operand:XF 3 "mult_operator")
13919 (const_string "fmul")
13920 (match_operand:XF 3 "div_operator")
13921 (const_string "fdiv")
13923 (const_string "fop")))
13924 (set_attr "mode" "XF")])
13926 (define_insn "*fop_xf_2_i387"
13927 [(set (match_operand:XF 0 "register_operand" "=f")
13928 (match_operator:XF 3 "binary_fp_operator"
13930 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13931 (match_operand:XF 2 "register_operand" "0")]))]
13933 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13934 { return output_387_binary_op (insn, operands); }
13935 [(set (attr "type")
13936 (cond [(match_operand:XF 3 "mult_operator")
13937 (const_string "fmul")
13938 (match_operand:XF 3 "div_operator")
13939 (const_string "fdiv")
13941 (const_string "fop")))
13942 (set_attr "fp_int_src" "true")
13943 (set_attr "mode" "<MODE>")])
13945 (define_insn "*fop_xf_3_i387"
13946 [(set (match_operand:XF 0 "register_operand" "=f")
13947 (match_operator:XF 3 "binary_fp_operator"
13948 [(match_operand:XF 1 "register_operand" "0")
13950 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13952 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13953 { return output_387_binary_op (insn, operands); }
13954 [(set (attr "type")
13955 (cond [(match_operand:XF 3 "mult_operator")
13956 (const_string "fmul")
13957 (match_operand:XF 3 "div_operator")
13958 (const_string "fdiv")
13960 (const_string "fop")))
13961 (set_attr "fp_int_src" "true")
13962 (set_attr "mode" "<MODE>")])
13964 (define_insn "*fop_xf_4_i387"
13965 [(set (match_operand:XF 0 "register_operand" "=f,f")
13966 (match_operator:XF 3 "binary_fp_operator"
13968 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13969 (match_operand:XF 2 "register_operand" "0,f")]))]
13971 "* return output_387_binary_op (insn, operands);"
13972 [(set (attr "type")
13973 (cond [(match_operand:XF 3 "mult_operator")
13974 (const_string "fmul")
13975 (match_operand:XF 3 "div_operator")
13976 (const_string "fdiv")
13978 (const_string "fop")))
13979 (set_attr "mode" "<MODE>")])
13981 (define_insn "*fop_xf_5_i387"
13982 [(set (match_operand:XF 0 "register_operand" "=f,f")
13983 (match_operator:XF 3 "binary_fp_operator"
13984 [(match_operand:XF 1 "register_operand" "0,f")
13986 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13988 "* return output_387_binary_op (insn, operands);"
13989 [(set (attr "type")
13990 (cond [(match_operand:XF 3 "mult_operator")
13991 (const_string "fmul")
13992 (match_operand:XF 3 "div_operator")
13993 (const_string "fdiv")
13995 (const_string "fop")))
13996 (set_attr "mode" "<MODE>")])
13998 (define_insn "*fop_xf_6_i387"
13999 [(set (match_operand:XF 0 "register_operand" "=f,f")
14000 (match_operator:XF 3 "binary_fp_operator"
14002 (match_operand:MODEF 1 "register_operand" "0,f"))
14004 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14006 "* return output_387_binary_op (insn, operands);"
14007 [(set (attr "type")
14008 (cond [(match_operand:XF 3 "mult_operator")
14009 (const_string "fmul")
14010 (match_operand:XF 3 "div_operator")
14011 (const_string "fdiv")
14013 (const_string "fop")))
14014 (set_attr "mode" "<MODE>")])
14016 ;; FPU special functions.
14018 ;; This pattern implements a no-op XFmode truncation for
14019 ;; all fancy i386 XFmode math functions.
14021 (define_insn "truncxf<mode>2_i387_noop_unspec"
14022 [(set (match_operand:MODEF 0 "register_operand" "=f")
14023 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14024 UNSPEC_TRUNC_NOOP))]
14025 "TARGET_USE_FANCY_MATH_387"
14026 "* return output_387_reg_move (insn, operands);"
14027 [(set_attr "type" "fmov")
14028 (set_attr "mode" "<MODE>")])
14030 (define_insn "sqrtxf2"
14031 [(set (match_operand:XF 0 "register_operand" "=f")
14032 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14033 "TARGET_USE_FANCY_MATH_387"
14035 [(set_attr "type" "fpspc")
14036 (set_attr "mode" "XF")
14037 (set_attr "athlon_decode" "direct")
14038 (set_attr "amdfam10_decode" "direct")
14039 (set_attr "bdver1_decode" "direct")])
14041 (define_insn "sqrt_extend<mode>xf2_i387"
14042 [(set (match_operand:XF 0 "register_operand" "=f")
14045 (match_operand:MODEF 1 "register_operand" "0"))))]
14046 "TARGET_USE_FANCY_MATH_387"
14048 [(set_attr "type" "fpspc")
14049 (set_attr "mode" "XF")
14050 (set_attr "athlon_decode" "direct")
14051 (set_attr "amdfam10_decode" "direct")
14052 (set_attr "bdver1_decode" "direct")])
14054 (define_insn "*rsqrtsf2_sse"
14055 [(set (match_operand:SF 0 "register_operand" "=x")
14056 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14059 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14060 [(set_attr "type" "sse")
14061 (set_attr "atom_sse_attr" "rcp")
14062 (set_attr "btver2_sse_attr" "rcp")
14063 (set_attr "prefix" "maybe_vex")
14064 (set_attr "mode" "SF")])
14066 (define_expand "rsqrtsf2"
14067 [(set (match_operand:SF 0 "register_operand")
14068 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14072 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14076 (define_insn "*sqrt<mode>2_sse"
14077 [(set (match_operand:MODEF 0 "register_operand" "=x")
14079 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14080 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14081 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14082 [(set_attr "type" "sse")
14083 (set_attr "atom_sse_attr" "sqrt")
14084 (set_attr "btver2_sse_attr" "sqrt")
14085 (set_attr "prefix" "maybe_vex")
14086 (set_attr "mode" "<MODE>")
14087 (set_attr "athlon_decode" "*")
14088 (set_attr "amdfam10_decode" "*")
14089 (set_attr "bdver1_decode" "*")])
14091 (define_expand "sqrt<mode>2"
14092 [(set (match_operand:MODEF 0 "register_operand")
14094 (match_operand:MODEF 1 "nonimmediate_operand")))]
14095 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14096 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14098 if (<MODE>mode == SFmode
14100 && TARGET_RECIP_SQRT
14101 && !optimize_function_for_size_p (cfun)
14102 && flag_finite_math_only && !flag_trapping_math
14103 && flag_unsafe_math_optimizations)
14105 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14109 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14111 rtx op0 = gen_reg_rtx (XFmode);
14112 rtx op1 = force_reg (<MODE>mode, operands[1]);
14114 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14115 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14120 (define_insn "fpremxf4_i387"
14121 [(set (match_operand:XF 0 "register_operand" "=f")
14122 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14123 (match_operand:XF 3 "register_operand" "1")]
14125 (set (match_operand:XF 1 "register_operand" "=u")
14126 (unspec:XF [(match_dup 2) (match_dup 3)]
14128 (set (reg:CCFP FPSR_REG)
14129 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14131 "TARGET_USE_FANCY_MATH_387
14132 && flag_finite_math_only"
14134 [(set_attr "type" "fpspc")
14135 (set_attr "mode" "XF")])
14137 (define_expand "fmodxf3"
14138 [(use (match_operand:XF 0 "register_operand"))
14139 (use (match_operand:XF 1 "general_operand"))
14140 (use (match_operand:XF 2 "general_operand"))]
14141 "TARGET_USE_FANCY_MATH_387
14142 && flag_finite_math_only"
14144 rtx_code_label *label = gen_label_rtx ();
14146 rtx op1 = gen_reg_rtx (XFmode);
14147 rtx op2 = gen_reg_rtx (XFmode);
14149 emit_move_insn (op2, operands[2]);
14150 emit_move_insn (op1, operands[1]);
14152 emit_label (label);
14153 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14154 ix86_emit_fp_unordered_jump (label);
14155 LABEL_NUSES (label) = 1;
14157 emit_move_insn (operands[0], op1);
14161 (define_expand "fmod<mode>3"
14162 [(use (match_operand:MODEF 0 "register_operand"))
14163 (use (match_operand:MODEF 1 "general_operand"))
14164 (use (match_operand:MODEF 2 "general_operand"))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && flag_finite_math_only"
14168 rtx (*gen_truncxf) (rtx, rtx);
14170 rtx_code_label *label = gen_label_rtx ();
14172 rtx op1 = gen_reg_rtx (XFmode);
14173 rtx op2 = gen_reg_rtx (XFmode);
14175 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14178 emit_label (label);
14179 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14180 ix86_emit_fp_unordered_jump (label);
14181 LABEL_NUSES (label) = 1;
14183 /* Truncate the result properly for strict SSE math. */
14184 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14185 && !TARGET_MIX_SSE_I387)
14186 gen_truncxf = gen_truncxf<mode>2;
14188 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14190 emit_insn (gen_truncxf (operands[0], op1));
14194 (define_insn "fprem1xf4_i387"
14195 [(set (match_operand:XF 0 "register_operand" "=f")
14196 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14197 (match_operand:XF 3 "register_operand" "1")]
14199 (set (match_operand:XF 1 "register_operand" "=u")
14200 (unspec:XF [(match_dup 2) (match_dup 3)]
14202 (set (reg:CCFP FPSR_REG)
14203 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14205 "TARGET_USE_FANCY_MATH_387
14206 && flag_finite_math_only"
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "XF")])
14211 (define_expand "remainderxf3"
14212 [(use (match_operand:XF 0 "register_operand"))
14213 (use (match_operand:XF 1 "general_operand"))
14214 (use (match_operand:XF 2 "general_operand"))]
14215 "TARGET_USE_FANCY_MATH_387
14216 && flag_finite_math_only"
14218 rtx_code_label *label = gen_label_rtx ();
14220 rtx op1 = gen_reg_rtx (XFmode);
14221 rtx op2 = gen_reg_rtx (XFmode);
14223 emit_move_insn (op2, operands[2]);
14224 emit_move_insn (op1, operands[1]);
14226 emit_label (label);
14227 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14228 ix86_emit_fp_unordered_jump (label);
14229 LABEL_NUSES (label) = 1;
14231 emit_move_insn (operands[0], op1);
14235 (define_expand "remainder<mode>3"
14236 [(use (match_operand:MODEF 0 "register_operand"))
14237 (use (match_operand:MODEF 1 "general_operand"))
14238 (use (match_operand:MODEF 2 "general_operand"))]
14239 "TARGET_USE_FANCY_MATH_387
14240 && flag_finite_math_only"
14242 rtx (*gen_truncxf) (rtx, rtx);
14244 rtx_code_label *label = gen_label_rtx ();
14246 rtx op1 = gen_reg_rtx (XFmode);
14247 rtx op2 = gen_reg_rtx (XFmode);
14249 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14250 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14252 emit_label (label);
14254 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14255 ix86_emit_fp_unordered_jump (label);
14256 LABEL_NUSES (label) = 1;
14258 /* Truncate the result properly for strict SSE math. */
14259 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14260 && !TARGET_MIX_SSE_I387)
14261 gen_truncxf = gen_truncxf<mode>2;
14263 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14265 emit_insn (gen_truncxf (operands[0], op1));
14269 (define_int_iterator SINCOS
14273 (define_int_attr sincos
14274 [(UNSPEC_SIN "sin")
14275 (UNSPEC_COS "cos")])
14277 (define_insn "*<sincos>xf2_i387"
14278 [(set (match_operand:XF 0 "register_operand" "=f")
14279 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14281 "TARGET_USE_FANCY_MATH_387
14282 && flag_unsafe_math_optimizations"
14284 [(set_attr "type" "fpspc")
14285 (set_attr "mode" "XF")])
14287 (define_insn "*<sincos>_extend<mode>xf2_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(float_extend:XF
14290 (match_operand:MODEF 1 "register_operand" "0"))]
14292 "TARGET_USE_FANCY_MATH_387
14293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14294 || TARGET_MIX_SSE_I387)
14295 && flag_unsafe_math_optimizations"
14297 [(set_attr "type" "fpspc")
14298 (set_attr "mode" "XF")])
14300 ;; When sincos pattern is defined, sin and cos builtin functions will be
14301 ;; expanded to sincos pattern with one of its outputs left unused.
14302 ;; CSE pass will figure out if two sincos patterns can be combined,
14303 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14304 ;; depending on the unused output.
14306 (define_insn "sincosxf3"
14307 [(set (match_operand:XF 0 "register_operand" "=f")
14308 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14309 UNSPEC_SINCOS_COS))
14310 (set (match_operand:XF 1 "register_operand" "=u")
14311 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14312 "TARGET_USE_FANCY_MATH_387
14313 && flag_unsafe_math_optimizations"
14315 [(set_attr "type" "fpspc")
14316 (set_attr "mode" "XF")])
14319 [(set (match_operand:XF 0 "register_operand")
14320 (unspec:XF [(match_operand:XF 2 "register_operand")]
14321 UNSPEC_SINCOS_COS))
14322 (set (match_operand:XF 1 "register_operand")
14323 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14324 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14325 && can_create_pseudo_p ()"
14326 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14329 [(set (match_operand:XF 0 "register_operand")
14330 (unspec:XF [(match_operand:XF 2 "register_operand")]
14331 UNSPEC_SINCOS_COS))
14332 (set (match_operand:XF 1 "register_operand")
14333 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14334 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14335 && can_create_pseudo_p ()"
14336 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14338 (define_insn "sincos_extend<mode>xf3_i387"
14339 [(set (match_operand:XF 0 "register_operand" "=f")
14340 (unspec:XF [(float_extend:XF
14341 (match_operand:MODEF 2 "register_operand" "0"))]
14342 UNSPEC_SINCOS_COS))
14343 (set (match_operand:XF 1 "register_operand" "=u")
14344 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14347 || TARGET_MIX_SSE_I387)
14348 && flag_unsafe_math_optimizations"
14350 [(set_attr "type" "fpspc")
14351 (set_attr "mode" "XF")])
14354 [(set (match_operand:XF 0 "register_operand")
14355 (unspec:XF [(float_extend:XF
14356 (match_operand:MODEF 2 "register_operand"))]
14357 UNSPEC_SINCOS_COS))
14358 (set (match_operand:XF 1 "register_operand")
14359 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14360 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14361 && can_create_pseudo_p ()"
14362 [(set (match_dup 1)
14363 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14366 [(set (match_operand:XF 0 "register_operand")
14367 (unspec:XF [(float_extend:XF
14368 (match_operand:MODEF 2 "register_operand"))]
14369 UNSPEC_SINCOS_COS))
14370 (set (match_operand:XF 1 "register_operand")
14371 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14372 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14373 && can_create_pseudo_p ()"
14374 [(set (match_dup 0)
14375 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14377 (define_expand "sincos<mode>3"
14378 [(use (match_operand:MODEF 0 "register_operand"))
14379 (use (match_operand:MODEF 1 "register_operand"))
14380 (use (match_operand:MODEF 2 "register_operand"))]
14381 "TARGET_USE_FANCY_MATH_387
14382 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14383 || TARGET_MIX_SSE_I387)
14384 && flag_unsafe_math_optimizations"
14386 rtx op0 = gen_reg_rtx (XFmode);
14387 rtx op1 = gen_reg_rtx (XFmode);
14389 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14390 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14391 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14395 (define_insn "fptanxf4_i387"
14396 [(set (match_operand:XF 0 "register_operand" "=f")
14397 (match_operand:XF 3 "const_double_operand" "F"))
14398 (set (match_operand:XF 1 "register_operand" "=u")
14399 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations
14403 && standard_80387_constant_p (operands[3]) == 2"
14405 [(set_attr "type" "fpspc")
14406 (set_attr "mode" "XF")])
14408 (define_insn "fptan_extend<mode>xf4_i387"
14409 [(set (match_operand:MODEF 0 "register_operand" "=f")
14410 (match_operand:MODEF 3 "const_double_operand" "F"))
14411 (set (match_operand:XF 1 "register_operand" "=u")
14412 (unspec:XF [(float_extend:XF
14413 (match_operand:MODEF 2 "register_operand" "0"))]
14415 "TARGET_USE_FANCY_MATH_387
14416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14417 || TARGET_MIX_SSE_I387)
14418 && flag_unsafe_math_optimizations
14419 && standard_80387_constant_p (operands[3]) == 2"
14421 [(set_attr "type" "fpspc")
14422 (set_attr "mode" "XF")])
14424 (define_expand "tanxf2"
14425 [(use (match_operand:XF 0 "register_operand"))
14426 (use (match_operand:XF 1 "register_operand"))]
14427 "TARGET_USE_FANCY_MATH_387
14428 && flag_unsafe_math_optimizations"
14430 rtx one = gen_reg_rtx (XFmode);
14431 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14433 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14437 (define_expand "tan<mode>2"
14438 [(use (match_operand:MODEF 0 "register_operand"))
14439 (use (match_operand:MODEF 1 "register_operand"))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442 || TARGET_MIX_SSE_I387)
14443 && flag_unsafe_math_optimizations"
14445 rtx op0 = gen_reg_rtx (XFmode);
14447 rtx one = gen_reg_rtx (<MODE>mode);
14448 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14450 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14451 operands[1], op2));
14452 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14456 (define_insn "*fpatanxf3_i387"
14457 [(set (match_operand:XF 0 "register_operand" "=f")
14458 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14459 (match_operand:XF 2 "register_operand" "u")]
14461 (clobber (match_scratch:XF 3 "=2"))]
14462 "TARGET_USE_FANCY_MATH_387
14463 && flag_unsafe_math_optimizations"
14465 [(set_attr "type" "fpspc")
14466 (set_attr "mode" "XF")])
14468 (define_insn "fpatan_extend<mode>xf3_i387"
14469 [(set (match_operand:XF 0 "register_operand" "=f")
14470 (unspec:XF [(float_extend:XF
14471 (match_operand:MODEF 1 "register_operand" "0"))
14473 (match_operand:MODEF 2 "register_operand" "u"))]
14475 (clobber (match_scratch:XF 3 "=2"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478 || TARGET_MIX_SSE_I387)
14479 && flag_unsafe_math_optimizations"
14481 [(set_attr "type" "fpspc")
14482 (set_attr "mode" "XF")])
14484 (define_expand "atan2xf3"
14485 [(parallel [(set (match_operand:XF 0 "register_operand")
14486 (unspec:XF [(match_operand:XF 2 "register_operand")
14487 (match_operand:XF 1 "register_operand")]
14489 (clobber (match_scratch:XF 3))])]
14490 "TARGET_USE_FANCY_MATH_387
14491 && flag_unsafe_math_optimizations")
14493 (define_expand "atan2<mode>3"
14494 [(use (match_operand:MODEF 0 "register_operand"))
14495 (use (match_operand:MODEF 1 "register_operand"))
14496 (use (match_operand:MODEF 2 "register_operand"))]
14497 "TARGET_USE_FANCY_MATH_387
14498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14499 || TARGET_MIX_SSE_I387)
14500 && flag_unsafe_math_optimizations"
14502 rtx op0 = gen_reg_rtx (XFmode);
14504 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14505 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14509 (define_expand "atanxf2"
14510 [(parallel [(set (match_operand:XF 0 "register_operand")
14511 (unspec:XF [(match_dup 2)
14512 (match_operand:XF 1 "register_operand")]
14514 (clobber (match_scratch:XF 3))])]
14515 "TARGET_USE_FANCY_MATH_387
14516 && flag_unsafe_math_optimizations"
14518 operands[2] = gen_reg_rtx (XFmode);
14519 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14522 (define_expand "atan<mode>2"
14523 [(use (match_operand:MODEF 0 "register_operand"))
14524 (use (match_operand:MODEF 1 "register_operand"))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527 || TARGET_MIX_SSE_I387)
14528 && flag_unsafe_math_optimizations"
14530 rtx op0 = gen_reg_rtx (XFmode);
14532 rtx op2 = gen_reg_rtx (<MODE>mode);
14533 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14535 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14536 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14540 (define_expand "asinxf2"
14541 [(set (match_dup 2)
14542 (mult:XF (match_operand:XF 1 "register_operand")
14544 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14545 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14546 (parallel [(set (match_operand:XF 0 "register_operand")
14547 (unspec:XF [(match_dup 5) (match_dup 1)]
14549 (clobber (match_scratch:XF 6))])]
14550 "TARGET_USE_FANCY_MATH_387
14551 && flag_unsafe_math_optimizations"
14555 if (optimize_insn_for_size_p ())
14558 for (i = 2; i < 6; i++)
14559 operands[i] = gen_reg_rtx (XFmode);
14561 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14564 (define_expand "asin<mode>2"
14565 [(use (match_operand:MODEF 0 "register_operand"))
14566 (use (match_operand:MODEF 1 "general_operand"))]
14567 "TARGET_USE_FANCY_MATH_387
14568 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14569 || TARGET_MIX_SSE_I387)
14570 && flag_unsafe_math_optimizations"
14572 rtx op0 = gen_reg_rtx (XFmode);
14573 rtx op1 = gen_reg_rtx (XFmode);
14575 if (optimize_insn_for_size_p ())
14578 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14579 emit_insn (gen_asinxf2 (op0, op1));
14580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14584 (define_expand "acosxf2"
14585 [(set (match_dup 2)
14586 (mult:XF (match_operand:XF 1 "register_operand")
14588 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14589 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14590 (parallel [(set (match_operand:XF 0 "register_operand")
14591 (unspec:XF [(match_dup 1) (match_dup 5)]
14593 (clobber (match_scratch:XF 6))])]
14594 "TARGET_USE_FANCY_MATH_387
14595 && flag_unsafe_math_optimizations"
14599 if (optimize_insn_for_size_p ())
14602 for (i = 2; i < 6; i++)
14603 operands[i] = gen_reg_rtx (XFmode);
14605 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14608 (define_expand "acos<mode>2"
14609 [(use (match_operand:MODEF 0 "register_operand"))
14610 (use (match_operand:MODEF 1 "general_operand"))]
14611 "TARGET_USE_FANCY_MATH_387
14612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14613 || TARGET_MIX_SSE_I387)
14614 && flag_unsafe_math_optimizations"
14616 rtx op0 = gen_reg_rtx (XFmode);
14617 rtx op1 = gen_reg_rtx (XFmode);
14619 if (optimize_insn_for_size_p ())
14622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14623 emit_insn (gen_acosxf2 (op0, op1));
14624 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14628 (define_insn "fyl2xxf3_i387"
14629 [(set (match_operand:XF 0 "register_operand" "=f")
14630 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14631 (match_operand:XF 2 "register_operand" "u")]
14633 (clobber (match_scratch:XF 3 "=2"))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && flag_unsafe_math_optimizations"
14637 [(set_attr "type" "fpspc")
14638 (set_attr "mode" "XF")])
14640 (define_insn "fyl2x_extend<mode>xf3_i387"
14641 [(set (match_operand:XF 0 "register_operand" "=f")
14642 (unspec:XF [(float_extend:XF
14643 (match_operand:MODEF 1 "register_operand" "0"))
14644 (match_operand:XF 2 "register_operand" "u")]
14646 (clobber (match_scratch:XF 3 "=2"))]
14647 "TARGET_USE_FANCY_MATH_387
14648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649 || TARGET_MIX_SSE_I387)
14650 && flag_unsafe_math_optimizations"
14652 [(set_attr "type" "fpspc")
14653 (set_attr "mode" "XF")])
14655 (define_expand "logxf2"
14656 [(parallel [(set (match_operand:XF 0 "register_operand")
14657 (unspec:XF [(match_operand:XF 1 "register_operand")
14658 (match_dup 2)] UNSPEC_FYL2X))
14659 (clobber (match_scratch:XF 3))])]
14660 "TARGET_USE_FANCY_MATH_387
14661 && flag_unsafe_math_optimizations"
14663 operands[2] = gen_reg_rtx (XFmode);
14664 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14667 (define_expand "log<mode>2"
14668 [(use (match_operand:MODEF 0 "register_operand"))
14669 (use (match_operand:MODEF 1 "register_operand"))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14672 || TARGET_MIX_SSE_I387)
14673 && flag_unsafe_math_optimizations"
14675 rtx op0 = gen_reg_rtx (XFmode);
14677 rtx op2 = gen_reg_rtx (XFmode);
14678 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14680 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14685 (define_expand "log10xf2"
14686 [(parallel [(set (match_operand:XF 0 "register_operand")
14687 (unspec:XF [(match_operand:XF 1 "register_operand")
14688 (match_dup 2)] UNSPEC_FYL2X))
14689 (clobber (match_scratch:XF 3))])]
14690 "TARGET_USE_FANCY_MATH_387
14691 && flag_unsafe_math_optimizations"
14693 operands[2] = gen_reg_rtx (XFmode);
14694 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14697 (define_expand "log10<mode>2"
14698 [(use (match_operand:MODEF 0 "register_operand"))
14699 (use (match_operand:MODEF 1 "register_operand"))]
14700 "TARGET_USE_FANCY_MATH_387
14701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14702 || TARGET_MIX_SSE_I387)
14703 && flag_unsafe_math_optimizations"
14705 rtx op0 = gen_reg_rtx (XFmode);
14707 rtx op2 = gen_reg_rtx (XFmode);
14708 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14710 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14711 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14715 (define_expand "log2xf2"
14716 [(parallel [(set (match_operand:XF 0 "register_operand")
14717 (unspec:XF [(match_operand:XF 1 "register_operand")
14718 (match_dup 2)] UNSPEC_FYL2X))
14719 (clobber (match_scratch:XF 3))])]
14720 "TARGET_USE_FANCY_MATH_387
14721 && flag_unsafe_math_optimizations"
14723 operands[2] = gen_reg_rtx (XFmode);
14724 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14727 (define_expand "log2<mode>2"
14728 [(use (match_operand:MODEF 0 "register_operand"))
14729 (use (match_operand:MODEF 1 "register_operand"))]
14730 "TARGET_USE_FANCY_MATH_387
14731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14732 || TARGET_MIX_SSE_I387)
14733 && flag_unsafe_math_optimizations"
14735 rtx op0 = gen_reg_rtx (XFmode);
14737 rtx op2 = gen_reg_rtx (XFmode);
14738 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14740 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14745 (define_insn "fyl2xp1xf3_i387"
14746 [(set (match_operand:XF 0 "register_operand" "=f")
14747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14748 (match_operand:XF 2 "register_operand" "u")]
14750 (clobber (match_scratch:XF 3 "=2"))]
14751 "TARGET_USE_FANCY_MATH_387
14752 && flag_unsafe_math_optimizations"
14754 [(set_attr "type" "fpspc")
14755 (set_attr "mode" "XF")])
14757 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14758 [(set (match_operand:XF 0 "register_operand" "=f")
14759 (unspec:XF [(float_extend:XF
14760 (match_operand:MODEF 1 "register_operand" "0"))
14761 (match_operand:XF 2 "register_operand" "u")]
14763 (clobber (match_scratch:XF 3 "=2"))]
14764 "TARGET_USE_FANCY_MATH_387
14765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14766 || TARGET_MIX_SSE_I387)
14767 && flag_unsafe_math_optimizations"
14769 [(set_attr "type" "fpspc")
14770 (set_attr "mode" "XF")])
14772 (define_expand "log1pxf2"
14773 [(use (match_operand:XF 0 "register_operand"))
14774 (use (match_operand:XF 1 "register_operand"))]
14775 "TARGET_USE_FANCY_MATH_387
14776 && flag_unsafe_math_optimizations"
14778 if (optimize_insn_for_size_p ())
14781 ix86_emit_i387_log1p (operands[0], operands[1]);
14785 (define_expand "log1p<mode>2"
14786 [(use (match_operand:MODEF 0 "register_operand"))
14787 (use (match_operand:MODEF 1 "register_operand"))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14790 || TARGET_MIX_SSE_I387)
14791 && flag_unsafe_math_optimizations"
14795 if (optimize_insn_for_size_p ())
14798 op0 = gen_reg_rtx (XFmode);
14800 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14802 ix86_emit_i387_log1p (op0, operands[1]);
14803 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14807 (define_insn "fxtractxf3_i387"
14808 [(set (match_operand:XF 0 "register_operand" "=f")
14809 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14810 UNSPEC_XTRACT_FRACT))
14811 (set (match_operand:XF 1 "register_operand" "=u")
14812 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14813 "TARGET_USE_FANCY_MATH_387
14814 && flag_unsafe_math_optimizations"
14816 [(set_attr "type" "fpspc")
14817 (set_attr "mode" "XF")])
14819 (define_insn "fxtract_extend<mode>xf3_i387"
14820 [(set (match_operand:XF 0 "register_operand" "=f")
14821 (unspec:XF [(float_extend:XF
14822 (match_operand:MODEF 2 "register_operand" "0"))]
14823 UNSPEC_XTRACT_FRACT))
14824 (set (match_operand:XF 1 "register_operand" "=u")
14825 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14826 "TARGET_USE_FANCY_MATH_387
14827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14828 || TARGET_MIX_SSE_I387)
14829 && flag_unsafe_math_optimizations"
14831 [(set_attr "type" "fpspc")
14832 (set_attr "mode" "XF")])
14834 (define_expand "logbxf2"
14835 [(parallel [(set (match_dup 2)
14836 (unspec:XF [(match_operand:XF 1 "register_operand")]
14837 UNSPEC_XTRACT_FRACT))
14838 (set (match_operand:XF 0 "register_operand")
14839 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14840 "TARGET_USE_FANCY_MATH_387
14841 && flag_unsafe_math_optimizations"
14842 "operands[2] = gen_reg_rtx (XFmode);")
14844 (define_expand "logb<mode>2"
14845 [(use (match_operand:MODEF 0 "register_operand"))
14846 (use (match_operand:MODEF 1 "register_operand"))]
14847 "TARGET_USE_FANCY_MATH_387
14848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14849 || TARGET_MIX_SSE_I387)
14850 && flag_unsafe_math_optimizations"
14852 rtx op0 = gen_reg_rtx (XFmode);
14853 rtx op1 = gen_reg_rtx (XFmode);
14855 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14860 (define_expand "ilogbxf2"
14861 [(use (match_operand:SI 0 "register_operand"))
14862 (use (match_operand:XF 1 "register_operand"))]
14863 "TARGET_USE_FANCY_MATH_387
14864 && flag_unsafe_math_optimizations"
14868 if (optimize_insn_for_size_p ())
14871 op0 = gen_reg_rtx (XFmode);
14872 op1 = gen_reg_rtx (XFmode);
14874 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14875 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14879 (define_expand "ilogb<mode>2"
14880 [(use (match_operand:SI 0 "register_operand"))
14881 (use (match_operand:MODEF 1 "register_operand"))]
14882 "TARGET_USE_FANCY_MATH_387
14883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14884 || TARGET_MIX_SSE_I387)
14885 && flag_unsafe_math_optimizations"
14889 if (optimize_insn_for_size_p ())
14892 op0 = gen_reg_rtx (XFmode);
14893 op1 = gen_reg_rtx (XFmode);
14895 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14896 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14900 (define_insn "*f2xm1xf2_i387"
14901 [(set (match_operand:XF 0 "register_operand" "=f")
14902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14904 "TARGET_USE_FANCY_MATH_387
14905 && flag_unsafe_math_optimizations"
14907 [(set_attr "type" "fpspc")
14908 (set_attr "mode" "XF")])
14910 (define_insn "fscalexf4_i387"
14911 [(set (match_operand:XF 0 "register_operand" "=f")
14912 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14913 (match_operand:XF 3 "register_operand" "1")]
14914 UNSPEC_FSCALE_FRACT))
14915 (set (match_operand:XF 1 "register_operand" "=u")
14916 (unspec:XF [(match_dup 2) (match_dup 3)]
14917 UNSPEC_FSCALE_EXP))]
14918 "TARGET_USE_FANCY_MATH_387
14919 && flag_unsafe_math_optimizations"
14921 [(set_attr "type" "fpspc")
14922 (set_attr "mode" "XF")])
14924 (define_expand "expNcorexf3"
14925 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14926 (match_operand:XF 2 "register_operand")))
14927 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14928 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14929 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14930 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14931 (parallel [(set (match_operand:XF 0 "register_operand")
14932 (unspec:XF [(match_dup 8) (match_dup 4)]
14933 UNSPEC_FSCALE_FRACT))
14935 (unspec:XF [(match_dup 8) (match_dup 4)]
14936 UNSPEC_FSCALE_EXP))])]
14937 "TARGET_USE_FANCY_MATH_387
14938 && flag_unsafe_math_optimizations"
14942 if (optimize_insn_for_size_p ())
14945 for (i = 3; i < 10; i++)
14946 operands[i] = gen_reg_rtx (XFmode);
14948 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14951 (define_expand "expxf2"
14952 [(use (match_operand:XF 0 "register_operand"))
14953 (use (match_operand:XF 1 "register_operand"))]
14954 "TARGET_USE_FANCY_MATH_387
14955 && flag_unsafe_math_optimizations"
14959 if (optimize_insn_for_size_p ())
14962 op2 = gen_reg_rtx (XFmode);
14963 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14965 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14969 (define_expand "exp<mode>2"
14970 [(use (match_operand:MODEF 0 "register_operand"))
14971 (use (match_operand:MODEF 1 "general_operand"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14974 || TARGET_MIX_SSE_I387)
14975 && flag_unsafe_math_optimizations"
14979 if (optimize_insn_for_size_p ())
14982 op0 = gen_reg_rtx (XFmode);
14983 op1 = gen_reg_rtx (XFmode);
14985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14986 emit_insn (gen_expxf2 (op0, op1));
14987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14991 (define_expand "exp10xf2"
14992 [(use (match_operand:XF 0 "register_operand"))
14993 (use (match_operand:XF 1 "register_operand"))]
14994 "TARGET_USE_FANCY_MATH_387
14995 && flag_unsafe_math_optimizations"
14999 if (optimize_insn_for_size_p ())
15002 op2 = gen_reg_rtx (XFmode);
15003 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15005 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15009 (define_expand "exp10<mode>2"
15010 [(use (match_operand:MODEF 0 "register_operand"))
15011 (use (match_operand:MODEF 1 "general_operand"))]
15012 "TARGET_USE_FANCY_MATH_387
15013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15014 || TARGET_MIX_SSE_I387)
15015 && flag_unsafe_math_optimizations"
15019 if (optimize_insn_for_size_p ())
15022 op0 = gen_reg_rtx (XFmode);
15023 op1 = gen_reg_rtx (XFmode);
15025 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15026 emit_insn (gen_exp10xf2 (op0, op1));
15027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15031 (define_expand "exp2xf2"
15032 [(use (match_operand:XF 0 "register_operand"))
15033 (use (match_operand:XF 1 "register_operand"))]
15034 "TARGET_USE_FANCY_MATH_387
15035 && flag_unsafe_math_optimizations"
15039 if (optimize_insn_for_size_p ())
15042 op2 = gen_reg_rtx (XFmode);
15043 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15045 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15049 (define_expand "exp2<mode>2"
15050 [(use (match_operand:MODEF 0 "register_operand"))
15051 (use (match_operand:MODEF 1 "general_operand"))]
15052 "TARGET_USE_FANCY_MATH_387
15053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15054 || TARGET_MIX_SSE_I387)
15055 && flag_unsafe_math_optimizations"
15059 if (optimize_insn_for_size_p ())
15062 op0 = gen_reg_rtx (XFmode);
15063 op1 = gen_reg_rtx (XFmode);
15065 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15066 emit_insn (gen_exp2xf2 (op0, op1));
15067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15071 (define_expand "expm1xf2"
15072 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15074 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15075 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15076 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15077 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15078 (parallel [(set (match_dup 7)
15079 (unspec:XF [(match_dup 6) (match_dup 4)]
15080 UNSPEC_FSCALE_FRACT))
15082 (unspec:XF [(match_dup 6) (match_dup 4)]
15083 UNSPEC_FSCALE_EXP))])
15084 (parallel [(set (match_dup 10)
15085 (unspec:XF [(match_dup 9) (match_dup 8)]
15086 UNSPEC_FSCALE_FRACT))
15087 (set (match_dup 11)
15088 (unspec:XF [(match_dup 9) (match_dup 8)]
15089 UNSPEC_FSCALE_EXP))])
15090 (set (match_dup 12) (minus:XF (match_dup 10)
15091 (float_extend:XF (match_dup 13))))
15092 (set (match_operand:XF 0 "register_operand")
15093 (plus:XF (match_dup 12) (match_dup 7)))]
15094 "TARGET_USE_FANCY_MATH_387
15095 && flag_unsafe_math_optimizations"
15099 if (optimize_insn_for_size_p ())
15102 for (i = 2; i < 13; i++)
15103 operands[i] = gen_reg_rtx (XFmode);
15106 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15108 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15111 (define_expand "expm1<mode>2"
15112 [(use (match_operand:MODEF 0 "register_operand"))
15113 (use (match_operand:MODEF 1 "general_operand"))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15116 || TARGET_MIX_SSE_I387)
15117 && flag_unsafe_math_optimizations"
15121 if (optimize_insn_for_size_p ())
15124 op0 = gen_reg_rtx (XFmode);
15125 op1 = gen_reg_rtx (XFmode);
15127 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15128 emit_insn (gen_expm1xf2 (op0, op1));
15129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15133 (define_expand "ldexpxf3"
15134 [(match_operand:XF 0 "register_operand")
15135 (match_operand:XF 1 "register_operand")
15136 (match_operand:SI 2 "register_operand")]
15137 "TARGET_USE_FANCY_MATH_387
15138 && flag_unsafe_math_optimizations"
15141 if (optimize_insn_for_size_p ())
15144 tmp1 = gen_reg_rtx (XFmode);
15145 tmp2 = gen_reg_rtx (XFmode);
15147 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15148 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15149 operands[1], tmp1));
15153 (define_expand "ldexp<mode>3"
15154 [(use (match_operand:MODEF 0 "register_operand"))
15155 (use (match_operand:MODEF 1 "general_operand"))
15156 (use (match_operand:SI 2 "register_operand"))]
15157 "TARGET_USE_FANCY_MATH_387
15158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15159 || TARGET_MIX_SSE_I387)
15160 && flag_unsafe_math_optimizations"
15164 if (optimize_insn_for_size_p ())
15167 op0 = gen_reg_rtx (XFmode);
15168 op1 = gen_reg_rtx (XFmode);
15170 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15171 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15172 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15176 (define_expand "scalbxf3"
15177 [(parallel [(set (match_operand:XF 0 " register_operand")
15178 (unspec:XF [(match_operand:XF 1 "register_operand")
15179 (match_operand:XF 2 "register_operand")]
15180 UNSPEC_FSCALE_FRACT))
15182 (unspec:XF [(match_dup 1) (match_dup 2)]
15183 UNSPEC_FSCALE_EXP))])]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_unsafe_math_optimizations"
15187 if (optimize_insn_for_size_p ())
15190 operands[3] = gen_reg_rtx (XFmode);
15193 (define_expand "scalb<mode>3"
15194 [(use (match_operand:MODEF 0 "register_operand"))
15195 (use (match_operand:MODEF 1 "general_operand"))
15196 (use (match_operand:MODEF 2 "general_operand"))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199 || TARGET_MIX_SSE_I387)
15200 && flag_unsafe_math_optimizations"
15204 if (optimize_insn_for_size_p ())
15207 op0 = gen_reg_rtx (XFmode);
15208 op1 = gen_reg_rtx (XFmode);
15209 op2 = gen_reg_rtx (XFmode);
15211 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15212 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15213 emit_insn (gen_scalbxf3 (op0, op1, op2));
15214 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15218 (define_expand "significandxf2"
15219 [(parallel [(set (match_operand:XF 0 "register_operand")
15220 (unspec:XF [(match_operand:XF 1 "register_operand")]
15221 UNSPEC_XTRACT_FRACT))
15223 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15224 "TARGET_USE_FANCY_MATH_387
15225 && flag_unsafe_math_optimizations"
15226 "operands[2] = gen_reg_rtx (XFmode);")
15228 (define_expand "significand<mode>2"
15229 [(use (match_operand:MODEF 0 "register_operand"))
15230 (use (match_operand:MODEF 1 "register_operand"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15233 || TARGET_MIX_SSE_I387)
15234 && flag_unsafe_math_optimizations"
15236 rtx op0 = gen_reg_rtx (XFmode);
15237 rtx op1 = gen_reg_rtx (XFmode);
15239 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15245 (define_insn "sse4_1_round<mode>2"
15246 [(set (match_operand:MODEF 0 "register_operand" "=x")
15247 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15248 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15251 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15252 [(set_attr "type" "ssecvt")
15253 (set_attr "prefix_extra" "1")
15254 (set_attr "prefix" "maybe_vex")
15255 (set_attr "mode" "<MODE>")])
15257 (define_insn "rintxf2"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15261 "TARGET_USE_FANCY_MATH_387
15262 && flag_unsafe_math_optimizations"
15264 [(set_attr "type" "fpspc")
15265 (set_attr "mode" "XF")])
15267 (define_expand "rint<mode>2"
15268 [(use (match_operand:MODEF 0 "register_operand"))
15269 (use (match_operand:MODEF 1 "register_operand"))]
15270 "(TARGET_USE_FANCY_MATH_387
15271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15272 || TARGET_MIX_SSE_I387)
15273 && flag_unsafe_math_optimizations)
15274 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15275 && !flag_trapping_math)"
15277 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15278 && !flag_trapping_math)
15281 emit_insn (gen_sse4_1_round<mode>2
15282 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15283 else if (optimize_insn_for_size_p ())
15286 ix86_expand_rint (operands[0], operands[1]);
15290 rtx op0 = gen_reg_rtx (XFmode);
15291 rtx op1 = gen_reg_rtx (XFmode);
15293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15294 emit_insn (gen_rintxf2 (op0, op1));
15296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15301 (define_expand "round<mode>2"
15302 [(match_operand:X87MODEF 0 "register_operand")
15303 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15304 "(TARGET_USE_FANCY_MATH_387
15305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15306 || TARGET_MIX_SSE_I387)
15307 && flag_unsafe_math_optimizations)
15308 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15309 && !flag_trapping_math && !flag_rounding_math)"
15311 if (optimize_insn_for_size_p ())
15314 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15315 && !flag_trapping_math && !flag_rounding_math)
15319 operands[1] = force_reg (<MODE>mode, operands[1]);
15320 ix86_expand_round_sse4 (operands[0], operands[1]);
15322 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15323 ix86_expand_round (operands[0], operands[1]);
15325 ix86_expand_rounddf_32 (operands[0], operands[1]);
15329 operands[1] = force_reg (<MODE>mode, operands[1]);
15330 ix86_emit_i387_round (operands[0], operands[1]);
15335 (define_insn_and_split "*fistdi2_1"
15336 [(set (match_operand:DI 0 "nonimmediate_operand")
15337 (unspec:DI [(match_operand:XF 1 "register_operand")]
15339 "TARGET_USE_FANCY_MATH_387
15340 && can_create_pseudo_p ()"
15345 if (memory_operand (operands[0], VOIDmode))
15346 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15349 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15350 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15355 [(set_attr "type" "fpspc")
15356 (set_attr "mode" "DI")])
15358 (define_insn "fistdi2"
15359 [(set (match_operand:DI 0 "memory_operand" "=m")
15360 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15362 (clobber (match_scratch:XF 2 "=&1f"))]
15363 "TARGET_USE_FANCY_MATH_387"
15364 "* return output_fix_trunc (insn, operands, false);"
15365 [(set_attr "type" "fpspc")
15366 (set_attr "mode" "DI")])
15368 (define_insn "fistdi2_with_temp"
15369 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15370 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15372 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15373 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15374 "TARGET_USE_FANCY_MATH_387"
15376 [(set_attr "type" "fpspc")
15377 (set_attr "mode" "DI")])
15380 [(set (match_operand:DI 0 "register_operand")
15381 (unspec:DI [(match_operand:XF 1 "register_operand")]
15383 (clobber (match_operand:DI 2 "memory_operand"))
15384 (clobber (match_scratch 3))]
15386 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15387 (clobber (match_dup 3))])
15388 (set (match_dup 0) (match_dup 2))])
15391 [(set (match_operand:DI 0 "memory_operand")
15392 (unspec:DI [(match_operand:XF 1 "register_operand")]
15394 (clobber (match_operand:DI 2 "memory_operand"))
15395 (clobber (match_scratch 3))]
15397 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15398 (clobber (match_dup 3))])])
15400 (define_insn_and_split "*fist<mode>2_1"
15401 [(set (match_operand:SWI24 0 "register_operand")
15402 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15404 "TARGET_USE_FANCY_MATH_387
15405 && can_create_pseudo_p ()"
15410 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15411 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15415 [(set_attr "type" "fpspc")
15416 (set_attr "mode" "<MODE>")])
15418 (define_insn "fist<mode>2"
15419 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15420 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15422 "TARGET_USE_FANCY_MATH_387"
15423 "* return output_fix_trunc (insn, operands, false);"
15424 [(set_attr "type" "fpspc")
15425 (set_attr "mode" "<MODE>")])
15427 (define_insn "fist<mode>2_with_temp"
15428 [(set (match_operand:SWI24 0 "register_operand" "=r")
15429 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15431 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15432 "TARGET_USE_FANCY_MATH_387"
15434 [(set_attr "type" "fpspc")
15435 (set_attr "mode" "<MODE>")])
15438 [(set (match_operand:SWI24 0 "register_operand")
15439 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15441 (clobber (match_operand:SWI24 2 "memory_operand"))]
15443 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15444 (set (match_dup 0) (match_dup 2))])
15447 [(set (match_operand:SWI24 0 "memory_operand")
15448 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15450 (clobber (match_operand:SWI24 2 "memory_operand"))]
15452 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15454 (define_expand "lrintxf<mode>2"
15455 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15456 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15458 "TARGET_USE_FANCY_MATH_387")
15460 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15461 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15462 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15463 UNSPEC_FIX_NOTRUNC))]
15464 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15466 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15467 [(match_operand:SWI248x 0 "nonimmediate_operand")
15468 (match_operand:X87MODEF 1 "register_operand")]
15469 "(TARGET_USE_FANCY_MATH_387
15470 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15471 || TARGET_MIX_SSE_I387)
15472 && flag_unsafe_math_optimizations)
15473 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15474 && <SWI248x:MODE>mode != HImode
15475 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15476 && !flag_trapping_math && !flag_rounding_math)"
15478 if (optimize_insn_for_size_p ())
15481 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15482 && <SWI248x:MODE>mode != HImode
15483 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15484 && !flag_trapping_math && !flag_rounding_math)
15485 ix86_expand_lround (operands[0], operands[1]);
15487 ix86_emit_i387_round (operands[0], operands[1]);
15491 (define_int_iterator FRNDINT_ROUNDING
15492 [UNSPEC_FRNDINT_FLOOR
15493 UNSPEC_FRNDINT_CEIL
15494 UNSPEC_FRNDINT_TRUNC])
15496 (define_int_iterator FIST_ROUNDING
15500 ;; Base name for define_insn
15501 (define_int_attr rounding_insn
15502 [(UNSPEC_FRNDINT_FLOOR "floor")
15503 (UNSPEC_FRNDINT_CEIL "ceil")
15504 (UNSPEC_FRNDINT_TRUNC "btrunc")
15505 (UNSPEC_FIST_FLOOR "floor")
15506 (UNSPEC_FIST_CEIL "ceil")])
15508 (define_int_attr rounding
15509 [(UNSPEC_FRNDINT_FLOOR "floor")
15510 (UNSPEC_FRNDINT_CEIL "ceil")
15511 (UNSPEC_FRNDINT_TRUNC "trunc")
15512 (UNSPEC_FIST_FLOOR "floor")
15513 (UNSPEC_FIST_CEIL "ceil")])
15515 (define_int_attr ROUNDING
15516 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15517 (UNSPEC_FRNDINT_CEIL "CEIL")
15518 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15519 (UNSPEC_FIST_FLOOR "FLOOR")
15520 (UNSPEC_FIST_CEIL "CEIL")])
15522 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15523 (define_insn_and_split "frndintxf2_<rounding>"
15524 [(set (match_operand:XF 0 "register_operand")
15525 (unspec:XF [(match_operand:XF 1 "register_operand")]
15527 (clobber (reg:CC FLAGS_REG))]
15528 "TARGET_USE_FANCY_MATH_387
15529 && flag_unsafe_math_optimizations
15530 && can_create_pseudo_p ()"
15535 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15537 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15538 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15540 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15541 operands[2], operands[3]));
15544 [(set_attr "type" "frndint")
15545 (set_attr "i387_cw" "<rounding>")
15546 (set_attr "mode" "XF")])
15548 (define_insn "frndintxf2_<rounding>_i387"
15549 [(set (match_operand:XF 0 "register_operand" "=f")
15550 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15552 (use (match_operand:HI 2 "memory_operand" "m"))
15553 (use (match_operand:HI 3 "memory_operand" "m"))]
15554 "TARGET_USE_FANCY_MATH_387
15555 && flag_unsafe_math_optimizations"
15556 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15557 [(set_attr "type" "frndint")
15558 (set_attr "i387_cw" "<rounding>")
15559 (set_attr "mode" "XF")])
15561 (define_expand "<rounding_insn>xf2"
15562 [(parallel [(set (match_operand:XF 0 "register_operand")
15563 (unspec:XF [(match_operand:XF 1 "register_operand")]
15565 (clobber (reg:CC FLAGS_REG))])]
15566 "TARGET_USE_FANCY_MATH_387
15567 && flag_unsafe_math_optimizations
15568 && !optimize_insn_for_size_p ()")
15570 (define_expand "<rounding_insn><mode>2"
15571 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15572 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15574 (clobber (reg:CC FLAGS_REG))])]
15575 "(TARGET_USE_FANCY_MATH_387
15576 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15577 || TARGET_MIX_SSE_I387)
15578 && flag_unsafe_math_optimizations)
15579 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15580 && !flag_trapping_math)"
15582 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15583 && !flag_trapping_math)
15586 emit_insn (gen_sse4_1_round<mode>2
15587 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15588 else if (optimize_insn_for_size_p ())
15590 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15592 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15593 ix86_expand_floorceil (operands[0], operands[1], true);
15594 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15595 ix86_expand_floorceil (operands[0], operands[1], false);
15596 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15597 ix86_expand_trunc (operands[0], operands[1]);
15599 gcc_unreachable ();
15603 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15604 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15605 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15606 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15607 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15608 ix86_expand_truncdf_32 (operands[0], operands[1]);
15610 gcc_unreachable ();
15617 if (optimize_insn_for_size_p ())
15620 op0 = gen_reg_rtx (XFmode);
15621 op1 = gen_reg_rtx (XFmode);
15622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15623 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15630 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15631 (define_insn_and_split "frndintxf2_mask_pm"
15632 [(set (match_operand:XF 0 "register_operand")
15633 (unspec:XF [(match_operand:XF 1 "register_operand")]
15634 UNSPEC_FRNDINT_MASK_PM))
15635 (clobber (reg:CC FLAGS_REG))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && flag_unsafe_math_optimizations
15638 && can_create_pseudo_p ()"
15643 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15645 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15646 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15648 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15649 operands[2], operands[3]));
15652 [(set_attr "type" "frndint")
15653 (set_attr "i387_cw" "mask_pm")
15654 (set_attr "mode" "XF")])
15656 (define_insn "frndintxf2_mask_pm_i387"
15657 [(set (match_operand:XF 0 "register_operand" "=f")
15658 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15659 UNSPEC_FRNDINT_MASK_PM))
15660 (use (match_operand:HI 2 "memory_operand" "m"))
15661 (use (match_operand:HI 3 "memory_operand" "m"))]
15662 "TARGET_USE_FANCY_MATH_387
15663 && flag_unsafe_math_optimizations"
15664 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15665 [(set_attr "type" "frndint")
15666 (set_attr "i387_cw" "mask_pm")
15667 (set_attr "mode" "XF")])
15669 (define_expand "nearbyintxf2"
15670 [(parallel [(set (match_operand:XF 0 "register_operand")
15671 (unspec:XF [(match_operand:XF 1 "register_operand")]
15672 UNSPEC_FRNDINT_MASK_PM))
15673 (clobber (reg:CC FLAGS_REG))])]
15674 "TARGET_USE_FANCY_MATH_387
15675 && flag_unsafe_math_optimizations")
15677 (define_expand "nearbyint<mode>2"
15678 [(use (match_operand:MODEF 0 "register_operand"))
15679 (use (match_operand:MODEF 1 "register_operand"))]
15680 "TARGET_USE_FANCY_MATH_387
15681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15682 || TARGET_MIX_SSE_I387)
15683 && flag_unsafe_math_optimizations"
15685 rtx op0 = gen_reg_rtx (XFmode);
15686 rtx op1 = gen_reg_rtx (XFmode);
15688 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15689 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15691 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15695 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15696 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15697 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15698 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15700 (clobber (reg:CC FLAGS_REG))]
15701 "TARGET_USE_FANCY_MATH_387
15702 && flag_unsafe_math_optimizations
15703 && can_create_pseudo_p ()"
15708 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15710 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15711 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15712 if (memory_operand (operands[0], VOIDmode))
15713 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15714 operands[2], operands[3]));
15717 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15718 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15719 (operands[0], operands[1], operands[2],
15720 operands[3], operands[4]));
15724 [(set_attr "type" "fistp")
15725 (set_attr "i387_cw" "<rounding>")
15726 (set_attr "mode" "<MODE>")])
15728 (define_insn "fistdi2_<rounding>"
15729 [(set (match_operand:DI 0 "memory_operand" "=m")
15730 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15732 (use (match_operand:HI 2 "memory_operand" "m"))
15733 (use (match_operand:HI 3 "memory_operand" "m"))
15734 (clobber (match_scratch:XF 4 "=&1f"))]
15735 "TARGET_USE_FANCY_MATH_387
15736 && flag_unsafe_math_optimizations"
15737 "* return output_fix_trunc (insn, operands, false);"
15738 [(set_attr "type" "fistp")
15739 (set_attr "i387_cw" "<rounding>")
15740 (set_attr "mode" "DI")])
15742 (define_insn "fistdi2_<rounding>_with_temp"
15743 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15744 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15746 (use (match_operand:HI 2 "memory_operand" "m,m"))
15747 (use (match_operand:HI 3 "memory_operand" "m,m"))
15748 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15749 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && flag_unsafe_math_optimizations"
15753 [(set_attr "type" "fistp")
15754 (set_attr "i387_cw" "<rounding>")
15755 (set_attr "mode" "DI")])
15758 [(set (match_operand:DI 0 "register_operand")
15759 (unspec:DI [(match_operand:XF 1 "register_operand")]
15761 (use (match_operand:HI 2 "memory_operand"))
15762 (use (match_operand:HI 3 "memory_operand"))
15763 (clobber (match_operand:DI 4 "memory_operand"))
15764 (clobber (match_scratch 5))]
15766 [(parallel [(set (match_dup 4)
15767 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15768 (use (match_dup 2))
15769 (use (match_dup 3))
15770 (clobber (match_dup 5))])
15771 (set (match_dup 0) (match_dup 4))])
15774 [(set (match_operand:DI 0 "memory_operand")
15775 (unspec:DI [(match_operand:XF 1 "register_operand")]
15777 (use (match_operand:HI 2 "memory_operand"))
15778 (use (match_operand:HI 3 "memory_operand"))
15779 (clobber (match_operand:DI 4 "memory_operand"))
15780 (clobber (match_scratch 5))]
15782 [(parallel [(set (match_dup 0)
15783 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15784 (use (match_dup 2))
15785 (use (match_dup 3))
15786 (clobber (match_dup 5))])])
15788 (define_insn "fist<mode>2_<rounding>"
15789 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15790 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15792 (use (match_operand:HI 2 "memory_operand" "m"))
15793 (use (match_operand:HI 3 "memory_operand" "m"))]
15794 "TARGET_USE_FANCY_MATH_387
15795 && flag_unsafe_math_optimizations"
15796 "* return output_fix_trunc (insn, operands, false);"
15797 [(set_attr "type" "fistp")
15798 (set_attr "i387_cw" "<rounding>")
15799 (set_attr "mode" "<MODE>")])
15801 (define_insn "fist<mode>2_<rounding>_with_temp"
15802 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15803 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15805 (use (match_operand:HI 2 "memory_operand" "m,m"))
15806 (use (match_operand:HI 3 "memory_operand" "m,m"))
15807 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15808 "TARGET_USE_FANCY_MATH_387
15809 && flag_unsafe_math_optimizations"
15811 [(set_attr "type" "fistp")
15812 (set_attr "i387_cw" "<rounding>")
15813 (set_attr "mode" "<MODE>")])
15816 [(set (match_operand:SWI24 0 "register_operand")
15817 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15819 (use (match_operand:HI 2 "memory_operand"))
15820 (use (match_operand:HI 3 "memory_operand"))
15821 (clobber (match_operand:SWI24 4 "memory_operand"))]
15823 [(parallel [(set (match_dup 4)
15824 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15825 (use (match_dup 2))
15826 (use (match_dup 3))])
15827 (set (match_dup 0) (match_dup 4))])
15830 [(set (match_operand:SWI24 0 "memory_operand")
15831 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15833 (use (match_operand:HI 2 "memory_operand"))
15834 (use (match_operand:HI 3 "memory_operand"))
15835 (clobber (match_operand:SWI24 4 "memory_operand"))]
15837 [(parallel [(set (match_dup 0)
15838 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15839 (use (match_dup 2))
15840 (use (match_dup 3))])])
15842 (define_expand "l<rounding_insn>xf<mode>2"
15843 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15844 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15846 (clobber (reg:CC FLAGS_REG))])]
15847 "TARGET_USE_FANCY_MATH_387
15848 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15849 && flag_unsafe_math_optimizations")
15851 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15852 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15853 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15855 (clobber (reg:CC FLAGS_REG))])]
15856 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15857 && !flag_trapping_math"
15859 if (TARGET_64BIT && optimize_insn_for_size_p ())
15862 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15863 ix86_expand_lfloorceil (operands[0], operands[1], true);
15864 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15865 ix86_expand_lfloorceil (operands[0], operands[1], false);
15867 gcc_unreachable ();
15872 (define_insn "fxam<mode>2_i387"
15873 [(set (match_operand:HI 0 "register_operand" "=a")
15875 [(match_operand:X87MODEF 1 "register_operand" "f")]
15877 "TARGET_USE_FANCY_MATH_387"
15878 "fxam\n\tfnstsw\t%0"
15879 [(set_attr "type" "multi")
15880 (set_attr "length" "4")
15881 (set_attr "unit" "i387")
15882 (set_attr "mode" "<MODE>")])
15884 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15885 [(set (match_operand:HI 0 "register_operand")
15887 [(match_operand:MODEF 1 "memory_operand")]
15889 "TARGET_USE_FANCY_MATH_387
15890 && can_create_pseudo_p ()"
15893 [(set (match_dup 2)(match_dup 1))
15895 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15897 operands[2] = gen_reg_rtx (<MODE>mode);
15899 MEM_VOLATILE_P (operands[1]) = 1;
15901 [(set_attr "type" "multi")
15902 (set_attr "unit" "i387")
15903 (set_attr "mode" "<MODE>")])
15905 (define_expand "isinfxf2"
15906 [(use (match_operand:SI 0 "register_operand"))
15907 (use (match_operand:XF 1 "register_operand"))]
15908 "TARGET_USE_FANCY_MATH_387
15909 && ix86_libc_has_function (function_c99_misc)"
15911 rtx mask = GEN_INT (0x45);
15912 rtx val = GEN_INT (0x05);
15916 rtx scratch = gen_reg_rtx (HImode);
15917 rtx res = gen_reg_rtx (QImode);
15919 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15921 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15922 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15923 cond = gen_rtx_fmt_ee (EQ, QImode,
15924 gen_rtx_REG (CCmode, FLAGS_REG),
15926 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15927 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15931 (define_expand "isinf<mode>2"
15932 [(use (match_operand:SI 0 "register_operand"))
15933 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15934 "TARGET_USE_FANCY_MATH_387
15935 && ix86_libc_has_function (function_c99_misc)
15936 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15938 rtx mask = GEN_INT (0x45);
15939 rtx val = GEN_INT (0x05);
15943 rtx scratch = gen_reg_rtx (HImode);
15944 rtx res = gen_reg_rtx (QImode);
15946 /* Remove excess precision by forcing value through memory. */
15947 if (memory_operand (operands[1], VOIDmode))
15948 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15951 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15953 emit_move_insn (temp, operands[1]);
15954 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15957 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15958 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15959 cond = gen_rtx_fmt_ee (EQ, QImode,
15960 gen_rtx_REG (CCmode, FLAGS_REG),
15962 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15963 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15967 (define_expand "signbitxf2"
15968 [(use (match_operand:SI 0 "register_operand"))
15969 (use (match_operand:XF 1 "register_operand"))]
15970 "TARGET_USE_FANCY_MATH_387"
15972 rtx scratch = gen_reg_rtx (HImode);
15974 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15975 emit_insn (gen_andsi3 (operands[0],
15976 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15980 (define_insn "movmsk_df"
15981 [(set (match_operand:SI 0 "register_operand" "=r")
15983 [(match_operand:DF 1 "register_operand" "x")]
15985 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15986 "%vmovmskpd\t{%1, %0|%0, %1}"
15987 [(set_attr "type" "ssemov")
15988 (set_attr "prefix" "maybe_vex")
15989 (set_attr "mode" "DF")])
15991 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15992 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15993 (define_expand "signbitdf2"
15994 [(use (match_operand:SI 0 "register_operand"))
15995 (use (match_operand:DF 1 "register_operand"))]
15996 "TARGET_USE_FANCY_MATH_387
15997 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15999 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16001 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16002 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16006 rtx scratch = gen_reg_rtx (HImode);
16008 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16009 emit_insn (gen_andsi3 (operands[0],
16010 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16015 (define_expand "signbitsf2"
16016 [(use (match_operand:SI 0 "register_operand"))
16017 (use (match_operand:SF 1 "register_operand"))]
16018 "TARGET_USE_FANCY_MATH_387
16019 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16021 rtx scratch = gen_reg_rtx (HImode);
16023 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16024 emit_insn (gen_andsi3 (operands[0],
16025 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16029 ;; Block operation instructions
16032 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16035 [(set_attr "length" "1")
16036 (set_attr "length_immediate" "0")
16037 (set_attr "modrm" "0")])
16039 (define_expand "movmem<mode>"
16040 [(use (match_operand:BLK 0 "memory_operand"))
16041 (use (match_operand:BLK 1 "memory_operand"))
16042 (use (match_operand:SWI48 2 "nonmemory_operand"))
16043 (use (match_operand:SWI48 3 "const_int_operand"))
16044 (use (match_operand:SI 4 "const_int_operand"))
16045 (use (match_operand:SI 5 "const_int_operand"))
16046 (use (match_operand:SI 6 ""))
16047 (use (match_operand:SI 7 ""))
16048 (use (match_operand:SI 8 ""))]
16051 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16052 operands[2], NULL, operands[3],
16053 operands[4], operands[5],
16054 operands[6], operands[7],
16055 operands[8], false))
16061 ;; Most CPUs don't like single string operations
16062 ;; Handle this case here to simplify previous expander.
16064 (define_expand "strmov"
16065 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16066 (set (match_operand 1 "memory_operand") (match_dup 4))
16067 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16068 (clobber (reg:CC FLAGS_REG))])
16069 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16070 (clobber (reg:CC FLAGS_REG))])]
16073 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16075 /* If .md ever supports :P for Pmode, these can be directly
16076 in the pattern above. */
16077 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16078 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16080 /* Can't use this if the user has appropriated esi or edi. */
16081 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16082 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16084 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16085 operands[2], operands[3],
16086 operands[5], operands[6]));
16090 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16093 (define_expand "strmov_singleop"
16094 [(parallel [(set (match_operand 1 "memory_operand")
16095 (match_operand 3 "memory_operand"))
16096 (set (match_operand 0 "register_operand")
16098 (set (match_operand 2 "register_operand")
16099 (match_operand 5))])]
16101 "ix86_current_function_needs_cld = 1;")
16103 (define_insn "*strmovdi_rex_1"
16104 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16105 (mem:DI (match_operand:P 3 "register_operand" "1")))
16106 (set (match_operand:P 0 "register_operand" "=D")
16107 (plus:P (match_dup 2)
16109 (set (match_operand:P 1 "register_operand" "=S")
16110 (plus:P (match_dup 3)
16113 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16115 [(set_attr "type" "str")
16116 (set_attr "memory" "both")
16117 (set_attr "mode" "DI")])
16119 (define_insn "*strmovsi_1"
16120 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16121 (mem:SI (match_operand:P 3 "register_operand" "1")))
16122 (set (match_operand:P 0 "register_operand" "=D")
16123 (plus:P (match_dup 2)
16125 (set (match_operand:P 1 "register_operand" "=S")
16126 (plus:P (match_dup 3)
16128 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16130 [(set_attr "type" "str")
16131 (set_attr "memory" "both")
16132 (set_attr "mode" "SI")])
16134 (define_insn "*strmovhi_1"
16135 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16136 (mem:HI (match_operand:P 3 "register_operand" "1")))
16137 (set (match_operand:P 0 "register_operand" "=D")
16138 (plus:P (match_dup 2)
16140 (set (match_operand:P 1 "register_operand" "=S")
16141 (plus:P (match_dup 3)
16143 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16145 [(set_attr "type" "str")
16146 (set_attr "memory" "both")
16147 (set_attr "mode" "HI")])
16149 (define_insn "*strmovqi_1"
16150 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16151 (mem:QI (match_operand:P 3 "register_operand" "1")))
16152 (set (match_operand:P 0 "register_operand" "=D")
16153 (plus:P (match_dup 2)
16155 (set (match_operand:P 1 "register_operand" "=S")
16156 (plus:P (match_dup 3)
16158 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16160 [(set_attr "type" "str")
16161 (set_attr "memory" "both")
16162 (set (attr "prefix_rex")
16164 (match_test "<P:MODE>mode == DImode")
16166 (const_string "*")))
16167 (set_attr "mode" "QI")])
16169 (define_expand "rep_mov"
16170 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16171 (set (match_operand 0 "register_operand")
16173 (set (match_operand 2 "register_operand")
16175 (set (match_operand 1 "memory_operand")
16176 (match_operand 3 "memory_operand"))
16177 (use (match_dup 4))])]
16179 "ix86_current_function_needs_cld = 1;")
16181 (define_insn "*rep_movdi_rex64"
16182 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16183 (set (match_operand:P 0 "register_operand" "=D")
16184 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16186 (match_operand:P 3 "register_operand" "0")))
16187 (set (match_operand:P 1 "register_operand" "=S")
16188 (plus:P (ashift:P (match_dup 5) (const_int 3))
16189 (match_operand:P 4 "register_operand" "1")))
16190 (set (mem:BLK (match_dup 3))
16191 (mem:BLK (match_dup 4)))
16192 (use (match_dup 5))]
16194 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16196 [(set_attr "type" "str")
16197 (set_attr "prefix_rep" "1")
16198 (set_attr "memory" "both")
16199 (set_attr "mode" "DI")])
16201 (define_insn "*rep_movsi"
16202 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16203 (set (match_operand:P 0 "register_operand" "=D")
16204 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16206 (match_operand:P 3 "register_operand" "0")))
16207 (set (match_operand:P 1 "register_operand" "=S")
16208 (plus:P (ashift:P (match_dup 5) (const_int 2))
16209 (match_operand:P 4 "register_operand" "1")))
16210 (set (mem:BLK (match_dup 3))
16211 (mem:BLK (match_dup 4)))
16212 (use (match_dup 5))]
16213 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16214 "%^rep{%;} movs{l|d}"
16215 [(set_attr "type" "str")
16216 (set_attr "prefix_rep" "1")
16217 (set_attr "memory" "both")
16218 (set_attr "mode" "SI")])
16220 (define_insn "*rep_movqi"
16221 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16222 (set (match_operand:P 0 "register_operand" "=D")
16223 (plus:P (match_operand:P 3 "register_operand" "0")
16224 (match_operand:P 5 "register_operand" "2")))
16225 (set (match_operand:P 1 "register_operand" "=S")
16226 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16227 (set (mem:BLK (match_dup 3))
16228 (mem:BLK (match_dup 4)))
16229 (use (match_dup 5))]
16230 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16232 [(set_attr "type" "str")
16233 (set_attr "prefix_rep" "1")
16234 (set_attr "memory" "both")
16235 (set_attr "mode" "QI")])
16237 (define_expand "setmem<mode>"
16238 [(use (match_operand:BLK 0 "memory_operand"))
16239 (use (match_operand:SWI48 1 "nonmemory_operand"))
16240 (use (match_operand:QI 2 "nonmemory_operand"))
16241 (use (match_operand 3 "const_int_operand"))
16242 (use (match_operand:SI 4 "const_int_operand"))
16243 (use (match_operand:SI 5 "const_int_operand"))
16244 (use (match_operand:SI 6 ""))
16245 (use (match_operand:SI 7 ""))
16246 (use (match_operand:SI 8 ""))]
16249 if (ix86_expand_set_or_movmem (operands[0], NULL,
16250 operands[1], operands[2],
16251 operands[3], operands[4],
16252 operands[5], operands[6],
16253 operands[7], operands[8], true))
16259 ;; Most CPUs don't like single string operations
16260 ;; Handle this case here to simplify previous expander.
16262 (define_expand "strset"
16263 [(set (match_operand 1 "memory_operand")
16264 (match_operand 2 "register_operand"))
16265 (parallel [(set (match_operand 0 "register_operand")
16267 (clobber (reg:CC FLAGS_REG))])]
16270 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16271 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16273 /* If .md ever supports :P for Pmode, this can be directly
16274 in the pattern above. */
16275 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16276 GEN_INT (GET_MODE_SIZE (GET_MODE
16278 /* Can't use this if the user has appropriated eax or edi. */
16279 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16280 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16282 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16288 (define_expand "strset_singleop"
16289 [(parallel [(set (match_operand 1 "memory_operand")
16290 (match_operand 2 "register_operand"))
16291 (set (match_operand 0 "register_operand")
16293 (unspec [(const_int 0)] UNSPEC_STOS)])]
16295 "ix86_current_function_needs_cld = 1;")
16297 (define_insn "*strsetdi_rex_1"
16298 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16299 (match_operand:DI 2 "register_operand" "a"))
16300 (set (match_operand:P 0 "register_operand" "=D")
16301 (plus:P (match_dup 1)
16303 (unspec [(const_int 0)] UNSPEC_STOS)]
16305 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16307 [(set_attr "type" "str")
16308 (set_attr "memory" "store")
16309 (set_attr "mode" "DI")])
16311 (define_insn "*strsetsi_1"
16312 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16313 (match_operand:SI 2 "register_operand" "a"))
16314 (set (match_operand:P 0 "register_operand" "=D")
16315 (plus:P (match_dup 1)
16317 (unspec [(const_int 0)] UNSPEC_STOS)]
16318 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16320 [(set_attr "type" "str")
16321 (set_attr "memory" "store")
16322 (set_attr "mode" "SI")])
16324 (define_insn "*strsethi_1"
16325 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16326 (match_operand:HI 2 "register_operand" "a"))
16327 (set (match_operand:P 0 "register_operand" "=D")
16328 (plus:P (match_dup 1)
16330 (unspec [(const_int 0)] UNSPEC_STOS)]
16331 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16333 [(set_attr "type" "str")
16334 (set_attr "memory" "store")
16335 (set_attr "mode" "HI")])
16337 (define_insn "*strsetqi_1"
16338 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16339 (match_operand:QI 2 "register_operand" "a"))
16340 (set (match_operand:P 0 "register_operand" "=D")
16341 (plus:P (match_dup 1)
16343 (unspec [(const_int 0)] UNSPEC_STOS)]
16344 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16346 [(set_attr "type" "str")
16347 (set_attr "memory" "store")
16348 (set (attr "prefix_rex")
16350 (match_test "<P:MODE>mode == DImode")
16352 (const_string "*")))
16353 (set_attr "mode" "QI")])
16355 (define_expand "rep_stos"
16356 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16357 (set (match_operand 0 "register_operand")
16359 (set (match_operand 2 "memory_operand") (const_int 0))
16360 (use (match_operand 3 "register_operand"))
16361 (use (match_dup 1))])]
16363 "ix86_current_function_needs_cld = 1;")
16365 (define_insn "*rep_stosdi_rex64"
16366 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16367 (set (match_operand:P 0 "register_operand" "=D")
16368 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16370 (match_operand:P 3 "register_operand" "0")))
16371 (set (mem:BLK (match_dup 3))
16373 (use (match_operand:DI 2 "register_operand" "a"))
16374 (use (match_dup 4))]
16376 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16378 [(set_attr "type" "str")
16379 (set_attr "prefix_rep" "1")
16380 (set_attr "memory" "store")
16381 (set_attr "mode" "DI")])
16383 (define_insn "*rep_stossi"
16384 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16385 (set (match_operand:P 0 "register_operand" "=D")
16386 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16388 (match_operand:P 3 "register_operand" "0")))
16389 (set (mem:BLK (match_dup 3))
16391 (use (match_operand:SI 2 "register_operand" "a"))
16392 (use (match_dup 4))]
16393 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16394 "%^rep{%;} stos{l|d}"
16395 [(set_attr "type" "str")
16396 (set_attr "prefix_rep" "1")
16397 (set_attr "memory" "store")
16398 (set_attr "mode" "SI")])
16400 (define_insn "*rep_stosqi"
16401 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16402 (set (match_operand:P 0 "register_operand" "=D")
16403 (plus:P (match_operand:P 3 "register_operand" "0")
16404 (match_operand:P 4 "register_operand" "1")))
16405 (set (mem:BLK (match_dup 3))
16407 (use (match_operand:QI 2 "register_operand" "a"))
16408 (use (match_dup 4))]
16409 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16411 [(set_attr "type" "str")
16412 (set_attr "prefix_rep" "1")
16413 (set_attr "memory" "store")
16414 (set (attr "prefix_rex")
16416 (match_test "<P:MODE>mode == DImode")
16418 (const_string "*")))
16419 (set_attr "mode" "QI")])
16421 (define_expand "cmpstrnsi"
16422 [(set (match_operand:SI 0 "register_operand")
16423 (compare:SI (match_operand:BLK 1 "general_operand")
16424 (match_operand:BLK 2 "general_operand")))
16425 (use (match_operand 3 "general_operand"))
16426 (use (match_operand 4 "immediate_operand"))]
16429 rtx addr1, addr2, out, outlow, count, countreg, align;
16431 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16434 /* Can't use this if the user has appropriated ecx, esi or edi. */
16435 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16440 out = gen_reg_rtx (SImode);
16442 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16443 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16444 if (addr1 != XEXP (operands[1], 0))
16445 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16446 if (addr2 != XEXP (operands[2], 0))
16447 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16449 count = operands[3];
16450 countreg = ix86_zero_extend_to_Pmode (count);
16452 /* %%% Iff we are testing strict equality, we can use known alignment
16453 to good advantage. This may be possible with combine, particularly
16454 once cc0 is dead. */
16455 align = operands[4];
16457 if (CONST_INT_P (count))
16459 if (INTVAL (count) == 0)
16461 emit_move_insn (operands[0], const0_rtx);
16464 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16465 operands[1], operands[2]));
16469 rtx (*gen_cmp) (rtx, rtx);
16471 gen_cmp = (TARGET_64BIT
16472 ? gen_cmpdi_1 : gen_cmpsi_1);
16474 emit_insn (gen_cmp (countreg, countreg));
16475 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16476 operands[1], operands[2]));
16479 outlow = gen_lowpart (QImode, out);
16480 emit_insn (gen_cmpintqi (outlow));
16481 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16483 if (operands[0] != out)
16484 emit_move_insn (operands[0], out);
16489 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16491 (define_expand "cmpintqi"
16492 [(set (match_dup 1)
16493 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16495 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16496 (parallel [(set (match_operand:QI 0 "register_operand")
16497 (minus:QI (match_dup 1)
16499 (clobber (reg:CC FLAGS_REG))])]
16502 operands[1] = gen_reg_rtx (QImode);
16503 operands[2] = gen_reg_rtx (QImode);
16506 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16507 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16509 (define_expand "cmpstrnqi_nz_1"
16510 [(parallel [(set (reg:CC FLAGS_REG)
16511 (compare:CC (match_operand 4 "memory_operand")
16512 (match_operand 5 "memory_operand")))
16513 (use (match_operand 2 "register_operand"))
16514 (use (match_operand:SI 3 "immediate_operand"))
16515 (clobber (match_operand 0 "register_operand"))
16516 (clobber (match_operand 1 "register_operand"))
16517 (clobber (match_dup 2))])]
16519 "ix86_current_function_needs_cld = 1;")
16521 (define_insn "*cmpstrnqi_nz_1"
16522 [(set (reg:CC FLAGS_REG)
16523 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16524 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16525 (use (match_operand:P 6 "register_operand" "2"))
16526 (use (match_operand:SI 3 "immediate_operand" "i"))
16527 (clobber (match_operand:P 0 "register_operand" "=S"))
16528 (clobber (match_operand:P 1 "register_operand" "=D"))
16529 (clobber (match_operand:P 2 "register_operand" "=c"))]
16530 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16532 [(set_attr "type" "str")
16533 (set_attr "mode" "QI")
16534 (set (attr "prefix_rex")
16536 (match_test "<P:MODE>mode == DImode")
16538 (const_string "*")))
16539 (set_attr "prefix_rep" "1")])
16541 ;; The same, but the count is not known to not be zero.
16543 (define_expand "cmpstrnqi_1"
16544 [(parallel [(set (reg:CC FLAGS_REG)
16545 (if_then_else:CC (ne (match_operand 2 "register_operand")
16547 (compare:CC (match_operand 4 "memory_operand")
16548 (match_operand 5 "memory_operand"))
16550 (use (match_operand:SI 3 "immediate_operand"))
16551 (use (reg:CC FLAGS_REG))
16552 (clobber (match_operand 0 "register_operand"))
16553 (clobber (match_operand 1 "register_operand"))
16554 (clobber (match_dup 2))])]
16556 "ix86_current_function_needs_cld = 1;")
16558 (define_insn "*cmpstrnqi_1"
16559 [(set (reg:CC FLAGS_REG)
16560 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16562 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16563 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16565 (use (match_operand:SI 3 "immediate_operand" "i"))
16566 (use (reg:CC FLAGS_REG))
16567 (clobber (match_operand:P 0 "register_operand" "=S"))
16568 (clobber (match_operand:P 1 "register_operand" "=D"))
16569 (clobber (match_operand:P 2 "register_operand" "=c"))]
16570 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16572 [(set_attr "type" "str")
16573 (set_attr "mode" "QI")
16574 (set (attr "prefix_rex")
16576 (match_test "<P:MODE>mode == DImode")
16578 (const_string "*")))
16579 (set_attr "prefix_rep" "1")])
16581 (define_expand "strlen<mode>"
16582 [(set (match_operand:P 0 "register_operand")
16583 (unspec:P [(match_operand:BLK 1 "general_operand")
16584 (match_operand:QI 2 "immediate_operand")
16585 (match_operand 3 "immediate_operand")]
16589 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16595 (define_expand "strlenqi_1"
16596 [(parallel [(set (match_operand 0 "register_operand")
16598 (clobber (match_operand 1 "register_operand"))
16599 (clobber (reg:CC FLAGS_REG))])]
16601 "ix86_current_function_needs_cld = 1;")
16603 (define_insn "*strlenqi_1"
16604 [(set (match_operand:P 0 "register_operand" "=&c")
16605 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16606 (match_operand:QI 2 "register_operand" "a")
16607 (match_operand:P 3 "immediate_operand" "i")
16608 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16609 (clobber (match_operand:P 1 "register_operand" "=D"))
16610 (clobber (reg:CC FLAGS_REG))]
16611 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16612 "%^repnz{%;} scasb"
16613 [(set_attr "type" "str")
16614 (set_attr "mode" "QI")
16615 (set (attr "prefix_rex")
16617 (match_test "<P:MODE>mode == DImode")
16619 (const_string "*")))
16620 (set_attr "prefix_rep" "1")])
16622 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16623 ;; handled in combine, but it is not currently up to the task.
16624 ;; When used for their truth value, the cmpstrn* expanders generate
16633 ;; The intermediate three instructions are unnecessary.
16635 ;; This one handles cmpstrn*_nz_1...
16638 (set (reg:CC FLAGS_REG)
16639 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16640 (mem:BLK (match_operand 5 "register_operand"))))
16641 (use (match_operand 6 "register_operand"))
16642 (use (match_operand:SI 3 "immediate_operand"))
16643 (clobber (match_operand 0 "register_operand"))
16644 (clobber (match_operand 1 "register_operand"))
16645 (clobber (match_operand 2 "register_operand"))])
16646 (set (match_operand:QI 7 "register_operand")
16647 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16648 (set (match_operand:QI 8 "register_operand")
16649 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16650 (set (reg FLAGS_REG)
16651 (compare (match_dup 7) (match_dup 8)))
16653 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16655 (set (reg:CC FLAGS_REG)
16656 (compare:CC (mem:BLK (match_dup 4))
16657 (mem:BLK (match_dup 5))))
16658 (use (match_dup 6))
16659 (use (match_dup 3))
16660 (clobber (match_dup 0))
16661 (clobber (match_dup 1))
16662 (clobber (match_dup 2))])])
16664 ;; ...and this one handles cmpstrn*_1.
16667 (set (reg:CC FLAGS_REG)
16668 (if_then_else:CC (ne (match_operand 6 "register_operand")
16670 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16671 (mem:BLK (match_operand 5 "register_operand")))
16673 (use (match_operand:SI 3 "immediate_operand"))
16674 (use (reg:CC FLAGS_REG))
16675 (clobber (match_operand 0 "register_operand"))
16676 (clobber (match_operand 1 "register_operand"))
16677 (clobber (match_operand 2 "register_operand"))])
16678 (set (match_operand:QI 7 "register_operand")
16679 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16680 (set (match_operand:QI 8 "register_operand")
16681 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16682 (set (reg FLAGS_REG)
16683 (compare (match_dup 7) (match_dup 8)))
16685 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16687 (set (reg:CC FLAGS_REG)
16688 (if_then_else:CC (ne (match_dup 6)
16690 (compare:CC (mem:BLK (match_dup 4))
16691 (mem:BLK (match_dup 5)))
16693 (use (match_dup 3))
16694 (use (reg:CC FLAGS_REG))
16695 (clobber (match_dup 0))
16696 (clobber (match_dup 1))
16697 (clobber (match_dup 2))])])
16699 ;; Conditional move instructions.
16701 (define_expand "mov<mode>cc"
16702 [(set (match_operand:SWIM 0 "register_operand")
16703 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16704 (match_operand:SWIM 2 "<general_operand>")
16705 (match_operand:SWIM 3 "<general_operand>")))]
16707 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16709 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16710 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16711 ;; So just document what we're doing explicitly.
16713 (define_expand "x86_mov<mode>cc_0_m1"
16715 [(set (match_operand:SWI48 0 "register_operand")
16716 (if_then_else:SWI48
16717 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16718 [(match_operand 1 "flags_reg_operand")
16722 (clobber (reg:CC FLAGS_REG))])])
16724 (define_insn "*x86_mov<mode>cc_0_m1"
16725 [(set (match_operand:SWI48 0 "register_operand" "=r")
16726 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16727 [(reg FLAGS_REG) (const_int 0)])
16730 (clobber (reg:CC FLAGS_REG))]
16732 "sbb{<imodesuffix>}\t%0, %0"
16733 ; Since we don't have the proper number of operands for an alu insn,
16734 ; fill in all the blanks.
16735 [(set_attr "type" "alu")
16736 (set_attr "use_carry" "1")
16737 (set_attr "pent_pair" "pu")
16738 (set_attr "memory" "none")
16739 (set_attr "imm_disp" "false")
16740 (set_attr "mode" "<MODE>")
16741 (set_attr "length_immediate" "0")])
16743 (define_insn "*x86_mov<mode>cc_0_m1_se"
16744 [(set (match_operand:SWI48 0 "register_operand" "=r")
16745 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16746 [(reg FLAGS_REG) (const_int 0)])
16749 (clobber (reg:CC FLAGS_REG))]
16751 "sbb{<imodesuffix>}\t%0, %0"
16752 [(set_attr "type" "alu")
16753 (set_attr "use_carry" "1")
16754 (set_attr "pent_pair" "pu")
16755 (set_attr "memory" "none")
16756 (set_attr "imm_disp" "false")
16757 (set_attr "mode" "<MODE>")
16758 (set_attr "length_immediate" "0")])
16760 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16761 [(set (match_operand:SWI48 0 "register_operand" "=r")
16762 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16763 [(reg FLAGS_REG) (const_int 0)])))
16764 (clobber (reg:CC FLAGS_REG))]
16766 "sbb{<imodesuffix>}\t%0, %0"
16767 [(set_attr "type" "alu")
16768 (set_attr "use_carry" "1")
16769 (set_attr "pent_pair" "pu")
16770 (set_attr "memory" "none")
16771 (set_attr "imm_disp" "false")
16772 (set_attr "mode" "<MODE>")
16773 (set_attr "length_immediate" "0")])
16775 (define_insn "*mov<mode>cc_noc"
16776 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16777 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16778 [(reg FLAGS_REG) (const_int 0)])
16779 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16780 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16781 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16783 cmov%O2%C1\t{%2, %0|%0, %2}
16784 cmov%O2%c1\t{%3, %0|%0, %3}"
16785 [(set_attr "type" "icmov")
16786 (set_attr "mode" "<MODE>")])
16788 ;; Don't do conditional moves with memory inputs. This splitter helps
16789 ;; register starved x86_32 by forcing inputs into registers before reload.
16791 [(set (match_operand:SWI248 0 "register_operand")
16792 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16793 [(reg FLAGS_REG) (const_int 0)])
16794 (match_operand:SWI248 2 "nonimmediate_operand")
16795 (match_operand:SWI248 3 "nonimmediate_operand")))]
16796 "!TARGET_64BIT && TARGET_CMOVE
16797 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16798 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16799 && can_create_pseudo_p ()
16800 && optimize_insn_for_speed_p ()"
16801 [(set (match_dup 0)
16802 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16804 if (MEM_P (operands[2]))
16805 operands[2] = force_reg (<MODE>mode, operands[2]);
16806 if (MEM_P (operands[3]))
16807 operands[3] = force_reg (<MODE>mode, operands[3]);
16810 (define_insn "*movqicc_noc"
16811 [(set (match_operand:QI 0 "register_operand" "=r,r")
16812 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16813 [(reg FLAGS_REG) (const_int 0)])
16814 (match_operand:QI 2 "register_operand" "r,0")
16815 (match_operand:QI 3 "register_operand" "0,r")))]
16816 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16818 [(set_attr "type" "icmov")
16819 (set_attr "mode" "QI")])
16822 [(set (match_operand:SWI12 0 "register_operand")
16823 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16824 [(reg FLAGS_REG) (const_int 0)])
16825 (match_operand:SWI12 2 "register_operand")
16826 (match_operand:SWI12 3 "register_operand")))]
16827 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16828 && reload_completed"
16829 [(set (match_dup 0)
16830 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16832 operands[0] = gen_lowpart (SImode, operands[0]);
16833 operands[2] = gen_lowpart (SImode, operands[2]);
16834 operands[3] = gen_lowpart (SImode, operands[3]);
16837 ;; Don't do conditional moves with memory inputs
16839 [(match_scratch:SWI248 2 "r")
16840 (set (match_operand:SWI248 0 "register_operand")
16841 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16842 [(reg FLAGS_REG) (const_int 0)])
16844 (match_operand:SWI248 3 "memory_operand")))]
16845 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16846 && optimize_insn_for_speed_p ()"
16847 [(set (match_dup 2) (match_dup 3))
16849 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16852 [(match_scratch:SWI248 2 "r")
16853 (set (match_operand:SWI248 0 "register_operand")
16854 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16855 [(reg FLAGS_REG) (const_int 0)])
16856 (match_operand:SWI248 3 "memory_operand")
16858 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16859 && optimize_insn_for_speed_p ()"
16860 [(set (match_dup 2) (match_dup 3))
16862 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16864 (define_expand "mov<mode>cc"
16865 [(set (match_operand:X87MODEF 0 "register_operand")
16866 (if_then_else:X87MODEF
16867 (match_operand 1 "comparison_operator")
16868 (match_operand:X87MODEF 2 "register_operand")
16869 (match_operand:X87MODEF 3 "register_operand")))]
16870 "(TARGET_80387 && TARGET_CMOVE)
16871 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16872 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16874 (define_insn "*movxfcc_1"
16875 [(set (match_operand:XF 0 "register_operand" "=f,f")
16876 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16877 [(reg FLAGS_REG) (const_int 0)])
16878 (match_operand:XF 2 "register_operand" "f,0")
16879 (match_operand:XF 3 "register_operand" "0,f")))]
16880 "TARGET_80387 && TARGET_CMOVE"
16882 fcmov%F1\t{%2, %0|%0, %2}
16883 fcmov%f1\t{%3, %0|%0, %3}"
16884 [(set_attr "type" "fcmov")
16885 (set_attr "mode" "XF")])
16887 (define_insn "*movdfcc_1"
16888 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16889 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16890 [(reg FLAGS_REG) (const_int 0)])
16891 (match_operand:DF 2 "nonimmediate_operand"
16893 (match_operand:DF 3 "nonimmediate_operand"
16894 "0 ,f,0 ,rm,0, rm")))]
16895 "TARGET_80387 && TARGET_CMOVE
16896 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16898 fcmov%F1\t{%2, %0|%0, %2}
16899 fcmov%f1\t{%3, %0|%0, %3}
16902 cmov%O2%C1\t{%2, %0|%0, %2}
16903 cmov%O2%c1\t{%3, %0|%0, %3}"
16904 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16905 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16906 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16909 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16910 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16911 [(reg FLAGS_REG) (const_int 0)])
16912 (match_operand:DF 2 "nonimmediate_operand")
16913 (match_operand:DF 3 "nonimmediate_operand")))]
16914 "!TARGET_64BIT && reload_completed"
16915 [(set (match_dup 2)
16916 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16918 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16920 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16921 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16924 (define_insn "*movsfcc_1_387"
16925 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16926 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16927 [(reg FLAGS_REG) (const_int 0)])
16928 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16929 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16930 "TARGET_80387 && TARGET_CMOVE
16931 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16933 fcmov%F1\t{%2, %0|%0, %2}
16934 fcmov%f1\t{%3, %0|%0, %3}
16935 cmov%O2%C1\t{%2, %0|%0, %2}
16936 cmov%O2%c1\t{%3, %0|%0, %3}"
16937 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16938 (set_attr "mode" "SF,SF,SI,SI")])
16940 ;; Don't do conditional moves with memory inputs. This splitter helps
16941 ;; register starved x86_32 by forcing inputs into registers before reload.
16943 [(set (match_operand:MODEF 0 "register_operand")
16944 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16945 [(reg FLAGS_REG) (const_int 0)])
16946 (match_operand:MODEF 2 "nonimmediate_operand")
16947 (match_operand:MODEF 3 "nonimmediate_operand")))]
16948 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16949 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16950 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16951 && can_create_pseudo_p ()
16952 && optimize_insn_for_speed_p ()"
16953 [(set (match_dup 0)
16954 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16956 if (MEM_P (operands[2]))
16957 operands[2] = force_reg (<MODE>mode, operands[2]);
16958 if (MEM_P (operands[3]))
16959 operands[3] = force_reg (<MODE>mode, operands[3]);
16962 ;; Don't do conditional moves with memory inputs
16964 [(match_scratch:MODEF 2 "r")
16965 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16966 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16967 [(reg FLAGS_REG) (const_int 0)])
16969 (match_operand:MODEF 3 "memory_operand")))]
16970 "(<MODE>mode != DFmode || TARGET_64BIT)
16971 && TARGET_80387 && TARGET_CMOVE
16972 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16973 && optimize_insn_for_speed_p ()"
16974 [(set (match_dup 2) (match_dup 3))
16976 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16979 [(match_scratch:MODEF 2 "r")
16980 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16981 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16982 [(reg FLAGS_REG) (const_int 0)])
16983 (match_operand:MODEF 3 "memory_operand")
16985 "(<MODE>mode != DFmode || TARGET_64BIT)
16986 && TARGET_80387 && TARGET_CMOVE
16987 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16988 && optimize_insn_for_speed_p ()"
16989 [(set (match_dup 2) (match_dup 3))
16991 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16993 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16994 ;; the scalar versions to have only XMM registers as operands.
16996 ;; XOP conditional move
16997 (define_insn "*xop_pcmov_<mode>"
16998 [(set (match_operand:MODEF 0 "register_operand" "=x")
16999 (if_then_else:MODEF
17000 (match_operand:MODEF 1 "register_operand" "x")
17001 (match_operand:MODEF 2 "register_operand" "x")
17002 (match_operand:MODEF 3 "register_operand" "x")))]
17004 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17005 [(set_attr "type" "sse4arg")])
17007 ;; These versions of the min/max patterns are intentionally ignorant of
17008 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17009 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17010 ;; are undefined in this condition, we're certain this is correct.
17012 (define_insn "<code><mode>3"
17013 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17015 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17016 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17017 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17019 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17020 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17021 [(set_attr "isa" "noavx,avx")
17022 (set_attr "prefix" "orig,vex")
17023 (set_attr "type" "sseadd")
17024 (set_attr "mode" "<MODE>")])
17026 ;; These versions of the min/max patterns implement exactly the operations
17027 ;; min = (op1 < op2 ? op1 : op2)
17028 ;; max = (!(op1 < op2) ? op1 : op2)
17029 ;; Their operands are not commutative, and thus they may be used in the
17030 ;; presence of -0.0 and NaN.
17032 (define_int_iterator IEEE_MAXMIN
17036 (define_int_attr ieee_maxmin
17037 [(UNSPEC_IEEE_MAX "max")
17038 (UNSPEC_IEEE_MIN "min")])
17040 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17041 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17043 [(match_operand:MODEF 1 "register_operand" "0,x")
17044 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
17046 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17048 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17049 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17050 [(set_attr "isa" "noavx,avx")
17051 (set_attr "prefix" "orig,vex")
17052 (set_attr "type" "sseadd")
17053 (set_attr "mode" "<MODE>")])
17055 ;; Make two stack loads independent:
17057 ;; fld %st(0) -> fld bb
17058 ;; fmul bb fmul %st(1), %st
17060 ;; Actually we only match the last two instructions for simplicity.
17062 [(set (match_operand 0 "fp_register_operand")
17063 (match_operand 1 "fp_register_operand"))
17065 (match_operator 2 "binary_fp_operator"
17067 (match_operand 3 "memory_operand")]))]
17068 "REGNO (operands[0]) != REGNO (operands[1])"
17069 [(set (match_dup 0) (match_dup 3))
17070 (set (match_dup 0) (match_dup 4))]
17072 ;; The % modifier is not operational anymore in peephole2's, so we have to
17073 ;; swap the operands manually in the case of addition and multiplication.
17077 if (COMMUTATIVE_ARITH_P (operands[2]))
17078 op0 = operands[0], op1 = operands[1];
17080 op0 = operands[1], op1 = operands[0];
17082 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17083 GET_MODE (operands[2]),
17087 ;; Conditional addition patterns
17088 (define_expand "add<mode>cc"
17089 [(match_operand:SWI 0 "register_operand")
17090 (match_operand 1 "ordered_comparison_operator")
17091 (match_operand:SWI 2 "register_operand")
17092 (match_operand:SWI 3 "const_int_operand")]
17094 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17096 ;; Misc patterns (?)
17098 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17099 ;; Otherwise there will be nothing to keep
17101 ;; [(set (reg ebp) (reg esp))]
17102 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17103 ;; (clobber (eflags)]
17104 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17106 ;; in proper program order.
17108 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17109 [(set (match_operand:P 0 "register_operand" "=r,r")
17110 (plus:P (match_operand:P 1 "register_operand" "0,r")
17111 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17112 (clobber (reg:CC FLAGS_REG))
17113 (clobber (mem:BLK (scratch)))]
17116 switch (get_attr_type (insn))
17119 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17122 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17123 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17124 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17126 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17129 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17130 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17133 [(set (attr "type")
17134 (cond [(and (eq_attr "alternative" "0")
17135 (not (match_test "TARGET_OPT_AGU")))
17136 (const_string "alu")
17137 (match_operand:<MODE> 2 "const0_operand")
17138 (const_string "imov")
17140 (const_string "lea")))
17141 (set (attr "length_immediate")
17142 (cond [(eq_attr "type" "imov")
17144 (and (eq_attr "type" "alu")
17145 (match_operand 2 "const128_operand"))
17148 (const_string "*")))
17149 (set_attr "mode" "<MODE>")])
17151 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17152 [(set (match_operand:P 0 "register_operand" "=r")
17153 (minus:P (match_operand:P 1 "register_operand" "0")
17154 (match_operand:P 2 "register_operand" "r")))
17155 (clobber (reg:CC FLAGS_REG))
17156 (clobber (mem:BLK (scratch)))]
17158 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17159 [(set_attr "type" "alu")
17160 (set_attr "mode" "<MODE>")])
17162 (define_insn "allocate_stack_worker_probe_<mode>"
17163 [(set (match_operand:P 0 "register_operand" "=a")
17164 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17165 UNSPECV_STACK_PROBE))
17166 (clobber (reg:CC FLAGS_REG))]
17167 "ix86_target_stack_probe ()"
17168 "call\t___chkstk_ms"
17169 [(set_attr "type" "multi")
17170 (set_attr "length" "5")])
17172 (define_expand "allocate_stack"
17173 [(match_operand 0 "register_operand")
17174 (match_operand 1 "general_operand")]
17175 "ix86_target_stack_probe ()"
17179 #ifndef CHECK_STACK_LIMIT
17180 #define CHECK_STACK_LIMIT 0
17183 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17184 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17188 rtx (*insn) (rtx, rtx);
17190 x = copy_to_mode_reg (Pmode, operands[1]);
17192 insn = (TARGET_64BIT
17193 ? gen_allocate_stack_worker_probe_di
17194 : gen_allocate_stack_worker_probe_si);
17196 emit_insn (insn (x, x));
17199 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17200 stack_pointer_rtx, 0, OPTAB_DIRECT);
17202 if (x != stack_pointer_rtx)
17203 emit_move_insn (stack_pointer_rtx, x);
17205 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17209 ;; Use IOR for stack probes, this is shorter.
17210 (define_expand "probe_stack"
17211 [(match_operand 0 "memory_operand")]
17214 rtx (*gen_ior3) (rtx, rtx, rtx);
17216 gen_ior3 = (GET_MODE (operands[0]) == DImode
17217 ? gen_iordi3 : gen_iorsi3);
17219 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17223 (define_insn "adjust_stack_and_probe<mode>"
17224 [(set (match_operand:P 0 "register_operand" "=r")
17225 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17226 UNSPECV_PROBE_STACK_RANGE))
17227 (set (reg:P SP_REG)
17228 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17229 (clobber (reg:CC FLAGS_REG))
17230 (clobber (mem:BLK (scratch)))]
17232 "* return output_adjust_stack_and_probe (operands[0]);"
17233 [(set_attr "type" "multi")])
17235 (define_insn "probe_stack_range<mode>"
17236 [(set (match_operand:P 0 "register_operand" "=r")
17237 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17238 (match_operand:P 2 "const_int_operand" "n")]
17239 UNSPECV_PROBE_STACK_RANGE))
17240 (clobber (reg:CC FLAGS_REG))]
17242 "* return output_probe_stack_range (operands[0], operands[2]);"
17243 [(set_attr "type" "multi")])
17245 (define_expand "builtin_setjmp_receiver"
17246 [(label_ref (match_operand 0))]
17247 "!TARGET_64BIT && flag_pic"
17253 rtx_code_label *label_rtx = gen_label_rtx ();
17254 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17255 xops[0] = xops[1] = pic_offset_table_rtx;
17256 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17257 ix86_expand_binary_operator (MINUS, SImode, xops);
17261 emit_insn (gen_set_got (pic_offset_table_rtx));
17265 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17266 ;; Do not split instructions with mask registers.
17268 [(set (match_operand 0 "general_reg_operand")
17269 (match_operator 3 "promotable_binary_operator"
17270 [(match_operand 1 "general_reg_operand")
17271 (match_operand 2 "aligned_operand")]))
17272 (clobber (reg:CC FLAGS_REG))]
17273 "! TARGET_PARTIAL_REG_STALL && reload_completed
17274 && ((GET_MODE (operands[0]) == HImode
17275 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17276 /* ??? next two lines just !satisfies_constraint_K (...) */
17277 || !CONST_INT_P (operands[2])
17278 || satisfies_constraint_K (operands[2])))
17279 || (GET_MODE (operands[0]) == QImode
17280 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17281 [(parallel [(set (match_dup 0)
17282 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17283 (clobber (reg:CC FLAGS_REG))])]
17285 operands[0] = gen_lowpart (SImode, operands[0]);
17286 operands[1] = gen_lowpart (SImode, operands[1]);
17287 if (GET_CODE (operands[3]) != ASHIFT)
17288 operands[2] = gen_lowpart (SImode, operands[2]);
17289 operands[3] = shallow_copy_rtx (operands[3]);
17290 PUT_MODE (operands[3], SImode);
17293 ; Promote the QImode tests, as i386 has encoding of the AND
17294 ; instruction with 32-bit sign-extended immediate and thus the
17295 ; instruction size is unchanged, except in the %eax case for
17296 ; which it is increased by one byte, hence the ! optimize_size.
17298 [(set (match_operand 0 "flags_reg_operand")
17299 (match_operator 2 "compare_operator"
17300 [(and (match_operand 3 "aligned_operand")
17301 (match_operand 4 "const_int_operand"))
17303 (set (match_operand 1 "register_operand")
17304 (and (match_dup 3) (match_dup 4)))]
17305 "! TARGET_PARTIAL_REG_STALL && reload_completed
17306 && optimize_insn_for_speed_p ()
17307 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17308 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17309 /* Ensure that the operand will remain sign-extended immediate. */
17310 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17311 [(parallel [(set (match_dup 0)
17312 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17315 (and:SI (match_dup 3) (match_dup 4)))])]
17318 = gen_int_mode (INTVAL (operands[4])
17319 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17320 operands[1] = gen_lowpart (SImode, operands[1]);
17321 operands[3] = gen_lowpart (SImode, operands[3]);
17324 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17325 ; the TEST instruction with 32-bit sign-extended immediate and thus
17326 ; the instruction size would at least double, which is not what we
17327 ; want even with ! optimize_size.
17329 [(set (match_operand 0 "flags_reg_operand")
17330 (match_operator 1 "compare_operator"
17331 [(and (match_operand:HI 2 "aligned_operand")
17332 (match_operand:HI 3 "const_int_operand"))
17334 "! TARGET_PARTIAL_REG_STALL && reload_completed
17335 && ! TARGET_FAST_PREFIX
17336 && optimize_insn_for_speed_p ()
17337 /* Ensure that the operand will remain sign-extended immediate. */
17338 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17339 [(set (match_dup 0)
17340 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17344 = gen_int_mode (INTVAL (operands[3])
17345 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17346 operands[2] = gen_lowpart (SImode, operands[2]);
17350 [(set (match_operand 0 "register_operand")
17351 (neg (match_operand 1 "register_operand")))
17352 (clobber (reg:CC FLAGS_REG))]
17353 "! TARGET_PARTIAL_REG_STALL && reload_completed
17354 && (GET_MODE (operands[0]) == HImode
17355 || (GET_MODE (operands[0]) == QImode
17356 && (TARGET_PROMOTE_QImode
17357 || optimize_insn_for_size_p ())))"
17358 [(parallel [(set (match_dup 0)
17359 (neg:SI (match_dup 1)))
17360 (clobber (reg:CC FLAGS_REG))])]
17362 operands[0] = gen_lowpart (SImode, operands[0]);
17363 operands[1] = gen_lowpart (SImode, operands[1]);
17366 ;; Do not split instructions with mask regs.
17368 [(set (match_operand 0 "general_reg_operand")
17369 (not (match_operand 1 "general_reg_operand")))]
17370 "! TARGET_PARTIAL_REG_STALL && reload_completed
17371 && (GET_MODE (operands[0]) == HImode
17372 || (GET_MODE (operands[0]) == QImode
17373 && (TARGET_PROMOTE_QImode
17374 || optimize_insn_for_size_p ())))"
17375 [(set (match_dup 0)
17376 (not:SI (match_dup 1)))]
17378 operands[0] = gen_lowpart (SImode, operands[0]);
17379 operands[1] = gen_lowpart (SImode, operands[1]);
17382 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17383 ;; transform a complex memory operation into two memory to register operations.
17385 ;; Don't push memory operands
17387 [(set (match_operand:SWI 0 "push_operand")
17388 (match_operand:SWI 1 "memory_operand"))
17389 (match_scratch:SWI 2 "<r>")]
17390 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17391 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17392 [(set (match_dup 2) (match_dup 1))
17393 (set (match_dup 0) (match_dup 2))])
17395 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17398 [(set (match_operand:SF 0 "push_operand")
17399 (match_operand:SF 1 "memory_operand"))
17400 (match_scratch:SF 2 "r")]
17401 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17402 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17403 [(set (match_dup 2) (match_dup 1))
17404 (set (match_dup 0) (match_dup 2))])
17406 ;; Don't move an immediate directly to memory when the instruction
17407 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17409 [(match_scratch:SWI124 1 "<r>")
17410 (set (match_operand:SWI124 0 "memory_operand")
17412 "optimize_insn_for_speed_p ()
17413 && ((<MODE>mode == HImode
17414 && TARGET_LCP_STALL)
17415 || (!TARGET_USE_MOV0
17416 && TARGET_SPLIT_LONG_MOVES
17417 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17418 && peep2_regno_dead_p (0, FLAGS_REG)"
17419 [(parallel [(set (match_dup 2) (const_int 0))
17420 (clobber (reg:CC FLAGS_REG))])
17421 (set (match_dup 0) (match_dup 1))]
17422 "operands[2] = gen_lowpart (SImode, operands[1]);")
17425 [(match_scratch:SWI124 2 "<r>")
17426 (set (match_operand:SWI124 0 "memory_operand")
17427 (match_operand:SWI124 1 "immediate_operand"))]
17428 "optimize_insn_for_speed_p ()
17429 && ((<MODE>mode == HImode
17430 && TARGET_LCP_STALL)
17431 || (TARGET_SPLIT_LONG_MOVES
17432 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17433 [(set (match_dup 2) (match_dup 1))
17434 (set (match_dup 0) (match_dup 2))])
17436 ;; Don't compare memory with zero, load and use a test instead.
17438 [(set (match_operand 0 "flags_reg_operand")
17439 (match_operator 1 "compare_operator"
17440 [(match_operand:SI 2 "memory_operand")
17442 (match_scratch:SI 3 "r")]
17443 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17444 [(set (match_dup 3) (match_dup 2))
17445 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17447 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17448 ;; Don't split NOTs with a displacement operand, because resulting XOR
17449 ;; will not be pairable anyway.
17451 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17452 ;; represented using a modRM byte. The XOR replacement is long decoded,
17453 ;; so this split helps here as well.
17455 ;; Note: Can't do this as a regular split because we can't get proper
17456 ;; lifetime information then.
17459 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17460 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17461 "optimize_insn_for_speed_p ()
17462 && ((TARGET_NOT_UNPAIRABLE
17463 && (!MEM_P (operands[0])
17464 || !memory_displacement_operand (operands[0], <MODE>mode)))
17465 || (TARGET_NOT_VECTORMODE
17466 && long_memory_operand (operands[0], <MODE>mode)))
17467 && peep2_regno_dead_p (0, FLAGS_REG)"
17468 [(parallel [(set (match_dup 0)
17469 (xor:SWI124 (match_dup 1) (const_int -1)))
17470 (clobber (reg:CC FLAGS_REG))])])
17472 ;; Non pairable "test imm, reg" instructions can be translated to
17473 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17474 ;; byte opcode instead of two, have a short form for byte operands),
17475 ;; so do it for other CPUs as well. Given that the value was dead,
17476 ;; this should not create any new dependencies. Pass on the sub-word
17477 ;; versions if we're concerned about partial register stalls.
17480 [(set (match_operand 0 "flags_reg_operand")
17481 (match_operator 1 "compare_operator"
17482 [(and:SI (match_operand:SI 2 "register_operand")
17483 (match_operand:SI 3 "immediate_operand"))
17485 "ix86_match_ccmode (insn, CCNOmode)
17486 && (true_regnum (operands[2]) != AX_REG
17487 || satisfies_constraint_K (operands[3]))
17488 && peep2_reg_dead_p (1, operands[2])"
17490 [(set (match_dup 0)
17491 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17494 (and:SI (match_dup 2) (match_dup 3)))])])
17496 ;; We don't need to handle HImode case, because it will be promoted to SImode
17497 ;; on ! TARGET_PARTIAL_REG_STALL
17500 [(set (match_operand 0 "flags_reg_operand")
17501 (match_operator 1 "compare_operator"
17502 [(and:QI (match_operand:QI 2 "register_operand")
17503 (match_operand:QI 3 "immediate_operand"))
17505 "! TARGET_PARTIAL_REG_STALL
17506 && ix86_match_ccmode (insn, CCNOmode)
17507 && true_regnum (operands[2]) != AX_REG
17508 && peep2_reg_dead_p (1, operands[2])"
17510 [(set (match_dup 0)
17511 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17514 (and:QI (match_dup 2) (match_dup 3)))])])
17517 [(set (match_operand 0 "flags_reg_operand")
17518 (match_operator 1 "compare_operator"
17521 (match_operand 2 "ext_register_operand")
17524 (match_operand 3 "const_int_operand"))
17526 "! TARGET_PARTIAL_REG_STALL
17527 && ix86_match_ccmode (insn, CCNOmode)
17528 && true_regnum (operands[2]) != AX_REG
17529 && peep2_reg_dead_p (1, operands[2])"
17530 [(parallel [(set (match_dup 0)
17539 (set (zero_extract:SI (match_dup 2)
17547 (match_dup 3)))])])
17549 ;; Don't do logical operations with memory inputs.
17551 [(match_scratch:SI 2 "r")
17552 (parallel [(set (match_operand:SI 0 "register_operand")
17553 (match_operator:SI 3 "arith_or_logical_operator"
17555 (match_operand:SI 1 "memory_operand")]))
17556 (clobber (reg:CC FLAGS_REG))])]
17557 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17558 [(set (match_dup 2) (match_dup 1))
17559 (parallel [(set (match_dup 0)
17560 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17561 (clobber (reg:CC FLAGS_REG))])])
17564 [(match_scratch:SI 2 "r")
17565 (parallel [(set (match_operand:SI 0 "register_operand")
17566 (match_operator:SI 3 "arith_or_logical_operator"
17567 [(match_operand:SI 1 "memory_operand")
17569 (clobber (reg:CC FLAGS_REG))])]
17570 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17571 [(set (match_dup 2) (match_dup 1))
17572 (parallel [(set (match_dup 0)
17573 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17574 (clobber (reg:CC FLAGS_REG))])])
17576 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17577 ;; refers to the destination of the load!
17580 [(set (match_operand:SI 0 "register_operand")
17581 (match_operand:SI 1 "register_operand"))
17582 (parallel [(set (match_dup 0)
17583 (match_operator:SI 3 "commutative_operator"
17585 (match_operand:SI 2 "memory_operand")]))
17586 (clobber (reg:CC FLAGS_REG))])]
17587 "REGNO (operands[0]) != REGNO (operands[1])
17588 && GENERAL_REGNO_P (REGNO (operands[0]))
17589 && GENERAL_REGNO_P (REGNO (operands[1]))"
17590 [(set (match_dup 0) (match_dup 4))
17591 (parallel [(set (match_dup 0)
17592 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17593 (clobber (reg:CC FLAGS_REG))])]
17594 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17597 [(set (match_operand 0 "register_operand")
17598 (match_operand 1 "register_operand"))
17600 (match_operator 3 "commutative_operator"
17602 (match_operand 2 "memory_operand")]))]
17603 "REGNO (operands[0]) != REGNO (operands[1])
17604 && ((MMX_REGNO_P (REGNO (operands[0]))
17605 && MMX_REGNO_P (REGNO (operands[1])))
17606 || (SSE_REGNO_P (REGNO (operands[0]))
17607 && SSE_REGNO_P (REGNO (operands[1]))))"
17608 [(set (match_dup 0) (match_dup 2))
17610 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17612 ; Don't do logical operations with memory outputs
17614 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17615 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17616 ; the same decoder scheduling characteristics as the original.
17619 [(match_scratch:SI 2 "r")
17620 (parallel [(set (match_operand:SI 0 "memory_operand")
17621 (match_operator:SI 3 "arith_or_logical_operator"
17623 (match_operand:SI 1 "nonmemory_operand")]))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17626 /* Do not split stack checking probes. */
17627 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17628 [(set (match_dup 2) (match_dup 0))
17629 (parallel [(set (match_dup 2)
17630 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17631 (clobber (reg:CC FLAGS_REG))])
17632 (set (match_dup 0) (match_dup 2))])
17635 [(match_scratch:SI 2 "r")
17636 (parallel [(set (match_operand:SI 0 "memory_operand")
17637 (match_operator:SI 3 "arith_or_logical_operator"
17638 [(match_operand:SI 1 "nonmemory_operand")
17640 (clobber (reg:CC FLAGS_REG))])]
17641 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17642 /* Do not split stack checking probes. */
17643 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17644 [(set (match_dup 2) (match_dup 0))
17645 (parallel [(set (match_dup 2)
17646 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17647 (clobber (reg:CC FLAGS_REG))])
17648 (set (match_dup 0) (match_dup 2))])
17650 ;; Attempt to use arith or logical operations with memory outputs with
17651 ;; setting of flags.
17653 [(set (match_operand:SWI 0 "register_operand")
17654 (match_operand:SWI 1 "memory_operand"))
17655 (parallel [(set (match_dup 0)
17656 (match_operator:SWI 3 "plusminuslogic_operator"
17658 (match_operand:SWI 2 "<nonmemory_operand>")]))
17659 (clobber (reg:CC FLAGS_REG))])
17660 (set (match_dup 1) (match_dup 0))
17661 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17662 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17663 && peep2_reg_dead_p (4, operands[0])
17664 && !reg_overlap_mentioned_p (operands[0], operands[1])
17665 && !reg_overlap_mentioned_p (operands[0], operands[2])
17666 && (<MODE>mode != QImode
17667 || immediate_operand (operands[2], QImode)
17668 || q_regs_operand (operands[2], QImode))
17669 && ix86_match_ccmode (peep2_next_insn (3),
17670 (GET_CODE (operands[3]) == PLUS
17671 || GET_CODE (operands[3]) == MINUS)
17672 ? CCGOCmode : CCNOmode)"
17673 [(parallel [(set (match_dup 4) (match_dup 5))
17674 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17675 (match_dup 2)]))])]
17677 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17678 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17679 copy_rtx (operands[1]),
17680 copy_rtx (operands[2]));
17681 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17682 operands[5], const0_rtx);
17686 [(parallel [(set (match_operand:SWI 0 "register_operand")
17687 (match_operator:SWI 2 "plusminuslogic_operator"
17689 (match_operand:SWI 1 "memory_operand")]))
17690 (clobber (reg:CC FLAGS_REG))])
17691 (set (match_dup 1) (match_dup 0))
17692 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17693 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17694 && GET_CODE (operands[2]) != MINUS
17695 && peep2_reg_dead_p (3, operands[0])
17696 && !reg_overlap_mentioned_p (operands[0], operands[1])
17697 && ix86_match_ccmode (peep2_next_insn (2),
17698 GET_CODE (operands[2]) == PLUS
17699 ? CCGOCmode : CCNOmode)"
17700 [(parallel [(set (match_dup 3) (match_dup 4))
17701 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17702 (match_dup 0)]))])]
17704 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17705 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17706 copy_rtx (operands[1]),
17707 copy_rtx (operands[0]));
17708 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17709 operands[4], const0_rtx);
17713 [(set (match_operand:SWI12 0 "register_operand")
17714 (match_operand:SWI12 1 "memory_operand"))
17715 (parallel [(set (match_operand:SI 4 "register_operand")
17716 (match_operator:SI 3 "plusminuslogic_operator"
17718 (match_operand:SI 2 "nonmemory_operand")]))
17719 (clobber (reg:CC FLAGS_REG))])
17720 (set (match_dup 1) (match_dup 0))
17721 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17722 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17723 && REG_P (operands[0]) && REG_P (operands[4])
17724 && REGNO (operands[0]) == REGNO (operands[4])
17725 && peep2_reg_dead_p (4, operands[0])
17726 && (<MODE>mode != QImode
17727 || immediate_operand (operands[2], SImode)
17728 || q_regs_operand (operands[2], SImode))
17729 && !reg_overlap_mentioned_p (operands[0], operands[1])
17730 && !reg_overlap_mentioned_p (operands[0], operands[2])
17731 && ix86_match_ccmode (peep2_next_insn (3),
17732 (GET_CODE (operands[3]) == PLUS
17733 || GET_CODE (operands[3]) == MINUS)
17734 ? CCGOCmode : CCNOmode)"
17735 [(parallel [(set (match_dup 4) (match_dup 5))
17736 (set (match_dup 1) (match_dup 6))])]
17738 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17739 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17740 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17741 copy_rtx (operands[1]), operands[2]);
17742 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17743 operands[5], const0_rtx);
17744 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17745 copy_rtx (operands[1]),
17746 copy_rtx (operands[2]));
17749 ;; Attempt to always use XOR for zeroing registers.
17751 [(set (match_operand 0 "register_operand")
17752 (match_operand 1 "const0_operand"))]
17753 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17754 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17755 && GENERAL_REGNO_P (REGNO (operands[0]))
17756 && peep2_regno_dead_p (0, FLAGS_REG)"
17757 [(parallel [(set (match_dup 0) (const_int 0))
17758 (clobber (reg:CC FLAGS_REG))])]
17759 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17762 [(set (strict_low_part (match_operand 0 "register_operand"))
17764 "(GET_MODE (operands[0]) == QImode
17765 || GET_MODE (operands[0]) == HImode)
17766 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17767 && peep2_regno_dead_p (0, FLAGS_REG)"
17768 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17769 (clobber (reg:CC FLAGS_REG))])])
17771 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17773 [(set (match_operand:SWI248 0 "register_operand")
17775 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17776 && GENERAL_REGNO_P (REGNO (operands[0]))
17777 && peep2_regno_dead_p (0, FLAGS_REG)"
17778 [(parallel [(set (match_dup 0) (const_int -1))
17779 (clobber (reg:CC FLAGS_REG))])]
17781 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17782 operands[0] = gen_lowpart (SImode, operands[0]);
17785 ;; Attempt to convert simple lea to add/shift.
17786 ;; These can be created by move expanders.
17787 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17788 ;; relevant lea instructions were already split.
17791 [(set (match_operand:SWI48 0 "register_operand")
17792 (plus:SWI48 (match_dup 0)
17793 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17795 && peep2_regno_dead_p (0, FLAGS_REG)"
17796 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17797 (clobber (reg:CC FLAGS_REG))])])
17800 [(set (match_operand:SWI48 0 "register_operand")
17801 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17804 && peep2_regno_dead_p (0, FLAGS_REG)"
17805 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17806 (clobber (reg:CC FLAGS_REG))])])
17809 [(set (match_operand:DI 0 "register_operand")
17811 (plus:SI (match_operand:SI 1 "register_operand")
17812 (match_operand:SI 2 "nonmemory_operand"))))]
17813 "TARGET_64BIT && !TARGET_OPT_AGU
17814 && REGNO (operands[0]) == REGNO (operands[1])
17815 && peep2_regno_dead_p (0, FLAGS_REG)"
17816 [(parallel [(set (match_dup 0)
17817 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17818 (clobber (reg:CC FLAGS_REG))])])
17821 [(set (match_operand:DI 0 "register_operand")
17823 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17824 (match_operand:SI 2 "register_operand"))))]
17825 "TARGET_64BIT && !TARGET_OPT_AGU
17826 && REGNO (operands[0]) == REGNO (operands[2])
17827 && peep2_regno_dead_p (0, FLAGS_REG)"
17828 [(parallel [(set (match_dup 0)
17829 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17830 (clobber (reg:CC FLAGS_REG))])])
17833 [(set (match_operand:SWI48 0 "register_operand")
17834 (mult:SWI48 (match_dup 0)
17835 (match_operand:SWI48 1 "const_int_operand")))]
17836 "exact_log2 (INTVAL (operands[1])) >= 0
17837 && peep2_regno_dead_p (0, FLAGS_REG)"
17838 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17839 (clobber (reg:CC FLAGS_REG))])]
17840 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17843 [(set (match_operand:DI 0 "register_operand")
17845 (mult:SI (match_operand:SI 1 "register_operand")
17846 (match_operand:SI 2 "const_int_operand"))))]
17848 && exact_log2 (INTVAL (operands[2])) >= 0
17849 && REGNO (operands[0]) == REGNO (operands[1])
17850 && peep2_regno_dead_p (0, FLAGS_REG)"
17851 [(parallel [(set (match_dup 0)
17852 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17853 (clobber (reg:CC FLAGS_REG))])]
17854 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17856 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17857 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17858 ;; On many CPUs it is also faster, since special hardware to avoid esp
17859 ;; dependencies is present.
17861 ;; While some of these conversions may be done using splitters, we use
17862 ;; peepholes in order to allow combine_stack_adjustments pass to see
17863 ;; nonobfuscated RTL.
17865 ;; Convert prologue esp subtractions to push.
17866 ;; We need register to push. In order to keep verify_flow_info happy we have
17868 ;; - use scratch and clobber it in order to avoid dependencies
17869 ;; - use already live register
17870 ;; We can't use the second way right now, since there is no reliable way how to
17871 ;; verify that given register is live. First choice will also most likely in
17872 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17873 ;; call clobbered registers are dead. We may want to use base pointer as an
17874 ;; alternative when no register is available later.
17877 [(match_scratch:W 1 "r")
17878 (parallel [(set (reg:P SP_REG)
17879 (plus:P (reg:P SP_REG)
17880 (match_operand:P 0 "const_int_operand")))
17881 (clobber (reg:CC FLAGS_REG))
17882 (clobber (mem:BLK (scratch)))])]
17883 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17884 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17885 [(clobber (match_dup 1))
17886 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17887 (clobber (mem:BLK (scratch)))])])
17890 [(match_scratch:W 1 "r")
17891 (parallel [(set (reg:P SP_REG)
17892 (plus:P (reg:P SP_REG)
17893 (match_operand:P 0 "const_int_operand")))
17894 (clobber (reg:CC FLAGS_REG))
17895 (clobber (mem:BLK (scratch)))])]
17896 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17897 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17898 [(clobber (match_dup 1))
17899 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17900 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17901 (clobber (mem:BLK (scratch)))])])
17903 ;; Convert esp subtractions to push.
17905 [(match_scratch:W 1 "r")
17906 (parallel [(set (reg:P SP_REG)
17907 (plus:P (reg:P SP_REG)
17908 (match_operand:P 0 "const_int_operand")))
17909 (clobber (reg:CC FLAGS_REG))])]
17910 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17911 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17912 [(clobber (match_dup 1))
17913 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17916 [(match_scratch:W 1 "r")
17917 (parallel [(set (reg:P SP_REG)
17918 (plus:P (reg:P SP_REG)
17919 (match_operand:P 0 "const_int_operand")))
17920 (clobber (reg:CC FLAGS_REG))])]
17921 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17922 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17923 [(clobber (match_dup 1))
17924 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17925 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17927 ;; Convert epilogue deallocator to pop.
17929 [(match_scratch:W 1 "r")
17930 (parallel [(set (reg:P SP_REG)
17931 (plus:P (reg:P SP_REG)
17932 (match_operand:P 0 "const_int_operand")))
17933 (clobber (reg:CC FLAGS_REG))
17934 (clobber (mem:BLK (scratch)))])]
17935 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17936 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17937 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17938 (clobber (mem:BLK (scratch)))])])
17940 ;; Two pops case is tricky, since pop causes dependency
17941 ;; on destination register. We use two registers if available.
17943 [(match_scratch:W 1 "r")
17944 (match_scratch:W 2 "r")
17945 (parallel [(set (reg:P SP_REG)
17946 (plus:P (reg:P SP_REG)
17947 (match_operand:P 0 "const_int_operand")))
17948 (clobber (reg:CC FLAGS_REG))
17949 (clobber (mem:BLK (scratch)))])]
17950 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17951 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17952 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17953 (clobber (mem:BLK (scratch)))])
17954 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17957 [(match_scratch:W 1 "r")
17958 (parallel [(set (reg:P SP_REG)
17959 (plus:P (reg:P SP_REG)
17960 (match_operand:P 0 "const_int_operand")))
17961 (clobber (reg:CC FLAGS_REG))
17962 (clobber (mem:BLK (scratch)))])]
17963 "optimize_insn_for_size_p ()
17964 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17965 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17966 (clobber (mem:BLK (scratch)))])
17967 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17969 ;; Convert esp additions to pop.
17971 [(match_scratch:W 1 "r")
17972 (parallel [(set (reg:P SP_REG)
17973 (plus:P (reg:P SP_REG)
17974 (match_operand:P 0 "const_int_operand")))
17975 (clobber (reg:CC FLAGS_REG))])]
17976 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17977 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17979 ;; Two pops case is tricky, since pop causes dependency
17980 ;; on destination register. We use two registers if available.
17982 [(match_scratch:W 1 "r")
17983 (match_scratch:W 2 "r")
17984 (parallel [(set (reg:P SP_REG)
17985 (plus:P (reg:P SP_REG)
17986 (match_operand:P 0 "const_int_operand")))
17987 (clobber (reg:CC FLAGS_REG))])]
17988 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17989 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17990 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17993 [(match_scratch:W 1 "r")
17994 (parallel [(set (reg:P SP_REG)
17995 (plus:P (reg:P SP_REG)
17996 (match_operand:P 0 "const_int_operand")))
17997 (clobber (reg:CC FLAGS_REG))])]
17998 "optimize_insn_for_size_p ()
17999 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18000 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18001 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18003 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18004 ;; required and register dies. Similarly for 128 to -128.
18006 [(set (match_operand 0 "flags_reg_operand")
18007 (match_operator 1 "compare_operator"
18008 [(match_operand 2 "register_operand")
18009 (match_operand 3 "const_int_operand")]))]
18010 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18011 && incdec_operand (operands[3], GET_MODE (operands[3])))
18012 || (!TARGET_FUSE_CMP_AND_BRANCH
18013 && INTVAL (operands[3]) == 128))
18014 && ix86_match_ccmode (insn, CCGCmode)
18015 && peep2_reg_dead_p (1, operands[2])"
18016 [(parallel [(set (match_dup 0)
18017 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18018 (clobber (match_dup 2))])])
18020 ;; Convert imul by three, five and nine into lea
18023 [(set (match_operand:SWI48 0 "register_operand")
18024 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18025 (match_operand:SWI48 2 "const359_operand")))
18026 (clobber (reg:CC FLAGS_REG))])]
18027 "!TARGET_PARTIAL_REG_STALL
18028 || <MODE>mode == SImode
18029 || optimize_function_for_size_p (cfun)"
18030 [(set (match_dup 0)
18031 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18033 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18037 [(set (match_operand:SWI48 0 "register_operand")
18038 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18039 (match_operand:SWI48 2 "const359_operand")))
18040 (clobber (reg:CC FLAGS_REG))])]
18041 "optimize_insn_for_speed_p ()
18042 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18043 [(set (match_dup 0) (match_dup 1))
18045 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18047 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18049 ;; imul $32bit_imm, mem, reg is vector decoded, while
18050 ;; imul $32bit_imm, reg, reg is direct decoded.
18052 [(match_scratch:SWI48 3 "r")
18053 (parallel [(set (match_operand:SWI48 0 "register_operand")
18054 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18055 (match_operand:SWI48 2 "immediate_operand")))
18056 (clobber (reg:CC FLAGS_REG))])]
18057 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18058 && !satisfies_constraint_K (operands[2])"
18059 [(set (match_dup 3) (match_dup 1))
18060 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18061 (clobber (reg:CC FLAGS_REG))])])
18064 [(match_scratch:SI 3 "r")
18065 (parallel [(set (match_operand:DI 0 "register_operand")
18067 (mult:SI (match_operand:SI 1 "memory_operand")
18068 (match_operand:SI 2 "immediate_operand"))))
18069 (clobber (reg:CC FLAGS_REG))])]
18071 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18072 && !satisfies_constraint_K (operands[2])"
18073 [(set (match_dup 3) (match_dup 1))
18074 (parallel [(set (match_dup 0)
18075 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18076 (clobber (reg:CC FLAGS_REG))])])
18078 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18079 ;; Convert it into imul reg, reg
18080 ;; It would be better to force assembler to encode instruction using long
18081 ;; immediate, but there is apparently no way to do so.
18083 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18085 (match_operand:SWI248 1 "nonimmediate_operand")
18086 (match_operand:SWI248 2 "const_int_operand")))
18087 (clobber (reg:CC FLAGS_REG))])
18088 (match_scratch:SWI248 3 "r")]
18089 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18090 && satisfies_constraint_K (operands[2])"
18091 [(set (match_dup 3) (match_dup 2))
18092 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18093 (clobber (reg:CC FLAGS_REG))])]
18095 if (!rtx_equal_p (operands[0], operands[1]))
18096 emit_move_insn (operands[0], operands[1]);
18099 ;; After splitting up read-modify operations, array accesses with memory
18100 ;; operands might end up in form:
18102 ;; movl 4(%esp), %edx
18104 ;; instead of pre-splitting:
18106 ;; addl 4(%esp), %eax
18108 ;; movl 4(%esp), %edx
18109 ;; leal (%edx,%eax,4), %eax
18112 [(match_scratch:W 5 "r")
18113 (parallel [(set (match_operand 0 "register_operand")
18114 (ashift (match_operand 1 "register_operand")
18115 (match_operand 2 "const_int_operand")))
18116 (clobber (reg:CC FLAGS_REG))])
18117 (parallel [(set (match_operand 3 "register_operand")
18118 (plus (match_dup 0)
18119 (match_operand 4 "x86_64_general_operand")))
18120 (clobber (reg:CC FLAGS_REG))])]
18121 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18122 /* Validate MODE for lea. */
18123 && ((!TARGET_PARTIAL_REG_STALL
18124 && (GET_MODE (operands[0]) == QImode
18125 || GET_MODE (operands[0]) == HImode))
18126 || GET_MODE (operands[0]) == SImode
18127 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18128 && (rtx_equal_p (operands[0], operands[3])
18129 || peep2_reg_dead_p (2, operands[0]))
18130 /* We reorder load and the shift. */
18131 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18132 [(set (match_dup 5) (match_dup 4))
18133 (set (match_dup 0) (match_dup 1))]
18135 machine_mode op1mode = GET_MODE (operands[1]);
18136 machine_mode mode = op1mode == DImode ? DImode : SImode;
18137 int scale = 1 << INTVAL (operands[2]);
18138 rtx index = gen_lowpart (word_mode, operands[1]);
18139 rtx base = gen_lowpart (word_mode, operands[5]);
18140 rtx dest = gen_lowpart (mode, operands[3]);
18142 operands[1] = gen_rtx_PLUS (word_mode, base,
18143 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18144 if (mode != word_mode)
18145 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18147 operands[5] = base;
18148 if (op1mode != word_mode)
18149 operands[5] = gen_lowpart (op1mode, operands[5]);
18151 operands[0] = dest;
18154 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18155 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18156 ;; caught for use by garbage collectors and the like. Using an insn that
18157 ;; maps to SIGILL makes it more likely the program will rightfully die.
18158 ;; Keeping with tradition, "6" is in honor of #UD.
18159 (define_insn "trap"
18160 [(trap_if (const_int 1) (const_int 6))]
18163 #ifdef HAVE_AS_IX86_UD2
18166 return ASM_SHORT "0x0b0f";
18169 [(set_attr "length" "2")])
18171 (define_expand "prefetch"
18172 [(prefetch (match_operand 0 "address_operand")
18173 (match_operand:SI 1 "const_int_operand")
18174 (match_operand:SI 2 "const_int_operand"))]
18175 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18177 bool write = INTVAL (operands[1]) != 0;
18178 int locality = INTVAL (operands[2]);
18180 gcc_assert (IN_RANGE (locality, 0, 3));
18182 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18183 supported by SSE counterpart or the SSE prefetch is not available
18184 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18186 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18187 operands[2] = const2_rtx;
18188 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18189 operands[2] = GEN_INT (3);
18191 operands[1] = const0_rtx;
18194 (define_insn "*prefetch_sse"
18195 [(prefetch (match_operand 0 "address_operand" "p")
18197 (match_operand:SI 1 "const_int_operand"))]
18198 "TARGET_PREFETCH_SSE"
18200 static const char * const patterns[4] = {
18201 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18204 int locality = INTVAL (operands[1]);
18205 gcc_assert (IN_RANGE (locality, 0, 3));
18207 return patterns[locality];
18209 [(set_attr "type" "sse")
18210 (set_attr "atom_sse_attr" "prefetch")
18211 (set (attr "length_address")
18212 (symbol_ref "memory_address_length (operands[0], false)"))
18213 (set_attr "memory" "none")])
18215 (define_insn "*prefetch_3dnow"
18216 [(prefetch (match_operand 0 "address_operand" "p")
18217 (match_operand:SI 1 "const_int_operand" "n")
18221 if (INTVAL (operands[1]) == 0)
18222 return "prefetch\t%a0";
18224 return "prefetchw\t%a0";
18226 [(set_attr "type" "mmx")
18227 (set (attr "length_address")
18228 (symbol_ref "memory_address_length (operands[0], false)"))
18229 (set_attr "memory" "none")])
18231 (define_insn "*prefetch_prefetchwt1"
18232 [(prefetch (match_operand 0 "address_operand" "p")
18235 "TARGET_PREFETCHWT1"
18236 "prefetchwt1\t%a0";
18237 [(set_attr "type" "sse")
18238 (set (attr "length_address")
18239 (symbol_ref "memory_address_length (operands[0], false)"))
18240 (set_attr "memory" "none")])
18242 (define_expand "stack_protect_set"
18243 [(match_operand 0 "memory_operand")
18244 (match_operand 1 "memory_operand")]
18245 "TARGET_SSP_TLS_GUARD"
18247 rtx (*insn)(rtx, rtx);
18249 #ifdef TARGET_THREAD_SSP_OFFSET
18250 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18251 insn = (TARGET_LP64
18252 ? gen_stack_tls_protect_set_di
18253 : gen_stack_tls_protect_set_si);
18255 insn = (TARGET_LP64
18256 ? gen_stack_protect_set_di
18257 : gen_stack_protect_set_si);
18260 emit_insn (insn (operands[0], operands[1]));
18264 (define_insn "stack_protect_set_<mode>"
18265 [(set (match_operand:PTR 0 "memory_operand" "=m")
18266 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18268 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18269 (clobber (reg:CC FLAGS_REG))]
18270 "TARGET_SSP_TLS_GUARD"
18271 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18272 [(set_attr "type" "multi")])
18274 (define_insn "stack_tls_protect_set_<mode>"
18275 [(set (match_operand:PTR 0 "memory_operand" "=m")
18276 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18277 UNSPEC_SP_TLS_SET))
18278 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18279 (clobber (reg:CC FLAGS_REG))]
18281 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18282 [(set_attr "type" "multi")])
18284 (define_expand "stack_protect_test"
18285 [(match_operand 0 "memory_operand")
18286 (match_operand 1 "memory_operand")
18288 "TARGET_SSP_TLS_GUARD"
18290 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18292 rtx (*insn)(rtx, rtx, rtx);
18294 #ifdef TARGET_THREAD_SSP_OFFSET
18295 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18296 insn = (TARGET_LP64
18297 ? gen_stack_tls_protect_test_di
18298 : gen_stack_tls_protect_test_si);
18300 insn = (TARGET_LP64
18301 ? gen_stack_protect_test_di
18302 : gen_stack_protect_test_si);
18305 emit_insn (insn (flags, operands[0], operands[1]));
18307 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18308 flags, const0_rtx, operands[2]));
18312 (define_insn "stack_protect_test_<mode>"
18313 [(set (match_operand:CCZ 0 "flags_reg_operand")
18314 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18315 (match_operand:PTR 2 "memory_operand" "m")]
18317 (clobber (match_scratch:PTR 3 "=&r"))]
18318 "TARGET_SSP_TLS_GUARD"
18319 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18320 [(set_attr "type" "multi")])
18322 (define_insn "stack_tls_protect_test_<mode>"
18323 [(set (match_operand:CCZ 0 "flags_reg_operand")
18324 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18325 (match_operand:PTR 2 "const_int_operand" "i")]
18326 UNSPEC_SP_TLS_TEST))
18327 (clobber (match_scratch:PTR 3 "=r"))]
18329 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18330 [(set_attr "type" "multi")])
18332 (define_insn "sse4_2_crc32<mode>"
18333 [(set (match_operand:SI 0 "register_operand" "=r")
18335 [(match_operand:SI 1 "register_operand" "0")
18336 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18338 "TARGET_SSE4_2 || TARGET_CRC32"
18339 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18340 [(set_attr "type" "sselog1")
18341 (set_attr "prefix_rep" "1")
18342 (set_attr "prefix_extra" "1")
18343 (set (attr "prefix_data16")
18344 (if_then_else (match_operand:HI 2)
18346 (const_string "*")))
18347 (set (attr "prefix_rex")
18348 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18350 (const_string "*")))
18351 (set_attr "mode" "SI")])
18353 (define_insn "sse4_2_crc32di"
18354 [(set (match_operand:DI 0 "register_operand" "=r")
18356 [(match_operand:DI 1 "register_operand" "0")
18357 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18359 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18360 "crc32{q}\t{%2, %0|%0, %2}"
18361 [(set_attr "type" "sselog1")
18362 (set_attr "prefix_rep" "1")
18363 (set_attr "prefix_extra" "1")
18364 (set_attr "mode" "DI")])
18366 (define_insn "rdpmc"
18367 [(set (match_operand:DI 0 "register_operand" "=A")
18368 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18372 [(set_attr "type" "other")
18373 (set_attr "length" "2")])
18375 (define_insn "rdpmc_rex64"
18376 [(set (match_operand:DI 0 "register_operand" "=a")
18377 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18379 (set (match_operand:DI 1 "register_operand" "=d")
18380 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18383 [(set_attr "type" "other")
18384 (set_attr "length" "2")])
18386 (define_insn "rdtsc"
18387 [(set (match_operand:DI 0 "register_operand" "=A")
18388 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18391 [(set_attr "type" "other")
18392 (set_attr "length" "2")])
18394 (define_insn "rdtsc_rex64"
18395 [(set (match_operand:DI 0 "register_operand" "=a")
18396 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18397 (set (match_operand:DI 1 "register_operand" "=d")
18398 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18401 [(set_attr "type" "other")
18402 (set_attr "length" "2")])
18404 (define_insn "rdtscp"
18405 [(set (match_operand:DI 0 "register_operand" "=A")
18406 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18407 (set (match_operand:SI 1 "register_operand" "=c")
18408 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18411 [(set_attr "type" "other")
18412 (set_attr "length" "3")])
18414 (define_insn "rdtscp_rex64"
18415 [(set (match_operand:DI 0 "register_operand" "=a")
18416 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18417 (set (match_operand:DI 1 "register_operand" "=d")
18418 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18419 (set (match_operand:SI 2 "register_operand" "=c")
18420 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18423 [(set_attr "type" "other")
18424 (set_attr "length" "3")])
18426 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18428 ;; FXSR, XSAVE and XSAVEOPT instructions
18430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18432 (define_insn "fxsave"
18433 [(set (match_operand:BLK 0 "memory_operand" "=m")
18434 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18437 [(set_attr "type" "other")
18438 (set_attr "memory" "store")
18439 (set (attr "length")
18440 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18442 (define_insn "fxsave64"
18443 [(set (match_operand:BLK 0 "memory_operand" "=m")
18444 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18445 "TARGET_64BIT && TARGET_FXSR"
18447 [(set_attr "type" "other")
18448 (set_attr "memory" "store")
18449 (set (attr "length")
18450 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18452 (define_insn "fxrstor"
18453 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18457 [(set_attr "type" "other")
18458 (set_attr "memory" "load")
18459 (set (attr "length")
18460 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18462 (define_insn "fxrstor64"
18463 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18464 UNSPECV_FXRSTOR64)]
18465 "TARGET_64BIT && TARGET_FXSR"
18467 [(set_attr "type" "other")
18468 (set_attr "memory" "load")
18469 (set (attr "length")
18470 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18472 (define_int_iterator ANY_XSAVE
18474 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18475 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18476 (UNSPECV_XSAVES "TARGET_XSAVES")])
18478 (define_int_iterator ANY_XSAVE64
18480 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18481 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18482 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18484 (define_int_attr xsave
18485 [(UNSPECV_XSAVE "xsave")
18486 (UNSPECV_XSAVE64 "xsave64")
18487 (UNSPECV_XSAVEOPT "xsaveopt")
18488 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18489 (UNSPECV_XSAVEC "xsavec")
18490 (UNSPECV_XSAVEC64 "xsavec64")
18491 (UNSPECV_XSAVES "xsaves")
18492 (UNSPECV_XSAVES64 "xsaves64")])
18494 (define_int_iterator ANY_XRSTOR
18496 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18498 (define_int_iterator ANY_XRSTOR64
18500 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18502 (define_int_attr xrstor
18503 [(UNSPECV_XRSTOR "xrstor")
18504 (UNSPECV_XRSTOR64 "xrstor")
18505 (UNSPECV_XRSTORS "xrstors")
18506 (UNSPECV_XRSTORS64 "xrstors")])
18508 (define_insn "<xsave>"
18509 [(set (match_operand:BLK 0 "memory_operand" "=m")
18510 (unspec_volatile:BLK
18511 [(match_operand:DI 1 "register_operand" "A")]
18513 "!TARGET_64BIT && TARGET_XSAVE"
18515 [(set_attr "type" "other")
18516 (set_attr "memory" "store")
18517 (set (attr "length")
18518 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18520 (define_insn "<xsave>_rex64"
18521 [(set (match_operand:BLK 0 "memory_operand" "=m")
18522 (unspec_volatile:BLK
18523 [(match_operand:SI 1 "register_operand" "a")
18524 (match_operand:SI 2 "register_operand" "d")]
18526 "TARGET_64BIT && TARGET_XSAVE"
18528 [(set_attr "type" "other")
18529 (set_attr "memory" "store")
18530 (set (attr "length")
18531 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18533 (define_insn "<xsave>"
18534 [(set (match_operand:BLK 0 "memory_operand" "=m")
18535 (unspec_volatile:BLK
18536 [(match_operand:SI 1 "register_operand" "a")
18537 (match_operand:SI 2 "register_operand" "d")]
18539 "TARGET_64BIT && TARGET_XSAVE"
18541 [(set_attr "type" "other")
18542 (set_attr "memory" "store")
18543 (set (attr "length")
18544 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18546 (define_insn "<xrstor>"
18547 [(unspec_volatile:BLK
18548 [(match_operand:BLK 0 "memory_operand" "m")
18549 (match_operand:DI 1 "register_operand" "A")]
18551 "!TARGET_64BIT && TARGET_XSAVE"
18553 [(set_attr "type" "other")
18554 (set_attr "memory" "load")
18555 (set (attr "length")
18556 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18558 (define_insn "<xrstor>_rex64"
18559 [(unspec_volatile:BLK
18560 [(match_operand:BLK 0 "memory_operand" "m")
18561 (match_operand:SI 1 "register_operand" "a")
18562 (match_operand:SI 2 "register_operand" "d")]
18564 "TARGET_64BIT && TARGET_XSAVE"
18566 [(set_attr "type" "other")
18567 (set_attr "memory" "load")
18568 (set (attr "length")
18569 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18571 (define_insn "<xrstor>64"
18572 [(unspec_volatile:BLK
18573 [(match_operand:BLK 0 "memory_operand" "m")
18574 (match_operand:SI 1 "register_operand" "a")
18575 (match_operand:SI 2 "register_operand" "d")]
18577 "TARGET_64BIT && TARGET_XSAVE"
18579 [(set_attr "type" "other")
18580 (set_attr "memory" "load")
18581 (set (attr "length")
18582 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18584 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18586 ;; Floating-point instructions for atomic compound assignments
18588 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18590 ; Clobber all floating-point registers on environment save and restore
18591 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18592 (define_insn "fnstenv"
18593 [(set (match_operand:BLK 0 "memory_operand" "=m")
18594 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18595 (clobber (reg:HI FPCR_REG))
18596 (clobber (reg:XF ST0_REG))
18597 (clobber (reg:XF ST1_REG))
18598 (clobber (reg:XF ST2_REG))
18599 (clobber (reg:XF ST3_REG))
18600 (clobber (reg:XF ST4_REG))
18601 (clobber (reg:XF ST5_REG))
18602 (clobber (reg:XF ST6_REG))
18603 (clobber (reg:XF ST7_REG))]
18606 [(set_attr "type" "other")
18607 (set_attr "memory" "store")
18608 (set (attr "length")
18609 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18611 (define_insn "fldenv"
18612 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18614 (clobber (reg:CCFP FPSR_REG))
18615 (clobber (reg:HI FPCR_REG))
18616 (clobber (reg:XF ST0_REG))
18617 (clobber (reg:XF ST1_REG))
18618 (clobber (reg:XF ST2_REG))
18619 (clobber (reg:XF ST3_REG))
18620 (clobber (reg:XF ST4_REG))
18621 (clobber (reg:XF ST5_REG))
18622 (clobber (reg:XF ST6_REG))
18623 (clobber (reg:XF ST7_REG))]
18626 [(set_attr "type" "other")
18627 (set_attr "memory" "load")
18628 (set (attr "length")
18629 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18631 (define_insn "fnstsw"
18632 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18633 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18636 [(set_attr "type" "other,other")
18637 (set_attr "memory" "none,store")
18638 (set (attr "length")
18639 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18641 (define_insn "fnclex"
18642 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18645 [(set_attr "type" "other")
18646 (set_attr "memory" "none")
18647 (set_attr "length" "2")])
18649 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18651 ;; LWP instructions
18653 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18655 (define_expand "lwp_llwpcb"
18656 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18657 UNSPECV_LLWP_INTRINSIC)]
18660 (define_insn "*lwp_llwpcb<mode>1"
18661 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18662 UNSPECV_LLWP_INTRINSIC)]
18665 [(set_attr "type" "lwp")
18666 (set_attr "mode" "<MODE>")
18667 (set_attr "length" "5")])
18669 (define_expand "lwp_slwpcb"
18670 [(set (match_operand 0 "register_operand" "=r")
18671 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18676 insn = (Pmode == DImode
18678 : gen_lwp_slwpcbsi);
18680 emit_insn (insn (operands[0]));
18684 (define_insn "lwp_slwpcb<mode>"
18685 [(set (match_operand:P 0 "register_operand" "=r")
18686 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18689 [(set_attr "type" "lwp")
18690 (set_attr "mode" "<MODE>")
18691 (set_attr "length" "5")])
18693 (define_expand "lwp_lwpval<mode>3"
18694 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18695 (match_operand:SI 2 "nonimmediate_operand" "rm")
18696 (match_operand:SI 3 "const_int_operand" "i")]
18697 UNSPECV_LWPVAL_INTRINSIC)]
18699 ;; Avoid unused variable warning.
18700 "(void) operands[0];")
18702 (define_insn "*lwp_lwpval<mode>3_1"
18703 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18704 (match_operand:SI 1 "nonimmediate_operand" "rm")
18705 (match_operand:SI 2 "const_int_operand" "i")]
18706 UNSPECV_LWPVAL_INTRINSIC)]
18708 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18709 [(set_attr "type" "lwp")
18710 (set_attr "mode" "<MODE>")
18711 (set (attr "length")
18712 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18714 (define_expand "lwp_lwpins<mode>3"
18715 [(set (reg:CCC FLAGS_REG)
18716 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18717 (match_operand:SI 2 "nonimmediate_operand" "rm")
18718 (match_operand:SI 3 "const_int_operand" "i")]
18719 UNSPECV_LWPINS_INTRINSIC))
18720 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18721 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18724 (define_insn "*lwp_lwpins<mode>3_1"
18725 [(set (reg:CCC FLAGS_REG)
18726 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18727 (match_operand:SI 1 "nonimmediate_operand" "rm")
18728 (match_operand:SI 2 "const_int_operand" "i")]
18729 UNSPECV_LWPINS_INTRINSIC))]
18731 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18732 [(set_attr "type" "lwp")
18733 (set_attr "mode" "<MODE>")
18734 (set (attr "length")
18735 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18737 (define_int_iterator RDFSGSBASE
18741 (define_int_iterator WRFSGSBASE
18745 (define_int_attr fsgs
18746 [(UNSPECV_RDFSBASE "fs")
18747 (UNSPECV_RDGSBASE "gs")
18748 (UNSPECV_WRFSBASE "fs")
18749 (UNSPECV_WRGSBASE "gs")])
18751 (define_insn "rd<fsgs>base<mode>"
18752 [(set (match_operand:SWI48 0 "register_operand" "=r")
18753 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18754 "TARGET_64BIT && TARGET_FSGSBASE"
18756 [(set_attr "type" "other")
18757 (set_attr "prefix_extra" "2")])
18759 (define_insn "wr<fsgs>base<mode>"
18760 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18762 "TARGET_64BIT && TARGET_FSGSBASE"
18764 [(set_attr "type" "other")
18765 (set_attr "prefix_extra" "2")])
18767 (define_insn "rdrand<mode>_1"
18768 [(set (match_operand:SWI248 0 "register_operand" "=r")
18769 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18770 (set (reg:CCC FLAGS_REG)
18771 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18774 [(set_attr "type" "other")
18775 (set_attr "prefix_extra" "1")])
18777 (define_insn "rdseed<mode>_1"
18778 [(set (match_operand:SWI248 0 "register_operand" "=r")
18779 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18780 (set (reg:CCC FLAGS_REG)
18781 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18784 [(set_attr "type" "other")
18785 (set_attr "prefix_extra" "1")])
18787 (define_expand "pause"
18788 [(set (match_dup 0)
18789 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18792 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18793 MEM_VOLATILE_P (operands[0]) = 1;
18796 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18797 ;; They have the same encoding.
18798 (define_insn "*pause"
18799 [(set (match_operand:BLK 0)
18800 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18803 [(set_attr "length" "2")
18804 (set_attr "memory" "unknown")])
18806 (define_expand "xbegin"
18807 [(set (match_operand:SI 0 "register_operand")
18808 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18811 rtx_code_label *label = gen_label_rtx ();
18813 /* xbegin is emitted as jump_insn, so reload won't be able
18814 to reload its operand. Force the value into AX hard register. */
18815 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18816 emit_move_insn (ax_reg, constm1_rtx);
18818 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18820 emit_label (label);
18821 LABEL_NUSES (label) = 1;
18823 emit_move_insn (operands[0], ax_reg);
18828 (define_insn "xbegin_1"
18830 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18832 (label_ref (match_operand 1))
18834 (set (match_operand:SI 0 "register_operand" "+a")
18835 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18838 [(set_attr "type" "other")
18839 (set_attr "length" "6")])
18841 (define_insn "xend"
18842 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18845 [(set_attr "type" "other")
18846 (set_attr "length" "3")])
18848 (define_insn "xabort"
18849 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18853 [(set_attr "type" "other")
18854 (set_attr "length" "3")])
18856 (define_expand "xtest"
18857 [(set (match_operand:QI 0 "register_operand")
18858 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18861 emit_insn (gen_xtest_1 ());
18863 ix86_expand_setcc (operands[0], NE,
18864 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18868 (define_insn "xtest_1"
18869 [(set (reg:CCZ FLAGS_REG)
18870 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18873 [(set_attr "type" "other")
18874 (set_attr "length" "3")])
18876 (define_insn "pcommit"
18877 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18880 [(set_attr "type" "other")
18881 (set_attr "length" "4")])
18883 (define_insn "clwb"
18884 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18888 [(set_attr "type" "sse")
18889 (set_attr "atom_sse_attr" "fence")
18890 (set_attr "memory" "unknown")])
18892 (define_insn "clflushopt"
18893 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18894 UNSPECV_CLFLUSHOPT)]
18895 "TARGET_CLFLUSHOPT"
18897 [(set_attr "type" "sse")
18898 (set_attr "atom_sse_attr" "fence")
18899 (set_attr "memory" "unknown")])
18901 ;; MONITORX and MWAITX
18902 (define_insn "mwaitx"
18903 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18904 (match_operand:SI 1 "register_operand" "a")
18905 (match_operand:SI 2 "register_operand" "b")]
18908 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18909 ;; Since 32bit register operands are implicitly zero extended to 64bit,
18910 ;; we only need to set up 32bit registers.
18912 [(set_attr "length" "3")])
18914 (define_insn "monitorx_<mode>"
18915 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18916 (match_operand:SI 1 "register_operand" "c")
18917 (match_operand:SI 2 "register_operand" "d")]
18920 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18921 ;; RCX and RDX are used. Since 32bit register operands are implicitly
18922 ;; zero extended to 64bit, we only need to set up 32bit registers.
18924 [(set (attr "length")
18925 (symbol_ref ("(Pmode != word_mode) + 3")))])
18927 ;; MPX instructions
18929 (define_expand "<mode>_mk"
18930 [(set (match_operand:BND 0 "register_operand")
18934 [(match_operand:<bnd_ptr> 1 "register_operand")
18935 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18939 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18941 UNSPEC_BNDMK_ADDR);
18944 (define_insn "*<mode>_mk"
18945 [(set (match_operand:BND 0 "register_operand" "=w")
18947 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18949 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18950 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18951 UNSPEC_BNDMK_ADDR)])]
18954 "bndmk\t{%3, %0|%0, %3}"
18955 [(set_attr "type" "mpxmk")])
18957 (define_expand "mov<mode>"
18958 [(set (match_operand:BND 0 "general_operand")
18959 (match_operand:BND 1 "general_operand"))]
18962 ix86_expand_move (<MODE>mode, operands);DONE;
18965 (define_insn "*mov<mode>_internal_mpx"
18966 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18967 (match_operand:BND 1 "general_operand" "wm,w"))]
18969 "bndmov\t{%1, %0|%0, %1}"
18970 [(set_attr "type" "mpxmov")])
18972 (define_expand "<mode>_<bndcheck>"
18973 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18974 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18976 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18979 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18980 MEM_VOLATILE_P (operands[2]) = 1;
18983 (define_insn "*<mode>_<bndcheck>"
18984 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18985 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18986 (set (match_operand:BLK 2 "bnd_mem_operator")
18987 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18989 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18990 [(set_attr "type" "mpxchk")])
18992 (define_expand "<mode>_ldx"
18993 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18997 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18998 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19000 (use (mem:BLK (match_dup 1)))])]
19003 /* Avoid registers which connot be used as index. */
19004 if (!index_register_operand (operands[2], Pmode))
19006 rtx temp = gen_reg_rtx (Pmode);
19007 emit_move_insn (temp, operands[2]);
19008 operands[2] = temp;
19011 /* If it was a register originally then it may have
19012 mode other than Pmode. We need to extend in such
19013 case because bndldx may work only with Pmode regs. */
19014 if (GET_MODE (operands[2]) != Pmode)
19015 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
19017 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19019 UNSPEC_BNDLDX_ADDR);
19022 (define_insn "*<mode>_ldx"
19023 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
19025 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19027 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19028 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19029 UNSPEC_BNDLDX_ADDR)])]
19031 (use (mem:BLK (match_dup 1)))])]
19033 "bndldx\t{%3, %0|%0, %3}"
19034 [(set_attr "type" "mpxld")])
19036 (define_expand "<mode>_stx"
19037 [(parallel [(unspec [(mem:<bnd_ptr>
19039 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19040 (match_operand:<bnd_ptr> 1 "register_operand")]))
19041 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
19043 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19046 /* Avoid registers which connot be used as index. */
19047 if (!index_register_operand (operands[1], Pmode))
19049 rtx temp = gen_reg_rtx (Pmode);
19050 emit_move_insn (temp, operands[1]);
19051 operands[1] = temp;
19054 /* If it was a register originally then it may have
19055 mode other than Pmode. We need to extend in such
19056 case because bndstx may work only with Pmode regs. */
19057 if (GET_MODE (operands[1]) != Pmode)
19058 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
19060 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19062 UNSPEC_BNDLDX_ADDR);
19063 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19064 MEM_VOLATILE_P (operands[4]) = 1;
19067 (define_insn "*<mode>_stx"
19068 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19070 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19071 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19072 UNSPEC_BNDLDX_ADDR)])
19073 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
19074 (set (match_operand:BLK 4 "bnd_mem_operator")
19075 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19077 "bndstx\t{%2, %3|%3, %2}"
19078 [(set_attr "type" "mpxst")])
19080 (define_insn "move_size_reloc_<mode>"
19081 [(set (match_operand:SWI48 0 "register_operand" "=r")
19083 [(match_operand:SWI48 1 "symbol_operand")]
19087 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19088 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19090 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19092 [(set_attr "type" "imov")
19093 (set_attr "mode" "<MODE>")])
19097 (include "sync.md")