1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 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
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
116 ;; For SSE/MMX support:
124 ;; Generic math support
126 UNSPEC_IEEE_MIN ; not commutative
127 UNSPEC_IEEE_MAX ; not commutative
129 ;; x87 Floating point
145 UNSPEC_FRNDINT_MASK_PM
149 ;; x87 Double output FP
183 ;; For AVX512F support
187 (define_c_enum "unspecv" [
190 UNSPECV_PROBE_STACK_RANGE
193 UNSPECV_SPLIT_STACK_RETURN
199 UNSPECV_LLWP_INTRINSIC
200 UNSPECV_SLWP_INTRINSIC
201 UNSPECV_LWPVAL_INTRINSIC
202 UNSPECV_LWPINS_INTRINSIC
224 ;; For atomic compound assignments.
230 ;; For RDRAND support
233 ;; For RDSEED support
244 ;; For CLFLUSHOPT support
248 ;; Constants to represent rounding modes in the ROUND instruction
257 ;; Constants to represent AVX512F embeded rounding
259 [(ROUND_NEAREST_INT 0)
267 ;; Constants to represent pcomtrue/pcomfalse variants
277 ;; Constants used in the XOP pperm instruction
279 [(PPERM_SRC 0x00) /* copy source */
280 (PPERM_INVERT 0x20) /* invert source */
281 (PPERM_REVERSE 0x40) /* bit reverse source */
282 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
283 (PPERM_ZERO 0x80) /* all 0's */
284 (PPERM_ONES 0xa0) /* all 1's */
285 (PPERM_SIGN 0xc0) /* propagate sign bit */
286 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
287 (PPERM_SRC1 0x00) /* use first source byte */
288 (PPERM_SRC2 0x10) /* use second source byte */
291 ;; Registers by name.
370 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
373 ;; In C guard expressions, put expressions which may be compile-time
374 ;; constants first. This allows for better optimization. For
375 ;; example, write "TARGET_64BIT && reload_completed", not
376 ;; "reload_completed && TARGET_64BIT".
380 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
381 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
383 (const (symbol_ref "ix86_schedule")))
385 ;; A basic instruction type. Refinements due to arguments to be
386 ;; provided in other attributes.
389 alu,alu1,negnot,imov,imovx,lea,
390 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
391 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
392 push,pop,call,callv,leave,
394 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
395 fxch,fistp,fisttp,frndint,
396 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
397 ssemul,sseimul,ssediv,sselog,sselog1,
398 sseishft,sseishft1,ssecmp,ssecomi,
399 ssecvt,ssecvt1,sseicvt,sseins,
400 sseshuf,sseshuf1,ssemuladd,sse4arg,
402 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
403 (const_string "other"))
405 ;; Main data type used by the insn
407 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
409 (const_string "unknown"))
411 ;; The CPU unit operations uses.
412 (define_attr "unit" "integer,i387,sse,mmx,unknown"
413 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
414 fxch,fistp,fisttp,frndint")
415 (const_string "i387")
416 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417 ssemul,sseimul,ssediv,sselog,sselog1,
418 sseishft,sseishft1,ssecmp,ssecomi,
419 ssecvt,ssecvt1,sseicvt,sseins,
420 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
422 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
424 (eq_attr "type" "other")
425 (const_string "unknown")]
426 (const_string "integer")))
428 ;; The minimum required alignment of vector mode memory operands of the SSE
429 ;; (non-VEX/EVEX) instruction in bits, if it is different from
430 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
431 ;; multiple alternatives, this should be conservative maximum of those minimum
432 ;; required alignments.
433 (define_attr "ssememalign" "" (const_int 0))
435 ;; The (bounding maximum) length of an instruction immediate.
436 (define_attr "length_immediate" ""
437 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
438 bitmanip,imulx,msklog,mskmov")
440 (eq_attr "unit" "i387,sse,mmx")
442 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
443 rotate,rotatex,rotate1,imul,icmp,push,pop")
444 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
445 (eq_attr "type" "imov,test")
446 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
447 (eq_attr "type" "call")
448 (if_then_else (match_operand 0 "constant_call_address_operand")
451 (eq_attr "type" "callv")
452 (if_then_else (match_operand 1 "constant_call_address_operand")
455 ;; We don't know the size before shorten_branches. Expect
456 ;; the instruction to fit for better scheduling.
457 (eq_attr "type" "ibr")
460 (symbol_ref "/* Update immediate_length and other attributes! */
461 gcc_unreachable (),1")))
463 ;; The (bounding maximum) length of an instruction address.
464 (define_attr "length_address" ""
465 (cond [(eq_attr "type" "str,other,multi,fxch")
467 (and (eq_attr "type" "call")
468 (match_operand 0 "constant_call_address_operand"))
470 (and (eq_attr "type" "callv")
471 (match_operand 1 "constant_call_address_operand"))
474 (symbol_ref "ix86_attr_length_address_default (insn)")))
476 ;; Set when length prefix is used.
477 (define_attr "prefix_data16" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
480 (eq_attr "mode" "HI")
482 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
487 ;; Set when string REP prefix is used.
488 (define_attr "prefix_rep" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
491 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
496 ;; Set when 0f opcode prefix is used.
497 (define_attr "prefix_0f" ""
499 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
500 (eq_attr "unit" "sse,mmx"))
504 ;; Set when REX opcode prefix is used.
505 (define_attr "prefix_rex" ""
506 (cond [(not (match_test "TARGET_64BIT"))
508 (and (eq_attr "mode" "DI")
509 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
510 (eq_attr "unit" "!mmx")))
512 (and (eq_attr "mode" "QI")
513 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
515 (match_test "x86_extended_reg_mentioned_p (insn)")
517 (and (eq_attr "type" "imovx")
518 (match_operand:QI 1 "ext_QIreg_operand"))
523 ;; There are also additional prefixes in 3DNOW, SSSE3.
524 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
525 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
526 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
527 (define_attr "prefix_extra" ""
528 (cond [(eq_attr "type" "ssemuladd,sse4arg")
530 (eq_attr "type" "sseiadd1,ssecvt1")
535 ;; Prefix used: original, VEX or maybe VEX.
536 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
537 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
539 (eq_attr "mode" "XI,V16SF,V8DF")
540 (const_string "evex")
542 (const_string "orig")))
544 ;; VEX W bit is used.
545 (define_attr "prefix_vex_w" "" (const_int 0))
547 ;; The length of VEX prefix
548 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
549 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
550 ;; still prefix_0f 1, with prefix_extra 1.
551 (define_attr "length_vex" ""
552 (if_then_else (and (eq_attr "prefix_0f" "1")
553 (eq_attr "prefix_extra" "0"))
554 (if_then_else (eq_attr "prefix_vex_w" "1")
555 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
556 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
557 (if_then_else (eq_attr "prefix_vex_w" "1")
558 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
559 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
561 ;; 4-bytes evex prefix and 1 byte opcode.
562 (define_attr "length_evex" "" (const_int 5))
564 ;; Set when modrm byte is used.
565 (define_attr "modrm" ""
566 (cond [(eq_attr "type" "str,leave")
568 (eq_attr "unit" "i387")
570 (and (eq_attr "type" "incdec")
571 (and (not (match_test "TARGET_64BIT"))
572 (ior (match_operand:SI 1 "register_operand")
573 (match_operand:HI 1 "register_operand"))))
575 (and (eq_attr "type" "push")
576 (not (match_operand 1 "memory_operand")))
578 (and (eq_attr "type" "pop")
579 (not (match_operand 0 "memory_operand")))
581 (and (eq_attr "type" "imov")
582 (and (not (eq_attr "mode" "DI"))
583 (ior (and (match_operand 0 "register_operand")
584 (match_operand 1 "immediate_operand"))
585 (ior (and (match_operand 0 "ax_reg_operand")
586 (match_operand 1 "memory_displacement_only_operand"))
587 (and (match_operand 0 "memory_displacement_only_operand")
588 (match_operand 1 "ax_reg_operand"))))))
590 (and (eq_attr "type" "call")
591 (match_operand 0 "constant_call_address_operand"))
593 (and (eq_attr "type" "callv")
594 (match_operand 1 "constant_call_address_operand"))
596 (and (eq_attr "type" "alu,alu1,icmp,test")
597 (match_operand 0 "ax_reg_operand"))
598 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
602 ;; The (bounding maximum) length of an instruction in bytes.
603 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
604 ;; Later we may want to split them and compute proper length as for
606 (define_attr "length" ""
607 (cond [(eq_attr "type" "other,multi,fistp,frndint")
609 (eq_attr "type" "fcmp")
611 (eq_attr "unit" "i387")
613 (plus (attr "prefix_data16")
614 (attr "length_address")))
615 (ior (eq_attr "prefix" "evex")
616 (and (ior (eq_attr "prefix" "maybe_evex")
617 (eq_attr "prefix" "maybe_vex"))
618 (match_test "TARGET_AVX512F")))
619 (plus (attr "length_evex")
620 (plus (attr "length_immediate")
622 (attr "length_address"))))
623 (ior (eq_attr "prefix" "vex")
624 (and (ior (eq_attr "prefix" "maybe_vex")
625 (eq_attr "prefix" "maybe_evex"))
626 (match_test "TARGET_AVX")))
627 (plus (attr "length_vex")
628 (plus (attr "length_immediate")
630 (attr "length_address"))))]
631 (plus (plus (attr "modrm")
632 (plus (attr "prefix_0f")
633 (plus (attr "prefix_rex")
634 (plus (attr "prefix_extra")
636 (plus (attr "prefix_rep")
637 (plus (attr "prefix_data16")
638 (plus (attr "length_immediate")
639 (attr "length_address")))))))
641 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
642 ;; `store' if there is a simple memory reference therein, or `unknown'
643 ;; if the instruction is complex.
645 (define_attr "memory" "none,load,store,both,unknown"
646 (cond [(eq_attr "type" "other,multi,str,lwp")
647 (const_string "unknown")
648 (eq_attr "type" "lea,fcmov,fpspc")
649 (const_string "none")
650 (eq_attr "type" "fistp,leave")
651 (const_string "both")
652 (eq_attr "type" "frndint")
653 (const_string "load")
654 (eq_attr "type" "push")
655 (if_then_else (match_operand 1 "memory_operand")
656 (const_string "both")
657 (const_string "store"))
658 (eq_attr "type" "pop")
659 (if_then_else (match_operand 0 "memory_operand")
660 (const_string "both")
661 (const_string "load"))
662 (eq_attr "type" "setcc")
663 (if_then_else (match_operand 0 "memory_operand")
664 (const_string "store")
665 (const_string "none"))
666 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
667 (if_then_else (ior (match_operand 0 "memory_operand")
668 (match_operand 1 "memory_operand"))
669 (const_string "load")
670 (const_string "none"))
671 (eq_attr "type" "ibr")
672 (if_then_else (match_operand 0 "memory_operand")
673 (const_string "load")
674 (const_string "none"))
675 (eq_attr "type" "call")
676 (if_then_else (match_operand 0 "constant_call_address_operand")
677 (const_string "none")
678 (const_string "load"))
679 (eq_attr "type" "callv")
680 (if_then_else (match_operand 1 "constant_call_address_operand")
681 (const_string "none")
682 (const_string "load"))
683 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
684 (match_operand 1 "memory_operand"))
685 (const_string "both")
686 (and (match_operand 0 "memory_operand")
687 (match_operand 1 "memory_operand"))
688 (const_string "both")
689 (match_operand 0 "memory_operand")
690 (const_string "store")
691 (match_operand 1 "memory_operand")
692 (const_string "load")
694 "!alu1,negnot,ishift1,
695 imov,imovx,icmp,test,bitmanip,
697 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
698 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
699 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
700 (match_operand 2 "memory_operand"))
701 (const_string "load")
702 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
703 (match_operand 3 "memory_operand"))
704 (const_string "load")
706 (const_string "none")))
708 ;; Indicates if an instruction has both an immediate and a displacement.
710 (define_attr "imm_disp" "false,true,unknown"
711 (cond [(eq_attr "type" "other,multi")
712 (const_string "unknown")
713 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
714 (and (match_operand 0 "memory_displacement_operand")
715 (match_operand 1 "immediate_operand")))
716 (const_string "true")
717 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
718 (and (match_operand 0 "memory_displacement_operand")
719 (match_operand 2 "immediate_operand")))
720 (const_string "true")
722 (const_string "false")))
724 ;; Indicates if an FP operation has an integer source.
726 (define_attr "fp_int_src" "false,true"
727 (const_string "false"))
729 ;; Defines rounding mode of an FP operation.
731 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
732 (const_string "any"))
734 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
735 (define_attr "use_carry" "0,1" (const_string "0"))
737 ;; Define attribute to indicate unaligned ssemov insns
738 (define_attr "movu" "0,1" (const_string "0"))
740 ;; Used to control the "enabled" attribute on a per-instruction basis.
741 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
742 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
743 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
744 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
745 (const_string "base"))
747 (define_attr "enabled" ""
748 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
749 (eq_attr "isa" "x64_sse4")
750 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
751 (eq_attr "isa" "x64_sse4_noavx")
752 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
753 (eq_attr "isa" "x64_avx")
754 (symbol_ref "TARGET_64BIT && TARGET_AVX")
755 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
756 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
757 (eq_attr "isa" "sse2_noavx")
758 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
759 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
760 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
761 (eq_attr "isa" "sse4_noavx")
762 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
763 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
764 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
765 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
766 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
767 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
768 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
769 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
770 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
771 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
772 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
773 (eq_attr "isa" "fma_avx512f")
774 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
775 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
776 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
777 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
778 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
782 (define_attr "preferred_for_speed" "" (const_int 1))
784 ;; Describe a user's asm statement.
785 (define_asm_attributes
786 [(set_attr "length" "128")
787 (set_attr "type" "multi")])
789 (define_code_iterator plusminus [plus minus])
791 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
793 (define_code_iterator multdiv [mult div])
795 ;; Base name for define_insn
796 (define_code_attr plusminus_insn
797 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
798 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
800 ;; Base name for insn mnemonic.
801 (define_code_attr plusminus_mnemonic
802 [(plus "add") (ss_plus "adds") (us_plus "addus")
803 (minus "sub") (ss_minus "subs") (us_minus "subus")])
804 (define_code_attr plusminus_carry_mnemonic
805 [(plus "adc") (minus "sbb")])
806 (define_code_attr multdiv_mnemonic
807 [(mult "mul") (div "div")])
809 ;; Mark commutative operators as such in constraints.
810 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
811 (minus "") (ss_minus "") (us_minus "")])
813 ;; Mapping of max and min
814 (define_code_iterator maxmin [smax smin umax umin])
816 ;; Mapping of signed max and min
817 (define_code_iterator smaxmin [smax smin])
819 ;; Mapping of unsigned max and min
820 (define_code_iterator umaxmin [umax umin])
822 ;; Base name for integer and FP insn mnemonic
823 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
824 (umax "maxu") (umin "minu")])
825 (define_code_attr maxmin_float [(smax "max") (smin "min")])
827 ;; Mapping of logic operators
828 (define_code_iterator any_logic [and ior xor])
829 (define_code_iterator any_or [ior xor])
830 (define_code_iterator fpint_logic [and xor])
832 ;; Base name for insn mnemonic.
833 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
835 ;; Mapping of logic-shift operators
836 (define_code_iterator any_lshift [ashift lshiftrt])
838 ;; Mapping of shift-right operators
839 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
841 ;; Mapping of all shift operators
842 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
844 ;; Base name for define_insn
845 (define_code_attr shift_insn
846 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
848 ;; Base name for insn mnemonic.
849 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
850 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
852 ;; Mapping of rotate operators
853 (define_code_iterator any_rotate [rotate rotatert])
855 ;; Base name for define_insn
856 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
858 ;; Base name for insn mnemonic.
859 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
861 ;; Mapping of abs neg operators
862 (define_code_iterator absneg [abs neg])
864 ;; Base name for x87 insn mnemonic.
865 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
867 ;; Used in signed and unsigned widening multiplications.
868 (define_code_iterator any_extend [sign_extend zero_extend])
870 ;; Prefix for insn menmonic.
871 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
873 ;; Prefix for define_insn
874 (define_code_attr u [(sign_extend "") (zero_extend "u")])
875 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
876 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
878 ;; Used in signed and unsigned truncations.
879 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
880 ;; Instruction suffix for truncations.
881 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
883 ;; Used in signed and unsigned fix.
884 (define_code_iterator any_fix [fix unsigned_fix])
885 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
887 ;; Used in signed and unsigned float.
888 (define_code_iterator any_float [float unsigned_float])
889 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
891 ;; All integer modes.
892 (define_mode_iterator SWI1248x [QI HI SI DI])
894 ;; All integer modes with AVX512BW.
895 (define_mode_iterator SWI1248_AVX512BW
896 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
898 ;; All integer modes without QImode.
899 (define_mode_iterator SWI248x [HI SI DI])
901 ;; All integer modes without QImode and HImode.
902 (define_mode_iterator SWI48x [SI DI])
904 ;; All integer modes without SImode and DImode.
905 (define_mode_iterator SWI12 [QI HI])
907 ;; All integer modes without DImode.
908 (define_mode_iterator SWI124 [QI HI SI])
910 ;; All integer modes without QImode and DImode.
911 (define_mode_iterator SWI24 [HI SI])
913 ;; Single word integer modes.
914 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
916 ;; Single word integer modes without QImode.
917 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
919 ;; Single word integer modes without QImode and HImode.
920 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
922 ;; All math-dependant single and double word integer modes.
923 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
924 (HI "TARGET_HIMODE_MATH")
925 SI DI (TI "TARGET_64BIT")])
927 ;; Math-dependant single word integer modes.
928 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
929 (HI "TARGET_HIMODE_MATH")
930 SI (DI "TARGET_64BIT")])
932 ;; Math-dependant integer modes without DImode.
933 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
934 (HI "TARGET_HIMODE_MATH")
937 ;; Math-dependant single word integer modes without QImode.
938 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
939 SI (DI "TARGET_64BIT")])
941 ;; Double word integer modes.
942 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
943 (TI "TARGET_64BIT")])
945 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
946 ;; compile time constant, it is faster to use <MODE_SIZE> than
947 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
948 ;; command line options just use GET_MODE_SIZE macro.
949 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
950 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
951 (V16QI "16") (V32QI "32") (V64QI "64")
952 (V8HI "16") (V16HI "32") (V32HI "64")
953 (V4SI "16") (V8SI "32") (V16SI "64")
954 (V2DI "16") (V4DI "32") (V8DI "64")
955 (V1TI "16") (V2TI "32") (V4TI "64")
956 (V2DF "16") (V4DF "32") (V8DF "64")
957 (V4SF "16") (V8SF "32") (V16SF "64")])
959 ;; Double word integer modes as mode attribute.
960 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
961 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
963 ;; Half mode for double word integer modes.
964 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
965 (DI "TARGET_64BIT")])
967 ;; Instruction suffix for integer modes.
968 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
970 ;; Instruction suffix for masks.
971 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
973 ;; Pointer size prefix for integer modes (Intel asm dialect)
974 (define_mode_attr iptrsize [(QI "BYTE")
979 ;; Register class for integer modes.
980 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
982 ;; Immediate operand constraint for integer modes.
983 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
985 ;; General operand constraint for word modes.
986 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
988 ;; Immediate operand constraint for double integer modes.
989 (define_mode_attr di [(SI "nF") (DI "e")])
991 ;; Immediate operand constraint for shifts.
992 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
994 ;; General operand predicate for integer modes.
995 (define_mode_attr general_operand
996 [(QI "general_operand")
997 (HI "general_operand")
998 (SI "x86_64_general_operand")
999 (DI "x86_64_general_operand")
1000 (TI "x86_64_general_operand")])
1002 ;; General sign extend operand predicate for integer modes,
1003 ;; which disallows VOIDmode operands and thus it is suitable
1004 ;; for use inside sign_extend.
1005 (define_mode_attr general_sext_operand
1006 [(QI "sext_operand")
1008 (SI "x86_64_sext_operand")
1009 (DI "x86_64_sext_operand")])
1011 ;; General sign/zero extend operand predicate for integer modes.
1012 (define_mode_attr general_szext_operand
1013 [(QI "general_operand")
1014 (HI "general_operand")
1015 (SI "x86_64_szext_general_operand")
1016 (DI "x86_64_szext_general_operand")])
1018 ;; Immediate operand predicate for integer modes.
1019 (define_mode_attr immediate_operand
1020 [(QI "immediate_operand")
1021 (HI "immediate_operand")
1022 (SI "x86_64_immediate_operand")
1023 (DI "x86_64_immediate_operand")])
1025 ;; Nonmemory operand predicate for integer modes.
1026 (define_mode_attr nonmemory_operand
1027 [(QI "nonmemory_operand")
1028 (HI "nonmemory_operand")
1029 (SI "x86_64_nonmemory_operand")
1030 (DI "x86_64_nonmemory_operand")])
1032 ;; Operand predicate for shifts.
1033 (define_mode_attr shift_operand
1034 [(QI "nonimmediate_operand")
1035 (HI "nonimmediate_operand")
1036 (SI "nonimmediate_operand")
1037 (DI "shiftdi_operand")
1038 (TI "register_operand")])
1040 ;; Operand predicate for shift argument.
1041 (define_mode_attr shift_immediate_operand
1042 [(QI "const_1_to_31_operand")
1043 (HI "const_1_to_31_operand")
1044 (SI "const_1_to_31_operand")
1045 (DI "const_1_to_63_operand")])
1047 ;; Input operand predicate for arithmetic left shifts.
1048 (define_mode_attr ashl_input_operand
1049 [(QI "nonimmediate_operand")
1050 (HI "nonimmediate_operand")
1051 (SI "nonimmediate_operand")
1052 (DI "ashldi_input_operand")
1053 (TI "reg_or_pm1_operand")])
1055 ;; SSE and x87 SFmode and DFmode floating point modes
1056 (define_mode_iterator MODEF [SF DF])
1058 ;; All x87 floating point modes
1059 (define_mode_iterator X87MODEF [SF DF XF])
1061 ;; SSE instruction suffix for various modes
1062 (define_mode_attr ssemodesuffix
1063 [(SF "ss") (DF "sd")
1064 (V16SF "ps") (V8DF "pd")
1065 (V8SF "ps") (V4DF "pd")
1066 (V4SF "ps") (V2DF "pd")
1067 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1068 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1069 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1071 ;; SSE vector suffix for floating point modes
1072 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1074 ;; SSE vector mode corresponding to a scalar mode
1075 (define_mode_attr ssevecmode
1076 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1077 (define_mode_attr ssevecmodelower
1078 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1080 ;; Instruction suffix for REX 64bit operators.
1081 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1083 ;; This mode iterator allows :P to be used for patterns that operate on
1084 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1085 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1087 ;; This mode iterator allows :W to be used for patterns that operate on
1088 ;; word_mode sized quantities.
1089 (define_mode_iterator W
1090 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1092 ;; This mode iterator allows :PTR to be used for patterns that operate on
1093 ;; ptr_mode sized quantities.
1094 (define_mode_iterator PTR
1095 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1097 ;; Scheduling descriptions
1099 (include "pentium.md")
1102 (include "athlon.md")
1103 (include "bdver1.md")
1104 (include "bdver3.md")
1105 (include "btver2.md")
1106 (include "geode.md")
1109 (include "core2.md")
1112 ;; Operand and operator predicates and constraints
1114 (include "predicates.md")
1115 (include "constraints.md")
1118 ;; Compare and branch/compare and store instructions.
1120 (define_expand "cbranch<mode>4"
1121 [(set (reg:CC FLAGS_REG)
1122 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1123 (match_operand:SDWIM 2 "<general_operand>")))
1124 (set (pc) (if_then_else
1125 (match_operator 0 "ordered_comparison_operator"
1126 [(reg:CC FLAGS_REG) (const_int 0)])
1127 (label_ref (match_operand 3))
1131 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1132 operands[1] = force_reg (<MODE>mode, operands[1]);
1133 ix86_expand_branch (GET_CODE (operands[0]),
1134 operands[1], operands[2], operands[3]);
1138 (define_expand "cstore<mode>4"
1139 [(set (reg:CC FLAGS_REG)
1140 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1141 (match_operand:SWIM 3 "<general_operand>")))
1142 (set (match_operand:QI 0 "register_operand")
1143 (match_operator 1 "ordered_comparison_operator"
1144 [(reg:CC FLAGS_REG) (const_int 0)]))]
1147 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1148 operands[2] = force_reg (<MODE>mode, operands[2]);
1149 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1150 operands[2], operands[3]);
1154 (define_expand "cmp<mode>_1"
1155 [(set (reg:CC FLAGS_REG)
1156 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1157 (match_operand:SWI48 1 "<general_operand>")))])
1159 (define_insn "*cmp<mode>_ccno_1"
1160 [(set (reg FLAGS_REG)
1161 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1162 (match_operand:SWI 1 "const0_operand")))]
1163 "ix86_match_ccmode (insn, CCNOmode)"
1165 test{<imodesuffix>}\t%0, %0
1166 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1167 [(set_attr "type" "test,icmp")
1168 (set_attr "length_immediate" "0,1")
1169 (set_attr "mode" "<MODE>")])
1171 (define_insn "*cmp<mode>_1"
1172 [(set (reg FLAGS_REG)
1173 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1174 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1175 "ix86_match_ccmode (insn, CCmode)"
1176 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1177 [(set_attr "type" "icmp")
1178 (set_attr "mode" "<MODE>")])
1180 (define_insn "*cmp<mode>_minus_1"
1181 [(set (reg FLAGS_REG)
1183 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1184 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1186 "ix86_match_ccmode (insn, CCGOCmode)"
1187 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1188 [(set_attr "type" "icmp")
1189 (set_attr "mode" "<MODE>")])
1191 (define_insn "*cmpqi_ext_1"
1192 [(set (reg FLAGS_REG)
1194 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1197 (match_operand 1 "ext_register_operand" "Q,Q")
1199 (const_int 8)) 0)))]
1200 "ix86_match_ccmode (insn, CCmode)"
1201 "cmp{b}\t{%h1, %0|%0, %h1}"
1202 [(set_attr "isa" "*,nox64")
1203 (set_attr "type" "icmp")
1204 (set_attr "mode" "QI")])
1206 (define_insn "*cmpqi_ext_2"
1207 [(set (reg FLAGS_REG)
1211 (match_operand 0 "ext_register_operand" "Q")
1214 (match_operand:QI 1 "const0_operand")))]
1215 "ix86_match_ccmode (insn, CCNOmode)"
1217 [(set_attr "type" "test")
1218 (set_attr "length_immediate" "0")
1219 (set_attr "mode" "QI")])
1221 (define_expand "cmpqi_ext_3"
1222 [(set (reg:CC FLAGS_REG)
1226 (match_operand 0 "ext_register_operand")
1229 (match_operand:QI 1 "const_int_operand")))])
1231 (define_insn "*cmpqi_ext_3"
1232 [(set (reg FLAGS_REG)
1236 (match_operand 0 "ext_register_operand" "Q,Q")
1239 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1240 "ix86_match_ccmode (insn, CCmode)"
1241 "cmp{b}\t{%1, %h0|%h0, %1}"
1242 [(set_attr "isa" "*,nox64")
1243 (set_attr "type" "icmp")
1244 (set_attr "modrm" "1")
1245 (set_attr "mode" "QI")])
1247 (define_insn "*cmpqi_ext_4"
1248 [(set (reg FLAGS_REG)
1252 (match_operand 0 "ext_register_operand" "Q")
1257 (match_operand 1 "ext_register_operand" "Q")
1259 (const_int 8)) 0)))]
1260 "ix86_match_ccmode (insn, CCmode)"
1261 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1262 [(set_attr "type" "icmp")
1263 (set_attr "mode" "QI")])
1265 ;; These implement float point compares.
1266 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1267 ;; which would allow mix and match FP modes on the compares. Which is what
1268 ;; the old patterns did, but with many more of them.
1270 (define_expand "cbranchxf4"
1271 [(set (reg:CC FLAGS_REG)
1272 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1273 (match_operand:XF 2 "nonmemory_operand")))
1274 (set (pc) (if_then_else
1275 (match_operator 0 "ix86_fp_comparison_operator"
1278 (label_ref (match_operand 3))
1282 ix86_expand_branch (GET_CODE (operands[0]),
1283 operands[1], operands[2], operands[3]);
1287 (define_expand "cstorexf4"
1288 [(set (reg:CC FLAGS_REG)
1289 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1290 (match_operand:XF 3 "nonmemory_operand")))
1291 (set (match_operand:QI 0 "register_operand")
1292 (match_operator 1 "ix86_fp_comparison_operator"
1297 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1298 operands[2], operands[3]);
1302 (define_expand "cbranch<mode>4"
1303 [(set (reg:CC FLAGS_REG)
1304 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1305 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1306 (set (pc) (if_then_else
1307 (match_operator 0 "ix86_fp_comparison_operator"
1310 (label_ref (match_operand 3))
1312 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1314 ix86_expand_branch (GET_CODE (operands[0]),
1315 operands[1], operands[2], operands[3]);
1319 (define_expand "cstore<mode>4"
1320 [(set (reg:CC FLAGS_REG)
1321 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1322 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1323 (set (match_operand:QI 0 "register_operand")
1324 (match_operator 1 "ix86_fp_comparison_operator"
1327 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1329 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1330 operands[2], operands[3]);
1334 (define_expand "cbranchcc4"
1335 [(set (pc) (if_then_else
1336 (match_operator 0 "comparison_operator"
1337 [(match_operand 1 "flags_reg_operand")
1338 (match_operand 2 "const0_operand")])
1339 (label_ref (match_operand 3))
1343 ix86_expand_branch (GET_CODE (operands[0]),
1344 operands[1], operands[2], operands[3]);
1348 (define_expand "cstorecc4"
1349 [(set (match_operand:QI 0 "register_operand")
1350 (match_operator 1 "comparison_operator"
1351 [(match_operand 2 "flags_reg_operand")
1352 (match_operand 3 "const0_operand")]))]
1355 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356 operands[2], operands[3]);
1361 ;; FP compares, step 1:
1362 ;; Set the FP condition codes.
1364 ;; CCFPmode compare with exceptions
1365 ;; CCFPUmode compare with no exceptions
1367 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1368 ;; used to manage the reg stack popping would not be preserved.
1370 (define_insn "*cmp<mode>_0_i387"
1371 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (match_operand:X87MODEF 1 "register_operand" "f")
1375 (match_operand:X87MODEF 2 "const0_operand"))]
1378 "* return output_fp_compare (insn, operands, false, false);"
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set_attr "mode" "<MODE>")])
1383 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1384 [(set (reg:CCFP FLAGS_REG)
1386 (match_operand:X87MODEF 1 "register_operand" "f")
1387 (match_operand:X87MODEF 2 "const0_operand")))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1391 "&& reload_completed"
1394 [(compare:CCFP (match_dup 1)(match_dup 2))]
1396 (set (reg:CC FLAGS_REG)
1397 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "mode" "<MODE>")])
1403 (define_insn "*cmpxf_i387"
1404 [(set (match_operand:HI 0 "register_operand" "=a")
1407 (match_operand:XF 1 "register_operand" "f")
1408 (match_operand:XF 2 "register_operand" "f"))]
1411 "* return output_fp_compare (insn, operands, false, false);"
1412 [(set_attr "type" "multi")
1413 (set_attr "unit" "i387")
1414 (set_attr "mode" "XF")])
1416 (define_insn_and_split "*cmpxf_cc_i387"
1417 [(set (reg:CCFP FLAGS_REG)
1419 (match_operand:XF 1 "register_operand" "f")
1420 (match_operand:XF 2 "register_operand" "f")))
1421 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1422 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1424 "&& reload_completed"
1427 [(compare:CCFP (match_dup 1)(match_dup 2))]
1429 (set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "mode" "XF")])
1436 (define_insn "*cmp<mode>_i387"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1440 (match_operand:MODEF 1 "register_operand" "f")
1441 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1444 "* return output_fp_compare (insn, operands, false, false);"
1445 [(set_attr "type" "multi")
1446 (set_attr "unit" "i387")
1447 (set_attr "mode" "<MODE>")])
1449 (define_insn_and_split "*cmp<mode>_cc_i387"
1450 [(set (reg:CCFP FLAGS_REG)
1452 (match_operand:MODEF 1 "register_operand" "f")
1453 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1454 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1455 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1457 "&& reload_completed"
1460 [(compare:CCFP (match_dup 1)(match_dup 2))]
1462 (set (reg:CC FLAGS_REG)
1463 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1465 [(set_attr "type" "multi")
1466 (set_attr "unit" "i387")
1467 (set_attr "mode" "<MODE>")])
1469 (define_insn "*cmpu<mode>_i387"
1470 [(set (match_operand:HI 0 "register_operand" "=a")
1473 (match_operand:X87MODEF 1 "register_operand" "f")
1474 (match_operand:X87MODEF 2 "register_operand" "f"))]
1477 "* return output_fp_compare (insn, operands, false, true);"
1478 [(set_attr "type" "multi")
1479 (set_attr "unit" "i387")
1480 (set_attr "mode" "<MODE>")])
1482 (define_insn_and_split "*cmpu<mode>_cc_i387"
1483 [(set (reg:CCFPU FLAGS_REG)
1485 (match_operand:X87MODEF 1 "register_operand" "f")
1486 (match_operand:X87MODEF 2 "register_operand" "f")))
1487 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1488 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1490 "&& reload_completed"
1493 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1495 (set (reg:CC FLAGS_REG)
1496 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1498 [(set_attr "type" "multi")
1499 (set_attr "unit" "i387")
1500 (set_attr "mode" "<MODE>")])
1502 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1503 [(set (match_operand:HI 0 "register_operand" "=a")
1506 (match_operand:X87MODEF 1 "register_operand" "f")
1507 (match_operator:X87MODEF 3 "float_operator"
1508 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1511 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1512 || optimize_function_for_size_p (cfun))"
1513 "* return output_fp_compare (insn, operands, false, false);"
1514 [(set_attr "type" "multi")
1515 (set_attr "unit" "i387")
1516 (set_attr "fp_int_src" "true")
1517 (set_attr "mode" "<SWI24:MODE>")])
1519 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1522 (match_operand:X87MODEF 1 "register_operand" "f")
1523 (match_operator:X87MODEF 3 "float_operator"
1524 [(match_operand:SWI24 2 "memory_operand" "m")])))
1525 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1526 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1527 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1528 || optimize_function_for_size_p (cfun))"
1530 "&& reload_completed"
1535 (match_op_dup 3 [(match_dup 2)]))]
1537 (set (reg:CC FLAGS_REG)
1538 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1540 [(set_attr "type" "multi")
1541 (set_attr "unit" "i387")
1542 (set_attr "fp_int_src" "true")
1543 (set_attr "mode" "<SWI24:MODE>")])
1545 ;; FP compares, step 2
1546 ;; Move the fpsw to ax.
1548 (define_insn "x86_fnstsw_1"
1549 [(set (match_operand:HI 0 "register_operand" "=a")
1550 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1553 [(set_attr "length" "2")
1554 (set_attr "mode" "SI")
1555 (set_attr "unit" "i387")])
1557 ;; FP compares, step 3
1558 ;; Get ax into flags, general case.
1560 (define_insn "x86_sahf_1"
1561 [(set (reg:CC FLAGS_REG)
1562 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1566 #ifndef HAVE_AS_IX86_SAHF
1568 return ASM_BYTE "0x9e";
1573 [(set_attr "length" "1")
1574 (set_attr "athlon_decode" "vector")
1575 (set_attr "amdfam10_decode" "direct")
1576 (set_attr "bdver1_decode" "direct")
1577 (set_attr "mode" "SI")])
1579 ;; Pentium Pro can do steps 1 through 3 in one go.
1580 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1581 ;; (these i387 instructions set flags directly)
1583 (define_mode_iterator FPCMP [CCFP CCFPU])
1584 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1586 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1587 [(set (reg:FPCMP FLAGS_REG)
1589 (match_operand:MODEF 0 "register_operand" "f,x")
1590 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1591 "TARGET_MIX_SSE_I387
1592 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1593 "* return output_fp_compare (insn, operands, true,
1594 <FPCMP:MODE>mode == CCFPUmode);"
1595 [(set_attr "type" "fcmp,ssecomi")
1596 (set_attr "prefix" "orig,maybe_vex")
1597 (set_attr "mode" "<MODEF:MODE>")
1598 (set (attr "prefix_rep")
1599 (if_then_else (eq_attr "type" "ssecomi")
1601 (const_string "*")))
1602 (set (attr "prefix_data16")
1603 (cond [(eq_attr "type" "fcmp")
1605 (eq_attr "mode" "DF")
1608 (const_string "0")))
1609 (set_attr "athlon_decode" "vector")
1610 (set_attr "amdfam10_decode" "direct")
1611 (set_attr "bdver1_decode" "double")])
1613 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1614 [(set (reg:FPCMP FLAGS_REG)
1616 (match_operand:MODEF 0 "register_operand" "x")
1617 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1619 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1620 "* return output_fp_compare (insn, operands, true,
1621 <FPCMP:MODE>mode == CCFPUmode);"
1622 [(set_attr "type" "ssecomi")
1623 (set_attr "prefix" "maybe_vex")
1624 (set_attr "mode" "<MODEF:MODE>")
1625 (set_attr "prefix_rep" "0")
1626 (set (attr "prefix_data16")
1627 (if_then_else (eq_attr "mode" "DF")
1629 (const_string "0")))
1630 (set_attr "athlon_decode" "vector")
1631 (set_attr "amdfam10_decode" "direct")
1632 (set_attr "bdver1_decode" "double")])
1634 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1635 [(set (reg:FPCMP FLAGS_REG)
1637 (match_operand:X87MODEF 0 "register_operand" "f")
1638 (match_operand:X87MODEF 1 "register_operand" "f")))]
1639 "TARGET_80387 && TARGET_CMOVE
1640 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1641 "* return output_fp_compare (insn, operands, true,
1642 <FPCMP:MODE>mode == CCFPUmode);"
1643 [(set_attr "type" "fcmp")
1644 (set_attr "mode" "<X87MODEF:MODE>")
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "direct")
1647 (set_attr "bdver1_decode" "double")])
1649 ;; Push/pop instructions.
1651 (define_insn "*push<mode>2"
1652 [(set (match_operand:DWI 0 "push_operand" "=<")
1653 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1656 [(set_attr "type" "multi")
1657 (set_attr "mode" "<MODE>")])
1660 [(set (match_operand:TI 0 "push_operand")
1661 (match_operand:TI 1 "general_operand"))]
1662 "TARGET_64BIT && reload_completed
1663 && !SSE_REG_P (operands[1])"
1665 "ix86_split_long_move (operands); DONE;")
1667 (define_insn "*pushdi2_rex64"
1668 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1669 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1674 [(set_attr "type" "push,multi")
1675 (set_attr "mode" "DI")])
1677 ;; Convert impossible pushes of immediate to existing instructions.
1678 ;; First try to get scratch register and go through it. In case this
1679 ;; fails, push sign extended lower part first and then overwrite
1680 ;; upper part by 32bit move.
1682 [(match_scratch:DI 2 "r")
1683 (set (match_operand:DI 0 "push_operand")
1684 (match_operand:DI 1 "immediate_operand"))]
1685 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1686 && !x86_64_immediate_operand (operands[1], DImode)"
1687 [(set (match_dup 2) (match_dup 1))
1688 (set (match_dup 0) (match_dup 2))])
1690 ;; We need to define this as both peepholer and splitter for case
1691 ;; peephole2 pass is not run.
1692 ;; "&& 1" is needed to keep it from matching the previous pattern.
1694 [(set (match_operand:DI 0 "push_operand")
1695 (match_operand:DI 1 "immediate_operand"))]
1696 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1697 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1698 [(set (match_dup 0) (match_dup 1))
1699 (set (match_dup 2) (match_dup 3))]
1701 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1703 operands[1] = gen_lowpart (DImode, operands[2]);
1704 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1709 [(set (match_operand:DI 0 "push_operand")
1710 (match_operand:DI 1 "immediate_operand"))]
1711 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1712 ? epilogue_completed : reload_completed)
1713 && !symbolic_operand (operands[1], DImode)
1714 && !x86_64_immediate_operand (operands[1], DImode)"
1715 [(set (match_dup 0) (match_dup 1))
1716 (set (match_dup 2) (match_dup 3))]
1718 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1720 operands[1] = gen_lowpart (DImode, operands[2]);
1721 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1726 [(set (match_operand:DI 0 "push_operand")
1727 (match_operand:DI 1 "general_operand"))]
1728 "!TARGET_64BIT && reload_completed
1729 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1731 "ix86_split_long_move (operands); DONE;")
1733 (define_insn "*pushsi2"
1734 [(set (match_operand:SI 0 "push_operand" "=<")
1735 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "SI")])
1741 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1742 ;; "push a byte/word". But actually we use pushl, which has the effect
1743 ;; of rounding the amount pushed up to a word.
1745 ;; For TARGET_64BIT we always round up to 8 bytes.
1746 (define_insn "*push<mode>2_rex64"
1747 [(set (match_operand:SWI124 0 "push_operand" "=X")
1748 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1751 [(set_attr "type" "push")
1752 (set_attr "mode" "DI")])
1754 (define_insn "*push<mode>2"
1755 [(set (match_operand:SWI12 0 "push_operand" "=X")
1756 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "SI")])
1762 (define_insn "*push<mode>2_prologue"
1763 [(set (match_operand:W 0 "push_operand" "=<")
1764 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1765 (clobber (mem:BLK (scratch)))]
1767 "push{<imodesuffix>}\t%1"
1768 [(set_attr "type" "push")
1769 (set_attr "mode" "<MODE>")])
1771 (define_insn "*pop<mode>1"
1772 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1773 (match_operand:W 1 "pop_operand" ">"))]
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1779 (define_insn "*pop<mode>1_epilogue"
1780 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1781 (match_operand:W 1 "pop_operand" ">"))
1782 (clobber (mem:BLK (scratch)))]
1784 "pop{<imodesuffix>}\t%0"
1785 [(set_attr "type" "pop")
1786 (set_attr "mode" "<MODE>")])
1788 (define_insn "*pushfl<mode>2"
1789 [(set (match_operand:W 0 "push_operand" "=<")
1790 (match_operand:W 1 "flags_reg_operand"))]
1792 "pushf{<imodesuffix>}"
1793 [(set_attr "type" "push")
1794 (set_attr "mode" "<MODE>")])
1796 (define_insn "*popfl<mode>1"
1797 [(set (match_operand:W 0 "flags_reg_operand")
1798 (match_operand:W 1 "pop_operand" ">"))]
1800 "popf{<imodesuffix>}"
1801 [(set_attr "type" "pop")
1802 (set_attr "mode" "<MODE>")])
1805 ;; Move instructions.
1807 (define_expand "movxi"
1808 [(set (match_operand:XI 0 "nonimmediate_operand")
1809 (match_operand:XI 1 "general_operand"))]
1811 "ix86_expand_move (XImode, operands); DONE;")
1813 ;; Reload patterns to support multi-word load/store
1814 ;; with non-offsetable address.
1815 (define_expand "reload_noff_store"
1816 [(parallel [(match_operand 0 "memory_operand" "=m")
1817 (match_operand 1 "register_operand" "r")
1818 (match_operand:DI 2 "register_operand" "=&r")])]
1821 rtx mem = operands[0];
1822 rtx addr = XEXP (mem, 0);
1824 emit_move_insn (operands[2], addr);
1825 mem = replace_equiv_address_nv (mem, operands[2]);
1827 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1831 (define_expand "reload_noff_load"
1832 [(parallel [(match_operand 0 "register_operand" "=r")
1833 (match_operand 1 "memory_operand" "m")
1834 (match_operand:DI 2 "register_operand" "=r")])]
1837 rtx mem = operands[1];
1838 rtx addr = XEXP (mem, 0);
1840 emit_move_insn (operands[2], addr);
1841 mem = replace_equiv_address_nv (mem, operands[2]);
1843 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1847 (define_expand "movoi"
1848 [(set (match_operand:OI 0 "nonimmediate_operand")
1849 (match_operand:OI 1 "general_operand"))]
1851 "ix86_expand_move (OImode, operands); DONE;")
1853 (define_expand "movti"
1854 [(set (match_operand:TI 0 "nonimmediate_operand")
1855 (match_operand:TI 1 "nonimmediate_operand"))]
1856 "TARGET_64BIT || TARGET_SSE"
1859 ix86_expand_move (TImode, operands);
1861 ix86_expand_vector_move (TImode, operands);
1865 ;; This expands to what emit_move_complex would generate if we didn't
1866 ;; have a movti pattern. Having this avoids problems with reload on
1867 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1868 ;; to have around all the time.
1869 (define_expand "movcdi"
1870 [(set (match_operand:CDI 0 "nonimmediate_operand")
1871 (match_operand:CDI 1 "general_operand"))]
1874 if (push_operand (operands[0], CDImode))
1875 emit_move_complex_push (CDImode, operands[0], operands[1]);
1877 emit_move_complex_parts (operands[0], operands[1]);
1881 (define_expand "mov<mode>"
1882 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1883 (match_operand:SWI1248x 1 "general_operand"))]
1885 "ix86_expand_move (<MODE>mode, operands); DONE;")
1887 (define_insn "*mov<mode>_xor"
1888 [(set (match_operand:SWI48 0 "register_operand" "=r")
1889 (match_operand:SWI48 1 "const0_operand"))
1890 (clobber (reg:CC FLAGS_REG))]
1893 [(set_attr "type" "alu1")
1894 (set_attr "mode" "SI")
1895 (set_attr "length_immediate" "0")])
1897 (define_insn "*mov<mode>_or"
1898 [(set (match_operand:SWI48 0 "register_operand" "=r")
1899 (match_operand:SWI48 1 "const_int_operand"))
1900 (clobber (reg:CC FLAGS_REG))]
1902 && operands[1] == constm1_rtx"
1903 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1904 [(set_attr "type" "alu1")
1905 (set_attr "mode" "<MODE>")
1906 (set_attr "length_immediate" "1")])
1908 (define_insn "*movxi_internal_avx512f"
1909 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1910 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1911 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1913 switch (which_alternative)
1916 return standard_sse_constant_opcode (insn, operands[1]);
1919 if (misaligned_operand (operands[0], XImode)
1920 || misaligned_operand (operands[1], XImode))
1921 return "vmovdqu32\t{%1, %0|%0, %1}";
1923 return "vmovdqa32\t{%1, %0|%0, %1}";
1928 [(set_attr "type" "sselog1,ssemov,ssemov")
1929 (set_attr "prefix" "evex")
1930 (set_attr "mode" "XI")])
1932 (define_insn "*movoi_internal_avx"
1933 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1934 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1935 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937 switch (get_attr_type (insn))
1940 return standard_sse_constant_opcode (insn, operands[1]);
1943 if (misaligned_operand (operands[0], OImode)
1944 || misaligned_operand (operands[1], OImode))
1946 if (get_attr_mode (insn) == MODE_V8SF)
1947 return "vmovups\t{%1, %0|%0, %1}";
1948 else if (get_attr_mode (insn) == MODE_XI)
1949 return "vmovdqu32\t{%1, %0|%0, %1}";
1951 return "vmovdqu\t{%1, %0|%0, %1}";
1955 if (get_attr_mode (insn) == MODE_V8SF)
1956 return "vmovaps\t{%1, %0|%0, %1}";
1957 else if (get_attr_mode (insn) == MODE_XI)
1958 return "vmovdqa32\t{%1, %0|%0, %1}";
1960 return "vmovdqa\t{%1, %0|%0, %1}";
1967 [(set_attr "type" "sselog1,ssemov,ssemov")
1968 (set_attr "prefix" "vex")
1970 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1971 (match_operand 1 "ext_sse_reg_operand"))
1973 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1974 (const_string "V8SF")
1975 (and (eq_attr "alternative" "2")
1976 (match_test "TARGET_SSE_TYPELESS_STORES"))
1977 (const_string "V8SF")
1979 (const_string "OI")))])
1981 (define_insn "*movti_internal"
1982 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
1983 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
1984 "(TARGET_64BIT || TARGET_SSE)
1985 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1987 switch (get_attr_type (insn))
1993 return standard_sse_constant_opcode (insn, operands[1]);
1996 /* TDmode values are passed as TImode on the stack. Moving them
1997 to stack may result in unaligned memory access. */
1998 if (misaligned_operand (operands[0], TImode)
1999 || misaligned_operand (operands[1], TImode))
2001 if (get_attr_mode (insn) == MODE_V4SF)
2002 return "%vmovups\t{%1, %0|%0, %1}";
2003 else if (get_attr_mode (insn) == MODE_XI)
2004 return "vmovdqu32\t{%1, %0|%0, %1}";
2006 return "%vmovdqu\t{%1, %0|%0, %1}";
2010 if (get_attr_mode (insn) == MODE_V4SF)
2011 return "%vmovaps\t{%1, %0|%0, %1}";
2012 else if (get_attr_mode (insn) == MODE_XI)
2013 return "vmovdqa32\t{%1, %0|%0, %1}";
2015 return "%vmovdqa\t{%1, %0|%0, %1}";
2022 [(set_attr "isa" "x64,x64,*,*,*")
2023 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2024 (set (attr "prefix")
2025 (if_then_else (eq_attr "type" "sselog1,ssemov")
2026 (const_string "maybe_vex")
2027 (const_string "orig")))
2029 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2030 (match_operand 1 "ext_sse_reg_operand"))
2032 (eq_attr "alternative" "0,1")
2034 (ior (not (match_test "TARGET_SSE2"))
2035 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2036 (const_string "V4SF")
2037 (and (eq_attr "alternative" "4")
2038 (match_test "TARGET_SSE_TYPELESS_STORES"))
2039 (const_string "V4SF")
2040 (match_test "TARGET_AVX")
2042 (match_test "optimize_function_for_size_p (cfun)")
2043 (const_string "V4SF")
2045 (const_string "TI")))])
2048 [(set (match_operand:TI 0 "nonimmediate_operand")
2049 (match_operand:TI 1 "general_operand"))]
2051 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2053 "ix86_split_long_move (operands); DONE;")
2055 (define_insn "*movdi_internal"
2056 [(set (match_operand:DI 0 "nonimmediate_operand"
2057 "=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")
2058 (match_operand:DI 1 "general_operand"
2059 "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"))]
2060 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2062 switch (get_attr_type (insn))
2065 return "kmovq\t{%1, %0|%0, %1}";
2071 return "pxor\t%0, %0";
2074 /* Handle broken assemblers that require movd instead of movq. */
2075 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2076 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2077 return "movd\t{%1, %0|%0, %1}";
2078 return "movq\t{%1, %0|%0, %1}";
2081 if (GENERAL_REG_P (operands[0]))
2082 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2084 return standard_sse_constant_opcode (insn, operands[1]);
2087 switch (get_attr_mode (insn))
2090 /* Handle broken assemblers that require movd instead of movq. */
2091 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2092 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2093 return "%vmovd\t{%1, %0|%0, %1}";
2094 return "%vmovq\t{%1, %0|%0, %1}";
2096 return "%vmovdqa\t{%1, %0|%0, %1}";
2098 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2101 gcc_assert (!TARGET_AVX);
2102 return "movlps\t{%1, %0|%0, %1}";
2104 return "%vmovaps\t{%1, %0|%0, %1}";
2111 if (SSE_REG_P (operands[0]))
2112 return "movq2dq\t{%1, %0|%0, %1}";
2114 return "movdq2q\t{%1, %0|%0, %1}";
2117 return "lea{q}\t{%E1, %0|%0, %E1}";
2120 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2121 if (get_attr_mode (insn) == MODE_SI)
2122 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2123 else if (which_alternative == 4)
2124 return "movabs{q}\t{%1, %0|%0, %1}";
2125 else if (ix86_use_lea_for_mov (insn, operands))
2126 return "lea{q}\t{%E1, %0|%0, %E1}";
2128 return "mov{q}\t{%1, %0|%0, %1}";
2135 (cond [(eq_attr "alternative" "0,1")
2136 (const_string "nox64")
2137 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2138 (const_string "x64")
2139 (eq_attr "alternative" "17")
2140 (const_string "x64_sse4")
2142 (const_string "*")))
2144 (cond [(eq_attr "alternative" "0,1")
2145 (const_string "multi")
2146 (eq_attr "alternative" "6")
2147 (const_string "mmx")
2148 (eq_attr "alternative" "7,8,9,10,11")
2149 (const_string "mmxmov")
2150 (eq_attr "alternative" "12,17")
2151 (const_string "sselog1")
2152 (eq_attr "alternative" "13,14,15,16,18")
2153 (const_string "ssemov")
2154 (eq_attr "alternative" "19,20")
2155 (const_string "ssecvt")
2156 (eq_attr "alternative" "21,22,23,24")
2157 (const_string "mskmov")
2158 (match_operand 1 "pic_32bit_operand")
2159 (const_string "lea")
2161 (const_string "imov")))
2164 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2166 (const_string "*")))
2167 (set (attr "length_immediate")
2168 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2170 (eq_attr "alternative" "17")
2173 (const_string "*")))
2174 (set (attr "prefix_rex")
2175 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2177 (const_string "*")))
2178 (set (attr "prefix_extra")
2179 (if_then_else (eq_attr "alternative" "17")
2181 (const_string "*")))
2182 (set (attr "prefix")
2183 (if_then_else (eq_attr "type" "sselog1,ssemov")
2184 (const_string "maybe_vex")
2185 (const_string "orig")))
2186 (set (attr "prefix_data16")
2187 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2189 (const_string "*")))
2191 (cond [(eq_attr "alternative" "2")
2193 (eq_attr "alternative" "12,13")
2194 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2195 (match_operand 1 "ext_sse_reg_operand"))
2197 (ior (not (match_test "TARGET_SSE2"))
2198 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2199 (const_string "V4SF")
2200 (match_test "TARGET_AVX")
2202 (match_test "optimize_function_for_size_p (cfun)")
2203 (const_string "V4SF")
2205 (const_string "TI"))
2207 (and (eq_attr "alternative" "14,15")
2208 (not (match_test "TARGET_SSE2")))
2209 (const_string "V2SF")
2210 (eq_attr "alternative" "17")
2213 (const_string "DI")))])
2216 [(set (match_operand:DI 0 "nonimmediate_operand")
2217 (match_operand:DI 1 "general_operand"))]
2218 "!TARGET_64BIT && reload_completed
2219 && !(MMX_REG_P (operands[0])
2220 || SSE_REG_P (operands[0])
2221 || MASK_REG_P (operands[0]))
2222 && !(MMX_REG_P (operands[1])
2223 || SSE_REG_P (operands[1])
2224 || MASK_REG_P (operands[1]))"
2226 "ix86_split_long_move (operands); DONE;")
2228 (define_insn "*movsi_internal"
2229 [(set (match_operand:SI 0 "nonimmediate_operand"
2230 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2231 (match_operand:SI 1 "general_operand"
2232 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2233 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2235 switch (get_attr_type (insn))
2238 if (GENERAL_REG_P (operands[0]))
2239 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2241 return standard_sse_constant_opcode (insn, operands[1]);
2244 return "kmovd\t{%1, %0|%0, %1}";
2247 switch (get_attr_mode (insn))
2250 return "%vmovd\t{%1, %0|%0, %1}";
2252 return "%vmovdqa\t{%1, %0|%0, %1}";
2254 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2257 return "%vmovaps\t{%1, %0|%0, %1}";
2260 gcc_assert (!TARGET_AVX);
2261 return "movss\t{%1, %0|%0, %1}";
2268 return "pxor\t%0, %0";
2271 switch (get_attr_mode (insn))
2274 return "movq\t{%1, %0|%0, %1}";
2276 return "movd\t{%1, %0|%0, %1}";
2283 return "lea{l}\t{%E1, %0|%0, %E1}";
2286 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287 if (ix86_use_lea_for_mov (insn, operands))
2288 return "lea{l}\t{%E1, %0|%0, %E1}";
2290 return "mov{l}\t{%1, %0|%0, %1}";
2297 (if_then_else (eq_attr "alternative" "11")
2298 (const_string "sse4")
2299 (const_string "*")))
2301 (cond [(eq_attr "alternative" "2")
2302 (const_string "mmx")
2303 (eq_attr "alternative" "3,4,5")
2304 (const_string "mmxmov")
2305 (eq_attr "alternative" "6,11")
2306 (const_string "sselog1")
2307 (eq_attr "alternative" "7,8,9,10,12")
2308 (const_string "ssemov")
2309 (eq_attr "alternative" "13,14")
2310 (const_string "mskmov")
2311 (match_operand 1 "pic_32bit_operand")
2312 (const_string "lea")
2314 (const_string "imov")))
2315 (set (attr "length_immediate")
2316 (if_then_else (eq_attr "alternative" "11")
2318 (const_string "*")))
2319 (set (attr "prefix_extra")
2320 (if_then_else (eq_attr "alternative" "11")
2322 (const_string "*")))
2323 (set (attr "prefix")
2324 (if_then_else (eq_attr "type" "sselog1,ssemov")
2325 (const_string "maybe_vex")
2326 (const_string "orig")))
2327 (set (attr "prefix_data16")
2328 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2330 (const_string "*")))
2332 (cond [(eq_attr "alternative" "2,3")
2334 (eq_attr "alternative" "6,7")
2335 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2336 (match_operand 1 "ext_sse_reg_operand"))
2338 (ior (not (match_test "TARGET_SSE2"))
2339 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2340 (const_string "V4SF")
2341 (match_test "TARGET_AVX")
2343 (match_test "optimize_function_for_size_p (cfun)")
2344 (const_string "V4SF")
2346 (const_string "TI"))
2348 (and (eq_attr "alternative" "8,9")
2349 (not (match_test "TARGET_SSE2")))
2351 (eq_attr "alternative" "11")
2354 (const_string "SI")))])
2356 (define_insn "kmovw"
2357 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2359 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2361 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2363 kmovw\t{%k1, %0|%0, %k1}
2364 kmovw\t{%1, %0|%0, %1}";
2365 [(set_attr "mode" "HI")
2366 (set_attr "type" "mskmov")
2367 (set_attr "prefix" "vex")])
2370 (define_insn "*movhi_internal"
2371 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2372 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2373 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2375 switch (get_attr_type (insn))
2378 /* movzwl is faster than movw on p2 due to partial word stalls,
2379 though not as fast as an aligned movl. */
2380 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2383 switch (which_alternative)
2385 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2386 case 5: return "kmovw\t{%1, %0|%0, %1}";
2387 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2388 default: gcc_unreachable ();
2392 if (get_attr_mode (insn) == MODE_SI)
2393 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2395 return "mov{w}\t{%1, %0|%0, %1}";
2399 (cond [(eq_attr "alternative" "4,5,6")
2400 (const_string "mskmov")
2401 (match_test "optimize_function_for_size_p (cfun)")
2402 (const_string "imov")
2403 (and (eq_attr "alternative" "0")
2404 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2405 (not (match_test "TARGET_HIMODE_MATH"))))
2406 (const_string "imov")
2407 (and (eq_attr "alternative" "1,2")
2408 (match_operand:HI 1 "aligned_operand"))
2409 (const_string "imov")
2410 (and (match_test "TARGET_MOVX")
2411 (eq_attr "alternative" "0,2"))
2412 (const_string "imovx")
2414 (const_string "imov")))
2415 (set (attr "prefix")
2416 (if_then_else (eq_attr "alternative" "4,5,6")
2417 (const_string "vex")
2418 (const_string "orig")))
2420 (cond [(eq_attr "type" "imovx")
2422 (and (eq_attr "alternative" "1,2")
2423 (match_operand:HI 1 "aligned_operand"))
2425 (and (eq_attr "alternative" "0")
2426 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2427 (not (match_test "TARGET_HIMODE_MATH"))))
2430 (const_string "HI")))])
2432 ;; Situation is quite tricky about when to choose full sized (SImode) move
2433 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2434 ;; partial register dependency machines (such as AMD Athlon), where QImode
2435 ;; moves issue extra dependency and for partial register stalls machines
2436 ;; that don't use QImode patterns (and QImode move cause stall on the next
2439 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2440 ;; register stall machines with, where we use QImode instructions, since
2441 ;; partial register stall can be caused there. Then we use movzx.
2443 (define_insn "*movqi_internal"
2444 [(set (match_operand:QI 0 "nonimmediate_operand"
2445 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2446 (match_operand:QI 1 "general_operand"
2447 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2448 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 switch (get_attr_type (insn))
2453 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2454 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2457 switch (which_alternative)
2459 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2460 : "kmovw\t{%k1, %0|%0, %k1}";
2461 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2462 : "kmovw\t{%1, %0|%0, %1}";
2463 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2464 : "kmovw\t{%1, %k0|%k0, %1}";
2467 gcc_assert (TARGET_AVX512DQ);
2468 return "kmovb\t{%1, %0|%0, %1}";
2469 default: gcc_unreachable ();
2473 if (get_attr_mode (insn) == MODE_SI)
2474 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2476 return "mov{b}\t{%1, %0|%0, %1}";
2479 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2481 (cond [(eq_attr "alternative" "3,5")
2482 (const_string "imovx")
2483 (eq_attr "alternative" "7,8,9,10,11")
2484 (const_string "mskmov")
2485 (and (eq_attr "alternative" "5")
2486 (not (match_operand:QI 1 "aligned_operand")))
2487 (const_string "imovx")
2488 (match_test "optimize_function_for_size_p (cfun)")
2489 (const_string "imov")
2490 (and (eq_attr "alternative" "3")
2491 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2492 (not (match_test "TARGET_QIMODE_MATH"))))
2493 (const_string "imov")
2494 (and (match_test "TARGET_MOVX")
2495 (eq_attr "alternative" "2"))
2496 (const_string "imovx")
2498 (const_string "imov")))
2499 (set (attr "prefix")
2500 (if_then_else (eq_attr "alternative" "7,8,9")
2501 (const_string "vex")
2502 (const_string "orig")))
2504 (cond [(eq_attr "alternative" "3,4,5")
2506 (eq_attr "alternative" "6")
2508 (eq_attr "type" "imovx")
2510 (and (eq_attr "type" "imov")
2511 (and (eq_attr "alternative" "0,1")
2512 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2513 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2514 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2516 ;; Avoid partial register stalls when not using QImode arithmetic
2517 (and (eq_attr "type" "imov")
2518 (and (eq_attr "alternative" "0,1")
2519 (and (match_test "TARGET_PARTIAL_REG_STALL")
2520 (not (match_test "TARGET_QIMODE_MATH")))))
2523 (const_string "QI")))])
2525 ;; Stores and loads of ax to arbitrary constant address.
2526 ;; We fake an second form of instruction to force reload to load address
2527 ;; into register when rax is not available
2528 (define_insn "*movabs<mode>_1"
2529 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2530 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2531 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2533 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2534 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2535 [(set_attr "type" "imov")
2536 (set_attr "modrm" "0,*")
2537 (set_attr "length_address" "8,0")
2538 (set_attr "length_immediate" "0,*")
2539 (set_attr "memory" "store")
2540 (set_attr "mode" "<MODE>")])
2542 (define_insn "*movabs<mode>_2"
2543 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2544 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2545 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2547 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2548 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2549 [(set_attr "type" "imov")
2550 (set_attr "modrm" "0,*")
2551 (set_attr "length_address" "8,0")
2552 (set_attr "length_immediate" "0")
2553 (set_attr "memory" "load")
2554 (set_attr "mode" "<MODE>")])
2556 (define_insn "*swap<mode>"
2557 [(set (match_operand:SWI48 0 "register_operand" "+r")
2558 (match_operand:SWI48 1 "register_operand" "+r"))
2562 "xchg{<imodesuffix>}\t%1, %0"
2563 [(set_attr "type" "imov")
2564 (set_attr "mode" "<MODE>")
2565 (set_attr "pent_pair" "np")
2566 (set_attr "athlon_decode" "vector")
2567 (set_attr "amdfam10_decode" "double")
2568 (set_attr "bdver1_decode" "double")])
2570 (define_insn "*swap<mode>_1"
2571 [(set (match_operand:SWI12 0 "register_operand" "+r")
2572 (match_operand:SWI12 1 "register_operand" "+r"))
2575 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2577 [(set_attr "type" "imov")
2578 (set_attr "mode" "SI")
2579 (set_attr "pent_pair" "np")
2580 (set_attr "athlon_decode" "vector")
2581 (set_attr "amdfam10_decode" "double")
2582 (set_attr "bdver1_decode" "double")])
2584 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2585 ;; is disabled for AMDFAM10
2586 (define_insn "*swap<mode>_2"
2587 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2588 (match_operand:SWI12 1 "register_operand" "+<r>"))
2591 "TARGET_PARTIAL_REG_STALL"
2592 "xchg{<imodesuffix>}\t%1, %0"
2593 [(set_attr "type" "imov")
2594 (set_attr "mode" "<MODE>")
2595 (set_attr "pent_pair" "np")
2596 (set_attr "athlon_decode" "vector")])
2598 (define_expand "movstrict<mode>"
2599 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2600 (match_operand:SWI12 1 "general_operand"))]
2603 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2605 if (GET_CODE (operands[0]) == SUBREG
2606 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2608 /* Don't generate memory->memory moves, go through a register */
2609 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2610 operands[1] = force_reg (<MODE>mode, operands[1]);
2613 (define_insn "*movstrict<mode>_1"
2614 [(set (strict_low_part
2615 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2616 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2617 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2618 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2619 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2620 [(set_attr "type" "imov")
2621 (set_attr "mode" "<MODE>")])
2623 (define_insn "*movstrict<mode>_xor"
2624 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2625 (match_operand:SWI12 1 "const0_operand"))
2626 (clobber (reg:CC FLAGS_REG))]
2628 "xor{<imodesuffix>}\t%0, %0"
2629 [(set_attr "type" "alu1")
2630 (set_attr "mode" "<MODE>")
2631 (set_attr "length_immediate" "0")])
2633 (define_insn "*mov<mode>_extv_1"
2634 [(set (match_operand:SWI24 0 "register_operand" "=R")
2635 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2639 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2640 [(set_attr "type" "imovx")
2641 (set_attr "mode" "SI")])
2643 (define_insn "*movqi_extv_1"
2644 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2645 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2650 switch (get_attr_type (insn))
2653 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2655 return "mov{b}\t{%h1, %0|%0, %h1}";
2658 [(set_attr "isa" "*,*,nox64")
2660 (if_then_else (and (match_operand:QI 0 "register_operand")
2661 (ior (not (match_operand:QI 0 "QIreg_operand"))
2662 (match_test "TARGET_MOVX")))
2663 (const_string "imovx")
2664 (const_string "imov")))
2666 (if_then_else (eq_attr "type" "imovx")
2668 (const_string "QI")))])
2670 (define_insn "*mov<mode>_extzv_1"
2671 [(set (match_operand:SWI48 0 "register_operand" "=R")
2672 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2676 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2677 [(set_attr "type" "imovx")
2678 (set_attr "mode" "SI")])
2680 (define_insn "*movqi_extzv_2"
2681 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2683 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2688 switch (get_attr_type (insn))
2691 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2693 return "mov{b}\t{%h1, %0|%0, %h1}";
2696 [(set_attr "isa" "*,*,nox64")
2698 (if_then_else (and (match_operand:QI 0 "register_operand")
2699 (ior (not (match_operand:QI 0 "QIreg_operand"))
2700 (match_test "TARGET_MOVX")))
2701 (const_string "imovx")
2702 (const_string "imov")))
2704 (if_then_else (eq_attr "type" "imovx")
2706 (const_string "QI")))])
2708 (define_insn "mov<mode>_insv_1"
2709 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2712 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2715 if (CONST_INT_P (operands[1]))
2716 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2717 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2719 [(set_attr "isa" "*,nox64")
2720 (set_attr "type" "imov")
2721 (set_attr "mode" "QI")])
2723 (define_insn "*movqi_insv_2"
2724 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2727 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2730 "mov{b}\t{%h1, %h0|%h0, %h1}"
2731 [(set_attr "type" "imov")
2732 (set_attr "mode" "QI")])
2734 ;; Floating point push instructions.
2736 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2737 (define_insn "*pushtf"
2738 [(set (match_operand:TF 0 "push_operand" "=<,<")
2739 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2740 "(TARGET_64BIT || TARGET_SSE)
2741 && (!can_create_pseudo_p ()
2742 || GET_CODE (operands[1]) != CONST_DOUBLE
2743 || standard_sse_constant_p (operands[1]))"
2745 /* This insn should be already split before reg-stack. */
2748 [(set_attr "isa" "*,x64")
2749 (set_attr "type" "multi")
2750 (set_attr "unit" "sse,*")
2751 (set_attr "mode" "TF,DI")])
2753 ;; %%% Kill this when call knows how to work this out.
2755 [(set (match_operand:TF 0 "push_operand")
2756 (match_operand:TF 1 "sse_reg_operand"))]
2757 "TARGET_SSE && reload_completed"
2758 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2759 (set (match_dup 0) (match_dup 1))]
2761 /* Preserve memory attributes. */
2762 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2765 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2766 (define_insn "*pushxf"
2767 [(set (match_operand:XF 0 "push_operand" "=<,<")
2768 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2769 "!can_create_pseudo_p ()
2770 || GET_CODE (operands[1]) != CONST_DOUBLE
2771 || standard_80387_constant_p (operands[1]) > 0"
2773 /* This insn should be already split before reg-stack. */
2776 [(set_attr "type" "multi")
2777 (set_attr "unit" "i387,*")
2779 (cond [(eq_attr "alternative" "1")
2780 (if_then_else (match_test "TARGET_64BIT")
2782 (const_string "SI"))
2784 (const_string "XF")))])
2786 ;; %%% Kill this when call knows how to work this out.
2788 [(set (match_operand:XF 0 "push_operand")
2789 (match_operand:XF 1 "fp_register_operand"))]
2791 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2792 (set (match_dup 0) (match_dup 1))]
2794 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2795 /* Preserve memory attributes. */
2796 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2799 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2800 (define_insn "*pushdf"
2801 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2802 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2803 "!can_create_pseudo_p ()
2804 || GET_CODE (operands[1]) != CONST_DOUBLE
2805 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2806 && standard_80387_constant_p (operands[1]) > 0)
2807 || (TARGET_SSE2 && TARGET_SSE_MATH
2808 && standard_sse_constant_p (operands[1]))"
2810 /* This insn should be already split before reg-stack. */
2813 [(set_attr "isa" "*,nox64,x64,sse2")
2814 (set_attr "type" "multi")
2815 (set_attr "unit" "i387,*,*,sse")
2816 (set_attr "mode" "DF,SI,DI,DF")])
2818 ;; %%% Kill this when call knows how to work this out.
2820 [(set (match_operand:DF 0 "push_operand")
2821 (match_operand:DF 1 "any_fp_register_operand"))]
2823 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2824 (set (match_dup 0) (match_dup 1))]
2826 /* Preserve memory attributes. */
2827 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2830 (define_insn "*pushsf_rex64"
2831 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2832 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2835 /* Anything else should be already split before reg-stack. */
2836 gcc_assert (which_alternative == 1);
2837 return "push{q}\t%q1";
2839 [(set_attr "type" "multi,push,multi")
2840 (set_attr "unit" "i387,*,*")
2841 (set_attr "mode" "SF,DI,SF")])
2843 (define_insn "*pushsf"
2844 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2845 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2848 /* Anything else should be already split before reg-stack. */
2849 gcc_assert (which_alternative == 1);
2850 return "push{l}\t%1";
2852 [(set_attr "type" "multi,push,multi")
2853 (set_attr "unit" "i387,*,*")
2854 (set_attr "mode" "SF,SI,SF")])
2856 ;; %%% Kill this when call knows how to work this out.
2858 [(set (match_operand:SF 0 "push_operand")
2859 (match_operand:SF 1 "any_fp_register_operand"))]
2861 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2862 (set (match_dup 0) (match_dup 1))]
2864 rtx op = XEXP (operands[0], 0);
2865 if (GET_CODE (op) == PRE_DEC)
2867 gcc_assert (!TARGET_64BIT);
2872 op = XEXP (XEXP (op, 1), 1);
2873 gcc_assert (CONST_INT_P (op));
2876 /* Preserve memory attributes. */
2877 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2881 [(set (match_operand:SF 0 "push_operand")
2882 (match_operand:SF 1 "memory_operand"))]
2884 && (operands[2] = find_constant_src (insn))"
2885 [(set (match_dup 0) (match_dup 2))])
2888 [(set (match_operand 0 "push_operand")
2889 (match_operand 1 "general_operand"))]
2891 && (GET_MODE (operands[0]) == TFmode
2892 || GET_MODE (operands[0]) == XFmode
2893 || GET_MODE (operands[0]) == DFmode)
2894 && !ANY_FP_REG_P (operands[1])"
2896 "ix86_split_long_move (operands); DONE;")
2898 ;; Floating point move instructions.
2900 (define_expand "movtf"
2901 [(set (match_operand:TF 0 "nonimmediate_operand")
2902 (match_operand:TF 1 "nonimmediate_operand"))]
2903 "TARGET_64BIT || TARGET_SSE"
2904 "ix86_expand_move (TFmode, operands); DONE;")
2906 (define_expand "mov<mode>"
2907 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2908 (match_operand:X87MODEF 1 "general_operand"))]
2910 "ix86_expand_move (<MODE>mode, operands); DONE;")
2912 (define_insn "*movtf_internal"
2913 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2914 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2915 "(TARGET_64BIT || TARGET_SSE)
2916 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2917 && (!can_create_pseudo_p ()
2918 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2919 || GET_CODE (operands[1]) != CONST_DOUBLE
2920 || (optimize_function_for_size_p (cfun)
2921 && standard_sse_constant_p (operands[1])
2922 && !memory_operand (operands[0], TFmode))
2923 || (!TARGET_MEMORY_MISMATCH_STALL
2924 && memory_operand (operands[0], TFmode)))"
2926 switch (get_attr_type (insn))
2929 return standard_sse_constant_opcode (insn, operands[1]);
2932 /* Handle misaligned load/store since we
2933 don't have movmisaligntf pattern. */
2934 if (misaligned_operand (operands[0], TFmode)
2935 || misaligned_operand (operands[1], TFmode))
2937 if (get_attr_mode (insn) == MODE_V4SF)
2938 return "%vmovups\t{%1, %0|%0, %1}";
2940 return "%vmovdqu\t{%1, %0|%0, %1}";
2944 if (get_attr_mode (insn) == MODE_V4SF)
2945 return "%vmovaps\t{%1, %0|%0, %1}";
2947 return "%vmovdqa\t{%1, %0|%0, %1}";
2957 [(set_attr "isa" "*,*,*,x64,x64")
2958 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2959 (set (attr "prefix")
2960 (if_then_else (eq_attr "type" "sselog1,ssemov")
2961 (const_string "maybe_vex")
2962 (const_string "orig")))
2964 (cond [(eq_attr "alternative" "3,4")
2966 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2967 (const_string "V4SF")
2968 (and (eq_attr "alternative" "2")
2969 (match_test "TARGET_SSE_TYPELESS_STORES"))
2970 (const_string "V4SF")
2971 (match_test "TARGET_AVX")
2973 (ior (not (match_test "TARGET_SSE2"))
2974 (match_test "optimize_function_for_size_p (cfun)"))
2975 (const_string "V4SF")
2977 (const_string "TI")))])
2979 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2980 (define_insn "*movxf_internal"
2981 [(set (match_operand:XF 0 "nonimmediate_operand"
2982 "=f,m,f,?Yx*r ,!o ,!o")
2983 (match_operand:XF 1 "general_operand"
2984 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2985 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2986 && (!can_create_pseudo_p ()
2987 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2988 || GET_CODE (operands[1]) != CONST_DOUBLE
2989 || (optimize_function_for_size_p (cfun)
2990 && standard_80387_constant_p (operands[1]) > 0
2991 && !memory_operand (operands[0], XFmode))
2992 || (!TARGET_MEMORY_MISMATCH_STALL
2993 && memory_operand (operands[0], XFmode)))"
2995 switch (get_attr_type (insn))
2998 if (which_alternative == 2)
2999 return standard_80387_constant_opcode (operands[1]);
3000 return output_387_reg_move (insn, operands);
3009 [(set_attr "isa" "*,*,*,*,nox64,x64")
3010 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3012 (cond [(eq_attr "alternative" "3,4,5")
3013 (if_then_else (match_test "TARGET_64BIT")
3015 (const_string "SI"))
3017 (const_string "XF")))])
3019 ;; Possible store forwarding (partial memory) stall in alternative 4.
3020 (define_insn "*movdf_internal"
3021 [(set (match_operand:DF 0 "nonimmediate_operand"
3022 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3023 (match_operand:DF 1 "general_operand"
3024 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3025 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026 && (!can_create_pseudo_p ()
3027 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3028 || GET_CODE (operands[1]) != CONST_DOUBLE
3029 || (optimize_function_for_size_p (cfun)
3030 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3031 && standard_80387_constant_p (operands[1]) > 0)
3032 || (TARGET_SSE2 && TARGET_SSE_MATH
3033 && standard_sse_constant_p (operands[1])))
3034 && !memory_operand (operands[0], DFmode))
3035 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3036 && memory_operand (operands[0], DFmode)))"
3038 switch (get_attr_type (insn))
3041 if (which_alternative == 2)
3042 return standard_80387_constant_opcode (operands[1]);
3043 return output_387_reg_move (insn, operands);
3049 if (get_attr_mode (insn) == MODE_SI)
3050 return "mov{l}\t{%1, %k0|%k0, %1}";
3051 else if (which_alternative == 8)
3052 return "movabs{q}\t{%1, %0|%0, %1}";
3054 return "mov{q}\t{%1, %0|%0, %1}";
3057 return standard_sse_constant_opcode (insn, operands[1]);
3060 switch (get_attr_mode (insn))
3063 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3064 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3065 return "%vmovsd\t{%1, %0|%0, %1}";
3068 return "%vmovaps\t{%1, %0|%0, %1}";
3070 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3072 return "%vmovapd\t{%1, %0|%0, %1}";
3075 gcc_assert (!TARGET_AVX);
3076 return "movlps\t{%1, %0|%0, %1}";
3078 gcc_assert (!TARGET_AVX);
3079 return "movlpd\t{%1, %0|%0, %1}";
3082 /* Handle broken assemblers that require movd instead of movq. */
3083 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3084 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3085 return "%vmovd\t{%1, %0|%0, %1}";
3086 return "%vmovq\t{%1, %0|%0, %1}";
3097 (cond [(eq_attr "alternative" "3,4")
3098 (const_string "nox64")
3099 (eq_attr "alternative" "5,6,7,8,17,18")
3100 (const_string "x64")
3101 (eq_attr "alternative" "9,10,11,12")
3102 (const_string "sse2")
3104 (const_string "*")))
3106 (cond [(eq_attr "alternative" "0,1,2")
3107 (const_string "fmov")
3108 (eq_attr "alternative" "3,4")
3109 (const_string "multi")
3110 (eq_attr "alternative" "5,6,7,8")
3111 (const_string "imov")
3112 (eq_attr "alternative" "9,13")
3113 (const_string "sselog1")
3115 (const_string "ssemov")))
3117 (if_then_else (eq_attr "alternative" "8")
3119 (const_string "*")))
3120 (set (attr "length_immediate")
3121 (if_then_else (eq_attr "alternative" "8")
3123 (const_string "*")))
3124 (set (attr "prefix")
3125 (if_then_else (eq_attr "type" "sselog1,ssemov")
3126 (const_string "maybe_vex")
3127 (const_string "orig")))
3128 (set (attr "prefix_data16")
3130 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3131 (eq_attr "mode" "V1DF"))
3133 (const_string "*")))
3135 (cond [(eq_attr "alternative" "3,4,7")
3137 (eq_attr "alternative" "5,6,8,17,18")
3140 /* xorps is one byte shorter for non-AVX targets. */
3141 (eq_attr "alternative" "9,13")
3142 (cond [(not (match_test "TARGET_SSE2"))
3143 (const_string "V4SF")
3144 (match_test "TARGET_AVX512F")
3146 (match_test "TARGET_AVX")
3147 (const_string "V2DF")
3148 (match_test "optimize_function_for_size_p (cfun)")
3149 (const_string "V4SF")
3150 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3153 (const_string "V2DF"))
3155 /* For architectures resolving dependencies on
3156 whole SSE registers use movapd to break dependency
3157 chains, otherwise use short move to avoid extra work. */
3159 /* movaps is one byte shorter for non-AVX targets. */
3160 (eq_attr "alternative" "10,14")
3161 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3162 (match_operand 1 "ext_sse_reg_operand"))
3163 (const_string "V8DF")
3164 (ior (not (match_test "TARGET_SSE2"))
3165 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3166 (const_string "V4SF")
3167 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3168 (const_string "V2DF")
3169 (match_test "TARGET_AVX")
3171 (match_test "optimize_function_for_size_p (cfun)")
3172 (const_string "V4SF")
3174 (const_string "DF"))
3176 /* For architectures resolving dependencies on register
3177 parts we may avoid extra work to zero out upper part
3179 (eq_attr "alternative" "11,15")
3180 (cond [(not (match_test "TARGET_SSE2"))
3181 (const_string "V2SF")
3182 (match_test "TARGET_AVX")
3184 (match_test "TARGET_SSE_SPLIT_REGS")
3185 (const_string "V1DF")
3187 (const_string "DF"))
3189 (and (eq_attr "alternative" "12,16")
3190 (not (match_test "TARGET_SSE2")))
3191 (const_string "V2SF")
3193 (const_string "DF")))])
3195 (define_insn "*movsf_internal"
3196 [(set (match_operand:SF 0 "nonimmediate_operand"
3197 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3198 (match_operand:SF 1 "general_operand"
3199 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3200 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201 && (!can_create_pseudo_p ()
3202 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203 || GET_CODE (operands[1]) != CONST_DOUBLE
3204 || (optimize_function_for_size_p (cfun)
3205 && ((!TARGET_SSE_MATH
3206 && standard_80387_constant_p (operands[1]) > 0)
3208 && standard_sse_constant_p (operands[1]))))
3209 || memory_operand (operands[0], SFmode))"
3211 switch (get_attr_type (insn))
3214 if (which_alternative == 2)
3215 return standard_80387_constant_opcode (operands[1]);
3216 return output_387_reg_move (insn, operands);
3219 return "mov{l}\t{%1, %0|%0, %1}";
3222 return standard_sse_constant_opcode (insn, operands[1]);
3225 switch (get_attr_mode (insn))
3228 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3229 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3230 return "%vmovss\t{%1, %0|%0, %1}";
3233 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3235 return "%vmovaps\t{%1, %0|%0, %1}";
3238 return "%vmovd\t{%1, %0|%0, %1}";
3245 switch (get_attr_mode (insn))
3248 return "movq\t{%1, %0|%0, %1}";
3250 return "movd\t{%1, %0|%0, %1}";
3261 (cond [(eq_attr "alternative" "0,1,2")
3262 (const_string "fmov")
3263 (eq_attr "alternative" "3,4")
3264 (const_string "imov")
3265 (eq_attr "alternative" "5")
3266 (const_string "sselog1")
3267 (eq_attr "alternative" "11,12,13,14,15")
3268 (const_string "mmxmov")
3270 (const_string "ssemov")))
3271 (set (attr "prefix")
3272 (if_then_else (eq_attr "type" "sselog1,ssemov")
3273 (const_string "maybe_vex")
3274 (const_string "orig")))
3275 (set (attr "prefix_data16")
3276 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3278 (const_string "*")))
3280 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3282 (eq_attr "alternative" "11")
3284 (eq_attr "alternative" "5")
3285 (cond [(not (match_test "TARGET_SSE2"))
3286 (const_string "V4SF")
3287 (match_test "TARGET_AVX512F")
3288 (const_string "V16SF")
3289 (match_test "TARGET_AVX")
3290 (const_string "V4SF")
3291 (match_test "optimize_function_for_size_p (cfun)")
3292 (const_string "V4SF")
3293 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3296 (const_string "V4SF"))
3298 /* For architectures resolving dependencies on
3299 whole SSE registers use APS move to break dependency
3300 chains, otherwise use short move to avoid extra work.
3302 Do the same for architectures resolving dependencies on
3303 the parts. While in DF mode it is better to always handle
3304 just register parts, the SF mode is different due to lack
3305 of instructions to load just part of the register. It is
3306 better to maintain the whole registers in single format
3307 to avoid problems on using packed logical operations. */
3308 (eq_attr "alternative" "6")
3309 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3310 (match_operand 1 "ext_sse_reg_operand"))
3311 (const_string "V16SF")
3312 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3313 (match_test "TARGET_SSE_SPLIT_REGS"))
3314 (const_string "V4SF")
3316 (const_string "SF"))
3318 (const_string "SF")))])
3321 [(set (match_operand 0 "any_fp_register_operand")
3322 (match_operand 1 "memory_operand"))]
3324 && (GET_MODE (operands[0]) == TFmode
3325 || GET_MODE (operands[0]) == XFmode
3326 || GET_MODE (operands[0]) == DFmode
3327 || GET_MODE (operands[0]) == SFmode)
3328 && (operands[2] = find_constant_src (insn))"
3329 [(set (match_dup 0) (match_dup 2))]
3331 rtx c = operands[2];
3332 int r = REGNO (operands[0]);
3334 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3335 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3340 [(set (match_operand 0 "any_fp_register_operand")
3341 (float_extend (match_operand 1 "memory_operand")))]
3343 && (GET_MODE (operands[0]) == TFmode
3344 || GET_MODE (operands[0]) == XFmode
3345 || GET_MODE (operands[0]) == DFmode)
3346 && (operands[2] = find_constant_src (insn))"
3347 [(set (match_dup 0) (match_dup 2))]
3349 rtx c = operands[2];
3350 int r = REGNO (operands[0]);
3352 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3353 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3359 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3360 (match_operand:X87MODEF 1 "immediate_operand"))]
3362 && (standard_80387_constant_p (operands[1]) == 8
3363 || standard_80387_constant_p (operands[1]) == 9)"
3364 [(set (match_dup 0)(match_dup 1))
3366 (neg:X87MODEF (match_dup 0)))]
3370 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371 if (real_isnegzero (&r))
3372 operands[1] = CONST0_RTX (<MODE>mode);
3374 operands[1] = CONST1_RTX (<MODE>mode);
3378 [(set (match_operand 0 "nonimmediate_operand")
3379 (match_operand 1 "general_operand"))]
3381 && (GET_MODE (operands[0]) == TFmode
3382 || GET_MODE (operands[0]) == XFmode
3383 || GET_MODE (operands[0]) == DFmode)
3384 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3386 "ix86_split_long_move (operands); DONE;")
3388 (define_insn "swapxf"
3389 [(set (match_operand:XF 0 "register_operand" "+f")
3390 (match_operand:XF 1 "register_operand" "+f"))
3395 if (STACK_TOP_P (operands[0]))
3400 [(set_attr "type" "fxch")
3401 (set_attr "mode" "XF")])
3403 (define_insn "*swap<mode>"
3404 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3405 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3408 "TARGET_80387 || reload_completed"
3410 if (STACK_TOP_P (operands[0]))
3415 [(set_attr "type" "fxch")
3416 (set_attr "mode" "<MODE>")])
3418 ;; Zero extension instructions
3420 (define_expand "zero_extendsidi2"
3421 [(set (match_operand:DI 0 "nonimmediate_operand")
3422 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3424 (define_insn "*zero_extendsidi2"
3425 [(set (match_operand:DI 0 "nonimmediate_operand"
3426 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3428 (match_operand:SI 1 "x86_64_zext_operand"
3429 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3432 switch (get_attr_type (insn))
3435 if (ix86_use_lea_for_mov (insn, operands))
3436 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3438 return "mov{l}\t{%1, %k0|%k0, %1}";
3444 return "movd\t{%1, %0|%0, %1}";
3447 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3450 if (GENERAL_REG_P (operands[0]))
3451 return "%vmovd\t{%1, %k0|%k0, %1}";
3453 return "%vmovd\t{%1, %0|%0, %1}";
3460 (cond [(eq_attr "alternative" "0,1,2")
3461 (const_string "nox64")
3462 (eq_attr "alternative" "3,7")
3463 (const_string "x64")
3464 (eq_attr "alternative" "8")
3465 (const_string "x64_sse4")
3466 (eq_attr "alternative" "10")
3467 (const_string "sse2")
3469 (const_string "*")))
3471 (cond [(eq_attr "alternative" "0,1,2,4")
3472 (const_string "multi")
3473 (eq_attr "alternative" "5,6")
3474 (const_string "mmxmov")
3475 (eq_attr "alternative" "7,9,10")
3476 (const_string "ssemov")
3477 (eq_attr "alternative" "8")
3478 (const_string "sselog1")
3480 (const_string "imovx")))
3481 (set (attr "prefix_extra")
3482 (if_then_else (eq_attr "alternative" "8")
3484 (const_string "*")))
3485 (set (attr "length_immediate")
3486 (if_then_else (eq_attr "alternative" "8")
3488 (const_string "*")))
3489 (set (attr "prefix")
3490 (if_then_else (eq_attr "type" "ssemov,sselog1")
3491 (const_string "maybe_vex")
3492 (const_string "orig")))
3493 (set (attr "prefix_0f")
3494 (if_then_else (eq_attr "type" "imovx")
3496 (const_string "*")))
3498 (cond [(eq_attr "alternative" "5,6")
3500 (eq_attr "alternative" "7,8,9")
3503 (const_string "SI")))])
3506 [(set (match_operand:DI 0 "memory_operand")
3507 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3509 [(set (match_dup 4) (const_int 0))]
3510 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3513 [(set (match_operand:DI 0 "register_operand")
3514 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3515 "!TARGET_64BIT && reload_completed
3516 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3517 && true_regnum (operands[0]) == true_regnum (operands[1])"
3518 [(set (match_dup 4) (const_int 0))]
3519 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3522 [(set (match_operand:DI 0 "nonimmediate_operand")
3523 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3524 "!TARGET_64BIT && reload_completed
3525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3526 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3527 [(set (match_dup 3) (match_dup 1))
3528 (set (match_dup 4) (const_int 0))]
3529 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3531 (define_insn "zero_extend<mode>di2"
3532 [(set (match_operand:DI 0 "register_operand" "=r")
3534 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3536 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3537 [(set_attr "type" "imovx")
3538 (set_attr "mode" "SI")])
3540 (define_expand "zero_extend<mode>si2"
3541 [(set (match_operand:SI 0 "register_operand")
3542 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3545 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3547 operands[1] = force_reg (<MODE>mode, operands[1]);
3548 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3553 (define_insn_and_split "zero_extend<mode>si2_and"
3554 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3556 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3557 (clobber (reg:CC FLAGS_REG))]
3558 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3560 "&& reload_completed"
3561 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3562 (clobber (reg:CC FLAGS_REG))])]
3564 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3566 ix86_expand_clear (operands[0]);
3568 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3569 emit_insn (gen_movstrict<mode>
3570 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3574 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3576 [(set_attr "type" "alu1")
3577 (set_attr "mode" "SI")])
3579 (define_insn "*zero_extend<mode>si2"
3580 [(set (match_operand:SI 0 "register_operand" "=r")
3582 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3583 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3584 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "SI")])
3588 (define_expand "zero_extendqihi2"
3589 [(set (match_operand:HI 0 "register_operand")
3590 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3593 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3595 operands[1] = force_reg (QImode, operands[1]);
3596 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3601 (define_insn_and_split "zero_extendqihi2_and"
3602 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3603 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3604 (clobber (reg:CC FLAGS_REG))]
3605 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3607 "&& reload_completed"
3608 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3609 (clobber (reg:CC FLAGS_REG))])]
3611 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3613 ix86_expand_clear (operands[0]);
3615 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3616 emit_insn (gen_movstrictqi
3617 (gen_lowpart (QImode, operands[0]), operands[1]));
3621 operands[0] = gen_lowpart (SImode, operands[0]);
3623 [(set_attr "type" "alu1")
3624 (set_attr "mode" "SI")])
3626 ; zero extend to SImode to avoid partial register stalls
3627 (define_insn "*zero_extendqihi2"
3628 [(set (match_operand:HI 0 "register_operand" "=r")
3629 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3630 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3631 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3632 [(set_attr "type" "imovx")
3633 (set_attr "mode" "SI")])
3635 ;; Sign extension instructions
3637 (define_expand "extendsidi2"
3638 [(set (match_operand:DI 0 "register_operand")
3639 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3644 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3649 (define_insn "*extendsidi2_rex64"
3650 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3651 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3655 movs{lq|x}\t{%1, %0|%0, %1}"
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "DI")
3658 (set_attr "prefix_0f" "0")
3659 (set_attr "modrm" "0,1")])
3661 (define_insn "extendsidi2_1"
3662 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3663 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3664 (clobber (reg:CC FLAGS_REG))
3665 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3669 ;; Split the memory case. If the source register doesn't die, it will stay
3670 ;; this way, if it does die, following peephole2s take care of it.
3672 [(set (match_operand:DI 0 "memory_operand")
3673 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3674 (clobber (reg:CC FLAGS_REG))
3675 (clobber (match_operand:SI 2 "register_operand"))]
3679 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3681 emit_move_insn (operands[3], operands[1]);
3683 /* Generate a cltd if possible and doing so it profitable. */
3684 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3685 && true_regnum (operands[1]) == AX_REG
3686 && true_regnum (operands[2]) == DX_REG)
3688 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3692 emit_move_insn (operands[2], operands[1]);
3693 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3695 emit_move_insn (operands[4], operands[2]);
3699 ;; Peepholes for the case where the source register does die, after
3700 ;; being split with the above splitter.
3702 [(set (match_operand:SI 0 "memory_operand")
3703 (match_operand:SI 1 "register_operand"))
3704 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3705 (parallel [(set (match_dup 2)
3706 (ashiftrt:SI (match_dup 2) (const_int 31)))
3707 (clobber (reg:CC FLAGS_REG))])
3708 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3709 "REGNO (operands[1]) != REGNO (operands[2])
3710 && peep2_reg_dead_p (2, operands[1])
3711 && peep2_reg_dead_p (4, operands[2])
3712 && !reg_mentioned_p (operands[2], operands[3])"
3713 [(set (match_dup 0) (match_dup 1))
3714 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3715 (clobber (reg:CC FLAGS_REG))])
3716 (set (match_dup 3) (match_dup 1))])
3719 [(set (match_operand:SI 0 "memory_operand")
3720 (match_operand:SI 1 "register_operand"))
3721 (parallel [(set (match_operand:SI 2 "register_operand")
3722 (ashiftrt:SI (match_dup 1) (const_int 31)))
3723 (clobber (reg:CC FLAGS_REG))])
3724 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3725 "/* cltd is shorter than sarl $31, %eax */
3726 !optimize_function_for_size_p (cfun)
3727 && true_regnum (operands[1]) == AX_REG
3728 && true_regnum (operands[2]) == DX_REG
3729 && peep2_reg_dead_p (2, operands[1])
3730 && peep2_reg_dead_p (3, operands[2])
3731 && !reg_mentioned_p (operands[2], operands[3])"
3732 [(set (match_dup 0) (match_dup 1))
3733 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3734 (clobber (reg:CC FLAGS_REG))])
3735 (set (match_dup 3) (match_dup 1))])
3737 ;; Extend to register case. Optimize case where source and destination
3738 ;; registers match and cases where we can use cltd.
3740 [(set (match_operand:DI 0 "register_operand")
3741 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3742 (clobber (reg:CC FLAGS_REG))
3743 (clobber (match_scratch:SI 2))]
3747 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3749 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3750 emit_move_insn (operands[3], operands[1]);
3752 /* Generate a cltd if possible and doing so it profitable. */
3753 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3754 && true_regnum (operands[3]) == AX_REG
3755 && true_regnum (operands[4]) == DX_REG)
3757 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3761 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3762 emit_move_insn (operands[4], operands[1]);
3764 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3768 (define_insn "extend<mode>di2"
3769 [(set (match_operand:DI 0 "register_operand" "=r")
3771 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3773 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3774 [(set_attr "type" "imovx")
3775 (set_attr "mode" "DI")])
3777 (define_insn "extendhisi2"
3778 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3779 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3782 switch (get_attr_prefix_0f (insn))
3785 return "{cwtl|cwde}";
3787 return "movs{wl|x}\t{%1, %0|%0, %1}";
3790 [(set_attr "type" "imovx")
3791 (set_attr "mode" "SI")
3792 (set (attr "prefix_0f")
3793 ;; movsx is short decodable while cwtl is vector decoded.
3794 (if_then_else (and (eq_attr "cpu" "!k6")
3795 (eq_attr "alternative" "0"))
3797 (const_string "1")))
3799 (if_then_else (eq_attr "prefix_0f" "0")
3801 (const_string "1")))])
3803 (define_insn "*extendhisi2_zext"
3804 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3807 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3810 switch (get_attr_prefix_0f (insn))
3813 return "{cwtl|cwde}";
3815 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3818 [(set_attr "type" "imovx")
3819 (set_attr "mode" "SI")
3820 (set (attr "prefix_0f")
3821 ;; movsx is short decodable while cwtl is vector decoded.
3822 (if_then_else (and (eq_attr "cpu" "!k6")
3823 (eq_attr "alternative" "0"))
3825 (const_string "1")))
3827 (if_then_else (eq_attr "prefix_0f" "0")
3829 (const_string "1")))])
3831 (define_insn "extendqisi2"
3832 [(set (match_operand:SI 0 "register_operand" "=r")
3833 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3835 "movs{bl|x}\t{%1, %0|%0, %1}"
3836 [(set_attr "type" "imovx")
3837 (set_attr "mode" "SI")])
3839 (define_insn "*extendqisi2_zext"
3840 [(set (match_operand:DI 0 "register_operand" "=r")
3842 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3844 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3845 [(set_attr "type" "imovx")
3846 (set_attr "mode" "SI")])
3848 (define_insn "extendqihi2"
3849 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3850 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3853 switch (get_attr_prefix_0f (insn))
3856 return "{cbtw|cbw}";
3858 return "movs{bw|x}\t{%1, %0|%0, %1}";
3861 [(set_attr "type" "imovx")
3862 (set_attr "mode" "HI")
3863 (set (attr "prefix_0f")
3864 ;; movsx is short decodable while cwtl is vector decoded.
3865 (if_then_else (and (eq_attr "cpu" "!k6")
3866 (eq_attr "alternative" "0"))
3868 (const_string "1")))
3870 (if_then_else (eq_attr "prefix_0f" "0")
3872 (const_string "1")))])
3874 ;; Conversions between float and double.
3876 ;; These are all no-ops in the model used for the 80387.
3877 ;; So just emit moves.
3879 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3881 [(set (match_operand:DF 0 "push_operand")
3882 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3884 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3885 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3888 [(set (match_operand:XF 0 "push_operand")
3889 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3891 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3892 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3893 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3895 (define_expand "extendsfdf2"
3896 [(set (match_operand:DF 0 "nonimmediate_operand")
3897 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3898 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3900 /* ??? Needed for compress_float_constant since all fp constants
3901 are TARGET_LEGITIMATE_CONSTANT_P. */
3902 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3904 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3905 && standard_80387_constant_p (operands[1]) > 0)
3907 operands[1] = simplify_const_unary_operation
3908 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3909 emit_move_insn_1 (operands[0], operands[1]);
3912 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3916 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3918 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3920 We do the conversion post reload to avoid producing of 128bit spills
3921 that might lead to ICE on 32bit target. The sequence unlikely combine
3924 [(set (match_operand:DF 0 "register_operand")
3926 (match_operand:SF 1 "nonimmediate_operand")))]
3927 "TARGET_USE_VECTOR_FP_CONVERTS
3928 && optimize_insn_for_speed_p ()
3929 && reload_completed && SSE_REG_P (operands[0])"
3934 (parallel [(const_int 0) (const_int 1)]))))]
3936 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3937 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3938 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3939 Try to avoid move when unpacking can be done in source. */
3940 if (REG_P (operands[1]))
3942 /* If it is unsafe to overwrite upper half of source, we need
3943 to move to destination and unpack there. */
3944 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3945 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3946 && true_regnum (operands[0]) != true_regnum (operands[1]))
3948 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3949 emit_move_insn (tmp, operands[1]);
3952 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3953 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3957 emit_insn (gen_vec_setv4sf_0 (operands[3],
3958 CONST0_RTX (V4SFmode), operands[1]));
3961 ;; It's more profitable to split and then extend in the same register.
3963 [(set (match_operand:DF 0 "register_operand")
3965 (match_operand:SF 1 "memory_operand")))]
3966 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3967 && optimize_insn_for_speed_p ()
3968 && SSE_REG_P (operands[0])"
3969 [(set (match_dup 2) (match_dup 1))
3970 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3971 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3973 (define_insn "*extendsfdf2_mixed"
3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3976 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3977 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3979 switch (which_alternative)
3983 return output_387_reg_move (insn, operands);
3986 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3992 [(set_attr "type" "fmov,fmov,ssecvt")
3993 (set_attr "prefix" "orig,orig,maybe_vex")
3994 (set_attr "mode" "SF,XF,DF")])
3996 (define_insn "*extendsfdf2_sse"
3997 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3998 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3999 "TARGET_SSE2 && TARGET_SSE_MATH"
4000 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4001 [(set_attr "type" "ssecvt")
4002 (set_attr "prefix" "maybe_vex")
4003 (set_attr "mode" "DF")])
4005 (define_insn "*extendsfdf2_i387"
4006 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4007 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4009 "* return output_387_reg_move (insn, operands);"
4010 [(set_attr "type" "fmov")
4011 (set_attr "mode" "SF,XF")])
4013 (define_expand "extend<mode>xf2"
4014 [(set (match_operand:XF 0 "nonimmediate_operand")
4015 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4018 /* ??? Needed for compress_float_constant since all fp constants
4019 are TARGET_LEGITIMATE_CONSTANT_P. */
4020 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4022 if (standard_80387_constant_p (operands[1]) > 0)
4024 operands[1] = simplify_const_unary_operation
4025 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4026 emit_move_insn_1 (operands[0], operands[1]);
4029 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4033 (define_insn "*extend<mode>xf2_i387"
4034 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4036 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4038 "* return output_387_reg_move (insn, operands);"
4039 [(set_attr "type" "fmov")
4040 (set_attr "mode" "<MODE>,XF")])
4042 ;; %%% This seems bad bad news.
4043 ;; This cannot output into an f-reg because there is no way to be sure
4044 ;; of truncating in that case. Otherwise this is just like a simple move
4045 ;; insn. So we pretend we can output to a reg in order to get better
4046 ;; register preferencing, but we really use a stack slot.
4048 ;; Conversion from DFmode to SFmode.
4050 (define_expand "truncdfsf2"
4051 [(set (match_operand:SF 0 "nonimmediate_operand")
4053 (match_operand:DF 1 "nonimmediate_operand")))]
4054 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4056 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4058 else if (flag_unsafe_math_optimizations)
4062 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4063 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4068 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4070 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4072 We do the conversion post reload to avoid producing of 128bit spills
4073 that might lead to ICE on 32bit target. The sequence unlikely combine
4076 [(set (match_operand:SF 0 "register_operand")
4078 (match_operand:DF 1 "nonimmediate_operand")))]
4079 "TARGET_USE_VECTOR_FP_CONVERTS
4080 && optimize_insn_for_speed_p ()
4081 && reload_completed && SSE_REG_P (operands[0])"
4084 (float_truncate:V2SF
4088 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4089 operands[3] = CONST0_RTX (V2SFmode);
4090 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4091 /* Use movsd for loading from memory, unpcklpd for registers.
4092 Try to avoid move when unpacking can be done in source, or SSE3
4093 movddup is available. */
4094 if (REG_P (operands[1]))
4097 && true_regnum (operands[0]) != true_regnum (operands[1])
4098 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4099 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4101 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4102 emit_move_insn (tmp, operands[1]);
4105 else if (!TARGET_SSE3)
4106 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4107 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4110 emit_insn (gen_sse2_loadlpd (operands[4],
4111 CONST0_RTX (V2DFmode), operands[1]));
4114 ;; It's more profitable to split and then extend in the same register.
4116 [(set (match_operand:SF 0 "register_operand")
4118 (match_operand:DF 1 "memory_operand")))]
4119 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4120 && optimize_insn_for_speed_p ()
4121 && SSE_REG_P (operands[0])"
4122 [(set (match_dup 2) (match_dup 1))
4123 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4124 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4126 (define_expand "truncdfsf2_with_temp"
4127 [(parallel [(set (match_operand:SF 0)
4128 (float_truncate:SF (match_operand:DF 1)))
4129 (clobber (match_operand:SF 2))])])
4131 (define_insn "*truncdfsf_fast_mixed"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4134 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4135 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4137 switch (which_alternative)
4140 return output_387_reg_move (insn, operands);
4142 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4147 [(set_attr "type" "fmov,ssecvt")
4148 (set_attr "prefix" "orig,maybe_vex")
4149 (set_attr "mode" "SF")])
4151 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4152 ;; because nothing we do here is unsafe.
4153 (define_insn "*truncdfsf_fast_sse"
4154 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4156 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4157 "TARGET_SSE2 && TARGET_SSE_MATH"
4158 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4159 [(set_attr "type" "ssecvt")
4160 (set_attr "prefix" "maybe_vex")
4161 (set_attr "mode" "SF")])
4163 (define_insn "*truncdfsf_fast_i387"
4164 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4166 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4167 "TARGET_80387 && flag_unsafe_math_optimizations"
4168 "* return output_387_reg_move (insn, operands);"
4169 [(set_attr "type" "fmov")
4170 (set_attr "mode" "SF")])
4172 (define_insn "*truncdfsf_mixed"
4173 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4175 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4176 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4177 "TARGET_MIX_SSE_I387"
4179 switch (which_alternative)
4182 return output_387_reg_move (insn, operands);
4184 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4190 [(set_attr "isa" "*,sse2,*,*,*")
4191 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4192 (set_attr "unit" "*,*,i387,i387,i387")
4193 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4194 (set_attr "mode" "SF")])
4196 (define_insn "*truncdfsf_i387"
4197 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4199 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4200 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4203 switch (which_alternative)
4206 return output_387_reg_move (insn, operands);
4212 [(set_attr "type" "fmov,multi,multi,multi")
4213 (set_attr "unit" "*,i387,i387,i387")
4214 (set_attr "mode" "SF")])
4216 (define_insn "*truncdfsf2_i387_1"
4217 [(set (match_operand:SF 0 "memory_operand" "=m")
4219 (match_operand:DF 1 "register_operand" "f")))]
4221 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4222 && !TARGET_MIX_SSE_I387"
4223 "* return output_387_reg_move (insn, operands);"
4224 [(set_attr "type" "fmov")
4225 (set_attr "mode" "SF")])
4228 [(set (match_operand:SF 0 "register_operand")
4230 (match_operand:DF 1 "fp_register_operand")))
4231 (clobber (match_operand 2))]
4233 [(set (match_dup 2) (match_dup 1))
4234 (set (match_dup 0) (match_dup 2))]
4235 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4237 ;; Conversion from XFmode to {SF,DF}mode
4239 (define_expand "truncxf<mode>2"
4240 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4241 (float_truncate:MODEF
4242 (match_operand:XF 1 "register_operand")))
4243 (clobber (match_dup 2))])]
4246 if (flag_unsafe_math_optimizations)
4248 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4249 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4250 if (reg != operands[0])
4251 emit_move_insn (operands[0], reg);
4255 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4258 (define_insn "*truncxfsf2_mixed"
4259 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4261 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4262 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4265 gcc_assert (!which_alternative);
4266 return output_387_reg_move (insn, operands);
4268 [(set_attr "type" "fmov,multi,multi,multi")
4269 (set_attr "unit" "*,i387,i387,i387")
4270 (set_attr "mode" "SF")])
4272 (define_insn "*truncxfdf2_mixed"
4273 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4275 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4276 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4279 gcc_assert (!which_alternative);
4280 return output_387_reg_move (insn, operands);
4282 [(set_attr "isa" "*,*,sse2,*")
4283 (set_attr "type" "fmov,multi,multi,multi")
4284 (set_attr "unit" "*,i387,i387,i387")
4285 (set_attr "mode" "DF")])
4287 (define_insn "truncxf<mode>2_i387_noop"
4288 [(set (match_operand:MODEF 0 "register_operand" "=f")
4289 (float_truncate:MODEF
4290 (match_operand:XF 1 "register_operand" "f")))]
4291 "TARGET_80387 && flag_unsafe_math_optimizations"
4292 "* return output_387_reg_move (insn, operands);"
4293 [(set_attr "type" "fmov")
4294 (set_attr "mode" "<MODE>")])
4296 (define_insn "*truncxf<mode>2_i387"
4297 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4298 (float_truncate:MODEF
4299 (match_operand:XF 1 "register_operand" "f")))]
4301 "* return output_387_reg_move (insn, operands);"
4302 [(set_attr "type" "fmov")
4303 (set_attr "mode" "<MODE>")])
4306 [(set (match_operand:MODEF 0 "register_operand")
4307 (float_truncate:MODEF
4308 (match_operand:XF 1 "register_operand")))
4309 (clobber (match_operand:MODEF 2 "memory_operand"))]
4310 "TARGET_80387 && reload_completed"
4311 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4312 (set (match_dup 0) (match_dup 2))])
4315 [(set (match_operand:MODEF 0 "memory_operand")
4316 (float_truncate:MODEF
4317 (match_operand:XF 1 "register_operand")))
4318 (clobber (match_operand:MODEF 2 "memory_operand"))]
4320 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4322 ;; Signed conversion to DImode.
4324 (define_expand "fix_truncxfdi2"
4325 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4326 (fix:DI (match_operand:XF 1 "register_operand")))
4327 (clobber (reg:CC FLAGS_REG))])]
4332 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4337 (define_expand "fix_trunc<mode>di2"
4338 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4339 (fix:DI (match_operand:MODEF 1 "register_operand")))
4340 (clobber (reg:CC FLAGS_REG))])]
4341 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4344 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4346 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4349 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4351 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4352 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4353 if (out != operands[0])
4354 emit_move_insn (operands[0], out);
4359 ;; Signed conversion to SImode.
4361 (define_expand "fix_truncxfsi2"
4362 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4363 (fix:SI (match_operand:XF 1 "register_operand")))
4364 (clobber (reg:CC FLAGS_REG))])]
4369 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4374 (define_expand "fix_trunc<mode>si2"
4375 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4376 (fix:SI (match_operand:MODEF 1 "register_operand")))
4377 (clobber (reg:CC FLAGS_REG))])]
4378 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4381 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4383 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4386 if (SSE_FLOAT_MODE_P (<MODE>mode))
4388 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4389 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4390 if (out != operands[0])
4391 emit_move_insn (operands[0], out);
4396 ;; Signed conversion to HImode.
4398 (define_expand "fix_trunc<mode>hi2"
4399 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4400 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4401 (clobber (reg:CC FLAGS_REG))])]
4403 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4407 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4412 ;; Unsigned conversion to SImode.
4414 (define_expand "fixuns_trunc<mode>si2"
4416 [(set (match_operand:SI 0 "register_operand")
4418 (match_operand:MODEF 1 "nonimmediate_operand")))
4420 (clobber (match_scratch:<ssevecmode> 3))
4421 (clobber (match_scratch:<ssevecmode> 4))])]
4422 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4424 machine_mode mode = <MODE>mode;
4425 machine_mode vecmode = <ssevecmode>mode;
4426 REAL_VALUE_TYPE TWO31r;
4429 if (optimize_insn_for_size_p ())
4432 real_ldexp (&TWO31r, &dconst1, 31);
4433 two31 = const_double_from_real_value (TWO31r, mode);
4434 two31 = ix86_build_const_vector (vecmode, true, two31);
4435 operands[2] = force_reg (vecmode, two31);
4438 (define_insn_and_split "*fixuns_trunc<mode>_1"
4439 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4441 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4442 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4443 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4444 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4445 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4446 && optimize_function_for_speed_p (cfun)"
4448 "&& reload_completed"
4451 ix86_split_convert_uns_si_sse (operands);
4455 ;; Unsigned conversion to HImode.
4456 ;; Without these patterns, we'll try the unsigned SI conversion which
4457 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4459 (define_expand "fixuns_trunc<mode>hi2"
4461 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4462 (set (match_operand:HI 0 "nonimmediate_operand")
4463 (subreg:HI (match_dup 2) 0))]
4464 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4465 "operands[2] = gen_reg_rtx (SImode);")
4467 ;; When SSE is available, it is always faster to use it!
4468 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4469 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4470 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4471 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4472 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4473 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4474 [(set_attr "type" "sseicvt")
4475 (set_attr "prefix" "maybe_vex")
4476 (set (attr "prefix_rex")
4478 (match_test "<SWI48:MODE>mode == DImode")
4480 (const_string "*")))
4481 (set_attr "mode" "<MODEF:MODE>")
4482 (set_attr "athlon_decode" "double,vector")
4483 (set_attr "amdfam10_decode" "double,double")
4484 (set_attr "bdver1_decode" "double,double")])
4486 ;; Avoid vector decoded forms of the instruction.
4488 [(match_scratch:MODEF 2 "x")
4489 (set (match_operand:SWI48 0 "register_operand")
4490 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4491 "TARGET_AVOID_VECTOR_DECODE
4492 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4493 && optimize_insn_for_speed_p ()"
4494 [(set (match_dup 2) (match_dup 1))
4495 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4497 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4498 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4499 (fix:SWI248x (match_operand 1 "register_operand")))]
4500 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4502 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4503 && (TARGET_64BIT || <MODE>mode != DImode))
4505 && can_create_pseudo_p ()"
4510 if (memory_operand (operands[0], VOIDmode))
4511 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4514 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4515 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4521 [(set_attr "type" "fisttp")
4522 (set_attr "mode" "<MODE>")])
4524 (define_insn "fix_trunc<mode>_i387_fisttp"
4525 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4526 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4527 (clobber (match_scratch:XF 2 "=&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && (TARGET_64BIT || <MODE>mode != DImode))
4532 && TARGET_SSE_MATH)"
4533 "* return output_fix_trunc (insn, operands, true);"
4534 [(set_attr "type" "fisttp")
4535 (set_attr "mode" "<MODE>")])
4537 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4538 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4539 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4540 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4541 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && (TARGET_64BIT || <MODE>mode != DImode))
4546 && TARGET_SSE_MATH)"
4548 [(set_attr "type" "fisttp")
4549 (set_attr "mode" "<MODE>")])
4552 [(set (match_operand:SWI248x 0 "register_operand")
4553 (fix:SWI248x (match_operand 1 "register_operand")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand"))
4555 (clobber (match_scratch 3))]
4557 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4558 (clobber (match_dup 3))])
4559 (set (match_dup 0) (match_dup 2))])
4562 [(set (match_operand:SWI248x 0 "memory_operand")
4563 (fix:SWI248x (match_operand 1 "register_operand")))
4564 (clobber (match_operand:SWI248x 2 "memory_operand"))
4565 (clobber (match_scratch 3))]
4567 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4568 (clobber (match_dup 3))])])
4570 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4571 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4572 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4573 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4574 ;; function in i386.c.
4575 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4576 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4577 (fix:SWI248x (match_operand 1 "register_operand")))
4578 (clobber (reg:CC FLAGS_REG))]
4579 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4582 && (TARGET_64BIT || <MODE>mode != DImode))
4583 && can_create_pseudo_p ()"
4588 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4590 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4591 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4592 if (memory_operand (operands[0], VOIDmode))
4593 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4594 operands[2], operands[3]));
4597 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4598 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4599 operands[2], operands[3],
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "<MODE>")])
4608 (define_insn "fix_truncdi_i387"
4609 [(set (match_operand:DI 0 "memory_operand" "=m")
4610 (fix:DI (match_operand 1 "register_operand" "f")))
4611 (use (match_operand:HI 2 "memory_operand" "m"))
4612 (use (match_operand:HI 3 "memory_operand" "m"))
4613 (clobber (match_scratch:XF 4 "=&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617 "* return output_fix_trunc (insn, operands, false);"
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "DI")])
4622 (define_insn "fix_truncdi_i387_with_temp"
4623 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4624 (fix:DI (match_operand 1 "register_operand" "f,f")))
4625 (use (match_operand:HI 2 "memory_operand" "m,m"))
4626 (use (match_operand:HI 3 "memory_operand" "m,m"))
4627 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4628 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4629 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4633 [(set_attr "type" "fistp")
4634 (set_attr "i387_cw" "trunc")
4635 (set_attr "mode" "DI")])
4638 [(set (match_operand:DI 0 "register_operand")
4639 (fix:DI (match_operand 1 "register_operand")))
4640 (use (match_operand:HI 2 "memory_operand"))
4641 (use (match_operand:HI 3 "memory_operand"))
4642 (clobber (match_operand:DI 4 "memory_operand"))
4643 (clobber (match_scratch 5))]
4645 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4648 (clobber (match_dup 5))])
4649 (set (match_dup 0) (match_dup 4))])
4652 [(set (match_operand:DI 0 "memory_operand")
4653 (fix:DI (match_operand 1 "register_operand")))
4654 (use (match_operand:HI 2 "memory_operand"))
4655 (use (match_operand:HI 3 "memory_operand"))
4656 (clobber (match_operand:DI 4 "memory_operand"))
4657 (clobber (match_scratch 5))]
4659 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4662 (clobber (match_dup 5))])])
4664 (define_insn "fix_trunc<mode>_i387"
4665 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4666 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4667 (use (match_operand:HI 2 "memory_operand" "m"))
4668 (use (match_operand:HI 3 "memory_operand" "m"))]
4669 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4671 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4672 "* return output_fix_trunc (insn, operands, false);"
4673 [(set_attr "type" "fistp")
4674 (set_attr "i387_cw" "trunc")
4675 (set_attr "mode" "<MODE>")])
4677 (define_insn "fix_trunc<mode>_i387_with_temp"
4678 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4679 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4680 (use (match_operand:HI 2 "memory_operand" "m,m"))
4681 (use (match_operand:HI 3 "memory_operand" "m,m"))
4682 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4687 [(set_attr "type" "fistp")
4688 (set_attr "i387_cw" "trunc")
4689 (set_attr "mode" "<MODE>")])
4692 [(set (match_operand:SWI24 0 "register_operand")
4693 (fix:SWI24 (match_operand 1 "register_operand")))
4694 (use (match_operand:HI 2 "memory_operand"))
4695 (use (match_operand:HI 3 "memory_operand"))
4696 (clobber (match_operand:SWI24 4 "memory_operand"))]
4698 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4700 (use (match_dup 3))])
4701 (set (match_dup 0) (match_dup 4))])
4704 [(set (match_operand:SWI24 0 "memory_operand")
4705 (fix:SWI24 (match_operand 1 "register_operand")))
4706 (use (match_operand:HI 2 "memory_operand"))
4707 (use (match_operand:HI 3 "memory_operand"))
4708 (clobber (match_operand:SWI24 4 "memory_operand"))]
4710 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4712 (use (match_dup 3))])])
4714 (define_insn "x86_fnstcw_1"
4715 [(set (match_operand:HI 0 "memory_operand" "=m")
4716 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4719 [(set (attr "length")
4720 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4721 (set_attr "mode" "HI")
4722 (set_attr "unit" "i387")
4723 (set_attr "bdver1_decode" "vector")])
4725 (define_insn "x86_fldcw_1"
4726 [(set (reg:HI FPCR_REG)
4727 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4730 [(set (attr "length")
4731 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4732 (set_attr "mode" "HI")
4733 (set_attr "unit" "i387")
4734 (set_attr "athlon_decode" "vector")
4735 (set_attr "amdfam10_decode" "vector")
4736 (set_attr "bdver1_decode" "vector")])
4738 ;; Conversion between fixed point and floating point.
4740 ;; Even though we only accept memory inputs, the backend _really_
4741 ;; wants to be able to do this between registers. Thankfully, LRA
4742 ;; will fix this up for us during register allocation.
4744 (define_insn "floathi<mode>2"
4745 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4746 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4749 || TARGET_MIX_SSE_I387)"
4751 [(set_attr "type" "fmov")
4752 (set_attr "mode" "<MODE>")
4753 (set_attr "fp_int_src" "true")])
4755 (define_insn "float<SWI48x:mode>xf2"
4756 [(set (match_operand:XF 0 "register_operand" "=f")
4757 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4760 [(set_attr "type" "fmov")
4761 (set_attr "mode" "XF")
4762 (set_attr "fp_int_src" "true")])
4764 (define_expand "float<SWI48:mode><MODEF:mode>2"
4765 [(set (match_operand:MODEF 0 "register_operand")
4766 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4767 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4769 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4770 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4772 rtx reg = gen_reg_rtx (XFmode);
4773 rtx (*insn)(rtx, rtx);
4775 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4777 if (<MODEF:MODE>mode == SFmode)
4778 insn = gen_truncxfsf2;
4779 else if (<MODEF:MODE>mode == DFmode)
4780 insn = gen_truncxfdf2;
4784 emit_insn (insn (operands[0], reg));
4789 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4790 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4792 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4793 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4796 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4797 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4798 [(set_attr "type" "fmov,sseicvt,sseicvt")
4799 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4800 (set_attr "mode" "<MODEF:MODE>")
4801 (set (attr "prefix_rex")
4803 (and (eq_attr "prefix" "maybe_vex")
4804 (match_test "<SWI48:MODE>mode == DImode"))
4806 (const_string "*")))
4807 (set_attr "unit" "i387,*,*")
4808 (set_attr "athlon_decode" "*,double,direct")
4809 (set_attr "amdfam10_decode" "*,vector,double")
4810 (set_attr "bdver1_decode" "*,double,direct")
4811 (set_attr "fp_int_src" "true")
4812 (set (attr "enabled")
4813 (cond [(eq_attr "alternative" "0")
4814 (symbol_ref "TARGET_MIX_SSE_I387
4815 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4818 (symbol_ref "true")))
4819 (set (attr "preferred_for_speed")
4820 (cond [(eq_attr "alternative" "1")
4821 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4822 (symbol_ref "true")))
4825 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4826 [(set (match_operand:MODEF 0 "register_operand" "=f")
4827 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4828 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4830 [(set_attr "type" "fmov")
4831 (set_attr "mode" "<MODEF:MODE>")
4832 (set_attr "fp_int_src" "true")])
4834 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4835 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4836 ;; alternative in sse2_loadld.
4838 [(set (match_operand:MODEF 0 "register_operand")
4839 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4840 "TARGET_SSE2 && TARGET_SSE_MATH
4841 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4842 && reload_completed && SSE_REG_P (operands[0])
4843 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4846 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4848 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4850 emit_insn (gen_sse2_loadld (operands[4],
4851 CONST0_RTX (V4SImode), operands[1]));
4853 if (<ssevecmode>mode == V4SFmode)
4854 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4856 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4860 ;; Avoid partial SSE register dependency stalls
4862 [(set (match_operand:MODEF 0 "register_operand")
4863 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4864 "TARGET_SSE2 && TARGET_SSE_MATH
4865 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4866 && optimize_function_for_speed_p (cfun)
4867 && reload_completed && SSE_REG_P (operands[0])"
4870 const machine_mode vmode = <MODEF:ssevecmode>mode;
4871 const machine_mode mode = <MODEF:MODE>mode;
4872 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4874 emit_move_insn (op0, CONST0_RTX (vmode));
4876 t = gen_rtx_FLOAT (mode, operands[1]);
4877 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4878 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4879 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4883 ;; Break partial reg stall for cvtsd2ss.
4886 [(set (match_operand:SF 0 "register_operand")
4888 (match_operand:DF 1 "nonimmediate_operand")))]
4889 "TARGET_SSE2 && TARGET_SSE_MATH
4890 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4891 && optimize_function_for_speed_p (cfun)
4892 && SSE_REG_P (operands[0])
4893 && (!SSE_REG_P (operands[1])
4894 || REGNO (operands[0]) != REGNO (operands[1]))"
4898 (float_truncate:V2SF
4903 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4905 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4907 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4910 ;; Break partial reg stall for cvtss2sd.
4913 [(set (match_operand:DF 0 "register_operand")
4915 (match_operand:SF 1 "nonimmediate_operand")))]
4916 "TARGET_SSE2 && TARGET_SSE_MATH
4917 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4918 && optimize_function_for_speed_p (cfun)
4919 && SSE_REG_P (operands[0])
4920 && (!SSE_REG_P (operands[1])
4921 || REGNO (operands[0]) != REGNO (operands[1]))"
4927 (parallel [(const_int 0) (const_int 1)])))
4931 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4933 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4935 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4938 ;; Avoid store forwarding (partial memory) stall penalty
4939 ;; by passing DImode value through XMM registers. */
4941 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4942 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4944 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4945 (clobber (match_scratch:V4SI 3 "=X,x"))
4946 (clobber (match_scratch:V4SI 4 "=X,x"))
4947 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4948 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4949 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4950 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4952 [(set_attr "type" "multi")
4953 (set_attr "mode" "<X87MODEF:MODE>")
4954 (set_attr "unit" "i387")
4955 (set_attr "fp_int_src" "true")])
4958 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4959 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4960 (clobber (match_scratch:V4SI 3))
4961 (clobber (match_scratch:V4SI 4))
4962 (clobber (match_operand:DI 2 "memory_operand"))]
4963 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4964 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4965 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4966 && reload_completed"
4967 [(set (match_dup 2) (match_dup 3))
4968 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4970 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4971 Assemble the 64-bit DImode value in an xmm register. */
4972 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4973 gen_rtx_SUBREG (SImode, operands[1], 0)));
4974 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4975 gen_rtx_SUBREG (SImode, operands[1], 4)));
4976 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4979 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4983 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4984 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4985 (clobber (match_scratch:V4SI 3))
4986 (clobber (match_scratch:V4SI 4))
4987 (clobber (match_operand:DI 2 "memory_operand"))]
4988 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4989 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4990 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4991 && reload_completed"
4992 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4994 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4995 [(set (match_operand:MODEF 0 "register_operand")
4996 (unsigned_float:MODEF
4997 (match_operand:SWI12 1 "nonimmediate_operand")))]
4999 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5001 operands[1] = convert_to_mode (SImode, operands[1], 1);
5002 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5006 ;; Avoid store forwarding (partial memory) stall penalty by extending
5007 ;; SImode value to DImode through XMM register instead of pushing two
5008 ;; SImode values to stack. Also note that fild loads from memory only.
5010 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5011 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5012 (unsigned_float:X87MODEF
5013 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5014 (clobber (match_scratch:DI 3 "=x"))
5015 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5017 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5018 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5020 "&& reload_completed"
5021 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5022 (set (match_dup 2) (match_dup 3))
5024 (float:X87MODEF (match_dup 2)))]
5026 [(set_attr "type" "multi")
5027 (set_attr "mode" "<MODE>")])
5029 (define_expand "floatunssi<mode>2"
5031 [(set (match_operand:X87MODEF 0 "register_operand")
5032 (unsigned_float:X87MODEF
5033 (match_operand:SI 1 "nonimmediate_operand")))
5034 (clobber (match_scratch:DI 3))
5035 (clobber (match_dup 2))])]
5037 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5038 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5039 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5041 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5043 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5047 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5050 (define_expand "floatunsdisf2"
5051 [(use (match_operand:SF 0 "register_operand"))
5052 (use (match_operand:DI 1 "nonimmediate_operand"))]
5053 "TARGET_64BIT && TARGET_SSE_MATH"
5054 "x86_emit_floatuns (operands); DONE;")
5056 (define_expand "floatunsdidf2"
5057 [(use (match_operand:DF 0 "register_operand"))
5058 (use (match_operand:DI 1 "nonimmediate_operand"))]
5059 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5060 && TARGET_SSE2 && TARGET_SSE_MATH"
5063 x86_emit_floatuns (operands);
5065 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5069 ;; Load effective address instructions
5071 (define_insn_and_split "*lea<mode>"
5072 [(set (match_operand:SWI48 0 "register_operand" "=r")
5073 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5076 if (SImode_address_operand (operands[1], VOIDmode))
5078 gcc_assert (TARGET_64BIT);
5079 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5082 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5084 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5087 machine_mode mode = <MODE>mode;
5090 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5091 change operands[] array behind our back. */
5092 pat = PATTERN (curr_insn);
5094 operands[0] = SET_DEST (pat);
5095 operands[1] = SET_SRC (pat);
5097 /* Emit all operations in SImode for zero-extended addresses. */
5098 if (SImode_address_operand (operands[1], VOIDmode))
5101 ix86_split_lea_for_addr (curr_insn, operands, mode);
5103 /* Zero-extend return register to DImode for zero-extended addresses. */
5104 if (mode != <MODE>mode)
5105 emit_insn (gen_zero_extendsidi2
5106 (operands[0], gen_lowpart (mode, operands[0])));
5110 [(set_attr "type" "lea")
5113 (match_operand 1 "SImode_address_operand")
5115 (const_string "<MODE>")))])
5119 (define_expand "add<mode>3"
5120 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5121 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5122 (match_operand:SDWIM 2 "<general_operand>")))]
5124 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5126 (define_insn_and_split "*add<dwi>3_doubleword"
5127 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5129 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5130 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5131 (clobber (reg:CC FLAGS_REG))]
5132 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5135 [(parallel [(set (reg:CC FLAGS_REG)
5136 (unspec:CC [(match_dup 1) (match_dup 2)]
5139 (plus:DWIH (match_dup 1) (match_dup 2)))])
5140 (parallel [(set (match_dup 3)
5144 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5146 (clobber (reg:CC FLAGS_REG))])]
5147 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5149 (define_insn "*add<mode>3_cc"
5150 [(set (reg:CC FLAGS_REG)
5152 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5153 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5155 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5156 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5157 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5158 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5159 [(set_attr "type" "alu")
5160 (set_attr "mode" "<MODE>")])
5162 (define_insn "addqi3_cc"
5163 [(set (reg:CC FLAGS_REG)
5165 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5166 (match_operand:QI 2 "general_operand" "qn,qm")]
5168 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5169 (plus:QI (match_dup 1) (match_dup 2)))]
5170 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5171 "add{b}\t{%2, %0|%0, %2}"
5172 [(set_attr "type" "alu")
5173 (set_attr "mode" "QI")])
5175 (define_insn "*add<mode>_1"
5176 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5178 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5179 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5180 (clobber (reg:CC FLAGS_REG))]
5181 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5183 switch (get_attr_type (insn))
5189 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5190 if (operands[2] == const1_rtx)
5191 return "inc{<imodesuffix>}\t%0";
5194 gcc_assert (operands[2] == constm1_rtx);
5195 return "dec{<imodesuffix>}\t%0";
5199 /* For most processors, ADD is faster than LEA. This alternative
5200 was added to use ADD as much as possible. */
5201 if (which_alternative == 2)
5204 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5209 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5211 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5215 (cond [(eq_attr "alternative" "3")
5216 (const_string "lea")
5217 (match_operand:SWI48 2 "incdec_operand")
5218 (const_string "incdec")
5220 (const_string "alu")))
5221 (set (attr "length_immediate")
5223 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5225 (const_string "*")))
5226 (set_attr "mode" "<MODE>")])
5228 ;; It may seem that nonimmediate operand is proper one for operand 1.
5229 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5230 ;; we take care in ix86_binary_operator_ok to not allow two memory
5231 ;; operands so proper swapping will be done in reload. This allow
5232 ;; patterns constructed from addsi_1 to match.
5234 (define_insn "addsi_1_zext"
5235 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5237 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5238 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5239 (clobber (reg:CC FLAGS_REG))]
5240 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5242 switch (get_attr_type (insn))
5248 if (operands[2] == const1_rtx)
5249 return "inc{l}\t%k0";
5252 gcc_assert (operands[2] == constm1_rtx);
5253 return "dec{l}\t%k0";
5257 /* For most processors, ADD is faster than LEA. This alternative
5258 was added to use ADD as much as possible. */
5259 if (which_alternative == 1)
5262 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5265 if (x86_maybe_negate_const_int (&operands[2], SImode))
5266 return "sub{l}\t{%2, %k0|%k0, %2}";
5268 return "add{l}\t{%2, %k0|%k0, %2}";
5272 (cond [(eq_attr "alternative" "2")
5273 (const_string "lea")
5274 (match_operand:SI 2 "incdec_operand")
5275 (const_string "incdec")
5277 (const_string "alu")))
5278 (set (attr "length_immediate")
5280 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5282 (const_string "*")))
5283 (set_attr "mode" "SI")])
5285 (define_insn "*addhi_1"
5286 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5287 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5288 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5289 (clobber (reg:CC FLAGS_REG))]
5290 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5292 switch (get_attr_type (insn))
5298 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5299 if (operands[2] == const1_rtx)
5300 return "inc{w}\t%0";
5303 gcc_assert (operands[2] == constm1_rtx);
5304 return "dec{w}\t%0";
5308 /* For most processors, ADD is faster than LEA. This alternative
5309 was added to use ADD as much as possible. */
5310 if (which_alternative == 2)
5313 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5316 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5317 if (x86_maybe_negate_const_int (&operands[2], HImode))
5318 return "sub{w}\t{%2, %0|%0, %2}";
5320 return "add{w}\t{%2, %0|%0, %2}";
5324 (cond [(eq_attr "alternative" "3")
5325 (const_string "lea")
5326 (match_operand:HI 2 "incdec_operand")
5327 (const_string "incdec")
5329 (const_string "alu")))
5330 (set (attr "length_immediate")
5332 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5334 (const_string "*")))
5335 (set_attr "mode" "HI,HI,HI,SI")])
5337 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5338 (define_insn "*addqi_1"
5339 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5340 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5341 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5342 (clobber (reg:CC FLAGS_REG))]
5343 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5345 bool widen = (which_alternative == 3 || which_alternative == 4);
5347 switch (get_attr_type (insn))
5353 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354 if (operands[2] == const1_rtx)
5355 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5358 gcc_assert (operands[2] == constm1_rtx);
5359 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5363 /* For most processors, ADD is faster than LEA. These alternatives
5364 were added to use ADD as much as possible. */
5365 if (which_alternative == 2 || which_alternative == 4)
5368 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5371 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5372 if (x86_maybe_negate_const_int (&operands[2], QImode))
5375 return "sub{l}\t{%2, %k0|%k0, %2}";
5377 return "sub{b}\t{%2, %0|%0, %2}";
5380 return "add{l}\t{%k2, %k0|%k0, %k2}";
5382 return "add{b}\t{%2, %0|%0, %2}";
5386 (cond [(eq_attr "alternative" "5")
5387 (const_string "lea")
5388 (match_operand:QI 2 "incdec_operand")
5389 (const_string "incdec")
5391 (const_string "alu")))
5392 (set (attr "length_immediate")
5394 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5396 (const_string "*")))
5397 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5399 (define_insn "*addqi_1_slp"
5400 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5401 (plus:QI (match_dup 0)
5402 (match_operand:QI 1 "general_operand" "qn,qm")))
5403 (clobber (reg:CC FLAGS_REG))]
5404 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5407 switch (get_attr_type (insn))
5410 if (operands[1] == const1_rtx)
5411 return "inc{b}\t%0";
5414 gcc_assert (operands[1] == constm1_rtx);
5415 return "dec{b}\t%0";
5419 if (x86_maybe_negate_const_int (&operands[1], QImode))
5420 return "sub{b}\t{%1, %0|%0, %1}";
5422 return "add{b}\t{%1, %0|%0, %1}";
5426 (if_then_else (match_operand:QI 1 "incdec_operand")
5427 (const_string "incdec")
5428 (const_string "alu1")))
5429 (set (attr "memory")
5430 (if_then_else (match_operand 1 "memory_operand")
5431 (const_string "load")
5432 (const_string "none")))
5433 (set_attr "mode" "QI")])
5435 ;; Split non destructive adds if we cannot use lea.
5437 [(set (match_operand:SWI48 0 "register_operand")
5438 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5439 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5440 (clobber (reg:CC FLAGS_REG))]
5441 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5442 [(set (match_dup 0) (match_dup 1))
5443 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5444 (clobber (reg:CC FLAGS_REG))])])
5446 ;; Convert add to the lea pattern to avoid flags dependency.
5448 [(set (match_operand:SWI 0 "register_operand")
5449 (plus:SWI (match_operand:SWI 1 "register_operand")
5450 (match_operand:SWI 2 "<nonmemory_operand>")))
5451 (clobber (reg:CC FLAGS_REG))]
5452 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5455 machine_mode mode = <MODE>mode;
5458 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5461 operands[0] = gen_lowpart (mode, operands[0]);
5462 operands[1] = gen_lowpart (mode, operands[1]);
5463 operands[2] = gen_lowpart (mode, operands[2]);
5466 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5468 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5472 ;; Split non destructive adds if we cannot use lea.
5474 [(set (match_operand:DI 0 "register_operand")
5476 (plus:SI (match_operand:SI 1 "register_operand")
5477 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5478 (clobber (reg:CC FLAGS_REG))]
5480 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5481 [(set (match_dup 3) (match_dup 1))
5482 (parallel [(set (match_dup 0)
5483 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5484 (clobber (reg:CC FLAGS_REG))])]
5485 "operands[3] = gen_lowpart (SImode, operands[0]);")
5487 ;; Convert add to the lea pattern to avoid flags dependency.
5489 [(set (match_operand:DI 0 "register_operand")
5491 (plus:SI (match_operand:SI 1 "register_operand")
5492 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5493 (clobber (reg:CC FLAGS_REG))]
5494 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5496 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5498 (define_insn "*add<mode>_2"
5499 [(set (reg FLAGS_REG)
5502 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5503 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5506 (plus:SWI (match_dup 1) (match_dup 2)))]
5507 "ix86_match_ccmode (insn, CCGOCmode)
5508 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5510 switch (get_attr_type (insn))
5513 if (operands[2] == const1_rtx)
5514 return "inc{<imodesuffix>}\t%0";
5517 gcc_assert (operands[2] == constm1_rtx);
5518 return "dec{<imodesuffix>}\t%0";
5522 if (which_alternative == 2)
5525 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5528 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5530 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5532 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5536 (if_then_else (match_operand:SWI 2 "incdec_operand")
5537 (const_string "incdec")
5538 (const_string "alu")))
5539 (set (attr "length_immediate")
5541 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5543 (const_string "*")))
5544 (set_attr "mode" "<MODE>")])
5546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5547 (define_insn "*addsi_2_zext"
5548 [(set (reg FLAGS_REG)
5550 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5551 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5553 (set (match_operand:DI 0 "register_operand" "=r,r")
5554 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5555 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5556 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5558 switch (get_attr_type (insn))
5561 if (operands[2] == const1_rtx)
5562 return "inc{l}\t%k0";
5565 gcc_assert (operands[2] == constm1_rtx);
5566 return "dec{l}\t%k0";
5570 if (which_alternative == 1)
5573 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5576 if (x86_maybe_negate_const_int (&operands[2], SImode))
5577 return "sub{l}\t{%2, %k0|%k0, %2}";
5579 return "add{l}\t{%2, %k0|%k0, %2}";
5583 (if_then_else (match_operand:SI 2 "incdec_operand")
5584 (const_string "incdec")
5585 (const_string "alu")))
5586 (set (attr "length_immediate")
5588 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5590 (const_string "*")))
5591 (set_attr "mode" "SI")])
5593 (define_insn "*add<mode>_3"
5594 [(set (reg FLAGS_REG)
5596 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5597 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5598 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5599 "ix86_match_ccmode (insn, CCZmode)
5600 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5602 switch (get_attr_type (insn))
5605 if (operands[2] == const1_rtx)
5606 return "inc{<imodesuffix>}\t%0";
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{<imodesuffix>}\t%0";
5614 if (which_alternative == 1)
5617 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5622 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5624 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5628 (if_then_else (match_operand:SWI 2 "incdec_operand")
5629 (const_string "incdec")
5630 (const_string "alu")))
5631 (set (attr "length_immediate")
5633 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5635 (const_string "*")))
5636 (set_attr "mode" "<MODE>")])
5638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5639 (define_insn "*addsi_3_zext"
5640 [(set (reg FLAGS_REG)
5642 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5643 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5644 (set (match_operand:DI 0 "register_operand" "=r,r")
5645 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5646 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5647 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5649 switch (get_attr_type (insn))
5652 if (operands[2] == const1_rtx)
5653 return "inc{l}\t%k0";
5656 gcc_assert (operands[2] == constm1_rtx);
5657 return "dec{l}\t%k0";
5661 if (which_alternative == 1)
5664 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5667 if (x86_maybe_negate_const_int (&operands[2], SImode))
5668 return "sub{l}\t{%2, %k0|%k0, %2}";
5670 return "add{l}\t{%2, %k0|%k0, %2}";
5674 (if_then_else (match_operand:SI 2 "incdec_operand")
5675 (const_string "incdec")
5676 (const_string "alu")))
5677 (set (attr "length_immediate")
5679 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5681 (const_string "*")))
5682 (set_attr "mode" "SI")])
5684 ; For comparisons against 1, -1 and 128, we may generate better code
5685 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5686 ; is matched then. We can't accept general immediate, because for
5687 ; case of overflows, the result is messed up.
5688 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5689 ; only for comparisons not depending on it.
5691 (define_insn "*adddi_4"
5692 [(set (reg FLAGS_REG)
5694 (match_operand:DI 1 "nonimmediate_operand" "0")
5695 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5696 (clobber (match_scratch:DI 0 "=rm"))]
5698 && ix86_match_ccmode (insn, CCGCmode)"
5700 switch (get_attr_type (insn))
5703 if (operands[2] == constm1_rtx)
5704 return "inc{q}\t%0";
5707 gcc_assert (operands[2] == const1_rtx);
5708 return "dec{q}\t%0";
5712 if (x86_maybe_negate_const_int (&operands[2], DImode))
5713 return "add{q}\t{%2, %0|%0, %2}";
5715 return "sub{q}\t{%2, %0|%0, %2}";
5719 (if_then_else (match_operand:DI 2 "incdec_operand")
5720 (const_string "incdec")
5721 (const_string "alu")))
5722 (set (attr "length_immediate")
5724 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5726 (const_string "*")))
5727 (set_attr "mode" "DI")])
5729 ; For comparisons against 1, -1 and 128, we may generate better code
5730 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5731 ; is matched then. We can't accept general immediate, because for
5732 ; case of overflows, the result is messed up.
5733 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5734 ; only for comparisons not depending on it.
5736 (define_insn "*add<mode>_4"
5737 [(set (reg FLAGS_REG)
5739 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5740 (match_operand:SWI124 2 "const_int_operand" "n")))
5741 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5742 "ix86_match_ccmode (insn, CCGCmode)"
5744 switch (get_attr_type (insn))
5747 if (operands[2] == constm1_rtx)
5748 return "inc{<imodesuffix>}\t%0";
5751 gcc_assert (operands[2] == const1_rtx);
5752 return "dec{<imodesuffix>}\t%0";
5756 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5757 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5759 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5763 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5764 (const_string "incdec")
5765 (const_string "alu")))
5766 (set (attr "length_immediate")
5768 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5770 (const_string "*")))
5771 (set_attr "mode" "<MODE>")])
5773 (define_insn "*add<mode>_5"
5774 [(set (reg FLAGS_REG)
5777 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5778 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5780 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5781 "ix86_match_ccmode (insn, CCGOCmode)
5782 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5784 switch (get_attr_type (insn))
5787 if (operands[2] == const1_rtx)
5788 return "inc{<imodesuffix>}\t%0";
5791 gcc_assert (operands[2] == constm1_rtx);
5792 return "dec{<imodesuffix>}\t%0";
5796 if (which_alternative == 1)
5799 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5802 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5803 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5804 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5806 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5810 (if_then_else (match_operand:SWI 2 "incdec_operand")
5811 (const_string "incdec")
5812 (const_string "alu")))
5813 (set (attr "length_immediate")
5815 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5817 (const_string "*")))
5818 (set_attr "mode" "<MODE>")])
5820 (define_insn "addqi_ext_1"
5821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5826 (match_operand 1 "ext_register_operand" "0,0")
5829 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5830 (clobber (reg:CC FLAGS_REG))]
5833 switch (get_attr_type (insn))
5836 if (operands[2] == const1_rtx)
5837 return "inc{b}\t%h0";
5840 gcc_assert (operands[2] == constm1_rtx);
5841 return "dec{b}\t%h0";
5845 return "add{b}\t{%2, %h0|%h0, %2}";
5848 [(set_attr "isa" "*,nox64")
5850 (if_then_else (match_operand:QI 2 "incdec_operand")
5851 (const_string "incdec")
5852 (const_string "alu")))
5853 (set_attr "modrm" "1")
5854 (set_attr "mode" "QI")])
5856 (define_insn "*addqi_ext_2"
5857 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5862 (match_operand 1 "ext_register_operand" "%0")
5866 (match_operand 2 "ext_register_operand" "Q")
5869 (clobber (reg:CC FLAGS_REG))]
5871 "add{b}\t{%h2, %h0|%h0, %h2}"
5872 [(set_attr "type" "alu")
5873 (set_attr "mode" "QI")])
5875 ;; Add with jump on overflow.
5876 (define_expand "addv<mode>4"
5877 [(parallel [(set (reg:CCO FLAGS_REG)
5880 (match_operand:SWI 1 "nonimmediate_operand"))
5883 (plus:SWI (match_dup 1)
5884 (match_operand:SWI 2
5885 "<general_operand>")))))
5886 (set (match_operand:SWI 0 "register_operand")
5887 (plus:SWI (match_dup 1) (match_dup 2)))])
5888 (set (pc) (if_then_else
5889 (eq (reg:CCO FLAGS_REG) (const_int 0))
5890 (label_ref (match_operand 3))
5894 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5895 if (CONST_INT_P (operands[2]))
5896 operands[4] = operands[2];
5898 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5901 (define_insn "*addv<mode>4"
5902 [(set (reg:CCO FLAGS_REG)
5905 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5907 (match_operand:SWI 2 "<general_sext_operand>"
5910 (plus:SWI (match_dup 1) (match_dup 2)))))
5911 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5912 (plus:SWI (match_dup 1) (match_dup 2)))]
5913 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5914 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5915 [(set_attr "type" "alu")
5916 (set_attr "mode" "<MODE>")])
5918 (define_insn "*addv<mode>4_1"
5919 [(set (reg:CCO FLAGS_REG)
5922 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5923 (match_operand:<DWI> 3 "const_int_operand" "i"))
5925 (plus:SWI (match_dup 1)
5926 (match_operand:SWI 2 "x86_64_immediate_operand"
5928 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5929 (plus:SWI (match_dup 1) (match_dup 2)))]
5930 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5931 && CONST_INT_P (operands[2])
5932 && INTVAL (operands[2]) == INTVAL (operands[3])"
5933 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5934 [(set_attr "type" "alu")
5935 (set_attr "mode" "<MODE>")
5936 (set (attr "length_immediate")
5937 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5939 (match_test "<MODE_SIZE> == 8")
5941 (const_string "<MODE_SIZE>")))])
5943 ;; The lea patterns for modes less than 32 bits need to be matched by
5944 ;; several insns converted to real lea by splitters.
5946 (define_insn_and_split "*lea_general_1"
5947 [(set (match_operand 0 "register_operand" "=r")
5948 (plus (plus (match_operand 1 "index_register_operand" "l")
5949 (match_operand 2 "register_operand" "r"))
5950 (match_operand 3 "immediate_operand" "i")))]
5951 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5952 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5953 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5954 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5955 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5956 || GET_MODE (operands[3]) == VOIDmode)"
5958 "&& reload_completed"
5961 machine_mode mode = SImode;
5964 operands[0] = gen_lowpart (mode, operands[0]);
5965 operands[1] = gen_lowpart (mode, operands[1]);
5966 operands[2] = gen_lowpart (mode, operands[2]);
5967 operands[3] = gen_lowpart (mode, operands[3]);
5969 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5972 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5975 [(set_attr "type" "lea")
5976 (set_attr "mode" "SI")])
5978 (define_insn_and_split "*lea_general_2"
5979 [(set (match_operand 0 "register_operand" "=r")
5980 (plus (mult (match_operand 1 "index_register_operand" "l")
5981 (match_operand 2 "const248_operand" "n"))
5982 (match_operand 3 "nonmemory_operand" "ri")))]
5983 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5984 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5985 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5986 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5987 || GET_MODE (operands[3]) == VOIDmode)"
5989 "&& reload_completed"
5992 machine_mode mode = SImode;
5995 operands[0] = gen_lowpart (mode, operands[0]);
5996 operands[1] = gen_lowpart (mode, operands[1]);
5997 operands[3] = gen_lowpart (mode, operands[3]);
5999 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (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_3"
6009 [(set (match_operand 0 "register_operand" "=r")
6010 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6011 (match_operand 2 "const248_operand" "n"))
6012 (match_operand 3 "register_operand" "r"))
6013 (match_operand 4 "immediate_operand" "i")))]
6014 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6015 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6016 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6017 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
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]);
6028 operands[4] = gen_lowpart (mode, operands[4]);
6030 pat = gen_rtx_PLUS (mode,
6032 gen_rtx_MULT (mode, operands[1],
6037 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6040 [(set_attr "type" "lea")
6041 (set_attr "mode" "SI")])
6043 (define_insn_and_split "*lea_general_4"
6044 [(set (match_operand 0 "register_operand" "=r")
6046 (match_operand 1 "index_register_operand" "l")
6047 (match_operand 2 "const_int_operand" "n"))
6048 (match_operand 3 "const_int_operand" "n")))]
6049 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6050 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6051 || GET_MODE (operands[0]) == SImode
6052 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6053 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6054 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6055 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6056 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6058 "&& reload_completed"
6061 machine_mode mode = GET_MODE (operands[0]);
6064 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6067 operands[0] = gen_lowpart (mode, operands[0]);
6068 operands[1] = gen_lowpart (mode, operands[1]);
6071 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6073 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6074 INTVAL (operands[3]));
6076 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6079 [(set_attr "type" "lea")
6081 (if_then_else (match_operand:DI 0)
6083 (const_string "SI")))])
6085 ;; Subtract instructions
6087 (define_expand "sub<mode>3"
6088 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6089 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6090 (match_operand:SDWIM 2 "<general_operand>")))]
6092 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6094 (define_insn_and_split "*sub<dwi>3_doubleword"
6095 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6097 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6098 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6099 (clobber (reg:CC FLAGS_REG))]
6100 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6103 [(parallel [(set (reg:CC FLAGS_REG)
6104 (compare:CC (match_dup 1) (match_dup 2)))
6106 (minus:DWIH (match_dup 1) (match_dup 2)))])
6107 (parallel [(set (match_dup 3)
6111 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6113 (clobber (reg:CC FLAGS_REG))])]
6114 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6116 (define_insn "*sub<mode>_1"
6117 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6119 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6120 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6123 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6124 [(set_attr "type" "alu")
6125 (set_attr "mode" "<MODE>")])
6127 (define_insn "*subsi_1_zext"
6128 [(set (match_operand:DI 0 "register_operand" "=r")
6130 (minus:SI (match_operand:SI 1 "register_operand" "0")
6131 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6132 (clobber (reg:CC FLAGS_REG))]
6133 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6134 "sub{l}\t{%2, %k0|%k0, %2}"
6135 [(set_attr "type" "alu")
6136 (set_attr "mode" "SI")])
6138 (define_insn "*subqi_1_slp"
6139 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6140 (minus:QI (match_dup 0)
6141 (match_operand:QI 1 "general_operand" "qn,qm")))
6142 (clobber (reg:CC FLAGS_REG))]
6143 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6144 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6145 "sub{b}\t{%1, %0|%0, %1}"
6146 [(set_attr "type" "alu1")
6147 (set_attr "mode" "QI")])
6149 (define_insn "*sub<mode>_2"
6150 [(set (reg FLAGS_REG)
6153 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6154 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6156 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6157 (minus:SWI (match_dup 1) (match_dup 2)))]
6158 "ix86_match_ccmode (insn, CCGOCmode)
6159 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6160 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6161 [(set_attr "type" "alu")
6162 (set_attr "mode" "<MODE>")])
6164 (define_insn "*subsi_2_zext"
6165 [(set (reg FLAGS_REG)
6167 (minus:SI (match_operand:SI 1 "register_operand" "0")
6168 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6170 (set (match_operand:DI 0 "register_operand" "=r")
6172 (minus:SI (match_dup 1)
6174 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6175 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6176 "sub{l}\t{%2, %k0|%k0, %2}"
6177 [(set_attr "type" "alu")
6178 (set_attr "mode" "SI")])
6180 ;; Subtract with jump on overflow.
6181 (define_expand "subv<mode>4"
6182 [(parallel [(set (reg:CCO FLAGS_REG)
6183 (eq:CCO (minus:<DWI>
6185 (match_operand:SWI 1 "nonimmediate_operand"))
6188 (minus:SWI (match_dup 1)
6189 (match_operand:SWI 2
6190 "<general_operand>")))))
6191 (set (match_operand:SWI 0 "register_operand")
6192 (minus:SWI (match_dup 1) (match_dup 2)))])
6193 (set (pc) (if_then_else
6194 (eq (reg:CCO FLAGS_REG) (const_int 0))
6195 (label_ref (match_operand 3))
6199 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6200 if (CONST_INT_P (operands[2]))
6201 operands[4] = operands[2];
6203 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6206 (define_insn "*subv<mode>4"
6207 [(set (reg:CCO FLAGS_REG)
6208 (eq:CCO (minus:<DWI>
6210 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6212 (match_operand:SWI 2 "<general_sext_operand>"
6215 (minus:SWI (match_dup 1) (match_dup 2)))))
6216 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6217 (minus:SWI (match_dup 1) (match_dup 2)))]
6218 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6219 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6220 [(set_attr "type" "alu")
6221 (set_attr "mode" "<MODE>")])
6223 (define_insn "*subv<mode>4_1"
6224 [(set (reg:CCO FLAGS_REG)
6225 (eq:CCO (minus:<DWI>
6227 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6228 (match_operand:<DWI> 3 "const_int_operand" "i"))
6230 (minus:SWI (match_dup 1)
6231 (match_operand:SWI 2 "x86_64_immediate_operand"
6233 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6234 (minus:SWI (match_dup 1) (match_dup 2)))]
6235 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6236 && CONST_INT_P (operands[2])
6237 && INTVAL (operands[2]) == INTVAL (operands[3])"
6238 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6239 [(set_attr "type" "alu")
6240 (set_attr "mode" "<MODE>")
6241 (set (attr "length_immediate")
6242 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6244 (match_test "<MODE_SIZE> == 8")
6246 (const_string "<MODE_SIZE>")))])
6248 (define_insn "*sub<mode>_3"
6249 [(set (reg FLAGS_REG)
6250 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6251 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6252 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6253 (minus:SWI (match_dup 1) (match_dup 2)))]
6254 "ix86_match_ccmode (insn, CCmode)
6255 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6256 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6257 [(set_attr "type" "alu")
6258 (set_attr "mode" "<MODE>")])
6260 (define_insn "*subsi_3_zext"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:SI 1 "register_operand" "0")
6263 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6264 (set (match_operand:DI 0 "register_operand" "=r")
6266 (minus:SI (match_dup 1)
6268 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6269 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6270 "sub{l}\t{%2, %1|%1, %2}"
6271 [(set_attr "type" "alu")
6272 (set_attr "mode" "SI")])
6274 ;; Add with carry and subtract with borrow
6276 (define_expand "<plusminus_insn><mode>3_carry"
6278 [(set (match_operand:SWI 0 "nonimmediate_operand")
6280 (match_operand:SWI 1 "nonimmediate_operand")
6281 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6282 [(match_operand 3 "flags_reg_operand")
6284 (match_operand:SWI 2 "<general_operand>"))))
6285 (clobber (reg:CC FLAGS_REG))])]
6286 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6288 (define_insn "*<plusminus_insn><mode>3_carry"
6289 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6291 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6293 (match_operator 3 "ix86_carry_flag_operator"
6294 [(reg FLAGS_REG) (const_int 0)])
6295 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6296 (clobber (reg:CC FLAGS_REG))]
6297 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6298 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6299 [(set_attr "type" "alu")
6300 (set_attr "use_carry" "1")
6301 (set_attr "pent_pair" "pu")
6302 (set_attr "mode" "<MODE>")])
6304 (define_insn "*addsi3_carry_zext"
6305 [(set (match_operand:DI 0 "register_operand" "=r")
6307 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6308 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6309 [(reg FLAGS_REG) (const_int 0)])
6310 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6311 (clobber (reg:CC FLAGS_REG))]
6312 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6313 "adc{l}\t{%2, %k0|%k0, %2}"
6314 [(set_attr "type" "alu")
6315 (set_attr "use_carry" "1")
6316 (set_attr "pent_pair" "pu")
6317 (set_attr "mode" "SI")])
6319 (define_insn "*subsi3_carry_zext"
6320 [(set (match_operand:DI 0 "register_operand" "=r")
6322 (minus:SI (match_operand:SI 1 "register_operand" "0")
6323 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6324 [(reg FLAGS_REG) (const_int 0)])
6325 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6326 (clobber (reg:CC FLAGS_REG))]
6327 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6328 "sbb{l}\t{%2, %k0|%k0, %2}"
6329 [(set_attr "type" "alu")
6330 (set_attr "pent_pair" "pu")
6331 (set_attr "mode" "SI")])
6335 (define_insn "adcx<mode>3"
6336 [(set (reg:CCC FLAGS_REG)
6339 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6341 (match_operator 4 "ix86_carry_flag_operator"
6342 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6343 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6345 (set (match_operand:SWI48 0 "register_operand" "=r")
6346 (plus:SWI48 (match_dup 1)
6347 (plus:SWI48 (match_op_dup 4
6348 [(match_dup 3) (const_int 0)])
6350 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6351 "adcx\t{%2, %0|%0, %2}"
6352 [(set_attr "type" "alu")
6353 (set_attr "use_carry" "1")
6354 (set_attr "mode" "<MODE>")])
6356 ;; Overflow setting add instructions
6358 (define_insn "*add<mode>3_cconly_overflow"
6359 [(set (reg:CCC FLAGS_REG)
6362 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6363 (match_operand:SWI 2 "<general_operand>" "<g>"))
6365 (clobber (match_scratch:SWI 0 "=<r>"))]
6366 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6367 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6368 [(set_attr "type" "alu")
6369 (set_attr "mode" "<MODE>")])
6371 (define_insn "*add<mode>3_cc_overflow"
6372 [(set (reg:CCC FLAGS_REG)
6375 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6376 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6378 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6379 (plus:SWI (match_dup 1) (match_dup 2)))]
6380 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6381 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6382 [(set_attr "type" "alu")
6383 (set_attr "mode" "<MODE>")])
6385 (define_insn "*addsi3_zext_cc_overflow"
6386 [(set (reg:CCC FLAGS_REG)
6389 (match_operand:SI 1 "nonimmediate_operand" "%0")
6390 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6392 (set (match_operand:DI 0 "register_operand" "=r")
6393 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6394 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6395 "add{l}\t{%2, %k0|%k0, %2}"
6396 [(set_attr "type" "alu")
6397 (set_attr "mode" "SI")])
6399 ;; The patterns that match these are at the end of this file.
6401 (define_expand "<plusminus_insn>xf3"
6402 [(set (match_operand:XF 0 "register_operand")
6404 (match_operand:XF 1 "register_operand")
6405 (match_operand:XF 2 "register_operand")))]
6408 (define_expand "<plusminus_insn><mode>3"
6409 [(set (match_operand:MODEF 0 "register_operand")
6411 (match_operand:MODEF 1 "register_operand")
6412 (match_operand:MODEF 2 "nonimmediate_operand")))]
6413 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6414 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6416 ;; Multiply instructions
6418 (define_expand "mul<mode>3"
6419 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6421 (match_operand:SWIM248 1 "register_operand")
6422 (match_operand:SWIM248 2 "<general_operand>")))
6423 (clobber (reg:CC FLAGS_REG))])])
6425 (define_expand "mulqi3"
6426 [(parallel [(set (match_operand:QI 0 "register_operand")
6428 (match_operand:QI 1 "register_operand")
6429 (match_operand:QI 2 "nonimmediate_operand")))
6430 (clobber (reg:CC FLAGS_REG))])]
6431 "TARGET_QIMODE_MATH")
6434 ;; IMUL reg32/64, reg32/64, imm8 Direct
6435 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6436 ;; IMUL reg32/64, reg32/64, imm32 Direct
6437 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6438 ;; IMUL reg32/64, reg32/64 Direct
6439 ;; IMUL reg32/64, mem32/64 Direct
6441 ;; On BDVER1, all above IMULs use DirectPath
6443 (define_insn "*mul<mode>3_1"
6444 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6446 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6447 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6448 (clobber (reg:CC FLAGS_REG))]
6449 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6451 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6452 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6453 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6454 [(set_attr "type" "imul")
6455 (set_attr "prefix_0f" "0,0,1")
6456 (set (attr "athlon_decode")
6457 (cond [(eq_attr "cpu" "athlon")
6458 (const_string "vector")
6459 (eq_attr "alternative" "1")
6460 (const_string "vector")
6461 (and (eq_attr "alternative" "2")
6462 (match_operand 1 "memory_operand"))
6463 (const_string "vector")]
6464 (const_string "direct")))
6465 (set (attr "amdfam10_decode")
6466 (cond [(and (eq_attr "alternative" "0,1")
6467 (match_operand 1 "memory_operand"))
6468 (const_string "vector")]
6469 (const_string "direct")))
6470 (set_attr "bdver1_decode" "direct")
6471 (set_attr "mode" "<MODE>")])
6473 (define_insn "*mulsi3_1_zext"
6474 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6476 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6477 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6478 (clobber (reg:CC FLAGS_REG))]
6480 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6482 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6483 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6484 imul{l}\t{%2, %k0|%k0, %2}"
6485 [(set_attr "type" "imul")
6486 (set_attr "prefix_0f" "0,0,1")
6487 (set (attr "athlon_decode")
6488 (cond [(eq_attr "cpu" "athlon")
6489 (const_string "vector")
6490 (eq_attr "alternative" "1")
6491 (const_string "vector")
6492 (and (eq_attr "alternative" "2")
6493 (match_operand 1 "memory_operand"))
6494 (const_string "vector")]
6495 (const_string "direct")))
6496 (set (attr "amdfam10_decode")
6497 (cond [(and (eq_attr "alternative" "0,1")
6498 (match_operand 1 "memory_operand"))
6499 (const_string "vector")]
6500 (const_string "direct")))
6501 (set_attr "bdver1_decode" "direct")
6502 (set_attr "mode" "SI")])
6505 ;; IMUL reg16, reg16, imm8 VectorPath
6506 ;; IMUL reg16, mem16, imm8 VectorPath
6507 ;; IMUL reg16, reg16, imm16 VectorPath
6508 ;; IMUL reg16, mem16, imm16 VectorPath
6509 ;; IMUL reg16, reg16 Direct
6510 ;; IMUL reg16, mem16 Direct
6512 ;; On BDVER1, all HI MULs use DoublePath
6514 (define_insn "*mulhi3_1"
6515 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6516 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6517 (match_operand:HI 2 "general_operand" "K,n,mr")))
6518 (clobber (reg:CC FLAGS_REG))]
6520 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6522 imul{w}\t{%2, %1, %0|%0, %1, %2}
6523 imul{w}\t{%2, %1, %0|%0, %1, %2}
6524 imul{w}\t{%2, %0|%0, %2}"
6525 [(set_attr "type" "imul")
6526 (set_attr "prefix_0f" "0,0,1")
6527 (set (attr "athlon_decode")
6528 (cond [(eq_attr "cpu" "athlon")
6529 (const_string "vector")
6530 (eq_attr "alternative" "1,2")
6531 (const_string "vector")]
6532 (const_string "direct")))
6533 (set (attr "amdfam10_decode")
6534 (cond [(eq_attr "alternative" "0,1")
6535 (const_string "vector")]
6536 (const_string "direct")))
6537 (set_attr "bdver1_decode" "double")
6538 (set_attr "mode" "HI")])
6540 ;;On AMDFAM10 and BDVER1
6544 (define_insn "*mulqi3_1"
6545 [(set (match_operand:QI 0 "register_operand" "=a")
6546 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6547 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6548 (clobber (reg:CC FLAGS_REG))]
6550 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6552 [(set_attr "type" "imul")
6553 (set_attr "length_immediate" "0")
6554 (set (attr "athlon_decode")
6555 (if_then_else (eq_attr "cpu" "athlon")
6556 (const_string "vector")
6557 (const_string "direct")))
6558 (set_attr "amdfam10_decode" "direct")
6559 (set_attr "bdver1_decode" "direct")
6560 (set_attr "mode" "QI")])
6562 ;; Multiply with jump on overflow.
6563 (define_expand "mulv<mode>4"
6564 [(parallel [(set (reg:CCO FLAGS_REG)
6567 (match_operand:SWI48 1 "register_operand"))
6570 (mult:SWI48 (match_dup 1)
6571 (match_operand:SWI48 2
6572 "<general_operand>")))))
6573 (set (match_operand:SWI48 0 "register_operand")
6574 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6575 (set (pc) (if_then_else
6576 (eq (reg:CCO FLAGS_REG) (const_int 0))
6577 (label_ref (match_operand 3))
6581 if (CONST_INT_P (operands[2]))
6582 operands[4] = operands[2];
6584 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6587 (define_insn "*mulv<mode>4"
6588 [(set (reg:CCO FLAGS_REG)
6591 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6593 (match_operand:SWI48 2 "<general_sext_operand>"
6596 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6597 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6598 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6599 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6601 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6602 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6603 [(set_attr "type" "imul")
6604 (set_attr "prefix_0f" "0,1")
6605 (set (attr "athlon_decode")
6606 (cond [(eq_attr "cpu" "athlon")
6607 (const_string "vector")
6608 (eq_attr "alternative" "0")
6609 (const_string "vector")
6610 (and (eq_attr "alternative" "1")
6611 (match_operand 1 "memory_operand"))
6612 (const_string "vector")]
6613 (const_string "direct")))
6614 (set (attr "amdfam10_decode")
6615 (cond [(and (eq_attr "alternative" "1")
6616 (match_operand 1 "memory_operand"))
6617 (const_string "vector")]
6618 (const_string "direct")))
6619 (set_attr "bdver1_decode" "direct")
6620 (set_attr "mode" "<MODE>")])
6622 (define_insn "*mulv<mode>4_1"
6623 [(set (reg:CCO FLAGS_REG)
6626 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6627 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6629 (mult:SWI48 (match_dup 1)
6630 (match_operand:SWI 2 "x86_64_immediate_operand"
6632 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6633 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6634 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6635 && CONST_INT_P (operands[2])
6636 && INTVAL (operands[2]) == INTVAL (operands[3])"
6638 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6639 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6640 [(set_attr "type" "imul")
6641 (set (attr "athlon_decode")
6642 (cond [(eq_attr "cpu" "athlon")
6643 (const_string "vector")
6644 (eq_attr "alternative" "1")
6645 (const_string "vector")]
6646 (const_string "direct")))
6647 (set (attr "amdfam10_decode")
6648 (cond [(match_operand 1 "memory_operand")
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set_attr "bdver1_decode" "direct")
6652 (set_attr "mode" "<MODE>")
6653 (set (attr "length_immediate")
6654 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6656 (match_test "<MODE_SIZE> == 8")
6658 (const_string "<MODE_SIZE>")))])
6660 (define_expand "<u>mul<mode><dwi>3"
6661 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6664 (match_operand:DWIH 1 "nonimmediate_operand"))
6666 (match_operand:DWIH 2 "register_operand"))))
6667 (clobber (reg:CC FLAGS_REG))])])
6669 (define_expand "<u>mulqihi3"
6670 [(parallel [(set (match_operand:HI 0 "register_operand")
6673 (match_operand:QI 1 "nonimmediate_operand"))
6675 (match_operand:QI 2 "register_operand"))))
6676 (clobber (reg:CC FLAGS_REG))])]
6677 "TARGET_QIMODE_MATH")
6679 (define_insn "*bmi2_umulditi3_1"
6680 [(set (match_operand:DI 0 "register_operand" "=r")
6682 (match_operand:DI 2 "nonimmediate_operand" "%d")
6683 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6684 (set (match_operand:DI 1 "register_operand" "=r")
6687 (mult:TI (zero_extend:TI (match_dup 2))
6688 (zero_extend:TI (match_dup 3)))
6690 "TARGET_64BIT && TARGET_BMI2
6691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6692 "mulx\t{%3, %0, %1|%1, %0, %3}"
6693 [(set_attr "type" "imulx")
6694 (set_attr "prefix" "vex")
6695 (set_attr "mode" "DI")])
6697 (define_insn "*bmi2_umulsidi3_1"
6698 [(set (match_operand:SI 0 "register_operand" "=r")
6700 (match_operand:SI 2 "nonimmediate_operand" "%d")
6701 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6702 (set (match_operand:SI 1 "register_operand" "=r")
6705 (mult:DI (zero_extend:DI (match_dup 2))
6706 (zero_extend:DI (match_dup 3)))
6708 "!TARGET_64BIT && TARGET_BMI2
6709 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710 "mulx\t{%3, %0, %1|%1, %0, %3}"
6711 [(set_attr "type" "imulx")
6712 (set_attr "prefix" "vex")
6713 (set_attr "mode" "SI")])
6715 (define_insn "*umul<mode><dwi>3_1"
6716 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6719 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6721 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6726 mul{<imodesuffix>}\t%2"
6727 [(set_attr "isa" "bmi2,*")
6728 (set_attr "type" "imulx,imul")
6729 (set_attr "length_immediate" "*,0")
6730 (set (attr "athlon_decode")
6731 (cond [(eq_attr "alternative" "1")
6732 (if_then_else (eq_attr "cpu" "athlon")
6733 (const_string "vector")
6734 (const_string "double"))]
6735 (const_string "*")))
6736 (set_attr "amdfam10_decode" "*,double")
6737 (set_attr "bdver1_decode" "*,direct")
6738 (set_attr "prefix" "vex,orig")
6739 (set_attr "mode" "<MODE>")])
6741 ;; Convert mul to the mulx pattern to avoid flags dependency.
6743 [(set (match_operand:<DWI> 0 "register_operand")
6746 (match_operand:DWIH 1 "register_operand"))
6748 (match_operand:DWIH 2 "nonimmediate_operand"))))
6749 (clobber (reg:CC FLAGS_REG))]
6750 "TARGET_BMI2 && reload_completed
6751 && true_regnum (operands[1]) == DX_REG"
6752 [(parallel [(set (match_dup 3)
6753 (mult:DWIH (match_dup 1) (match_dup 2)))
6757 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6758 (zero_extend:<DWI> (match_dup 2)))
6761 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6763 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6766 (define_insn "*mul<mode><dwi>3_1"
6767 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6770 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6772 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6773 (clobber (reg:CC FLAGS_REG))]
6774 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 "imul{<imodesuffix>}\t%2"
6776 [(set_attr "type" "imul")
6777 (set_attr "length_immediate" "0")
6778 (set (attr "athlon_decode")
6779 (if_then_else (eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (const_string "double")))
6782 (set_attr "amdfam10_decode" "double")
6783 (set_attr "bdver1_decode" "direct")
6784 (set_attr "mode" "<MODE>")])
6786 (define_insn "*<u>mulqihi3_1"
6787 [(set (match_operand:HI 0 "register_operand" "=a")
6790 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6792 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6793 (clobber (reg:CC FLAGS_REG))]
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 "<sgnprefix>mul{b}\t%2"
6797 [(set_attr "type" "imul")
6798 (set_attr "length_immediate" "0")
6799 (set (attr "athlon_decode")
6800 (if_then_else (eq_attr "cpu" "athlon")
6801 (const_string "vector")
6802 (const_string "direct")))
6803 (set_attr "amdfam10_decode" "direct")
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "QI")])
6807 (define_expand "<s>mul<mode>3_highpart"
6808 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6813 (match_operand:SWI48 1 "nonimmediate_operand"))
6815 (match_operand:SWI48 2 "register_operand")))
6817 (clobber (match_scratch:SWI48 3))
6818 (clobber (reg:CC FLAGS_REG))])]
6820 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6822 (define_insn "*<s>muldi3_highpart_1"
6823 [(set (match_operand:DI 0 "register_operand" "=d")
6828 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6830 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6832 (clobber (match_scratch:DI 3 "=1"))
6833 (clobber (reg:CC FLAGS_REG))]
6835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6836 "<sgnprefix>mul{q}\t%2"
6837 [(set_attr "type" "imul")
6838 (set_attr "length_immediate" "0")
6839 (set (attr "athlon_decode")
6840 (if_then_else (eq_attr "cpu" "athlon")
6841 (const_string "vector")
6842 (const_string "double")))
6843 (set_attr "amdfam10_decode" "double")
6844 (set_attr "bdver1_decode" "direct")
6845 (set_attr "mode" "DI")])
6847 (define_insn "*<s>mulsi3_highpart_1"
6848 [(set (match_operand:SI 0 "register_operand" "=d")
6853 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6855 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6857 (clobber (match_scratch:SI 3 "=1"))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6860 "<sgnprefix>mul{l}\t%2"
6861 [(set_attr "type" "imul")
6862 (set_attr "length_immediate" "0")
6863 (set (attr "athlon_decode")
6864 (if_then_else (eq_attr "cpu" "athlon")
6865 (const_string "vector")
6866 (const_string "double")))
6867 (set_attr "amdfam10_decode" "double")
6868 (set_attr "bdver1_decode" "direct")
6869 (set_attr "mode" "SI")])
6871 (define_insn "*<s>mulsi3_highpart_zext"
6872 [(set (match_operand:DI 0 "register_operand" "=d")
6873 (zero_extend:DI (truncate:SI
6875 (mult:DI (any_extend:DI
6876 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6878 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6880 (clobber (match_scratch:SI 3 "=1"))
6881 (clobber (reg:CC FLAGS_REG))]
6883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884 "<sgnprefix>mul{l}\t%2"
6885 [(set_attr "type" "imul")
6886 (set_attr "length_immediate" "0")
6887 (set (attr "athlon_decode")
6888 (if_then_else (eq_attr "cpu" "athlon")
6889 (const_string "vector")
6890 (const_string "double")))
6891 (set_attr "amdfam10_decode" "double")
6892 (set_attr "bdver1_decode" "direct")
6893 (set_attr "mode" "SI")])
6895 ;; The patterns that match these are at the end of this file.
6897 (define_expand "mulxf3"
6898 [(set (match_operand:XF 0 "register_operand")
6899 (mult:XF (match_operand:XF 1 "register_operand")
6900 (match_operand:XF 2 "register_operand")))]
6903 (define_expand "mul<mode>3"
6904 [(set (match_operand:MODEF 0 "register_operand")
6905 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6906 (match_operand:MODEF 2 "nonimmediate_operand")))]
6907 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6908 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6910 ;; Divide instructions
6912 ;; The patterns that match these are at the end of this file.
6914 (define_expand "divxf3"
6915 [(set (match_operand:XF 0 "register_operand")
6916 (div:XF (match_operand:XF 1 "register_operand")
6917 (match_operand:XF 2 "register_operand")))]
6920 (define_expand "divdf3"
6921 [(set (match_operand:DF 0 "register_operand")
6922 (div:DF (match_operand:DF 1 "register_operand")
6923 (match_operand:DF 2 "nonimmediate_operand")))]
6924 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6925 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6927 (define_expand "divsf3"
6928 [(set (match_operand:SF 0 "register_operand")
6929 (div:SF (match_operand:SF 1 "register_operand")
6930 (match_operand:SF 2 "nonimmediate_operand")))]
6931 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6936 && optimize_insn_for_speed_p ()
6937 && flag_finite_math_only && !flag_trapping_math
6938 && flag_unsafe_math_optimizations)
6940 ix86_emit_swdivsf (operands[0], operands[1],
6941 operands[2], SFmode);
6946 ;; Divmod instructions.
6948 (define_expand "divmod<mode>4"
6949 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6951 (match_operand:SWIM248 1 "register_operand")
6952 (match_operand:SWIM248 2 "nonimmediate_operand")))
6953 (set (match_operand:SWIM248 3 "register_operand")
6954 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6955 (clobber (reg:CC FLAGS_REG))])])
6957 ;; Split with 8bit unsigned divide:
6958 ;; if (dividend an divisor are in [0-255])
6959 ;; use 8bit unsigned integer divide
6961 ;; use original integer divide
6963 [(set (match_operand:SWI48 0 "register_operand")
6964 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6965 (match_operand:SWI48 3 "nonimmediate_operand")))
6966 (set (match_operand:SWI48 1 "register_operand")
6967 (mod:SWI48 (match_dup 2) (match_dup 3)))
6968 (clobber (reg:CC FLAGS_REG))]
6969 "TARGET_USE_8BIT_IDIV
6970 && TARGET_QIMODE_MATH
6971 && can_create_pseudo_p ()
6972 && !optimize_insn_for_size_p ()"
6974 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6976 (define_insn_and_split "divmod<mode>4_1"
6977 [(set (match_operand:SWI48 0 "register_operand" "=a")
6978 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6979 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6980 (set (match_operand:SWI48 1 "register_operand" "=&d")
6981 (mod:SWI48 (match_dup 2) (match_dup 3)))
6982 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6983 (clobber (reg:CC FLAGS_REG))]
6987 [(parallel [(set (match_dup 1)
6988 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6989 (clobber (reg:CC FLAGS_REG))])
6990 (parallel [(set (match_dup 0)
6991 (div:SWI48 (match_dup 2) (match_dup 3)))
6993 (mod:SWI48 (match_dup 2) (match_dup 3)))
6995 (clobber (reg:CC FLAGS_REG))])]
6997 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6999 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7000 operands[4] = operands[2];
7003 /* Avoid use of cltd in favor of a mov+shift. */
7004 emit_move_insn (operands[1], operands[2]);
7005 operands[4] = operands[1];
7008 [(set_attr "type" "multi")
7009 (set_attr "mode" "<MODE>")])
7011 (define_insn_and_split "*divmod<mode>4"
7012 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7013 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7014 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7015 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7016 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7017 (clobber (reg:CC FLAGS_REG))]
7021 [(parallel [(set (match_dup 1)
7022 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7023 (clobber (reg:CC FLAGS_REG))])
7024 (parallel [(set (match_dup 0)
7025 (div:SWIM248 (match_dup 2) (match_dup 3)))
7027 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7029 (clobber (reg:CC FLAGS_REG))])]
7031 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7033 if (<MODE>mode != HImode
7034 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7035 operands[4] = operands[2];
7038 /* Avoid use of cltd in favor of a mov+shift. */
7039 emit_move_insn (operands[1], operands[2]);
7040 operands[4] = operands[1];
7043 [(set_attr "type" "multi")
7044 (set_attr "mode" "<MODE>")])
7046 (define_insn "*divmod<mode>4_noext"
7047 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7048 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7049 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7050 (set (match_operand:SWIM248 1 "register_operand" "=d")
7051 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7052 (use (match_operand:SWIM248 4 "register_operand" "1"))
7053 (clobber (reg:CC FLAGS_REG))]
7055 "idiv{<imodesuffix>}\t%3"
7056 [(set_attr "type" "idiv")
7057 (set_attr "mode" "<MODE>")])
7059 (define_expand "divmodqi4"
7060 [(parallel [(set (match_operand:QI 0 "register_operand")
7062 (match_operand:QI 1 "register_operand")
7063 (match_operand:QI 2 "nonimmediate_operand")))
7064 (set (match_operand:QI 3 "register_operand")
7065 (mod:QI (match_dup 1) (match_dup 2)))
7066 (clobber (reg:CC FLAGS_REG))])]
7067 "TARGET_QIMODE_MATH"
7072 tmp0 = gen_reg_rtx (HImode);
7073 tmp1 = gen_reg_rtx (HImode);
7075 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7077 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7078 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7080 /* Extract remainder from AH. */
7081 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7082 insn = emit_move_insn (operands[3], tmp1);
7084 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7085 set_unique_reg_note (insn, REG_EQUAL, mod);
7087 /* Extract quotient from AL. */
7088 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7090 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7091 set_unique_reg_note (insn, REG_EQUAL, div);
7096 ;; Divide AX by r/m8, with result stored in
7099 ;; Change div/mod to HImode and extend the second argument to HImode
7100 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7101 ;; combine may fail.
7102 (define_insn "divmodhiqi3"
7103 [(set (match_operand:HI 0 "register_operand" "=a")
7108 (mod:HI (match_operand:HI 1 "register_operand" "0")
7110 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7114 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7115 (clobber (reg:CC FLAGS_REG))]
7116 "TARGET_QIMODE_MATH"
7118 [(set_attr "type" "idiv")
7119 (set_attr "mode" "QI")])
7121 (define_expand "udivmod<mode>4"
7122 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7124 (match_operand:SWIM248 1 "register_operand")
7125 (match_operand:SWIM248 2 "nonimmediate_operand")))
7126 (set (match_operand:SWIM248 3 "register_operand")
7127 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7128 (clobber (reg:CC FLAGS_REG))])])
7130 ;; Split with 8bit unsigned divide:
7131 ;; if (dividend an divisor are in [0-255])
7132 ;; use 8bit unsigned integer divide
7134 ;; use original integer divide
7136 [(set (match_operand:SWI48 0 "register_operand")
7137 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7138 (match_operand:SWI48 3 "nonimmediate_operand")))
7139 (set (match_operand:SWI48 1 "register_operand")
7140 (umod:SWI48 (match_dup 2) (match_dup 3)))
7141 (clobber (reg:CC FLAGS_REG))]
7142 "TARGET_USE_8BIT_IDIV
7143 && TARGET_QIMODE_MATH
7144 && can_create_pseudo_p ()
7145 && !optimize_insn_for_size_p ()"
7147 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7149 (define_insn_and_split "udivmod<mode>4_1"
7150 [(set (match_operand:SWI48 0 "register_operand" "=a")
7151 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7152 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7153 (set (match_operand:SWI48 1 "register_operand" "=&d")
7154 (umod:SWI48 (match_dup 2) (match_dup 3)))
7155 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7156 (clobber (reg:CC FLAGS_REG))]
7160 [(set (match_dup 1) (const_int 0))
7161 (parallel [(set (match_dup 0)
7162 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7164 (umod:SWI48 (match_dup 2) (match_dup 3)))
7166 (clobber (reg:CC FLAGS_REG))])]
7168 [(set_attr "type" "multi")
7169 (set_attr "mode" "<MODE>")])
7171 (define_insn_and_split "*udivmod<mode>4"
7172 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7173 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7174 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7175 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7176 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7177 (clobber (reg:CC FLAGS_REG))]
7181 [(set (match_dup 1) (const_int 0))
7182 (parallel [(set (match_dup 0)
7183 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7185 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7187 (clobber (reg:CC FLAGS_REG))])]
7189 [(set_attr "type" "multi")
7190 (set_attr "mode" "<MODE>")])
7192 (define_insn "*udivmod<mode>4_noext"
7193 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7194 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7195 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7196 (set (match_operand:SWIM248 1 "register_operand" "=d")
7197 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7198 (use (match_operand:SWIM248 4 "register_operand" "1"))
7199 (clobber (reg:CC FLAGS_REG))]
7201 "div{<imodesuffix>}\t%3"
7202 [(set_attr "type" "idiv")
7203 (set_attr "mode" "<MODE>")])
7205 (define_expand "udivmodqi4"
7206 [(parallel [(set (match_operand:QI 0 "register_operand")
7208 (match_operand:QI 1 "register_operand")
7209 (match_operand:QI 2 "nonimmediate_operand")))
7210 (set (match_operand:QI 3 "register_operand")
7211 (umod:QI (match_dup 1) (match_dup 2)))
7212 (clobber (reg:CC FLAGS_REG))])]
7213 "TARGET_QIMODE_MATH"
7218 tmp0 = gen_reg_rtx (HImode);
7219 tmp1 = gen_reg_rtx (HImode);
7221 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7223 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7224 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7226 /* Extract remainder from AH. */
7227 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7228 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7229 insn = emit_move_insn (operands[3], tmp1);
7231 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7232 set_unique_reg_note (insn, REG_EQUAL, mod);
7234 /* Extract quotient from AL. */
7235 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7237 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7238 set_unique_reg_note (insn, REG_EQUAL, div);
7243 (define_insn "udivmodhiqi3"
7244 [(set (match_operand:HI 0 "register_operand" "=a")
7249 (mod:HI (match_operand:HI 1 "register_operand" "0")
7251 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7255 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7256 (clobber (reg:CC FLAGS_REG))]
7257 "TARGET_QIMODE_MATH"
7259 [(set_attr "type" "idiv")
7260 (set_attr "mode" "QI")])
7262 ;; We cannot use div/idiv for double division, because it causes
7263 ;; "division by zero" on the overflow and that's not what we expect
7264 ;; from truncate. Because true (non truncating) double division is
7265 ;; never generated, we can't create this insn anyway.
7268 ; [(set (match_operand:SI 0 "register_operand" "=a")
7270 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7272 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7273 ; (set (match_operand:SI 3 "register_operand" "=d")
7275 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7276 ; (clobber (reg:CC FLAGS_REG))]
7278 ; "div{l}\t{%2, %0|%0, %2}"
7279 ; [(set_attr "type" "idiv")])
7281 ;;- Logical AND instructions
7283 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7284 ;; Note that this excludes ah.
7286 (define_expand "testsi_ccno_1"
7287 [(set (reg:CCNO FLAGS_REG)
7289 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7290 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7293 (define_expand "testqi_ccz_1"
7294 [(set (reg:CCZ FLAGS_REG)
7295 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7296 (match_operand:QI 1 "nonmemory_operand"))
7299 (define_expand "testdi_ccno_1"
7300 [(set (reg:CCNO FLAGS_REG)
7302 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7303 (match_operand:DI 1 "x86_64_szext_general_operand"))
7305 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7307 (define_insn "*testdi_1"
7308 [(set (reg FLAGS_REG)
7311 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7312 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7314 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7315 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7317 test{l}\t{%k1, %k0|%k0, %k1}
7318 test{l}\t{%k1, %k0|%k0, %k1}
7319 test{q}\t{%1, %0|%0, %1}
7320 test{q}\t{%1, %0|%0, %1}
7321 test{q}\t{%1, %0|%0, %1}"
7322 [(set_attr "type" "test")
7323 (set_attr "modrm" "0,1,0,1,1")
7324 (set_attr "mode" "SI,SI,DI,DI,DI")])
7326 (define_insn "*testqi_1_maybe_si"
7327 [(set (reg FLAGS_REG)
7330 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7331 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7333 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7334 && ix86_match_ccmode (insn,
7335 CONST_INT_P (operands[1])
7336 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7338 if (which_alternative == 3)
7340 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7341 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7342 return "test{l}\t{%1, %k0|%k0, %1}";
7344 return "test{b}\t{%1, %0|%0, %1}";
7346 [(set_attr "type" "test")
7347 (set_attr "modrm" "0,1,1,1")
7348 (set_attr "mode" "QI,QI,QI,SI")
7349 (set_attr "pent_pair" "uv,np,uv,np")])
7351 (define_insn "*test<mode>_1"
7352 [(set (reg FLAGS_REG)
7355 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7356 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7358 "ix86_match_ccmode (insn, CCNOmode)
7359 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7360 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7361 [(set_attr "type" "test")
7362 (set_attr "modrm" "0,1,1")
7363 (set_attr "mode" "<MODE>")
7364 (set_attr "pent_pair" "uv,np,uv")])
7366 (define_expand "testqi_ext_ccno_0"
7367 [(set (reg:CCNO FLAGS_REG)
7371 (match_operand 0 "ext_register_operand")
7374 (match_operand 1 "const_int_operand"))
7377 (define_insn "*testqi_ext_0"
7378 [(set (reg FLAGS_REG)
7382 (match_operand 0 "ext_register_operand" "Q")
7385 (match_operand 1 "const_int_operand" "n"))
7387 "ix86_match_ccmode (insn, CCNOmode)"
7388 "test{b}\t{%1, %h0|%h0, %1}"
7389 [(set_attr "type" "test")
7390 (set_attr "mode" "QI")
7391 (set_attr "length_immediate" "1")
7392 (set_attr "modrm" "1")
7393 (set_attr "pent_pair" "np")])
7395 (define_insn "*testqi_ext_1"
7396 [(set (reg FLAGS_REG)
7400 (match_operand 0 "ext_register_operand" "Q,Q")
7404 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7406 "ix86_match_ccmode (insn, CCNOmode)"
7407 "test{b}\t{%1, %h0|%h0, %1}"
7408 [(set_attr "isa" "*,nox64")
7409 (set_attr "type" "test")
7410 (set_attr "mode" "QI")])
7412 (define_insn "*testqi_ext_2"
7413 [(set (reg FLAGS_REG)
7417 (match_operand 0 "ext_register_operand" "Q")
7421 (match_operand 1 "ext_register_operand" "Q")
7425 "ix86_match_ccmode (insn, CCNOmode)"
7426 "test{b}\t{%h1, %h0|%h0, %h1}"
7427 [(set_attr "type" "test")
7428 (set_attr "mode" "QI")])
7430 ;; Combine likes to form bit extractions for some tests. Humor it.
7431 (define_insn "*testqi_ext_3"
7432 [(set (reg FLAGS_REG)
7433 (compare (zero_extract:SWI48
7434 (match_operand 0 "nonimmediate_operand" "rm")
7435 (match_operand:SWI48 1 "const_int_operand")
7436 (match_operand:SWI48 2 "const_int_operand"))
7438 "ix86_match_ccmode (insn, CCNOmode)
7439 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7440 || GET_MODE (operands[0]) == SImode
7441 || GET_MODE (operands[0]) == HImode
7442 || GET_MODE (operands[0]) == QImode)
7443 /* Ensure that resulting mask is zero or sign extended operand. */
7444 && INTVAL (operands[2]) >= 0
7445 && ((INTVAL (operands[1]) > 0
7446 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7447 || (<MODE>mode == DImode
7448 && INTVAL (operands[1]) > 32
7449 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7453 [(set (match_operand 0 "flags_reg_operand")
7454 (match_operator 1 "compare_operator"
7456 (match_operand 2 "nonimmediate_operand")
7457 (match_operand 3 "const_int_operand")
7458 (match_operand 4 "const_int_operand"))
7460 "ix86_match_ccmode (insn, CCNOmode)"
7461 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7463 rtx val = operands[2];
7464 HOST_WIDE_INT len = INTVAL (operands[3]);
7465 HOST_WIDE_INT pos = INTVAL (operands[4]);
7467 machine_mode mode, submode;
7469 mode = GET_MODE (val);
7472 /* ??? Combine likes to put non-volatile mem extractions in QImode
7473 no matter the size of the test. So find a mode that works. */
7474 if (! MEM_VOLATILE_P (val))
7476 mode = smallest_mode_for_size (pos + len, MODE_INT);
7477 val = adjust_address (val, mode, 0);
7480 else if (GET_CODE (val) == SUBREG
7481 && (submode = GET_MODE (SUBREG_REG (val)),
7482 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7483 && pos + len <= GET_MODE_BITSIZE (submode)
7484 && GET_MODE_CLASS (submode) == MODE_INT)
7486 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7488 val = SUBREG_REG (val);
7490 else if (mode == HImode && pos + len <= 8)
7492 /* Small HImode tests can be converted to QImode. */
7494 val = gen_lowpart (QImode, val);
7497 if (len == HOST_BITS_PER_WIDE_INT)
7500 mask = ((HOST_WIDE_INT)1 << len) - 1;
7503 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7506 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7507 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7508 ;; this is relatively important trick.
7509 ;; Do the conversion only post-reload to avoid limiting of the register class
7512 [(set (match_operand 0 "flags_reg_operand")
7513 (match_operator 1 "compare_operator"
7514 [(and (match_operand 2 "register_operand")
7515 (match_operand 3 "const_int_operand"))
7518 && QI_REG_P (operands[2])
7519 && GET_MODE (operands[2]) != QImode
7520 && ((ix86_match_ccmode (insn, CCZmode)
7521 && !(INTVAL (operands[3]) & ~(255 << 8)))
7522 || (ix86_match_ccmode (insn, CCNOmode)
7523 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7526 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7530 operands[2] = gen_lowpart (SImode, operands[2]);
7531 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7535 [(set (match_operand 0 "flags_reg_operand")
7536 (match_operator 1 "compare_operator"
7537 [(and (match_operand 2 "nonimmediate_operand")
7538 (match_operand 3 "const_int_operand"))
7541 && GET_MODE (operands[2]) != QImode
7542 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7543 && ((ix86_match_ccmode (insn, CCZmode)
7544 && !(INTVAL (operands[3]) & ~255))
7545 || (ix86_match_ccmode (insn, CCNOmode)
7546 && !(INTVAL (operands[3]) & ~127)))"
7548 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7551 operands[2] = gen_lowpart (QImode, operands[2]);
7552 operands[3] = gen_lowpart (QImode, operands[3]);
7556 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7557 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7558 (match_operand:SWI1248x 2 "mask_reg_operand")))
7559 (clobber (reg:CC FLAGS_REG))]
7560 "TARGET_AVX512F && reload_completed"
7562 (any_logic:SWI1248x (match_dup 1)
7565 (define_insn "*k<logic><mode>"
7566 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7567 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7568 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7571 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7572 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7574 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7576 [(set_attr "mode" "<MODE>")
7577 (set_attr "type" "msklog")
7578 (set_attr "prefix" "vex")])
7580 ;; %%% This used to optimize known byte-wide and operations to memory,
7581 ;; and sometimes to QImode registers. If this is considered useful,
7582 ;; it should be done with splitters.
7584 (define_expand "and<mode>3"
7585 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7586 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7587 (match_operand:SWIM 2 "<general_szext_operand>")))]
7590 machine_mode mode = <MODE>mode;
7591 rtx (*insn) (rtx, rtx);
7593 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7595 HOST_WIDE_INT ival = INTVAL (operands[2]);
7597 if (ival == (HOST_WIDE_INT) 0xffffffff)
7599 else if (ival == 0xffff)
7601 else if (ival == 0xff)
7605 if (mode == <MODE>mode)
7607 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7611 if (<MODE>mode == DImode)
7612 insn = (mode == SImode)
7613 ? gen_zero_extendsidi2
7615 ? gen_zero_extendhidi2
7616 : gen_zero_extendqidi2;
7617 else if (<MODE>mode == SImode)
7618 insn = (mode == HImode)
7619 ? gen_zero_extendhisi2
7620 : gen_zero_extendqisi2;
7621 else if (<MODE>mode == HImode)
7622 insn = gen_zero_extendqihi2;
7626 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7630 (define_insn "*anddi_1"
7631 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7633 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7634 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7635 (clobber (reg:CC FLAGS_REG))]
7636 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7638 switch (get_attr_type (insn))
7644 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7647 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7648 if (get_attr_mode (insn) == MODE_SI)
7649 return "and{l}\t{%k2, %k0|%k0, %k2}";
7651 return "and{q}\t{%2, %0|%0, %2}";
7654 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7655 (set_attr "length_immediate" "*,*,*,0,0")
7656 (set (attr "prefix_rex")
7658 (and (eq_attr "type" "imovx")
7659 (and (match_test "INTVAL (operands[2]) == 0xff")
7660 (match_operand 1 "ext_QIreg_operand")))
7662 (const_string "*")))
7663 (set_attr "mode" "SI,DI,DI,SI,DI")])
7665 (define_insn "*andsi_1"
7666 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7667 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7668 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "ix86_binary_operator_ok (AND, SImode, operands)"
7672 switch (get_attr_type (insn))
7678 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7681 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7682 return "and{l}\t{%2, %0|%0, %2}";
7685 [(set_attr "type" "alu,alu,imovx,msklog")
7686 (set (attr "prefix_rex")
7688 (and (eq_attr "type" "imovx")
7689 (and (match_test "INTVAL (operands[2]) == 0xff")
7690 (match_operand 1 "ext_QIreg_operand")))
7692 (const_string "*")))
7693 (set_attr "length_immediate" "*,*,0,0")
7694 (set_attr "mode" "SI")])
7696 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7697 (define_insn "*andsi_1_zext"
7698 [(set (match_operand:DI 0 "register_operand" "=r")
7700 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7701 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7702 (clobber (reg:CC FLAGS_REG))]
7703 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7704 "and{l}\t{%2, %k0|%k0, %2}"
7705 [(set_attr "type" "alu")
7706 (set_attr "mode" "SI")])
7708 (define_insn "*andhi_1"
7709 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7710 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7711 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7712 (clobber (reg:CC FLAGS_REG))]
7713 "ix86_binary_operator_ok (AND, HImode, operands)"
7715 switch (get_attr_type (insn))
7721 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7725 return "and{w}\t{%2, %0|%0, %2}";
7728 [(set_attr "type" "alu,alu,imovx,msklog")
7729 (set_attr "length_immediate" "*,*,0,*")
7730 (set (attr "prefix_rex")
7732 (and (eq_attr "type" "imovx")
7733 (match_operand 1 "ext_QIreg_operand"))
7735 (const_string "*")))
7736 (set_attr "mode" "HI,HI,SI,HI")])
7738 ;; %%% Potential partial reg stall on alternative 2. What to do?
7739 (define_insn "*andqi_1"
7740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7741 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7742 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7743 (clobber (reg:CC FLAGS_REG))]
7744 "ix86_binary_operator_ok (AND, QImode, operands)"
7746 switch (which_alternative)
7750 return "and{b}\t{%2, %0|%0, %2}";
7752 return "and{l}\t{%k2, %k0|%k0, %k2}";
7754 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7755 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7760 [(set_attr "type" "alu,alu,alu,msklog")
7761 (set_attr "mode" "QI,QI,SI,HI")])
7763 (define_insn "*andqi_1_slp"
7764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7765 (and:QI (match_dup 0)
7766 (match_operand:QI 1 "general_operand" "qn,qmn")))
7767 (clobber (reg:CC FLAGS_REG))]
7768 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7769 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7770 "and{b}\t{%1, %0|%0, %1}"
7771 [(set_attr "type" "alu1")
7772 (set_attr "mode" "QI")])
7774 (define_insn "kandn<mode>"
7775 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7778 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7779 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7780 (clobber (reg:CC FLAGS_REG))]
7783 switch (which_alternative)
7786 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7790 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7791 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7793 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7798 [(set_attr "isa" "bmi,*,avx512f")
7799 (set_attr "type" "bitmanip,*,msklog")
7800 (set_attr "prefix" "*,*,vex")
7801 (set_attr "btver2_decode" "direct,*,*")
7802 (set_attr "mode" "<MODE>")])
7805 [(set (match_operand:SWI12 0 "general_reg_operand")
7809 (match_operand:SWI12 1 "general_reg_operand")))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7813 (not:HI (match_dup 0)))
7814 (parallel [(set (match_dup 0)
7815 (and:HI (match_dup 0)
7817 (clobber (reg:CC FLAGS_REG))])])
7819 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7821 [(set (match_operand:DI 0 "register_operand")
7822 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7823 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7824 (clobber (reg:CC FLAGS_REG))]
7826 [(parallel [(set (match_dup 0)
7827 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7828 (clobber (reg:CC FLAGS_REG))])]
7829 "operands[2] = gen_lowpart (SImode, operands[2]);")
7832 [(set (match_operand:SWI248 0 "register_operand")
7833 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7834 (match_operand:SWI248 2 "const_int_operand")))
7835 (clobber (reg:CC FLAGS_REG))]
7837 && true_regnum (operands[0]) != true_regnum (operands[1])"
7840 HOST_WIDE_INT ival = INTVAL (operands[2]);
7842 rtx (*insn) (rtx, rtx);
7844 if (ival == (HOST_WIDE_INT) 0xffffffff)
7846 else if (ival == 0xffff)
7850 gcc_assert (ival == 0xff);
7854 if (<MODE>mode == DImode)
7855 insn = (mode == SImode)
7856 ? gen_zero_extendsidi2
7858 ? gen_zero_extendhidi2
7859 : gen_zero_extendqidi2;
7862 if (<MODE>mode != SImode)
7863 /* Zero extend to SImode to avoid partial register stalls. */
7864 operands[0] = gen_lowpart (SImode, operands[0]);
7866 insn = (mode == HImode)
7867 ? gen_zero_extendhisi2
7868 : gen_zero_extendqisi2;
7870 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7875 [(set (match_operand 0 "register_operand")
7877 (const_int -65536)))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7880 || optimize_function_for_size_p (cfun)"
7881 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7882 "operands[1] = gen_lowpart (HImode, operands[0]);")
7885 [(set (match_operand 0 "ext_register_operand")
7888 (clobber (reg:CC FLAGS_REG))]
7889 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7890 && reload_completed"
7891 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7892 "operands[1] = gen_lowpart (QImode, operands[0]);")
7895 [(set (match_operand 0 "ext_register_operand")
7897 (const_int -65281)))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7900 && reload_completed"
7901 [(parallel [(set (zero_extract:SI (match_dup 0)
7905 (zero_extract:SI (match_dup 0)
7908 (zero_extract:SI (match_dup 0)
7911 (clobber (reg:CC FLAGS_REG))])]
7912 "operands[0] = gen_lowpart (SImode, operands[0]);")
7914 (define_insn "*anddi_2"
7915 [(set (reg FLAGS_REG)
7918 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7919 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7921 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7922 (and:DI (match_dup 1) (match_dup 2)))]
7924 && ix86_match_ccmode
7926 /* If we are going to emit andl instead of andq, and the operands[2]
7927 constant might have the SImode sign bit set, make sure the sign
7928 flag isn't tested, because the instruction will set the sign flag
7929 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7930 conservatively assume it might have bit 31 set. */
7931 (satisfies_constraint_Z (operands[2])
7932 && (!CONST_INT_P (operands[2])
7933 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7934 ? CCZmode : CCNOmode)
7935 && ix86_binary_operator_ok (AND, DImode, operands)"
7937 and{l}\t{%k2, %k0|%k0, %k2}
7938 and{q}\t{%2, %0|%0, %2}
7939 and{q}\t{%2, %0|%0, %2}"
7940 [(set_attr "type" "alu")
7941 (set_attr "mode" "SI,DI,DI")])
7943 (define_insn "*andqi_2_maybe_si"
7944 [(set (reg FLAGS_REG)
7946 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7947 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7949 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7950 (and:QI (match_dup 1) (match_dup 2)))]
7951 "ix86_binary_operator_ok (AND, QImode, operands)
7952 && ix86_match_ccmode (insn,
7953 CONST_INT_P (operands[2])
7954 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7956 if (which_alternative == 2)
7958 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7959 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7960 return "and{l}\t{%2, %k0|%k0, %2}";
7962 return "and{b}\t{%2, %0|%0, %2}";
7964 [(set_attr "type" "alu")
7965 (set_attr "mode" "QI,QI,SI")])
7967 (define_insn "*and<mode>_2"
7968 [(set (reg FLAGS_REG)
7969 (compare (and:SWI124
7970 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7971 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7973 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7974 (and:SWI124 (match_dup 1) (match_dup 2)))]
7975 "ix86_match_ccmode (insn, CCNOmode)
7976 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7977 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7978 [(set_attr "type" "alu")
7979 (set_attr "mode" "<MODE>")])
7981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7982 (define_insn "*andsi_2_zext"
7983 [(set (reg FLAGS_REG)
7985 (match_operand:SI 1 "nonimmediate_operand" "%0")
7986 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7988 (set (match_operand:DI 0 "register_operand" "=r")
7989 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7990 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7991 && ix86_binary_operator_ok (AND, SImode, operands)"
7992 "and{l}\t{%2, %k0|%k0, %2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "SI")])
7996 (define_insn "*andqi_2_slp"
7997 [(set (reg FLAGS_REG)
7999 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8002 (set (strict_low_part (match_dup 0))
8003 (and:QI (match_dup 0) (match_dup 1)))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && ix86_match_ccmode (insn, CCNOmode)
8006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 "and{b}\t{%1, %0|%0, %1}"
8008 [(set_attr "type" "alu1")
8009 (set_attr "mode" "QI")])
8011 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8012 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8013 ;; for a QImode operand, which of course failed.
8014 (define_insn "andqi_ext_0"
8015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8020 (match_operand 1 "ext_register_operand" "0")
8023 (match_operand 2 "const_int_operand" "n")))
8024 (clobber (reg:CC FLAGS_REG))]
8026 "and{b}\t{%2, %h0|%h0, %2}"
8027 [(set_attr "type" "alu")
8028 (set_attr "length_immediate" "1")
8029 (set_attr "modrm" "1")
8030 (set_attr "mode" "QI")])
8032 ;; Generated by peephole translating test to and. This shows up
8033 ;; often in fp comparisons.
8034 (define_insn "*andqi_ext_0_cc"
8035 [(set (reg FLAGS_REG)
8039 (match_operand 1 "ext_register_operand" "0")
8042 (match_operand 2 "const_int_operand" "n"))
8044 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8053 "ix86_match_ccmode (insn, CCNOmode)"
8054 "and{b}\t{%2, %h0|%h0, %2}"
8055 [(set_attr "type" "alu")
8056 (set_attr "length_immediate" "1")
8057 (set_attr "modrm" "1")
8058 (set_attr "mode" "QI")])
8060 (define_insn "*andqi_ext_1"
8061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8066 (match_operand 1 "ext_register_operand" "0,0")
8070 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8071 (clobber (reg:CC FLAGS_REG))]
8073 "and{b}\t{%2, %h0|%h0, %2}"
8074 [(set_attr "isa" "*,nox64")
8075 (set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8079 (define_insn "*andqi_ext_2"
8080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8085 (match_operand 1 "ext_register_operand" "%0")
8089 (match_operand 2 "ext_register_operand" "Q")
8092 (clobber (reg:CC FLAGS_REG))]
8094 "and{b}\t{%h2, %h0|%h0, %h2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "length_immediate" "0")
8097 (set_attr "mode" "QI")])
8099 ;; Convert wide AND instructions with immediate operand to shorter QImode
8100 ;; equivalents when possible.
8101 ;; Don't do the splitting with memory operands, since it introduces risk
8102 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8103 ;; for size, but that can (should?) be handled by generic code instead.
8105 [(set (match_operand 0 "register_operand")
8106 (and (match_operand 1 "register_operand")
8107 (match_operand 2 "const_int_operand")))
8108 (clobber (reg:CC FLAGS_REG))]
8110 && QI_REG_P (operands[0])
8111 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8112 && !(~INTVAL (operands[2]) & ~(255 << 8))
8113 && GET_MODE (operands[0]) != QImode"
8114 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8115 (and:SI (zero_extract:SI (match_dup 1)
8116 (const_int 8) (const_int 8))
8118 (clobber (reg:CC FLAGS_REG))])]
8120 operands[0] = gen_lowpart (SImode, operands[0]);
8121 operands[1] = gen_lowpart (SImode, operands[1]);
8122 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8125 ;; Since AND can be encoded with sign extended immediate, this is only
8126 ;; profitable when 7th bit is not set.
8128 [(set (match_operand 0 "register_operand")
8129 (and (match_operand 1 "general_operand")
8130 (match_operand 2 "const_int_operand")))
8131 (clobber (reg:CC FLAGS_REG))]
8133 && ANY_QI_REG_P (operands[0])
8134 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8135 && !(~INTVAL (operands[2]) & ~255)
8136 && !(INTVAL (operands[2]) & 128)
8137 && GET_MODE (operands[0]) != QImode"
8138 [(parallel [(set (strict_low_part (match_dup 0))
8139 (and:QI (match_dup 1)
8141 (clobber (reg:CC FLAGS_REG))])]
8143 operands[0] = gen_lowpart (QImode, operands[0]);
8144 operands[1] = gen_lowpart (QImode, operands[1]);
8145 operands[2] = gen_lowpart (QImode, operands[2]);
8148 ;; Logical inclusive and exclusive OR instructions
8150 ;; %%% This used to optimize known byte-wide and operations to memory.
8151 ;; If this is considered useful, it should be done with splitters.
8153 (define_expand "<code><mode>3"
8154 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8155 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8156 (match_operand:SWIM 2 "<general_operand>")))]
8158 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8160 (define_insn "*<code><mode>_1"
8161 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8163 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8164 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8168 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8169 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8170 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8171 [(set_attr "type" "alu,alu,msklog")
8172 (set_attr "mode" "<MODE>")])
8174 (define_insn "*<code>hi_1"
8175 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8177 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8178 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8182 <logic>{w}\t{%2, %0|%0, %2}
8183 <logic>{w}\t{%2, %0|%0, %2}
8184 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8185 [(set_attr "type" "alu,alu,msklog")
8186 (set_attr "mode" "HI")])
8188 ;; %%% Potential partial reg stall on alternative 2. What to do?
8189 (define_insn "*<code>qi_1"
8190 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8191 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8192 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8193 (clobber (reg:CC FLAGS_REG))]
8194 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8196 <logic>{b}\t{%2, %0|%0, %2}
8197 <logic>{b}\t{%2, %0|%0, %2}
8198 <logic>{l}\t{%k2, %k0|%k0, %k2}
8199 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8200 [(set_attr "type" "alu,alu,alu,msklog")
8201 (set_attr "mode" "QI,QI,SI,HI")])
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 (define_insn "*<code>si_1_zext"
8205 [(set (match_operand:DI 0 "register_operand" "=r")
8207 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8209 (clobber (reg:CC FLAGS_REG))]
8210 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8211 "<logic>{l}\t{%2, %k0|%k0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "SI")])
8215 (define_insn "*<code>si_1_zext_imm"
8216 [(set (match_operand:DI 0 "register_operand" "=r")
8218 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8219 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8220 (clobber (reg:CC FLAGS_REG))]
8221 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8222 "<logic>{l}\t{%2, %k0|%k0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "mode" "SI")])
8226 (define_insn "*<code>qi_1_slp"
8227 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8228 (any_or:QI (match_dup 0)
8229 (match_operand:QI 1 "general_operand" "qmn,qn")))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8233 "<logic>{b}\t{%1, %0|%0, %1}"
8234 [(set_attr "type" "alu1")
8235 (set_attr "mode" "QI")])
8237 (define_insn "*<code><mode>_2"
8238 [(set (reg FLAGS_REG)
8239 (compare (any_or:SWI
8240 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8241 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8243 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8244 (any_or:SWI (match_dup 1) (match_dup 2)))]
8245 "ix86_match_ccmode (insn, CCNOmode)
8246 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8247 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "<MODE>")])
8251 (define_insn "kxnor<mode>"
8252 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8255 (match_operand:SWI12 1 "register_operand" "0,k")
8256 (match_operand:SWI12 2 "register_operand" "r,k"))))
8257 (clobber (reg:CC FLAGS_REG))]
8260 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8261 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8262 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8264 [(set_attr "type" "*,msklog")
8265 (set_attr "prefix" "*,vex")
8266 (set_attr "mode" "<MODE>")])
8268 (define_insn "kxnor<mode>"
8269 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8272 (match_operand:SWI48x 1 "register_operand" "0,k")
8273 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8274 (clobber (reg:CC FLAGS_REG))]
8278 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8279 [(set_attr "type" "*,msklog")
8280 (set_attr "prefix" "*,vex")
8281 (set_attr "mode" "<MODE>")])
8284 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8288 (match_operand:SWI1248x 1 "general_reg_operand"))))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "TARGET_AVX512F && reload_completed"
8291 [(parallel [(set (match_dup 0)
8292 (xor:HI (match_dup 0)
8294 (clobber (reg:CC FLAGS_REG))])
8296 (not:HI (match_dup 0)))])
8298 ;;There are kortrest[bdq] but no intrinsics for them.
8299 ;;We probably don't need to implement them.
8300 (define_insn "kortestzhi"
8301 [(set (reg:CCZ FLAGS_REG)
8304 (match_operand:HI 0 "register_operand" "k")
8305 (match_operand:HI 1 "register_operand" "k"))
8307 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8308 "kortestw\t{%1, %0|%0, %1}"
8309 [(set_attr "mode" "HI")
8310 (set_attr "type" "msklog")
8311 (set_attr "prefix" "vex")])
8313 (define_insn "kortestchi"
8314 [(set (reg:CCC FLAGS_REG)
8317 (match_operand:HI 0 "register_operand" "k")
8318 (match_operand:HI 1 "register_operand" "k"))
8320 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8321 "kortestw\t{%1, %0|%0, %1}"
8322 [(set_attr "mode" "HI")
8323 (set_attr "type" "msklog")
8324 (set_attr "prefix" "vex")])
8326 (define_insn "kunpckhi"
8327 [(set (match_operand:HI 0 "register_operand" "=k")
8330 (match_operand:HI 1 "register_operand" "k")
8332 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8334 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8335 [(set_attr "mode" "HI")
8336 (set_attr "type" "msklog")
8337 (set_attr "prefix" "vex")])
8339 (define_insn "kunpcksi"
8340 [(set (match_operand:SI 0 "register_operand" "=k")
8343 (match_operand:SI 1 "register_operand" "k")
8345 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8347 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8348 [(set_attr "mode" "SI")])
8350 (define_insn "kunpckdi"
8351 [(set (match_operand:DI 0 "register_operand" "=k")
8354 (match_operand:DI 1 "register_operand" "k")
8356 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8358 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8359 [(set_attr "mode" "DI")])
8361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8362 ;; ??? Special case for immediate operand is missing - it is tricky.
8363 (define_insn "*<code>si_2_zext"
8364 [(set (reg FLAGS_REG)
8365 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8366 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8368 (set (match_operand:DI 0 "register_operand" "=r")
8369 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8372 "<logic>{l}\t{%2, %k0|%k0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "SI")])
8376 (define_insn "*<code>si_2_zext_imm"
8377 [(set (reg FLAGS_REG)
8379 (match_operand:SI 1 "nonimmediate_operand" "%0")
8380 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8382 (set (match_operand:DI 0 "register_operand" "=r")
8383 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8384 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8385 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8386 "<logic>{l}\t{%2, %k0|%k0, %2}"
8387 [(set_attr "type" "alu")
8388 (set_attr "mode" "SI")])
8390 (define_insn "*<code>qi_2_slp"
8391 [(set (reg FLAGS_REG)
8392 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8393 (match_operand:QI 1 "general_operand" "qmn,qn"))
8395 (set (strict_low_part (match_dup 0))
8396 (any_or:QI (match_dup 0) (match_dup 1)))]
8397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && ix86_match_ccmode (insn, CCNOmode)
8399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400 "<logic>{b}\t{%1, %0|%0, %1}"
8401 [(set_attr "type" "alu1")
8402 (set_attr "mode" "QI")])
8404 (define_insn "*<code><mode>_3"
8405 [(set (reg FLAGS_REG)
8406 (compare (any_or:SWI
8407 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8408 (match_operand:SWI 2 "<general_operand>" "<g>"))
8410 (clobber (match_scratch:SWI 0 "=<r>"))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8413 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "<MODE>")])
8417 (define_insn "*<code>qi_ext_0"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423 (match_operand 1 "ext_register_operand" "0")
8426 (match_operand 2 "const_int_operand" "n")))
8427 (clobber (reg:CC FLAGS_REG))]
8428 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8429 "<logic>{b}\t{%2, %h0|%h0, %2}"
8430 [(set_attr "type" "alu")
8431 (set_attr "length_immediate" "1")
8432 (set_attr "modrm" "1")
8433 (set_attr "mode" "QI")])
8435 (define_insn "*<code>qi_ext_1"
8436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8441 (match_operand 1 "ext_register_operand" "0,0")
8445 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8446 (clobber (reg:CC FLAGS_REG))]
8447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8448 "<logic>{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "isa" "*,nox64")
8450 (set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8454 (define_insn "*<code>qi_ext_2"
8455 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8462 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8465 (clobber (reg:CC FLAGS_REG))]
8466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8467 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "length_immediate" "0")
8470 (set_attr "mode" "QI")])
8473 [(set (match_operand 0 "register_operand")
8474 (any_or (match_operand 1 "register_operand")
8475 (match_operand 2 "const_int_operand")))
8476 (clobber (reg:CC FLAGS_REG))]
8478 && QI_REG_P (operands[0])
8479 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8480 && !(INTVAL (operands[2]) & ~(255 << 8))
8481 && GET_MODE (operands[0]) != QImode"
8482 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8483 (any_or:SI (zero_extract:SI (match_dup 1)
8484 (const_int 8) (const_int 8))
8486 (clobber (reg:CC FLAGS_REG))])]
8488 operands[0] = gen_lowpart (SImode, operands[0]);
8489 operands[1] = gen_lowpart (SImode, operands[1]);
8490 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8493 ;; Since OR can be encoded with sign extended immediate, this is only
8494 ;; profitable when 7th bit is set.
8496 [(set (match_operand 0 "register_operand")
8497 (any_or (match_operand 1 "general_operand")
8498 (match_operand 2 "const_int_operand")))
8499 (clobber (reg:CC FLAGS_REG))]
8501 && ANY_QI_REG_P (operands[0])
8502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503 && !(INTVAL (operands[2]) & ~255)
8504 && (INTVAL (operands[2]) & 128)
8505 && GET_MODE (operands[0]) != QImode"
8506 [(parallel [(set (strict_low_part (match_dup 0))
8507 (any_or:QI (match_dup 1)
8509 (clobber (reg:CC FLAGS_REG))])]
8511 operands[0] = gen_lowpart (QImode, operands[0]);
8512 operands[1] = gen_lowpart (QImode, operands[1]);
8513 operands[2] = gen_lowpart (QImode, operands[2]);
8516 (define_expand "xorqi_cc_ext_1"
8518 (set (reg:CCNO FLAGS_REG)
8522 (match_operand 1 "ext_register_operand")
8525 (match_operand:QI 2 "const_int_operand"))
8527 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8537 (define_insn "*xorqi_cc_ext_1"
8538 [(set (reg FLAGS_REG)
8542 (match_operand 1 "ext_register_operand" "0,0")
8545 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8547 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8556 "ix86_match_ccmode (insn, CCNOmode)"
8557 "xor{b}\t{%2, %h0|%h0, %2}"
8558 [(set_attr "isa" "*,nox64")
8559 (set_attr "type" "alu")
8560 (set_attr "modrm" "1")
8561 (set_attr "mode" "QI")])
8563 ;; Negation instructions
8565 (define_expand "neg<mode>2"
8566 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8567 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8569 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8571 (define_insn_and_split "*neg<dwi>2_doubleword"
8572 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8573 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8579 [(set (reg:CCZ FLAGS_REG)
8580 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8581 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8584 (plus:DWIH (match_dup 3)
8585 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8587 (clobber (reg:CC FLAGS_REG))])
8590 (neg:DWIH (match_dup 2)))
8591 (clobber (reg:CC FLAGS_REG))])]
8592 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8594 (define_insn "*neg<mode>2_1"
8595 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8596 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8599 "neg{<imodesuffix>}\t%0"
8600 [(set_attr "type" "negnot")
8601 (set_attr "mode" "<MODE>")])
8603 ;; Combine is quite creative about this pattern.
8604 (define_insn "*negsi2_1_zext"
8605 [(set (match_operand:DI 0 "register_operand" "=r")
8607 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8613 [(set_attr "type" "negnot")
8614 (set_attr "mode" "SI")])
8616 ;; The problem with neg is that it does not perform (compare x 0),
8617 ;; it really performs (compare 0 x), which leaves us with the zero
8618 ;; flag being the only useful item.
8620 (define_insn "*neg<mode>2_cmpz"
8621 [(set (reg:CCZ FLAGS_REG)
8623 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8625 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8626 (neg:SWI (match_dup 1)))]
8627 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8628 "neg{<imodesuffix>}\t%0"
8629 [(set_attr "type" "negnot")
8630 (set_attr "mode" "<MODE>")])
8632 (define_insn "*negsi2_cmpz_zext"
8633 [(set (reg:CCZ FLAGS_REG)
8637 (match_operand:DI 1 "register_operand" "0")
8641 (set (match_operand:DI 0 "register_operand" "=r")
8642 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8645 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8647 [(set_attr "type" "negnot")
8648 (set_attr "mode" "SI")])
8650 ;; Negate with jump on overflow.
8651 (define_expand "negv<mode>3"
8652 [(parallel [(set (reg:CCO FLAGS_REG)
8653 (ne:CCO (match_operand:SWI 1 "register_operand")
8655 (set (match_operand:SWI 0 "register_operand")
8656 (neg:SWI (match_dup 1)))])
8657 (set (pc) (if_then_else
8658 (eq (reg:CCO FLAGS_REG) (const_int 0))
8659 (label_ref (match_operand 2))
8664 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8668 (define_insn "*negv<mode>3"
8669 [(set (reg:CCO FLAGS_REG)
8670 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8671 (match_operand:SWI 2 "const_int_operand")))
8672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8673 (neg:SWI (match_dup 1)))]
8674 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8675 && mode_signbit_p (<MODE>mode, operands[2])"
8676 "neg{<imodesuffix>}\t%0"
8677 [(set_attr "type" "negnot")
8678 (set_attr "mode" "<MODE>")])
8680 ;; Changing of sign for FP values is doable using integer unit too.
8682 (define_expand "<code><mode>2"
8683 [(set (match_operand:X87MODEF 0 "register_operand")
8684 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8685 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8686 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8688 (define_insn "*absneg<mode>2_mixed"
8689 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8690 (match_operator:MODEF 3 "absneg_operator"
8691 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8692 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8693 (clobber (reg:CC FLAGS_REG))]
8694 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8697 (define_insn "*absneg<mode>2_sse"
8698 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8699 (match_operator:MODEF 3 "absneg_operator"
8700 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8701 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8706 (define_insn "*absneg<mode>2_i387"
8707 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8708 (match_operator:X87MODEF 3 "absneg_operator"
8709 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8710 (use (match_operand 2))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8715 (define_expand "<code>tf2"
8716 [(set (match_operand:TF 0 "register_operand")
8717 (absneg:TF (match_operand:TF 1 "register_operand")))]
8719 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8721 (define_insn "*absnegtf2_sse"
8722 [(set (match_operand:TF 0 "register_operand" "=x,x")
8723 (match_operator:TF 3 "absneg_operator"
8724 [(match_operand:TF 1 "register_operand" "0,x")]))
8725 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8726 (clobber (reg:CC FLAGS_REG))]
8730 ;; Splitters for fp abs and neg.
8733 [(set (match_operand 0 "fp_register_operand")
8734 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8735 (use (match_operand 2))
8736 (clobber (reg:CC FLAGS_REG))]
8738 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8741 [(set (match_operand 0 "register_operand")
8742 (match_operator 3 "absneg_operator"
8743 [(match_operand 1 "register_operand")]))
8744 (use (match_operand 2 "nonimmediate_operand"))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "reload_completed && SSE_REG_P (operands[0])"
8747 [(set (match_dup 0) (match_dup 3))]
8749 machine_mode mode = GET_MODE (operands[0]);
8750 machine_mode vmode = GET_MODE (operands[2]);
8753 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8754 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8755 if (operands_match_p (operands[0], operands[2]))
8758 operands[1] = operands[2];
8761 if (GET_CODE (operands[3]) == ABS)
8762 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8764 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8769 [(set (match_operand:SF 0 "register_operand")
8770 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8771 (use (match_operand:V4SF 2))
8772 (clobber (reg:CC FLAGS_REG))]
8774 [(parallel [(set (match_dup 0) (match_dup 1))
8775 (clobber (reg:CC FLAGS_REG))])]
8778 operands[0] = gen_lowpart (SImode, operands[0]);
8779 if (GET_CODE (operands[1]) == ABS)
8781 tmp = gen_int_mode (0x7fffffff, SImode);
8782 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8786 tmp = gen_int_mode (0x80000000, SImode);
8787 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8793 [(set (match_operand:DF 0 "register_operand")
8794 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8795 (use (match_operand 2))
8796 (clobber (reg:CC FLAGS_REG))]
8798 [(parallel [(set (match_dup 0) (match_dup 1))
8799 (clobber (reg:CC FLAGS_REG))])]
8804 tmp = gen_lowpart (DImode, operands[0]);
8805 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8808 if (GET_CODE (operands[1]) == ABS)
8811 tmp = gen_rtx_NOT (DImode, tmp);
8815 operands[0] = gen_highpart (SImode, operands[0]);
8816 if (GET_CODE (operands[1]) == ABS)
8818 tmp = gen_int_mode (0x7fffffff, SImode);
8819 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8823 tmp = gen_int_mode (0x80000000, SImode);
8824 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8831 [(set (match_operand:XF 0 "register_operand")
8832 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8833 (use (match_operand 2))
8834 (clobber (reg:CC FLAGS_REG))]
8836 [(parallel [(set (match_dup 0) (match_dup 1))
8837 (clobber (reg:CC FLAGS_REG))])]
8840 operands[0] = gen_rtx_REG (SImode,
8841 true_regnum (operands[0])
8842 + (TARGET_64BIT ? 1 : 2));
8843 if (GET_CODE (operands[1]) == ABS)
8845 tmp = GEN_INT (0x7fff);
8846 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8850 tmp = GEN_INT (0x8000);
8851 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8856 ;; Conditionalize these after reload. If they match before reload, we
8857 ;; lose the clobber and ability to use integer instructions.
8859 (define_insn "*<code><mode>2_1"
8860 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8861 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8863 && (reload_completed
8864 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8865 "f<absneg_mnemonic>"
8866 [(set_attr "type" "fsgn")
8867 (set_attr "mode" "<MODE>")])
8869 (define_insn "*<code>extendsfdf2"
8870 [(set (match_operand:DF 0 "register_operand" "=f")
8871 (absneg:DF (float_extend:DF
8872 (match_operand:SF 1 "register_operand" "0"))))]
8873 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8874 "f<absneg_mnemonic>"
8875 [(set_attr "type" "fsgn")
8876 (set_attr "mode" "DF")])
8878 (define_insn "*<code>extendsfxf2"
8879 [(set (match_operand:XF 0 "register_operand" "=f")
8880 (absneg:XF (float_extend:XF
8881 (match_operand:SF 1 "register_operand" "0"))))]
8883 "f<absneg_mnemonic>"
8884 [(set_attr "type" "fsgn")
8885 (set_attr "mode" "XF")])
8887 (define_insn "*<code>extenddfxf2"
8888 [(set (match_operand:XF 0 "register_operand" "=f")
8889 (absneg:XF (float_extend:XF
8890 (match_operand:DF 1 "register_operand" "0"))))]
8892 "f<absneg_mnemonic>"
8893 [(set_attr "type" "fsgn")
8894 (set_attr "mode" "XF")])
8896 ;; Copysign instructions
8898 (define_mode_iterator CSGNMODE [SF DF TF])
8899 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8901 (define_expand "copysign<mode>3"
8902 [(match_operand:CSGNMODE 0 "register_operand")
8903 (match_operand:CSGNMODE 1 "nonmemory_operand")
8904 (match_operand:CSGNMODE 2 "register_operand")]
8905 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8906 || (TARGET_SSE && (<MODE>mode == TFmode))"
8907 "ix86_expand_copysign (operands); DONE;")
8909 (define_insn_and_split "copysign<mode>3_const"
8910 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8912 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8913 (match_operand:CSGNMODE 2 "register_operand" "0")
8914 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8916 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8917 || (TARGET_SSE && (<MODE>mode == TFmode))"
8919 "&& reload_completed"
8921 "ix86_split_copysign_const (operands); DONE;")
8923 (define_insn "copysign<mode>3_var"
8924 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8926 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8927 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8928 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8929 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8931 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8932 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8933 || (TARGET_SSE && (<MODE>mode == TFmode))"
8937 [(set (match_operand:CSGNMODE 0 "register_operand")
8939 [(match_operand:CSGNMODE 2 "register_operand")
8940 (match_operand:CSGNMODE 3 "register_operand")
8941 (match_operand:<CSGNVMODE> 4)
8942 (match_operand:<CSGNVMODE> 5)]
8944 (clobber (match_scratch:<CSGNVMODE> 1))]
8945 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8946 || (TARGET_SSE && (<MODE>mode == TFmode)))
8947 && reload_completed"
8949 "ix86_split_copysign_var (operands); DONE;")
8951 ;; One complement instructions
8953 (define_expand "one_cmpl<mode>2"
8954 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8955 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8957 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8959 (define_insn "*one_cmpl<mode>2_1"
8960 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8961 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8962 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8964 not{<imodesuffix>}\t%0
8965 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8966 [(set_attr "isa" "*,avx512bw")
8967 (set_attr "type" "negnot,msklog")
8968 (set_attr "prefix" "*,vex")
8969 (set_attr "mode" "<MODE>")])
8971 (define_insn "*one_cmplhi2_1"
8972 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8973 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8974 "ix86_unary_operator_ok (NOT, HImode, operands)"
8977 knotw\t{%1, %0|%0, %1}"
8978 [(set_attr "isa" "*,avx512f")
8979 (set_attr "type" "negnot,msklog")
8980 (set_attr "prefix" "*,vex")
8981 (set_attr "mode" "HI")])
8983 ;; %%% Potential partial reg stall on alternative 1. What to do?
8984 (define_insn "*one_cmplqi2_1"
8985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8986 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8987 "ix86_unary_operator_ok (NOT, QImode, operands)"
8989 switch (which_alternative)
8992 return "not{b}\t%0";
8994 return "not{l}\t%k0";
8996 if (TARGET_AVX512DQ)
8997 return "knotb\t{%1, %0|%0, %1}";
8998 return "knotw\t{%1, %0|%0, %1}";
9003 [(set_attr "isa" "*,*,avx512f")
9004 (set_attr "type" "negnot,negnot,msklog")
9005 (set_attr "prefix" "*,*,vex")
9006 (set_attr "mode" "QI,SI,QI")])
9008 ;; ??? Currently never generated - xor is used instead.
9009 (define_insn "*one_cmplsi2_1_zext"
9010 [(set (match_operand:DI 0 "register_operand" "=r")
9012 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9013 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9015 [(set_attr "type" "negnot")
9016 (set_attr "mode" "SI")])
9018 (define_insn "*one_cmpl<mode>2_2"
9019 [(set (reg FLAGS_REG)
9020 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9022 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9023 (not:SWI (match_dup 1)))]
9024 "ix86_match_ccmode (insn, CCNOmode)
9025 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9027 [(set_attr "type" "alu1")
9028 (set_attr "mode" "<MODE>")])
9031 [(set (match_operand 0 "flags_reg_operand")
9032 (match_operator 2 "compare_operator"
9033 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9035 (set (match_operand:SWI 1 "nonimmediate_operand")
9036 (not:SWI (match_dup 3)))]
9037 "ix86_match_ccmode (insn, CCNOmode)"
9038 [(parallel [(set (match_dup 0)
9039 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9042 (xor:SWI (match_dup 3) (const_int -1)))])])
9044 ;; ??? Currently never generated - xor is used instead.
9045 (define_insn "*one_cmplsi2_2_zext"
9046 [(set (reg FLAGS_REG)
9047 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9049 (set (match_operand:DI 0 "register_operand" "=r")
9050 (zero_extend:DI (not:SI (match_dup 1))))]
9051 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_unary_operator_ok (NOT, SImode, operands)"
9054 [(set_attr "type" "alu1")
9055 (set_attr "mode" "SI")])
9058 [(set (match_operand 0 "flags_reg_operand")
9059 (match_operator 2 "compare_operator"
9060 [(not:SI (match_operand:SI 3 "register_operand"))
9062 (set (match_operand:DI 1 "register_operand")
9063 (zero_extend:DI (not:SI (match_dup 3))))]
9064 "ix86_match_ccmode (insn, CCNOmode)"
9065 [(parallel [(set (match_dup 0)
9066 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9069 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9071 ;; Shift instructions
9073 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9074 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9075 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9076 ;; from the assembler input.
9078 ;; This instruction shifts the target reg/mem as usual, but instead of
9079 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9080 ;; is a left shift double, bits are taken from the high order bits of
9081 ;; reg, else if the insn is a shift right double, bits are taken from the
9082 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9083 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9085 ;; Since sh[lr]d does not change the `reg' operand, that is done
9086 ;; separately, making all shifts emit pairs of shift double and normal
9087 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9088 ;; support a 63 bit shift, each shift where the count is in a reg expands
9089 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9091 ;; If the shift count is a constant, we need never emit more than one
9092 ;; shift pair, instead using moves and sign extension for counts greater
9095 (define_expand "ashl<mode>3"
9096 [(set (match_operand:SDWIM 0 "<shift_operand>")
9097 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9098 (match_operand:QI 2 "nonmemory_operand")))]
9100 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9102 (define_insn "*ashl<mode>3_doubleword"
9103 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9104 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9105 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9106 (clobber (reg:CC FLAGS_REG))]
9109 [(set_attr "type" "multi")])
9112 [(set (match_operand:DWI 0 "register_operand")
9113 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9114 (match_operand:QI 2 "nonmemory_operand")))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9118 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9120 ;; By default we don't ask for a scratch register, because when DWImode
9121 ;; values are manipulated, registers are already at a premium. But if
9122 ;; we have one handy, we won't turn it away.
9125 [(match_scratch:DWIH 3 "r")
9126 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9128 (match_operand:<DWI> 1 "nonmemory_operand")
9129 (match_operand:QI 2 "nonmemory_operand")))
9130 (clobber (reg:CC FLAGS_REG))])
9134 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9136 (define_insn "x86_64_shld"
9137 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9138 (ior:DI (ashift:DI (match_dup 0)
9139 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9140 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9141 (minus:QI (const_int 64) (match_dup 2)))))
9142 (clobber (reg:CC FLAGS_REG))]
9144 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9145 [(set_attr "type" "ishift")
9146 (set_attr "prefix_0f" "1")
9147 (set_attr "mode" "DI")
9148 (set_attr "athlon_decode" "vector")
9149 (set_attr "amdfam10_decode" "vector")
9150 (set_attr "bdver1_decode" "vector")])
9152 (define_insn "x86_shld"
9153 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9154 (ior:SI (ashift:SI (match_dup 0)
9155 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9156 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9157 (minus:QI (const_int 32) (match_dup 2)))))
9158 (clobber (reg:CC FLAGS_REG))]
9160 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9161 [(set_attr "type" "ishift")
9162 (set_attr "prefix_0f" "1")
9163 (set_attr "mode" "SI")
9164 (set_attr "pent_pair" "np")
9165 (set_attr "athlon_decode" "vector")
9166 (set_attr "amdfam10_decode" "vector")
9167 (set_attr "bdver1_decode" "vector")])
9169 (define_expand "x86_shift<mode>_adj_1"
9170 [(set (reg:CCZ FLAGS_REG)
9171 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9174 (set (match_operand:SWI48 0 "register_operand")
9175 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9176 (match_operand:SWI48 1 "register_operand")
9179 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9180 (match_operand:SWI48 3 "register_operand")
9183 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9185 (define_expand "x86_shift<mode>_adj_2"
9186 [(use (match_operand:SWI48 0 "register_operand"))
9187 (use (match_operand:SWI48 1 "register_operand"))
9188 (use (match_operand:QI 2 "register_operand"))]
9191 rtx_code_label *label = gen_label_rtx ();
9194 emit_insn (gen_testqi_ccz_1 (operands[2],
9195 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9197 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9198 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9199 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9200 gen_rtx_LABEL_REF (VOIDmode, label),
9202 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9203 JUMP_LABEL (tmp) = label;
9205 emit_move_insn (operands[0], operands[1]);
9206 ix86_expand_clear (operands[1]);
9209 LABEL_NUSES (label) = 1;
9214 ;; Avoid useless masking of count operand.
9215 (define_insn "*ashl<mode>3_mask"
9216 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9218 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9221 (match_operand:SI 2 "register_operand" "c")
9222 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9223 (clobber (reg:CC FLAGS_REG))]
9224 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9226 == GET_MODE_BITSIZE (<MODE>mode)-1"
9228 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9230 [(set_attr "type" "ishift")
9231 (set_attr "mode" "<MODE>")])
9233 (define_insn "*bmi2_ashl<mode>3_1"
9234 [(set (match_operand:SWI48 0 "register_operand" "=r")
9235 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9236 (match_operand:SWI48 2 "register_operand" "r")))]
9238 "shlx\t{%2, %1, %0|%0, %1, %2}"
9239 [(set_attr "type" "ishiftx")
9240 (set_attr "mode" "<MODE>")])
9242 (define_insn "*ashl<mode>3_1"
9243 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9244 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9245 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9249 switch (get_attr_type (insn))
9256 gcc_assert (operands[2] == const1_rtx);
9257 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9258 return "add{<imodesuffix>}\t%0, %0";
9261 if (operands[2] == const1_rtx
9262 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9263 return "sal{<imodesuffix>}\t%0";
9265 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9268 [(set_attr "isa" "*,*,bmi2")
9270 (cond [(eq_attr "alternative" "1")
9271 (const_string "lea")
9272 (eq_attr "alternative" "2")
9273 (const_string "ishiftx")
9274 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275 (match_operand 0 "register_operand"))
9276 (match_operand 2 "const1_operand"))
9277 (const_string "alu")
9279 (const_string "ishift")))
9280 (set (attr "length_immediate")
9282 (ior (eq_attr "type" "alu")
9283 (and (eq_attr "type" "ishift")
9284 (and (match_operand 2 "const1_operand")
9285 (ior (match_test "TARGET_SHIFT1")
9286 (match_test "optimize_function_for_size_p (cfun)")))))
9288 (const_string "*")))
9289 (set_attr "mode" "<MODE>")])
9291 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9293 [(set (match_operand:SWI48 0 "register_operand")
9294 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9295 (match_operand:QI 2 "register_operand")))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "TARGET_BMI2 && reload_completed"
9299 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9300 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9302 (define_insn "*bmi2_ashlsi3_1_zext"
9303 [(set (match_operand:DI 0 "register_operand" "=r")
9305 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9306 (match_operand:SI 2 "register_operand" "r"))))]
9307 "TARGET_64BIT && TARGET_BMI2"
9308 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9309 [(set_attr "type" "ishiftx")
9310 (set_attr "mode" "SI")])
9312 (define_insn "*ashlsi3_1_zext"
9313 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9315 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9316 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9317 (clobber (reg:CC FLAGS_REG))]
9318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9320 switch (get_attr_type (insn))
9327 gcc_assert (operands[2] == const1_rtx);
9328 return "add{l}\t%k0, %k0";
9331 if (operands[2] == const1_rtx
9332 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9333 return "sal{l}\t%k0";
9335 return "sal{l}\t{%2, %k0|%k0, %2}";
9338 [(set_attr "isa" "*,*,bmi2")
9340 (cond [(eq_attr "alternative" "1")
9341 (const_string "lea")
9342 (eq_attr "alternative" "2")
9343 (const_string "ishiftx")
9344 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9345 (match_operand 2 "const1_operand"))
9346 (const_string "alu")
9348 (const_string "ishift")))
9349 (set (attr "length_immediate")
9351 (ior (eq_attr "type" "alu")
9352 (and (eq_attr "type" "ishift")
9353 (and (match_operand 2 "const1_operand")
9354 (ior (match_test "TARGET_SHIFT1")
9355 (match_test "optimize_function_for_size_p (cfun)")))))
9357 (const_string "*")))
9358 (set_attr "mode" "SI")])
9360 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9362 [(set (match_operand:DI 0 "register_operand")
9364 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9365 (match_operand:QI 2 "register_operand"))))
9366 (clobber (reg:CC FLAGS_REG))]
9367 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9369 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9370 "operands[2] = gen_lowpart (SImode, operands[2]);")
9372 (define_insn "*ashlhi3_1"
9373 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9374 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9375 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9379 switch (get_attr_type (insn))
9385 gcc_assert (operands[2] == const1_rtx);
9386 return "add{w}\t%0, %0";
9389 if (operands[2] == const1_rtx
9390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9391 return "sal{w}\t%0";
9393 return "sal{w}\t{%2, %0|%0, %2}";
9397 (cond [(eq_attr "alternative" "1")
9398 (const_string "lea")
9399 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9400 (match_operand 0 "register_operand"))
9401 (match_operand 2 "const1_operand"))
9402 (const_string "alu")
9404 (const_string "ishift")))
9405 (set (attr "length_immediate")
9407 (ior (eq_attr "type" "alu")
9408 (and (eq_attr "type" "ishift")
9409 (and (match_operand 2 "const1_operand")
9410 (ior (match_test "TARGET_SHIFT1")
9411 (match_test "optimize_function_for_size_p (cfun)")))))
9413 (const_string "*")))
9414 (set_attr "mode" "HI,SI")])
9416 ;; %%% Potential partial reg stall on alternative 1. What to do?
9417 (define_insn "*ashlqi3_1"
9418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9419 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9420 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9421 (clobber (reg:CC FLAGS_REG))]
9422 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9424 switch (get_attr_type (insn))
9430 gcc_assert (operands[2] == const1_rtx);
9431 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9432 return "add{l}\t%k0, %k0";
9434 return "add{b}\t%0, %0";
9437 if (operands[2] == const1_rtx
9438 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9440 if (get_attr_mode (insn) == MODE_SI)
9441 return "sal{l}\t%k0";
9443 return "sal{b}\t%0";
9447 if (get_attr_mode (insn) == MODE_SI)
9448 return "sal{l}\t{%2, %k0|%k0, %2}";
9450 return "sal{b}\t{%2, %0|%0, %2}";
9455 (cond [(eq_attr "alternative" "2")
9456 (const_string "lea")
9457 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9458 (match_operand 0 "register_operand"))
9459 (match_operand 2 "const1_operand"))
9460 (const_string "alu")
9462 (const_string "ishift")))
9463 (set (attr "length_immediate")
9465 (ior (eq_attr "type" "alu")
9466 (and (eq_attr "type" "ishift")
9467 (and (match_operand 2 "const1_operand")
9468 (ior (match_test "TARGET_SHIFT1")
9469 (match_test "optimize_function_for_size_p (cfun)")))))
9471 (const_string "*")))
9472 (set_attr "mode" "QI,SI,SI")])
9474 (define_insn "*ashlqi3_1_slp"
9475 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9476 (ashift:QI (match_dup 0)
9477 (match_operand:QI 1 "nonmemory_operand" "cI")))
9478 (clobber (reg:CC FLAGS_REG))]
9479 "(optimize_function_for_size_p (cfun)
9480 || !TARGET_PARTIAL_FLAG_REG_STALL
9481 || (operands[1] == const1_rtx
9483 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9485 switch (get_attr_type (insn))
9488 gcc_assert (operands[1] == const1_rtx);
9489 return "add{b}\t%0, %0";
9492 if (operands[1] == const1_rtx
9493 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9494 return "sal{b}\t%0";
9496 return "sal{b}\t{%1, %0|%0, %1}";
9500 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9501 (match_operand 0 "register_operand"))
9502 (match_operand 1 "const1_operand"))
9503 (const_string "alu")
9505 (const_string "ishift1")))
9506 (set (attr "length_immediate")
9508 (ior (eq_attr "type" "alu")
9509 (and (eq_attr "type" "ishift1")
9510 (and (match_operand 1 "const1_operand")
9511 (ior (match_test "TARGET_SHIFT1")
9512 (match_test "optimize_function_for_size_p (cfun)")))))
9514 (const_string "*")))
9515 (set_attr "mode" "QI")])
9517 ;; Convert ashift to the lea pattern to avoid flags dependency.
9519 [(set (match_operand 0 "register_operand")
9520 (ashift (match_operand 1 "index_register_operand")
9521 (match_operand:QI 2 "const_int_operand")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9525 && true_regnum (operands[0]) != true_regnum (operands[1])"
9528 machine_mode mode = GET_MODE (operands[0]);
9531 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9534 operands[0] = gen_lowpart (mode, operands[0]);
9535 operands[1] = gen_lowpart (mode, operands[1]);
9538 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9540 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9542 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9546 ;; Convert ashift to the lea pattern to avoid flags dependency.
9548 [(set (match_operand:DI 0 "register_operand")
9550 (ashift:SI (match_operand:SI 1 "index_register_operand")
9551 (match_operand:QI 2 "const_int_operand"))))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "TARGET_64BIT && reload_completed
9554 && true_regnum (operands[0]) != true_regnum (operands[1])"
9556 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9558 operands[1] = gen_lowpart (SImode, operands[1]);
9559 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9562 ;; This pattern can't accept a variable shift count, since shifts by
9563 ;; zero don't affect the flags. We assume that shifts by constant
9564 ;; zero are optimized away.
9565 (define_insn "*ashl<mode>3_cmp"
9566 [(set (reg FLAGS_REG)
9568 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9569 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9571 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9572 (ashift:SWI (match_dup 1) (match_dup 2)))]
9573 "(optimize_function_for_size_p (cfun)
9574 || !TARGET_PARTIAL_FLAG_REG_STALL
9575 || (operands[2] == const1_rtx
9577 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9578 && ix86_match_ccmode (insn, CCGOCmode)
9579 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9581 switch (get_attr_type (insn))
9584 gcc_assert (operands[2] == const1_rtx);
9585 return "add{<imodesuffix>}\t%0, %0";
9588 if (operands[2] == const1_rtx
9589 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9590 return "sal{<imodesuffix>}\t%0";
9592 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9596 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9597 (match_operand 0 "register_operand"))
9598 (match_operand 2 "const1_operand"))
9599 (const_string "alu")
9601 (const_string "ishift")))
9602 (set (attr "length_immediate")
9604 (ior (eq_attr "type" "alu")
9605 (and (eq_attr "type" "ishift")
9606 (and (match_operand 2 "const1_operand")
9607 (ior (match_test "TARGET_SHIFT1")
9608 (match_test "optimize_function_for_size_p (cfun)")))))
9610 (const_string "*")))
9611 (set_attr "mode" "<MODE>")])
9613 (define_insn "*ashlsi3_cmp_zext"
9614 [(set (reg FLAGS_REG)
9616 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9617 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9619 (set (match_operand:DI 0 "register_operand" "=r")
9620 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9622 && (optimize_function_for_size_p (cfun)
9623 || !TARGET_PARTIAL_FLAG_REG_STALL
9624 || (operands[2] == const1_rtx
9626 || TARGET_DOUBLE_WITH_ADD)))
9627 && ix86_match_ccmode (insn, CCGOCmode)
9628 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9630 switch (get_attr_type (insn))
9633 gcc_assert (operands[2] == const1_rtx);
9634 return "add{l}\t%k0, %k0";
9637 if (operands[2] == const1_rtx
9638 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9639 return "sal{l}\t%k0";
9641 return "sal{l}\t{%2, %k0|%k0, %2}";
9645 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9646 (match_operand 2 "const1_operand"))
9647 (const_string "alu")
9649 (const_string "ishift")))
9650 (set (attr "length_immediate")
9652 (ior (eq_attr "type" "alu")
9653 (and (eq_attr "type" "ishift")
9654 (and (match_operand 2 "const1_operand")
9655 (ior (match_test "TARGET_SHIFT1")
9656 (match_test "optimize_function_for_size_p (cfun)")))))
9658 (const_string "*")))
9659 (set_attr "mode" "SI")])
9661 (define_insn "*ashl<mode>3_cconly"
9662 [(set (reg FLAGS_REG)
9664 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9665 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9667 (clobber (match_scratch:SWI 0 "=<r>"))]
9668 "(optimize_function_for_size_p (cfun)
9669 || !TARGET_PARTIAL_FLAG_REG_STALL
9670 || (operands[2] == const1_rtx
9672 || TARGET_DOUBLE_WITH_ADD)))
9673 && ix86_match_ccmode (insn, CCGOCmode)"
9675 switch (get_attr_type (insn))
9678 gcc_assert (operands[2] == const1_rtx);
9679 return "add{<imodesuffix>}\t%0, %0";
9682 if (operands[2] == const1_rtx
9683 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9684 return "sal{<imodesuffix>}\t%0";
9686 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9690 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9691 (match_operand 0 "register_operand"))
9692 (match_operand 2 "const1_operand"))
9693 (const_string "alu")
9695 (const_string "ishift")))
9696 (set (attr "length_immediate")
9698 (ior (eq_attr "type" "alu")
9699 (and (eq_attr "type" "ishift")
9700 (and (match_operand 2 "const1_operand")
9701 (ior (match_test "TARGET_SHIFT1")
9702 (match_test "optimize_function_for_size_p (cfun)")))))
9704 (const_string "*")))
9705 (set_attr "mode" "<MODE>")])
9707 ;; See comment above `ashl<mode>3' about how this works.
9709 (define_expand "<shift_insn><mode>3"
9710 [(set (match_operand:SDWIM 0 "<shift_operand>")
9711 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9712 (match_operand:QI 2 "nonmemory_operand")))]
9714 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9716 ;; Avoid useless masking of count operand.
9717 (define_insn "*<shift_insn><mode>3_mask"
9718 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9720 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9723 (match_operand:SI 2 "register_operand" "c")
9724 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9727 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9728 == GET_MODE_BITSIZE (<MODE>mode)-1"
9730 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9732 [(set_attr "type" "ishift")
9733 (set_attr "mode" "<MODE>")])
9735 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9736 [(set (match_operand:DWI 0 "register_operand" "=r")
9737 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9738 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9739 (clobber (reg:CC FLAGS_REG))]
9742 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9744 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9745 [(set_attr "type" "multi")])
9747 ;; By default we don't ask for a scratch register, because when DWImode
9748 ;; values are manipulated, registers are already at a premium. But if
9749 ;; we have one handy, we won't turn it away.
9752 [(match_scratch:DWIH 3 "r")
9753 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9755 (match_operand:<DWI> 1 "register_operand")
9756 (match_operand:QI 2 "nonmemory_operand")))
9757 (clobber (reg:CC FLAGS_REG))])
9761 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9763 (define_insn "x86_64_shrd"
9764 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9765 (ior:DI (lshiftrt:DI (match_dup 0)
9766 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9767 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9768 (minus:QI (const_int 64) (match_dup 2)))))
9769 (clobber (reg:CC FLAGS_REG))]
9771 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9772 [(set_attr "type" "ishift")
9773 (set_attr "prefix_0f" "1")
9774 (set_attr "mode" "DI")
9775 (set_attr "athlon_decode" "vector")
9776 (set_attr "amdfam10_decode" "vector")
9777 (set_attr "bdver1_decode" "vector")])
9779 (define_insn "x86_shrd"
9780 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9781 (ior:SI (lshiftrt:SI (match_dup 0)
9782 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9783 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9784 (minus:QI (const_int 32) (match_dup 2)))))
9785 (clobber (reg:CC FLAGS_REG))]
9787 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9788 [(set_attr "type" "ishift")
9789 (set_attr "prefix_0f" "1")
9790 (set_attr "mode" "SI")
9791 (set_attr "pent_pair" "np")
9792 (set_attr "athlon_decode" "vector")
9793 (set_attr "amdfam10_decode" "vector")
9794 (set_attr "bdver1_decode" "vector")])
9796 (define_insn "ashrdi3_cvt"
9797 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9798 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9799 (match_operand:QI 2 "const_int_operand")))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_64BIT && INTVAL (operands[2]) == 63
9802 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9803 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9806 sar{q}\t{%2, %0|%0, %2}"
9807 [(set_attr "type" "imovx,ishift")
9808 (set_attr "prefix_0f" "0,*")
9809 (set_attr "length_immediate" "0,*")
9810 (set_attr "modrm" "0,1")
9811 (set_attr "mode" "DI")])
9813 (define_insn "ashrsi3_cvt"
9814 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9815 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9816 (match_operand:QI 2 "const_int_operand")))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "INTVAL (operands[2]) == 31
9819 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9820 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9823 sar{l}\t{%2, %0|%0, %2}"
9824 [(set_attr "type" "imovx,ishift")
9825 (set_attr "prefix_0f" "0,*")
9826 (set_attr "length_immediate" "0,*")
9827 (set_attr "modrm" "0,1")
9828 (set_attr "mode" "SI")])
9830 (define_insn "*ashrsi3_cvt_zext"
9831 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9833 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9834 (match_operand:QI 2 "const_int_operand"))))
9835 (clobber (reg:CC FLAGS_REG))]
9836 "TARGET_64BIT && INTVAL (operands[2]) == 31
9837 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9838 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9841 sar{l}\t{%2, %k0|%k0, %2}"
9842 [(set_attr "type" "imovx,ishift")
9843 (set_attr "prefix_0f" "0,*")
9844 (set_attr "length_immediate" "0,*")
9845 (set_attr "modrm" "0,1")
9846 (set_attr "mode" "SI")])
9848 (define_expand "x86_shift<mode>_adj_3"
9849 [(use (match_operand:SWI48 0 "register_operand"))
9850 (use (match_operand:SWI48 1 "register_operand"))
9851 (use (match_operand:QI 2 "register_operand"))]
9854 rtx_code_label *label = gen_label_rtx ();
9857 emit_insn (gen_testqi_ccz_1 (operands[2],
9858 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9860 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9861 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9862 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9863 gen_rtx_LABEL_REF (VOIDmode, label),
9865 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9866 JUMP_LABEL (tmp) = label;
9868 emit_move_insn (operands[0], operands[1]);
9869 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9870 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9872 LABEL_NUSES (label) = 1;
9877 (define_insn "*bmi2_<shift_insn><mode>3_1"
9878 [(set (match_operand:SWI48 0 "register_operand" "=r")
9879 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9880 (match_operand:SWI48 2 "register_operand" "r")))]
9882 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9883 [(set_attr "type" "ishiftx")
9884 (set_attr "mode" "<MODE>")])
9886 (define_insn "*<shift_insn><mode>3_1"
9887 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9889 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9890 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9894 switch (get_attr_type (insn))
9900 if (operands[2] == const1_rtx
9901 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9902 return "<shift>{<imodesuffix>}\t%0";
9904 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9907 [(set_attr "isa" "*,bmi2")
9908 (set_attr "type" "ishift,ishiftx")
9909 (set (attr "length_immediate")
9911 (and (match_operand 2 "const1_operand")
9912 (ior (match_test "TARGET_SHIFT1")
9913 (match_test "optimize_function_for_size_p (cfun)")))
9915 (const_string "*")))
9916 (set_attr "mode" "<MODE>")])
9918 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9920 [(set (match_operand:SWI48 0 "register_operand")
9921 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9922 (match_operand:QI 2 "register_operand")))
9923 (clobber (reg:CC FLAGS_REG))]
9924 "TARGET_BMI2 && reload_completed"
9926 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9927 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9929 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9930 [(set (match_operand:DI 0 "register_operand" "=r")
9932 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9933 (match_operand:SI 2 "register_operand" "r"))))]
9934 "TARGET_64BIT && TARGET_BMI2"
9935 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9936 [(set_attr "type" "ishiftx")
9937 (set_attr "mode" "SI")])
9939 (define_insn "*<shift_insn>si3_1_zext"
9940 [(set (match_operand:DI 0 "register_operand" "=r,r")
9942 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9943 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9944 (clobber (reg:CC FLAGS_REG))]
9945 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9947 switch (get_attr_type (insn))
9953 if (operands[2] == const1_rtx
9954 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9955 return "<shift>{l}\t%k0";
9957 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9960 [(set_attr "isa" "*,bmi2")
9961 (set_attr "type" "ishift,ishiftx")
9962 (set (attr "length_immediate")
9964 (and (match_operand 2 "const1_operand")
9965 (ior (match_test "TARGET_SHIFT1")
9966 (match_test "optimize_function_for_size_p (cfun)")))
9968 (const_string "*")))
9969 (set_attr "mode" "SI")])
9971 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9973 [(set (match_operand:DI 0 "register_operand")
9975 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9976 (match_operand:QI 2 "register_operand"))))
9977 (clobber (reg:CC FLAGS_REG))]
9978 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9980 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9981 "operands[2] = gen_lowpart (SImode, operands[2]);")
9983 (define_insn "*<shift_insn><mode>3_1"
9984 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9986 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9987 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9988 (clobber (reg:CC FLAGS_REG))]
9989 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9991 if (operands[2] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993 return "<shift>{<imodesuffix>}\t%0";
9995 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9997 [(set_attr "type" "ishift")
9998 (set (attr "length_immediate")
10000 (and (match_operand 2 "const1_operand")
10001 (ior (match_test "TARGET_SHIFT1")
10002 (match_test "optimize_function_for_size_p (cfun)")))
10004 (const_string "*")))
10005 (set_attr "mode" "<MODE>")])
10007 (define_insn "*<shift_insn>qi3_1_slp"
10008 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10009 (any_shiftrt:QI (match_dup 0)
10010 (match_operand:QI 1 "nonmemory_operand" "cI")))
10011 (clobber (reg:CC FLAGS_REG))]
10012 "(optimize_function_for_size_p (cfun)
10013 || !TARGET_PARTIAL_REG_STALL
10014 || (operands[1] == const1_rtx
10015 && TARGET_SHIFT1))"
10017 if (operands[1] == const1_rtx
10018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10019 return "<shift>{b}\t%0";
10021 return "<shift>{b}\t{%1, %0|%0, %1}";
10023 [(set_attr "type" "ishift1")
10024 (set (attr "length_immediate")
10026 (and (match_operand 1 "const1_operand")
10027 (ior (match_test "TARGET_SHIFT1")
10028 (match_test "optimize_function_for_size_p (cfun)")))
10030 (const_string "*")))
10031 (set_attr "mode" "QI")])
10033 ;; This pattern can't accept a variable shift count, since shifts by
10034 ;; zero don't affect the flags. We assume that shifts by constant
10035 ;; zero are optimized away.
10036 (define_insn "*<shift_insn><mode>3_cmp"
10037 [(set (reg FLAGS_REG)
10040 (match_operand:SWI 1 "nonimmediate_operand" "0")
10041 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10043 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10044 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10045 "(optimize_function_for_size_p (cfun)
10046 || !TARGET_PARTIAL_FLAG_REG_STALL
10047 || (operands[2] == const1_rtx
10049 && ix86_match_ccmode (insn, CCGOCmode)
10050 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10052 if (operands[2] == const1_rtx
10053 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10054 return "<shift>{<imodesuffix>}\t%0";
10056 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10058 [(set_attr "type" "ishift")
10059 (set (attr "length_immediate")
10061 (and (match_operand 2 "const1_operand")
10062 (ior (match_test "TARGET_SHIFT1")
10063 (match_test "optimize_function_for_size_p (cfun)")))
10065 (const_string "*")))
10066 (set_attr "mode" "<MODE>")])
10068 (define_insn "*<shift_insn>si3_cmp_zext"
10069 [(set (reg FLAGS_REG)
10071 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10072 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10074 (set (match_operand:DI 0 "register_operand" "=r")
10075 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10077 && (optimize_function_for_size_p (cfun)
10078 || !TARGET_PARTIAL_FLAG_REG_STALL
10079 || (operands[2] == const1_rtx
10081 && ix86_match_ccmode (insn, CCGOCmode)
10082 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10084 if (operands[2] == const1_rtx
10085 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086 return "<shift>{l}\t%k0";
10088 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10090 [(set_attr "type" "ishift")
10091 (set (attr "length_immediate")
10093 (and (match_operand 2 "const1_operand")
10094 (ior (match_test "TARGET_SHIFT1")
10095 (match_test "optimize_function_for_size_p (cfun)")))
10097 (const_string "*")))
10098 (set_attr "mode" "SI")])
10100 (define_insn "*<shift_insn><mode>3_cconly"
10101 [(set (reg FLAGS_REG)
10104 (match_operand:SWI 1 "register_operand" "0")
10105 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10107 (clobber (match_scratch:SWI 0 "=<r>"))]
10108 "(optimize_function_for_size_p (cfun)
10109 || !TARGET_PARTIAL_FLAG_REG_STALL
10110 || (operands[2] == const1_rtx
10112 && ix86_match_ccmode (insn, CCGOCmode)"
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116 return "<shift>{<imodesuffix>}\t%0";
10118 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10120 [(set_attr "type" "ishift")
10121 (set (attr "length_immediate")
10123 (and (match_operand 2 "const1_operand")
10124 (ior (match_test "TARGET_SHIFT1")
10125 (match_test "optimize_function_for_size_p (cfun)")))
10127 (const_string "*")))
10128 (set_attr "mode" "<MODE>")])
10130 ;; Rotate instructions
10132 (define_expand "<rotate_insn>ti3"
10133 [(set (match_operand:TI 0 "register_operand")
10134 (any_rotate:TI (match_operand:TI 1 "register_operand")
10135 (match_operand:QI 2 "nonmemory_operand")))]
10138 if (const_1_to_63_operand (operands[2], VOIDmode))
10139 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10140 (operands[0], operands[1], operands[2]));
10147 (define_expand "<rotate_insn>di3"
10148 [(set (match_operand:DI 0 "shiftdi_operand")
10149 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10150 (match_operand:QI 2 "nonmemory_operand")))]
10154 ix86_expand_binary_operator (<CODE>, DImode, operands);
10155 else if (const_1_to_31_operand (operands[2], VOIDmode))
10156 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10157 (operands[0], operands[1], operands[2]));
10164 (define_expand "<rotate_insn><mode>3"
10165 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10166 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10167 (match_operand:QI 2 "nonmemory_operand")))]
10169 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10171 ;; Avoid useless masking of count operand.
10172 (define_insn "*<rotate_insn><mode>3_mask"
10173 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10175 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10178 (match_operand:SI 2 "register_operand" "c")
10179 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10182 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10183 == GET_MODE_BITSIZE (<MODE>mode)-1"
10185 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10187 [(set_attr "type" "rotate")
10188 (set_attr "mode" "<MODE>")])
10190 ;; Implement rotation using two double-precision
10191 ;; shift instructions and a scratch register.
10193 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10194 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197 (clobber (reg:CC FLAGS_REG))
10198 (clobber (match_scratch:DWIH 3 "=&r"))]
10202 [(set (match_dup 3) (match_dup 4))
10204 [(set (match_dup 4)
10205 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10206 (lshiftrt:DWIH (match_dup 5)
10207 (minus:QI (match_dup 6) (match_dup 2)))))
10208 (clobber (reg:CC FLAGS_REG))])
10210 [(set (match_dup 5)
10211 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10212 (lshiftrt:DWIH (match_dup 3)
10213 (minus:QI (match_dup 6) (match_dup 2)))))
10214 (clobber (reg:CC FLAGS_REG))])]
10216 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10218 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10222 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10223 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10224 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10225 (clobber (reg:CC FLAGS_REG))
10226 (clobber (match_scratch:DWIH 3 "=&r"))]
10230 [(set (match_dup 3) (match_dup 4))
10232 [(set (match_dup 4)
10233 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10234 (ashift:DWIH (match_dup 5)
10235 (minus:QI (match_dup 6) (match_dup 2)))))
10236 (clobber (reg:CC FLAGS_REG))])
10238 [(set (match_dup 5)
10239 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10240 (ashift:DWIH (match_dup 3)
10241 (minus:QI (match_dup 6) (match_dup 2)))))
10242 (clobber (reg:CC FLAGS_REG))])]
10244 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10246 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 (define_insn "*bmi2_rorx<mode>3_1"
10250 [(set (match_operand:SWI48 0 "register_operand" "=r")
10251 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10252 (match_operand:QI 2 "immediate_operand" "<S>")))]
10254 "rorx\t{%2, %1, %0|%0, %1, %2}"
10255 [(set_attr "type" "rotatex")
10256 (set_attr "mode" "<MODE>")])
10258 (define_insn "*<rotate_insn><mode>3_1"
10259 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10261 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10262 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10263 (clobber (reg:CC FLAGS_REG))]
10264 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10266 switch (get_attr_type (insn))
10272 if (operands[2] == const1_rtx
10273 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10274 return "<rotate>{<imodesuffix>}\t%0";
10276 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10279 [(set_attr "isa" "*,bmi2")
10280 (set_attr "type" "rotate,rotatex")
10281 (set (attr "length_immediate")
10283 (and (eq_attr "type" "rotate")
10284 (and (match_operand 2 "const1_operand")
10285 (ior (match_test "TARGET_SHIFT1")
10286 (match_test "optimize_function_for_size_p (cfun)"))))
10288 (const_string "*")))
10289 (set_attr "mode" "<MODE>")])
10291 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10293 [(set (match_operand:SWI48 0 "register_operand")
10294 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10295 (match_operand:QI 2 "immediate_operand")))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "TARGET_BMI2 && reload_completed"
10298 [(set (match_dup 0)
10299 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10302 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10306 [(set (match_operand:SWI48 0 "register_operand")
10307 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10308 (match_operand:QI 2 "immediate_operand")))
10309 (clobber (reg:CC FLAGS_REG))]
10310 "TARGET_BMI2 && reload_completed"
10311 [(set (match_dup 0)
10312 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10314 (define_insn "*bmi2_rorxsi3_1_zext"
10315 [(set (match_operand:DI 0 "register_operand" "=r")
10317 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10318 (match_operand:QI 2 "immediate_operand" "I"))))]
10319 "TARGET_64BIT && TARGET_BMI2"
10320 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10321 [(set_attr "type" "rotatex")
10322 (set_attr "mode" "SI")])
10324 (define_insn "*<rotate_insn>si3_1_zext"
10325 [(set (match_operand:DI 0 "register_operand" "=r,r")
10327 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10328 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10329 (clobber (reg:CC FLAGS_REG))]
10330 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10332 switch (get_attr_type (insn))
10338 if (operands[2] == const1_rtx
10339 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10340 return "<rotate>{l}\t%k0";
10342 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10345 [(set_attr "isa" "*,bmi2")
10346 (set_attr "type" "rotate,rotatex")
10347 (set (attr "length_immediate")
10349 (and (eq_attr "type" "rotate")
10350 (and (match_operand 2 "const1_operand")
10351 (ior (match_test "TARGET_SHIFT1")
10352 (match_test "optimize_function_for_size_p (cfun)"))))
10354 (const_string "*")))
10355 (set_attr "mode" "SI")])
10357 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10359 [(set (match_operand:DI 0 "register_operand")
10361 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10362 (match_operand:QI 2 "immediate_operand"))))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10365 [(set (match_dup 0)
10366 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10369 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10373 [(set (match_operand:DI 0 "register_operand")
10375 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10376 (match_operand:QI 2 "immediate_operand"))))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10379 [(set (match_dup 0)
10380 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10382 (define_insn "*<rotate_insn><mode>3_1"
10383 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10384 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10385 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10386 (clobber (reg:CC FLAGS_REG))]
10387 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10389 if (operands[2] == const1_rtx
10390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10391 return "<rotate>{<imodesuffix>}\t%0";
10393 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10395 [(set_attr "type" "rotate")
10396 (set (attr "length_immediate")
10398 (and (match_operand 2 "const1_operand")
10399 (ior (match_test "TARGET_SHIFT1")
10400 (match_test "optimize_function_for_size_p (cfun)")))
10402 (const_string "*")))
10403 (set_attr "mode" "<MODE>")])
10405 (define_insn "*<rotate_insn>qi3_1_slp"
10406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10407 (any_rotate:QI (match_dup 0)
10408 (match_operand:QI 1 "nonmemory_operand" "cI")))
10409 (clobber (reg:CC FLAGS_REG))]
10410 "(optimize_function_for_size_p (cfun)
10411 || !TARGET_PARTIAL_REG_STALL
10412 || (operands[1] == const1_rtx
10413 && TARGET_SHIFT1))"
10415 if (operands[1] == const1_rtx
10416 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10417 return "<rotate>{b}\t%0";
10419 return "<rotate>{b}\t{%1, %0|%0, %1}";
10421 [(set_attr "type" "rotate1")
10422 (set (attr "length_immediate")
10424 (and (match_operand 1 "const1_operand")
10425 (ior (match_test "TARGET_SHIFT1")
10426 (match_test "optimize_function_for_size_p (cfun)")))
10428 (const_string "*")))
10429 (set_attr "mode" "QI")])
10432 [(set (match_operand:HI 0 "register_operand")
10433 (any_rotate:HI (match_dup 0) (const_int 8)))
10434 (clobber (reg:CC FLAGS_REG))]
10436 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10437 [(parallel [(set (strict_low_part (match_dup 0))
10438 (bswap:HI (match_dup 0)))
10439 (clobber (reg:CC FLAGS_REG))])])
10441 ;; Bit set / bit test instructions
10443 (define_expand "extv"
10444 [(set (match_operand:SI 0 "register_operand")
10445 (sign_extract:SI (match_operand:SI 1 "register_operand")
10446 (match_operand:SI 2 "const8_operand")
10447 (match_operand:SI 3 "const8_operand")))]
10450 /* Handle extractions from %ah et al. */
10451 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10454 /* From mips.md: extract_bit_field doesn't verify that our source
10455 matches the predicate, so check it again here. */
10456 if (! ext_register_operand (operands[1], VOIDmode))
10460 (define_expand "extzv"
10461 [(set (match_operand:SI 0 "register_operand")
10462 (zero_extract:SI (match_operand 1 "ext_register_operand")
10463 (match_operand:SI 2 "const8_operand")
10464 (match_operand:SI 3 "const8_operand")))]
10467 /* Handle extractions from %ah et al. */
10468 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10471 /* From mips.md: extract_bit_field doesn't verify that our source
10472 matches the predicate, so check it again here. */
10473 if (! ext_register_operand (operands[1], VOIDmode))
10477 (define_expand "insv"
10478 [(set (zero_extract (match_operand 0 "register_operand")
10479 (match_operand 1 "const_int_operand")
10480 (match_operand 2 "const_int_operand"))
10481 (match_operand 3 "register_operand"))]
10484 rtx (*gen_mov_insv_1) (rtx, rtx);
10486 if (ix86_expand_pinsr (operands))
10489 /* Handle insertions to %ah et al. */
10490 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10493 /* From mips.md: insert_bit_field doesn't verify that our source
10494 matches the predicate, so check it again here. */
10495 if (! ext_register_operand (operands[0], VOIDmode))
10498 gen_mov_insv_1 = (TARGET_64BIT
10499 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10501 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10505 ;; %%% bts, btr, btc, bt.
10506 ;; In general these instructions are *slow* when applied to memory,
10507 ;; since they enforce atomic operation. When applied to registers,
10508 ;; it depends on the cpu implementation. They're never faster than
10509 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10510 ;; no point. But in 64-bit, we can't hold the relevant immediates
10511 ;; within the instruction itself, so operating on bits in the high
10512 ;; 32-bits of a register becomes easier.
10514 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10515 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10516 ;; negdf respectively, so they can never be disabled entirely.
10518 (define_insn "*btsq"
10519 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10521 (match_operand:DI 1 "const_0_to_63_operand"))
10523 (clobber (reg:CC FLAGS_REG))]
10524 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10525 "bts{q}\t{%1, %0|%0, %1}"
10526 [(set_attr "type" "alu1")
10527 (set_attr "prefix_0f" "1")
10528 (set_attr "mode" "DI")])
10530 (define_insn "*btrq"
10531 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10533 (match_operand:DI 1 "const_0_to_63_operand"))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10537 "btr{q}\t{%1, %0|%0, %1}"
10538 [(set_attr "type" "alu1")
10539 (set_attr "prefix_0f" "1")
10540 (set_attr "mode" "DI")])
10542 (define_insn "*btcq"
10543 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10545 (match_operand:DI 1 "const_0_to_63_operand"))
10546 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10547 (clobber (reg:CC FLAGS_REG))]
10548 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10549 "btc{q}\t{%1, %0|%0, %1}"
10550 [(set_attr "type" "alu1")
10551 (set_attr "prefix_0f" "1")
10552 (set_attr "mode" "DI")])
10554 ;; Allow Nocona to avoid these instructions if a register is available.
10557 [(match_scratch:DI 2 "r")
10558 (parallel [(set (zero_extract:DI
10559 (match_operand:DI 0 "register_operand")
10561 (match_operand:DI 1 "const_0_to_63_operand"))
10563 (clobber (reg:CC FLAGS_REG))])]
10564 "TARGET_64BIT && !TARGET_USE_BT"
10567 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10570 if (HOST_BITS_PER_WIDE_INT >= 64)
10571 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10572 else if (i < HOST_BITS_PER_WIDE_INT)
10573 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10575 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10577 op1 = immed_double_const (lo, hi, DImode);
10580 emit_move_insn (operands[2], op1);
10584 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10589 [(match_scratch:DI 2 "r")
10590 (parallel [(set (zero_extract:DI
10591 (match_operand:DI 0 "register_operand")
10593 (match_operand:DI 1 "const_0_to_63_operand"))
10595 (clobber (reg:CC FLAGS_REG))])]
10596 "TARGET_64BIT && !TARGET_USE_BT"
10599 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10602 if (HOST_BITS_PER_WIDE_INT >= 64)
10603 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10604 else if (i < HOST_BITS_PER_WIDE_INT)
10605 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10607 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10609 op1 = immed_double_const (~lo, ~hi, DImode);
10612 emit_move_insn (operands[2], op1);
10616 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10621 [(match_scratch:DI 2 "r")
10622 (parallel [(set (zero_extract:DI
10623 (match_operand:DI 0 "register_operand")
10625 (match_operand:DI 1 "const_0_to_63_operand"))
10626 (not:DI (zero_extract:DI
10627 (match_dup 0) (const_int 1) (match_dup 1))))
10628 (clobber (reg:CC FLAGS_REG))])]
10629 "TARGET_64BIT && !TARGET_USE_BT"
10632 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10635 if (HOST_BITS_PER_WIDE_INT >= 64)
10636 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10637 else if (i < HOST_BITS_PER_WIDE_INT)
10638 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10640 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10642 op1 = immed_double_const (lo, hi, DImode);
10645 emit_move_insn (operands[2], op1);
10649 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10653 (define_insn "*bt<mode>"
10654 [(set (reg:CCC FLAGS_REG)
10656 (zero_extract:SWI48
10657 (match_operand:SWI48 0 "register_operand" "r")
10659 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10661 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10662 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10663 [(set_attr "type" "alu1")
10664 (set_attr "prefix_0f" "1")
10665 (set_attr "mode" "<MODE>")])
10667 ;; Store-flag instructions.
10669 ;; For all sCOND expanders, also expand the compare or test insn that
10670 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10672 (define_insn_and_split "*setcc_di_1"
10673 [(set (match_operand:DI 0 "register_operand" "=q")
10674 (match_operator:DI 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)]))]
10676 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10678 "&& reload_completed"
10679 [(set (match_dup 2) (match_dup 1))
10680 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10682 PUT_MODE (operands[1], QImode);
10683 operands[2] = gen_lowpart (QImode, operands[0]);
10686 (define_insn_and_split "*setcc_si_1_and"
10687 [(set (match_operand:SI 0 "register_operand" "=q")
10688 (match_operator:SI 1 "ix86_comparison_operator"
10689 [(reg FLAGS_REG) (const_int 0)]))
10690 (clobber (reg:CC FLAGS_REG))]
10691 "!TARGET_PARTIAL_REG_STALL
10692 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10694 "&& reload_completed"
10695 [(set (match_dup 2) (match_dup 1))
10696 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10697 (clobber (reg:CC FLAGS_REG))])]
10699 PUT_MODE (operands[1], QImode);
10700 operands[2] = gen_lowpart (QImode, operands[0]);
10703 (define_insn_and_split "*setcc_si_1_movzbl"
10704 [(set (match_operand:SI 0 "register_operand" "=q")
10705 (match_operator:SI 1 "ix86_comparison_operator"
10706 [(reg FLAGS_REG) (const_int 0)]))]
10707 "!TARGET_PARTIAL_REG_STALL
10708 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10710 "&& reload_completed"
10711 [(set (match_dup 2) (match_dup 1))
10712 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10714 PUT_MODE (operands[1], QImode);
10715 operands[2] = gen_lowpart (QImode, operands[0]);
10718 (define_insn "*setcc_qi"
10719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10720 (match_operator:QI 1 "ix86_comparison_operator"
10721 [(reg FLAGS_REG) (const_int 0)]))]
10724 [(set_attr "type" "setcc")
10725 (set_attr "mode" "QI")])
10727 (define_insn "*setcc_qi_slp"
10728 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10729 (match_operator:QI 1 "ix86_comparison_operator"
10730 [(reg FLAGS_REG) (const_int 0)]))]
10733 [(set_attr "type" "setcc")
10734 (set_attr "mode" "QI")])
10736 ;; In general it is not safe to assume too much about CCmode registers,
10737 ;; so simplify-rtx stops when it sees a second one. Under certain
10738 ;; conditions this is safe on x86, so help combine not create
10745 [(set (match_operand:QI 0 "nonimmediate_operand")
10746 (ne:QI (match_operator 1 "ix86_comparison_operator"
10747 [(reg FLAGS_REG) (const_int 0)])
10750 [(set (match_dup 0) (match_dup 1))]
10751 "PUT_MODE (operands[1], QImode);")
10754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10755 (ne:QI (match_operator 1 "ix86_comparison_operator"
10756 [(reg FLAGS_REG) (const_int 0)])
10759 [(set (match_dup 0) (match_dup 1))]
10760 "PUT_MODE (operands[1], QImode);")
10763 [(set (match_operand:QI 0 "nonimmediate_operand")
10764 (eq:QI (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10768 [(set (match_dup 0) (match_dup 1))]
10770 rtx new_op1 = copy_rtx (operands[1]);
10771 operands[1] = new_op1;
10772 PUT_MODE (new_op1, QImode);
10773 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10774 GET_MODE (XEXP (new_op1, 0))));
10776 /* Make sure that (a) the CCmode we have for the flags is strong
10777 enough for the reversed compare or (b) we have a valid FP compare. */
10778 if (! ix86_comparison_operator (new_op1, VOIDmode))
10783 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10784 (eq:QI (match_operator 1 "ix86_comparison_operator"
10785 [(reg FLAGS_REG) (const_int 0)])
10788 [(set (match_dup 0) (match_dup 1))]
10790 rtx new_op1 = copy_rtx (operands[1]);
10791 operands[1] = new_op1;
10792 PUT_MODE (new_op1, QImode);
10793 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10794 GET_MODE (XEXP (new_op1, 0))));
10796 /* Make sure that (a) the CCmode we have for the flags is strong
10797 enough for the reversed compare or (b) we have a valid FP compare. */
10798 if (! ix86_comparison_operator (new_op1, VOIDmode))
10802 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10803 ;; subsequent logical operations are used to imitate conditional moves.
10804 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10807 (define_insn "setcc_<mode>_sse"
10808 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10809 (match_operator:MODEF 3 "sse_comparison_operator"
10810 [(match_operand:MODEF 1 "register_operand" "0,x")
10811 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10812 "SSE_FLOAT_MODE_P (<MODE>mode)"
10814 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10815 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10816 [(set_attr "isa" "noavx,avx")
10817 (set_attr "type" "ssecmp")
10818 (set_attr "length_immediate" "1")
10819 (set_attr "prefix" "orig,vex")
10820 (set_attr "mode" "<MODE>")])
10822 ;; Basic conditional jump instructions.
10823 ;; We ignore the overflow flag for signed branch instructions.
10825 (define_insn "*jcc_1"
10827 (if_then_else (match_operator 1 "ix86_comparison_operator"
10828 [(reg FLAGS_REG) (const_int 0)])
10829 (label_ref (match_operand 0))
10833 [(set_attr "type" "ibr")
10834 (set_attr "modrm" "0")
10835 (set (attr "length")
10836 (if_then_else (and (ge (minus (match_dup 0) (pc))
10838 (lt (minus (match_dup 0) (pc))
10843 (define_insn "*jcc_2"
10845 (if_then_else (match_operator 1 "ix86_comparison_operator"
10846 [(reg FLAGS_REG) (const_int 0)])
10848 (label_ref (match_operand 0))))]
10851 [(set_attr "type" "ibr")
10852 (set_attr "modrm" "0")
10853 (set (attr "length")
10854 (if_then_else (and (ge (minus (match_dup 0) (pc))
10856 (lt (minus (match_dup 0) (pc))
10861 ;; In general it is not safe to assume too much about CCmode registers,
10862 ;; so simplify-rtx stops when it sees a second one. Under certain
10863 ;; conditions this is safe on x86, so help combine not create
10871 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10872 [(reg FLAGS_REG) (const_int 0)])
10874 (label_ref (match_operand 1))
10878 (if_then_else (match_dup 0)
10879 (label_ref (match_dup 1))
10881 "PUT_MODE (operands[0], VOIDmode);")
10885 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10886 [(reg FLAGS_REG) (const_int 0)])
10888 (label_ref (match_operand 1))
10892 (if_then_else (match_dup 0)
10893 (label_ref (match_dup 1))
10896 rtx new_op0 = copy_rtx (operands[0]);
10897 operands[0] = new_op0;
10898 PUT_MODE (new_op0, VOIDmode);
10899 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10900 GET_MODE (XEXP (new_op0, 0))));
10902 /* Make sure that (a) the CCmode we have for the flags is strong
10903 enough for the reversed compare or (b) we have a valid FP compare. */
10904 if (! ix86_comparison_operator (new_op0, VOIDmode))
10908 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10909 ;; pass generates from shift insn with QImode operand. Actually, the mode
10910 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10911 ;; appropriate modulo of the bit offset value.
10913 (define_insn_and_split "*jcc_bt<mode>"
10915 (if_then_else (match_operator 0 "bt_comparison_operator"
10916 [(zero_extract:SWI48
10917 (match_operand:SWI48 1 "register_operand" "r")
10920 (match_operand:QI 2 "register_operand" "r")))
10922 (label_ref (match_operand 3))
10924 (clobber (reg:CC FLAGS_REG))]
10925 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10928 [(set (reg:CCC FLAGS_REG)
10930 (zero_extract:SWI48
10936 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10937 (label_ref (match_dup 3))
10940 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10942 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10945 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10946 ;; zero extended to SImode.
10947 (define_insn_and_split "*jcc_bt<mode>_1"
10949 (if_then_else (match_operator 0 "bt_comparison_operator"
10950 [(zero_extract:SWI48
10951 (match_operand:SWI48 1 "register_operand" "r")
10953 (match_operand:SI 2 "register_operand" "r"))
10955 (label_ref (match_operand 3))
10957 (clobber (reg:CC FLAGS_REG))]
10958 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10961 [(set (reg:CCC FLAGS_REG)
10963 (zero_extract:SWI48
10969 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10970 (label_ref (match_dup 3))
10973 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10975 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10978 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10979 ;; also for DImode, this is what combine produces.
10980 (define_insn_and_split "*jcc_bt<mode>_mask"
10982 (if_then_else (match_operator 0 "bt_comparison_operator"
10983 [(zero_extract:SWI48
10984 (match_operand:SWI48 1 "register_operand" "r")
10987 (match_operand:SI 2 "register_operand" "r")
10988 (match_operand:SI 3 "const_int_operand" "n")))])
10989 (label_ref (match_operand 4))
10991 (clobber (reg:CC FLAGS_REG))]
10992 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10993 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10994 == GET_MODE_BITSIZE (<MODE>mode)-1"
10997 [(set (reg:CCC FLAGS_REG)
10999 (zero_extract:SWI48
11005 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11006 (label_ref (match_dup 4))
11009 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11011 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11014 (define_insn_and_split "*jcc_btsi_1"
11016 (if_then_else (match_operator 0 "bt_comparison_operator"
11019 (match_operand:SI 1 "register_operand" "r")
11020 (match_operand:QI 2 "register_operand" "r"))
11023 (label_ref (match_operand 3))
11025 (clobber (reg:CC FLAGS_REG))]
11026 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11029 [(set (reg:CCC FLAGS_REG)
11037 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11038 (label_ref (match_dup 3))
11041 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11043 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11046 ;; avoid useless masking of bit offset operand
11047 (define_insn_and_split "*jcc_btsi_mask_1"
11050 (match_operator 0 "bt_comparison_operator"
11053 (match_operand:SI 1 "register_operand" "r")
11056 (match_operand:SI 2 "register_operand" "r")
11057 (match_operand:SI 3 "const_int_operand" "n")) 0))
11060 (label_ref (match_operand 4))
11062 (clobber (reg:CC FLAGS_REG))]
11063 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11064 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11067 [(set (reg:CCC FLAGS_REG)
11075 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11076 (label_ref (match_dup 4))
11078 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11080 ;; Define combination compare-and-branch fp compare instructions to help
11083 (define_insn "*jcc<mode>_0_i387"
11085 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11086 [(match_operand:X87MODEF 1 "register_operand" "f")
11087 (match_operand:X87MODEF 2 "const0_operand")])
11088 (label_ref (match_operand 3))
11090 (clobber (reg:CCFP FPSR_REG))
11091 (clobber (reg:CCFP FLAGS_REG))
11092 (clobber (match_scratch:HI 4 "=a"))]
11093 "TARGET_80387 && !TARGET_CMOVE"
11096 (define_insn "*jcc<mode>_0_r_i387"
11098 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11099 [(match_operand:X87MODEF 1 "register_operand" "f")
11100 (match_operand:X87MODEF 2 "const0_operand")])
11102 (label_ref (match_operand 3))))
11103 (clobber (reg:CCFP FPSR_REG))
11104 (clobber (reg:CCFP FLAGS_REG))
11105 (clobber (match_scratch:HI 4 "=a"))]
11106 "TARGET_80387 && !TARGET_CMOVE"
11109 (define_insn "*jccxf_i387"
11111 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11112 [(match_operand:XF 1 "register_operand" "f")
11113 (match_operand:XF 2 "register_operand" "f")])
11114 (label_ref (match_operand 3))
11116 (clobber (reg:CCFP FPSR_REG))
11117 (clobber (reg:CCFP FLAGS_REG))
11118 (clobber (match_scratch:HI 4 "=a"))]
11119 "TARGET_80387 && !TARGET_CMOVE"
11122 (define_insn "*jccxf_r_i387"
11124 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11125 [(match_operand:XF 1 "register_operand" "f")
11126 (match_operand:XF 2 "register_operand" "f")])
11128 (label_ref (match_operand 3))))
11129 (clobber (reg:CCFP FPSR_REG))
11130 (clobber (reg:CCFP FLAGS_REG))
11131 (clobber (match_scratch:HI 4 "=a"))]
11132 "TARGET_80387 && !TARGET_CMOVE"
11135 (define_insn "*jcc<mode>_i387"
11137 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11138 [(match_operand:MODEF 1 "register_operand" "f")
11139 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11140 (label_ref (match_operand 3))
11142 (clobber (reg:CCFP FPSR_REG))
11143 (clobber (reg:CCFP FLAGS_REG))
11144 (clobber (match_scratch:HI 4 "=a"))]
11145 "TARGET_80387 && !TARGET_CMOVE"
11148 (define_insn "*jcc<mode>_r_i387"
11150 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11151 [(match_operand:MODEF 1 "register_operand" "f")
11152 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11154 (label_ref (match_operand 3))))
11155 (clobber (reg:CCFP FPSR_REG))
11156 (clobber (reg:CCFP FLAGS_REG))
11157 (clobber (match_scratch:HI 4 "=a"))]
11158 "TARGET_80387 && !TARGET_CMOVE"
11161 (define_insn "*jccu<mode>_i387"
11163 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11164 [(match_operand:X87MODEF 1 "register_operand" "f")
11165 (match_operand:X87MODEF 2 "register_operand" "f")])
11166 (label_ref (match_operand 3))
11168 (clobber (reg:CCFP FPSR_REG))
11169 (clobber (reg:CCFP FLAGS_REG))
11170 (clobber (match_scratch:HI 4 "=a"))]
11171 "TARGET_80387 && !TARGET_CMOVE"
11174 (define_insn "*jccu<mode>_r_i387"
11176 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11177 [(match_operand:X87MODEF 1 "register_operand" "f")
11178 (match_operand:X87MODEF 2 "register_operand" "f")])
11180 (label_ref (match_operand 3))))
11181 (clobber (reg:CCFP FPSR_REG))
11182 (clobber (reg:CCFP FLAGS_REG))
11183 (clobber (match_scratch:HI 4 "=a"))]
11184 "TARGET_80387 && !TARGET_CMOVE"
11189 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11190 [(match_operand:X87MODEF 1 "register_operand")
11191 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11193 (match_operand 4)))
11194 (clobber (reg:CCFP FPSR_REG))
11195 (clobber (reg:CCFP FLAGS_REG))]
11196 "TARGET_80387 && !TARGET_CMOVE
11197 && reload_completed"
11200 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11201 operands[3], operands[4], NULL_RTX);
11207 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11208 [(match_operand:X87MODEF 1 "register_operand")
11209 (match_operand:X87MODEF 2 "general_operand")])
11211 (match_operand 4)))
11212 (clobber (reg:CCFP FPSR_REG))
11213 (clobber (reg:CCFP FLAGS_REG))
11214 (clobber (match_scratch:HI 5))]
11215 "TARGET_80387 && !TARGET_CMOVE
11216 && reload_completed"
11219 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11220 operands[3], operands[4], operands[5]);
11224 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11225 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11226 ;; with a precedence over other operators and is always put in the first
11227 ;; place. Swap condition and operands to match ficom instruction.
11229 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11232 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11233 [(match_operator:X87MODEF 1 "float_operator"
11234 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11235 (match_operand:X87MODEF 3 "register_operand" "f")])
11236 (label_ref (match_operand 4))
11238 (clobber (reg:CCFP FPSR_REG))
11239 (clobber (reg:CCFP FLAGS_REG))
11240 (clobber (match_scratch:HI 5 "=a"))]
11241 "TARGET_80387 && !TARGET_CMOVE
11242 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11243 || optimize_function_for_size_p (cfun))"
11246 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11249 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11250 [(match_operator:X87MODEF 1 "float_operator"
11251 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11252 (match_operand:X87MODEF 3 "register_operand" "f")])
11254 (label_ref (match_operand 4))))
11255 (clobber (reg:CCFP FPSR_REG))
11256 (clobber (reg:CCFP FLAGS_REG))
11257 (clobber (match_scratch:HI 5 "=a"))]
11258 "TARGET_80387 && !TARGET_CMOVE
11259 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11260 || optimize_function_for_size_p (cfun))"
11266 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11267 [(match_operator:X87MODEF 1 "float_operator"
11268 [(match_operand:SWI24 2 "memory_operand")])
11269 (match_operand:X87MODEF 3 "register_operand")])
11271 (match_operand 5)))
11272 (clobber (reg:CCFP FPSR_REG))
11273 (clobber (reg:CCFP FLAGS_REG))
11274 (clobber (match_scratch:HI 6))]
11275 "TARGET_80387 && !TARGET_CMOVE
11276 && reload_completed"
11279 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11280 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11281 operands[4], operands[5], operands[6]);
11285 ;; Unconditional and other jump instructions
11287 (define_insn "jump"
11289 (label_ref (match_operand 0)))]
11292 [(set_attr "type" "ibr")
11293 (set (attr "length")
11294 (if_then_else (and (ge (minus (match_dup 0) (pc))
11296 (lt (minus (match_dup 0) (pc))
11300 (set_attr "modrm" "0")])
11302 (define_expand "indirect_jump"
11303 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11307 operands[0] = convert_memory_address (word_mode, operands[0]);
11310 (define_insn "*indirect_jump"
11311 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11314 [(set_attr "type" "ibr")
11315 (set_attr "length_immediate" "0")])
11317 (define_expand "tablejump"
11318 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11319 (use (label_ref (match_operand 1)))])]
11322 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11323 relative. Convert the relative address to an absolute address. */
11327 enum rtx_code code;
11329 /* We can't use @GOTOFF for text labels on VxWorks;
11330 see gotoff_operand. */
11331 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11335 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11337 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11341 op1 = pic_offset_table_rtx;
11346 op0 = pic_offset_table_rtx;
11350 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11355 operands[0] = convert_memory_address (word_mode, operands[0]);
11358 (define_insn "*tablejump_1"
11359 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11360 (use (label_ref (match_operand 1)))]
11363 [(set_attr "type" "ibr")
11364 (set_attr "length_immediate" "0")])
11366 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11369 [(set (reg FLAGS_REG) (match_operand 0))
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (set (match_operand 3 "q_regs_operand")
11374 (zero_extend (match_dup 1)))]
11375 "(peep2_reg_dead_p (3, operands[1])
11376 || operands_match_p (operands[1], operands[3]))
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(set (match_dup 4) (match_dup 0))
11379 (set (strict_low_part (match_dup 5))
11382 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11383 operands[5] = gen_lowpart (QImode, operands[3]);
11384 ix86_expand_clear (operands[3]);
11388 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11389 (match_operand 4)])
11390 (set (match_operand:QI 1 "register_operand")
11391 (match_operator:QI 2 "ix86_comparison_operator"
11392 [(reg FLAGS_REG) (const_int 0)]))
11393 (set (match_operand 3 "q_regs_operand")
11394 (zero_extend (match_dup 1)))]
11395 "(peep2_reg_dead_p (3, operands[1])
11396 || operands_match_p (operands[1], operands[3]))
11397 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11398 [(parallel [(set (match_dup 5) (match_dup 0))
11400 (set (strict_low_part (match_dup 6))
11403 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11404 operands[6] = gen_lowpart (QImode, operands[3]);
11405 ix86_expand_clear (operands[3]);
11408 ;; Similar, but match zero extend with andsi3.
11411 [(set (reg FLAGS_REG) (match_operand 0))
11412 (set (match_operand:QI 1 "register_operand")
11413 (match_operator:QI 2 "ix86_comparison_operator"
11414 [(reg FLAGS_REG) (const_int 0)]))
11415 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11416 (and:SI (match_dup 3) (const_int 255)))
11417 (clobber (reg:CC FLAGS_REG))])]
11418 "REGNO (operands[1]) == REGNO (operands[3])
11419 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11420 [(set (match_dup 4) (match_dup 0))
11421 (set (strict_low_part (match_dup 5))
11424 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11425 operands[5] = gen_lowpart (QImode, operands[3]);
11426 ix86_expand_clear (operands[3]);
11430 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11431 (match_operand 4)])
11432 (set (match_operand:QI 1 "register_operand")
11433 (match_operator:QI 2 "ix86_comparison_operator"
11434 [(reg FLAGS_REG) (const_int 0)]))
11435 (parallel [(set (match_operand 3 "q_regs_operand")
11436 (zero_extend (match_dup 1)))
11437 (clobber (reg:CC FLAGS_REG))])]
11438 "(peep2_reg_dead_p (3, operands[1])
11439 || operands_match_p (operands[1], operands[3]))
11440 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11441 [(parallel [(set (match_dup 5) (match_dup 0))
11443 (set (strict_low_part (match_dup 6))
11446 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11447 operands[6] = gen_lowpart (QImode, operands[3]);
11448 ix86_expand_clear (operands[3]);
11451 ;; Call instructions.
11453 ;; The predicates normally associated with named expanders are not properly
11454 ;; checked for calls. This is a bug in the generic code, but it isn't that
11455 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11457 ;; P6 processors will jump to the address after the decrement when %esp
11458 ;; is used as a call operand, so they will execute return address as a code.
11459 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11461 ;; Register constraint for call instruction.
11462 (define_mode_attr c [(SI "l") (DI "r")])
11464 ;; Call subroutine returning no value.
11466 (define_expand "call"
11467 [(call (match_operand:QI 0)
11469 (use (match_operand 2))]
11472 ix86_expand_call (NULL, operands[0], operands[1],
11473 operands[2], NULL, false);
11477 (define_expand "sibcall"
11478 [(call (match_operand:QI 0)
11480 (use (match_operand 2))]
11483 ix86_expand_call (NULL, operands[0], operands[1],
11484 operands[2], NULL, true);
11488 (define_insn "*call"
11489 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11490 (match_operand 1))]
11491 "!SIBLING_CALL_P (insn)"
11492 "* return ix86_output_call_insn (insn, operands[0]);"
11493 [(set_attr "type" "call")])
11495 (define_insn "*sibcall"
11496 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11497 (match_operand 1))]
11498 "SIBLING_CALL_P (insn)"
11499 "* return ix86_output_call_insn (insn, operands[0]);"
11500 [(set_attr "type" "call")])
11502 (define_insn "*sibcall_memory"
11503 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11505 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11507 "* return ix86_output_call_insn (insn, operands[0]);"
11508 [(set_attr "type" "call")])
11511 [(set (match_operand:W 0 "register_operand")
11512 (match_operand:W 1 "memory_operand"))
11513 (call (mem:QI (match_dup 0))
11514 (match_operand 3))]
11515 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11516 && peep2_reg_dead_p (2, operands[0])"
11517 [(parallel [(call (mem:QI (match_dup 1))
11519 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11522 [(set (match_operand:W 0 "register_operand")
11523 (match_operand:W 1 "memory_operand"))
11524 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11525 (call (mem:QI (match_dup 0))
11526 (match_operand 3))]
11527 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11528 && peep2_reg_dead_p (3, operands[0])"
11529 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11530 (parallel [(call (mem:QI (match_dup 1))
11532 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11534 (define_expand "call_pop"
11535 [(parallel [(call (match_operand:QI 0)
11536 (match_operand:SI 1))
11537 (set (reg:SI SP_REG)
11538 (plus:SI (reg:SI SP_REG)
11539 (match_operand:SI 3)))])]
11542 ix86_expand_call (NULL, operands[0], operands[1],
11543 operands[2], operands[3], false);
11547 (define_insn "*call_pop"
11548 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11550 (set (reg:SI SP_REG)
11551 (plus:SI (reg:SI SP_REG)
11552 (match_operand:SI 2 "immediate_operand" "i")))]
11553 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11554 "* return ix86_output_call_insn (insn, operands[0]);"
11555 [(set_attr "type" "call")])
11557 (define_insn "*sibcall_pop"
11558 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11560 (set (reg:SI SP_REG)
11561 (plus:SI (reg:SI SP_REG)
11562 (match_operand:SI 2 "immediate_operand" "i")))]
11563 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11564 "* return ix86_output_call_insn (insn, operands[0]);"
11565 [(set_attr "type" "call")])
11567 (define_insn "*sibcall_pop_memory"
11568 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11570 (set (reg:SI SP_REG)
11571 (plus:SI (reg:SI SP_REG)
11572 (match_operand:SI 2 "immediate_operand" "i")))
11573 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11575 "* return ix86_output_call_insn (insn, operands[0]);"
11576 [(set_attr "type" "call")])
11579 [(set (match_operand:SI 0 "register_operand")
11580 (match_operand:SI 1 "memory_operand"))
11581 (parallel [(call (mem:QI (match_dup 0))
11583 (set (reg:SI SP_REG)
11584 (plus:SI (reg:SI SP_REG)
11585 (match_operand:SI 4 "immediate_operand")))])]
11586 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11587 && peep2_reg_dead_p (2, operands[0])"
11588 [(parallel [(call (mem:QI (match_dup 1))
11590 (set (reg:SI SP_REG)
11591 (plus:SI (reg:SI SP_REG)
11593 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11596 [(set (match_operand:SI 0 "register_operand")
11597 (match_operand:SI 1 "memory_operand"))
11598 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11599 (parallel [(call (mem:QI (match_dup 0))
11601 (set (reg:SI SP_REG)
11602 (plus:SI (reg:SI SP_REG)
11603 (match_operand:SI 4 "immediate_operand")))])]
11604 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11605 && peep2_reg_dead_p (3, operands[0])"
11606 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11607 (parallel [(call (mem:QI (match_dup 1))
11609 (set (reg:SI SP_REG)
11610 (plus:SI (reg:SI SP_REG)
11612 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11614 ;; Combining simple memory jump instruction
11617 [(set (match_operand:W 0 "register_operand")
11618 (match_operand:W 1 "memory_operand"))
11619 (set (pc) (match_dup 0))]
11620 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11621 [(set (pc) (match_dup 1))])
11623 ;; Call subroutine, returning value in operand 0
11625 (define_expand "call_value"
11626 [(set (match_operand 0)
11627 (call (match_operand:QI 1)
11628 (match_operand 2)))
11629 (use (match_operand 3))]
11632 ix86_expand_call (operands[0], operands[1], operands[2],
11633 operands[3], NULL, false);
11637 (define_expand "sibcall_value"
11638 [(set (match_operand 0)
11639 (call (match_operand:QI 1)
11640 (match_operand 2)))
11641 (use (match_operand 3))]
11644 ix86_expand_call (operands[0], operands[1], operands[2],
11645 operands[3], NULL, true);
11649 (define_insn "*call_value"
11650 [(set (match_operand 0)
11651 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11652 (match_operand 2)))]
11653 "!SIBLING_CALL_P (insn)"
11654 "* return ix86_output_call_insn (insn, operands[1]);"
11655 [(set_attr "type" "callv")])
11657 (define_insn "*sibcall_value"
11658 [(set (match_operand 0)
11659 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11660 (match_operand 2)))]
11661 "SIBLING_CALL_P (insn)"
11662 "* return ix86_output_call_insn (insn, operands[1]);"
11663 [(set_attr "type" "callv")])
11665 (define_insn "*sibcall_value_memory"
11666 [(set (match_operand 0)
11667 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11668 (match_operand 2)))
11669 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11671 "* return ix86_output_call_insn (insn, operands[1]);"
11672 [(set_attr "type" "callv")])
11675 [(set (match_operand:W 0 "register_operand")
11676 (match_operand:W 1 "memory_operand"))
11677 (set (match_operand 2)
11678 (call (mem:QI (match_dup 0))
11679 (match_operand 3)))]
11680 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11681 && peep2_reg_dead_p (2, operands[0])"
11682 [(parallel [(set (match_dup 2)
11683 (call (mem:QI (match_dup 1))
11685 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11688 [(set (match_operand:W 0 "register_operand")
11689 (match_operand:W 1 "memory_operand"))
11690 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11691 (set (match_operand 2)
11692 (call (mem:QI (match_dup 0))
11693 (match_operand 3)))]
11694 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11695 && peep2_reg_dead_p (3, operands[0])"
11696 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11697 (parallel [(set (match_dup 2)
11698 (call (mem:QI (match_dup 1))
11700 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11702 (define_expand "call_value_pop"
11703 [(parallel [(set (match_operand 0)
11704 (call (match_operand:QI 1)
11705 (match_operand:SI 2)))
11706 (set (reg:SI SP_REG)
11707 (plus:SI (reg:SI SP_REG)
11708 (match_operand:SI 4)))])]
11711 ix86_expand_call (operands[0], operands[1], operands[2],
11712 operands[3], operands[4], false);
11716 (define_insn "*call_value_pop"
11717 [(set (match_operand 0)
11718 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11719 (match_operand 2)))
11720 (set (reg:SI SP_REG)
11721 (plus:SI (reg:SI SP_REG)
11722 (match_operand:SI 3 "immediate_operand" "i")))]
11723 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11724 "* return ix86_output_call_insn (insn, operands[1]);"
11725 [(set_attr "type" "callv")])
11727 (define_insn "*sibcall_value_pop"
11728 [(set (match_operand 0)
11729 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11730 (match_operand 2)))
11731 (set (reg:SI SP_REG)
11732 (plus:SI (reg:SI SP_REG)
11733 (match_operand:SI 3 "immediate_operand" "i")))]
11734 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11735 "* return ix86_output_call_insn (insn, operands[1]);"
11736 [(set_attr "type" "callv")])
11738 (define_insn "*sibcall_value_pop_memory"
11739 [(set (match_operand 0)
11740 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11741 (match_operand 2)))
11742 (set (reg:SI SP_REG)
11743 (plus:SI (reg:SI SP_REG)
11744 (match_operand:SI 3 "immediate_operand" "i")))
11745 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11747 "* return ix86_output_call_insn (insn, operands[1]);"
11748 [(set_attr "type" "callv")])
11751 [(set (match_operand:SI 0 "register_operand")
11752 (match_operand:SI 1 "memory_operand"))
11753 (parallel [(set (match_operand 2)
11754 (call (mem:QI (match_dup 0))
11755 (match_operand 3)))
11756 (set (reg:SI SP_REG)
11757 (plus:SI (reg:SI SP_REG)
11758 (match_operand:SI 4 "immediate_operand")))])]
11759 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11760 && peep2_reg_dead_p (2, operands[0])"
11761 [(parallel [(set (match_dup 2)
11762 (call (mem:QI (match_dup 1))
11764 (set (reg:SI SP_REG)
11765 (plus:SI (reg:SI SP_REG)
11767 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11770 [(set (match_operand:SI 0 "register_operand")
11771 (match_operand:SI 1 "memory_operand"))
11772 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11773 (parallel [(set (match_operand 2)
11774 (call (mem:QI (match_dup 0))
11775 (match_operand 3)))
11776 (set (reg:SI SP_REG)
11777 (plus:SI (reg:SI SP_REG)
11778 (match_operand:SI 4 "immediate_operand")))])]
11779 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11780 && peep2_reg_dead_p (3, operands[0])"
11781 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11782 (parallel [(set (match_dup 2)
11783 (call (mem:QI (match_dup 1))
11785 (set (reg:SI SP_REG)
11786 (plus:SI (reg:SI SP_REG)
11788 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11790 ;; Call subroutine returning any type.
11792 (define_expand "untyped_call"
11793 [(parallel [(call (match_operand 0)
11796 (match_operand 2)])]
11801 /* In order to give reg-stack an easier job in validating two
11802 coprocessor registers as containing a possible return value,
11803 simply pretend the untyped call returns a complex long double
11806 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11807 and should have the default ABI. */
11809 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11810 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11811 operands[0], const0_rtx,
11812 GEN_INT ((TARGET_64BIT
11813 ? (ix86_abi == SYSV_ABI
11814 ? X86_64_SSE_REGPARM_MAX
11815 : X86_64_MS_SSE_REGPARM_MAX)
11816 : X86_32_SSE_REGPARM_MAX)
11820 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11822 rtx set = XVECEXP (operands[2], 0, i);
11823 emit_move_insn (SET_DEST (set), SET_SRC (set));
11826 /* The optimizer does not know that the call sets the function value
11827 registers we stored in the result block. We avoid problems by
11828 claiming that all hard registers are used and clobbered at this
11830 emit_insn (gen_blockage ());
11835 ;; Prologue and epilogue instructions
11837 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11838 ;; all of memory. This blocks insns from being moved across this point.
11840 (define_insn "blockage"
11841 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11844 [(set_attr "length" "0")])
11846 ;; Do not schedule instructions accessing memory across this point.
11848 (define_expand "memory_blockage"
11849 [(set (match_dup 0)
11850 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11853 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11854 MEM_VOLATILE_P (operands[0]) = 1;
11857 (define_insn "*memory_blockage"
11858 [(set (match_operand:BLK 0)
11859 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11862 [(set_attr "length" "0")])
11864 ;; As USE insns aren't meaningful after reload, this is used instead
11865 ;; to prevent deleting instructions setting registers for PIC code
11866 (define_insn "prologue_use"
11867 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11870 [(set_attr "length" "0")])
11872 ;; Insn emitted into the body of a function to return from a function.
11873 ;; This is only done if the function's epilogue is known to be simple.
11874 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11876 (define_expand "return"
11878 "ix86_can_use_return_insn_p ()"
11880 if (crtl->args.pops_args)
11882 rtx popc = GEN_INT (crtl->args.pops_args);
11883 emit_jump_insn (gen_simple_return_pop_internal (popc));
11888 ;; We need to disable this for TARGET_SEH, as otherwise
11889 ;; shrink-wrapped prologue gets enabled too. This might exceed
11890 ;; the maximum size of prologue in unwind information.
11892 (define_expand "simple_return"
11896 if (crtl->args.pops_args)
11898 rtx popc = GEN_INT (crtl->args.pops_args);
11899 emit_jump_insn (gen_simple_return_pop_internal (popc));
11904 (define_insn "simple_return_internal"
11908 [(set_attr "length" "1")
11909 (set_attr "atom_unit" "jeu")
11910 (set_attr "length_immediate" "0")
11911 (set_attr "modrm" "0")])
11913 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11914 ;; instruction Athlon and K8 have.
11916 (define_insn "simple_return_internal_long"
11918 (unspec [(const_int 0)] UNSPEC_REP)]
11921 [(set_attr "length" "2")
11922 (set_attr "atom_unit" "jeu")
11923 (set_attr "length_immediate" "0")
11924 (set_attr "prefix_rep" "1")
11925 (set_attr "modrm" "0")])
11927 (define_insn "simple_return_pop_internal"
11929 (use (match_operand:SI 0 "const_int_operand"))]
11932 [(set_attr "length" "3")
11933 (set_attr "atom_unit" "jeu")
11934 (set_attr "length_immediate" "2")
11935 (set_attr "modrm" "0")])
11937 (define_insn "simple_return_indirect_internal"
11939 (use (match_operand:SI 0 "register_operand" "r"))]
11942 [(set_attr "type" "ibr")
11943 (set_attr "length_immediate" "0")])
11949 [(set_attr "length" "1")
11950 (set_attr "length_immediate" "0")
11951 (set_attr "modrm" "0")])
11953 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11954 (define_insn "nops"
11955 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11959 int num = INTVAL (operands[0]);
11961 gcc_assert (IN_RANGE (num, 1, 8));
11964 fputs ("\tnop\n", asm_out_file);
11968 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11969 (set_attr "length_immediate" "0")
11970 (set_attr "modrm" "0")])
11972 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11973 ;; branch prediction penalty for the third jump in a 16-byte
11977 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11980 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11981 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11983 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11984 The align insn is used to avoid 3 jump instructions in the row to improve
11985 branch prediction and the benefits hardly outweigh the cost of extra 8
11986 nops on the average inserted by full alignment pseudo operation. */
11990 [(set_attr "length" "16")])
11992 (define_expand "prologue"
11995 "ix86_expand_prologue (); DONE;")
11997 (define_insn "set_got"
11998 [(set (match_operand:SI 0 "register_operand" "=r")
11999 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12000 (clobber (reg:CC FLAGS_REG))]
12002 "* return output_set_got (operands[0], NULL_RTX);"
12003 [(set_attr "type" "multi")
12004 (set_attr "length" "12")])
12006 (define_insn "set_got_labelled"
12007 [(set (match_operand:SI 0 "register_operand" "=r")
12008 (unspec:SI [(label_ref (match_operand 1))]
12010 (clobber (reg:CC FLAGS_REG))]
12012 "* return output_set_got (operands[0], operands[1]);"
12013 [(set_attr "type" "multi")
12014 (set_attr "length" "12")])
12016 (define_insn "set_got_rex64"
12017 [(set (match_operand:DI 0 "register_operand" "=r")
12018 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12020 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12021 [(set_attr "type" "lea")
12022 (set_attr "length_address" "4")
12023 (set_attr "mode" "DI")])
12025 (define_insn "set_rip_rex64"
12026 [(set (match_operand:DI 0 "register_operand" "=r")
12027 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12029 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12030 [(set_attr "type" "lea")
12031 (set_attr "length_address" "4")
12032 (set_attr "mode" "DI")])
12034 (define_insn "set_got_offset_rex64"
12035 [(set (match_operand:DI 0 "register_operand" "=r")
12037 [(label_ref (match_operand 1))]
12038 UNSPEC_SET_GOT_OFFSET))]
12040 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12041 [(set_attr "type" "imov")
12042 (set_attr "length_immediate" "0")
12043 (set_attr "length_address" "8")
12044 (set_attr "mode" "DI")])
12046 (define_expand "epilogue"
12049 "ix86_expand_epilogue (1); DONE;")
12051 (define_expand "sibcall_epilogue"
12054 "ix86_expand_epilogue (0); DONE;")
12056 (define_expand "eh_return"
12057 [(use (match_operand 0 "register_operand"))]
12060 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12062 /* Tricky bit: we write the address of the handler to which we will
12063 be returning into someone else's stack frame, one word below the
12064 stack address we wish to restore. */
12065 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12066 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12067 tmp = gen_rtx_MEM (Pmode, tmp);
12068 emit_move_insn (tmp, ra);
12070 emit_jump_insn (gen_eh_return_internal ());
12075 (define_insn_and_split "eh_return_internal"
12079 "epilogue_completed"
12081 "ix86_expand_epilogue (2); DONE;")
12083 (define_insn "leave"
12084 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12085 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12086 (clobber (mem:BLK (scratch)))]
12089 [(set_attr "type" "leave")])
12091 (define_insn "leave_rex64"
12092 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12093 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12094 (clobber (mem:BLK (scratch)))]
12097 [(set_attr "type" "leave")])
12099 ;; Handle -fsplit-stack.
12101 (define_expand "split_stack_prologue"
12105 ix86_expand_split_stack_prologue ();
12109 ;; In order to support the call/return predictor, we use a return
12110 ;; instruction which the middle-end doesn't see.
12111 (define_insn "split_stack_return"
12112 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12113 UNSPECV_SPLIT_STACK_RETURN)]
12116 if (operands[0] == const0_rtx)
12121 [(set_attr "atom_unit" "jeu")
12122 (set_attr "modrm" "0")
12123 (set (attr "length")
12124 (if_then_else (match_operand:SI 0 "const0_operand")
12127 (set (attr "length_immediate")
12128 (if_then_else (match_operand:SI 0 "const0_operand")
12132 ;; If there are operand 0 bytes available on the stack, jump to
12135 (define_expand "split_stack_space_check"
12136 [(set (pc) (if_then_else
12137 (ltu (minus (reg SP_REG)
12138 (match_operand 0 "register_operand"))
12139 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12140 (label_ref (match_operand 1))
12144 rtx reg, size, limit;
12146 reg = gen_reg_rtx (Pmode);
12147 size = force_reg (Pmode, operands[0]);
12148 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12149 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12150 UNSPEC_STACK_CHECK);
12151 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12152 ix86_expand_branch (GEU, reg, limit, operands[1]);
12157 ;; Bit manipulation instructions.
12159 (define_expand "ffs<mode>2"
12160 [(set (match_dup 2) (const_int -1))
12161 (parallel [(set (match_dup 3) (match_dup 4))
12162 (set (match_operand:SWI48 0 "register_operand")
12164 (match_operand:SWI48 1 "nonimmediate_operand")))])
12165 (set (match_dup 0) (if_then_else:SWI48
12166 (eq (match_dup 3) (const_int 0))
12169 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12170 (clobber (reg:CC FLAGS_REG))])]
12173 machine_mode flags_mode;
12175 if (<MODE>mode == SImode && !TARGET_CMOVE)
12177 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12182 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12184 operands[2] = gen_reg_rtx (<MODE>mode);
12185 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12186 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12189 (define_insn_and_split "ffssi2_no_cmove"
12190 [(set (match_operand:SI 0 "register_operand" "=r")
12191 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12192 (clobber (match_scratch:SI 2 "=&q"))
12193 (clobber (reg:CC FLAGS_REG))]
12196 "&& reload_completed"
12197 [(parallel [(set (match_dup 4) (match_dup 5))
12198 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12199 (set (strict_low_part (match_dup 3))
12200 (eq:QI (match_dup 4) (const_int 0)))
12201 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12202 (clobber (reg:CC FLAGS_REG))])
12203 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12204 (clobber (reg:CC FLAGS_REG))])
12205 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12206 (clobber (reg:CC FLAGS_REG))])]
12208 machine_mode flags_mode
12209 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12211 operands[3] = gen_lowpart (QImode, operands[2]);
12212 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12213 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12215 ix86_expand_clear (operands[2]);
12218 (define_insn "*tzcnt<mode>_1"
12219 [(set (reg:CCC FLAGS_REG)
12220 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222 (set (match_operand:SWI48 0 "register_operand" "=r")
12223 (ctz:SWI48 (match_dup 1)))]
12224 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12225 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12226 [(set_attr "type" "alu1")
12227 (set_attr "prefix_0f" "1")
12228 (set_attr "prefix_rep" "1")
12229 (set_attr "btver2_decode" "double")
12230 (set_attr "mode" "<MODE>")])
12232 (define_insn "*bsf<mode>_1"
12233 [(set (reg:CCZ FLAGS_REG)
12234 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12236 (set (match_operand:SWI48 0 "register_operand" "=r")
12237 (ctz:SWI48 (match_dup 1)))]
12239 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "alu1")
12241 (set_attr "prefix_0f" "1")
12242 (set_attr "btver2_decode" "double")
12243 (set_attr "mode" "<MODE>")])
12245 (define_expand "ctz<mode>2"
12247 [(set (match_operand:SWI248 0 "register_operand")
12249 (match_operand:SWI248 1 "nonimmediate_operand")))
12250 (clobber (reg:CC FLAGS_REG))])])
12252 ; False dependency happens when destination is only updated by tzcnt,
12253 ; lzcnt or popcnt. There is no false dependency when destination is
12254 ; also used in source.
12255 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12256 [(set (match_operand:SWI48 0 "register_operand" "=r")
12258 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "(TARGET_BMI || TARGET_GENERIC)
12261 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12263 "&& reload_completed"
12265 [(set (match_dup 0)
12266 (ctz:SWI48 (match_dup 1)))
12267 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12268 (clobber (reg:CC FLAGS_REG))])]
12270 if (!reg_mentioned_p (operands[0], operands[1]))
12271 ix86_expand_clear (operands[0]);
12274 (define_insn "*ctz<mode>2_falsedep"
12275 [(set (match_operand:SWI48 0 "register_operand" "=r")
12277 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12278 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12279 UNSPEC_INSN_FALSE_DEP)
12280 (clobber (reg:CC FLAGS_REG))]
12284 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12285 else if (TARGET_GENERIC)
12286 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12287 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12289 gcc_unreachable ();
12291 [(set_attr "type" "alu1")
12292 (set_attr "prefix_0f" "1")
12293 (set_attr "prefix_rep" "1")
12294 (set_attr "mode" "<MODE>")])
12296 (define_insn "*ctz<mode>2"
12297 [(set (match_operand:SWI248 0 "register_operand" "=r")
12298 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12299 (clobber (reg:CC FLAGS_REG))]
12303 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12304 else if (optimize_function_for_size_p (cfun))
12306 else if (TARGET_GENERIC)
12307 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12308 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12310 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12312 [(set_attr "type" "alu1")
12313 (set_attr "prefix_0f" "1")
12314 (set (attr "prefix_rep")
12316 (ior (match_test "TARGET_BMI")
12317 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12318 (match_test "TARGET_GENERIC")))
12320 (const_string "0")))
12321 (set_attr "mode" "<MODE>")])
12323 (define_expand "clz<mode>2"
12325 [(set (match_operand:SWI248 0 "register_operand")
12328 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12329 (clobber (reg:CC FLAGS_REG))])
12331 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12332 (clobber (reg:CC FLAGS_REG))])]
12337 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12340 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12343 (define_expand "clz<mode>2_lzcnt"
12345 [(set (match_operand:SWI248 0 "register_operand")
12347 (match_operand:SWI248 1 "nonimmediate_operand")))
12348 (clobber (reg:CC FLAGS_REG))])]
12351 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12352 [(set (match_operand:SWI48 0 "register_operand" "=r")
12354 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12355 (clobber (reg:CC FLAGS_REG))]
12357 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12359 "&& reload_completed"
12361 [(set (match_dup 0)
12362 (clz:SWI48 (match_dup 1)))
12363 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12364 (clobber (reg:CC FLAGS_REG))])]
12366 if (!reg_mentioned_p (operands[0], operands[1]))
12367 ix86_expand_clear (operands[0]);
12370 (define_insn "*clz<mode>2_lzcnt_falsedep"
12371 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12374 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12375 UNSPEC_INSN_FALSE_DEP)
12376 (clobber (reg:CC FLAGS_REG))]
12378 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12379 [(set_attr "prefix_rep" "1")
12380 (set_attr "type" "bitmanip")
12381 (set_attr "mode" "<MODE>")])
12383 (define_insn "*clz<mode>2_lzcnt"
12384 [(set (match_operand:SWI248 0 "register_operand" "=r")
12385 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12386 (clobber (reg:CC FLAGS_REG))]
12388 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12389 [(set_attr "prefix_rep" "1")
12390 (set_attr "type" "bitmanip")
12391 (set_attr "mode" "<MODE>")])
12393 ;; BMI instructions.
12394 (define_insn "*bmi_andn_<mode>"
12395 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12398 (match_operand:SWI48 1 "register_operand" "r,r"))
12399 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12400 (clobber (reg:CC FLAGS_REG))]
12402 "andn\t{%2, %1, %0|%0, %1, %2}"
12403 [(set_attr "type" "bitmanip")
12404 (set_attr "btver2_decode" "direct, double")
12405 (set_attr "mode" "<MODE>")])
12407 (define_insn "bmi_bextr_<mode>"
12408 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12409 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12410 (match_operand:SWI48 2 "register_operand" "r,r")]
12412 (clobber (reg:CC FLAGS_REG))]
12414 "bextr\t{%2, %1, %0|%0, %1, %2}"
12415 [(set_attr "type" "bitmanip")
12416 (set_attr "btver2_decode" "direct, double")
12417 (set_attr "mode" "<MODE>")])
12419 (define_insn "*bmi_blsi_<mode>"
12420 [(set (match_operand:SWI48 0 "register_operand" "=r")
12423 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12425 (clobber (reg:CC FLAGS_REG))]
12427 "blsi\t{%1, %0|%0, %1}"
12428 [(set_attr "type" "bitmanip")
12429 (set_attr "btver2_decode" "double")
12430 (set_attr "mode" "<MODE>")])
12432 (define_insn "*bmi_blsmsk_<mode>"
12433 [(set (match_operand:SWI48 0 "register_operand" "=r")
12436 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12439 (clobber (reg:CC FLAGS_REG))]
12441 "blsmsk\t{%1, %0|%0, %1}"
12442 [(set_attr "type" "bitmanip")
12443 (set_attr "btver2_decode" "double")
12444 (set_attr "mode" "<MODE>")])
12446 (define_insn "*bmi_blsr_<mode>"
12447 [(set (match_operand:SWI48 0 "register_operand" "=r")
12450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12453 (clobber (reg:CC FLAGS_REG))]
12455 "blsr\t{%1, %0|%0, %1}"
12456 [(set_attr "type" "bitmanip")
12457 (set_attr "btver2_decode" "double")
12458 (set_attr "mode" "<MODE>")])
12460 ;; BMI2 instructions.
12461 (define_insn "bmi2_bzhi_<mode>3"
12462 [(set (match_operand:SWI48 0 "register_operand" "=r")
12463 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12464 (match_operand:SWI48 2 "register_operand" "r"))
12465 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12466 (clobber (reg:CC FLAGS_REG))]
12468 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12469 [(set_attr "type" "bitmanip")
12470 (set_attr "prefix" "vex")
12471 (set_attr "mode" "<MODE>")])
12473 (define_insn "bmi2_pdep_<mode>3"
12474 [(set (match_operand:SWI48 0 "register_operand" "=r")
12475 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12476 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12479 "pdep\t{%2, %1, %0|%0, %1, %2}"
12480 [(set_attr "type" "bitmanip")
12481 (set_attr "prefix" "vex")
12482 (set_attr "mode" "<MODE>")])
12484 (define_insn "bmi2_pext_<mode>3"
12485 [(set (match_operand:SWI48 0 "register_operand" "=r")
12486 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12487 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12490 "pext\t{%2, %1, %0|%0, %1, %2}"
12491 [(set_attr "type" "bitmanip")
12492 (set_attr "prefix" "vex")
12493 (set_attr "mode" "<MODE>")])
12495 ;; TBM instructions.
12496 (define_insn "tbm_bextri_<mode>"
12497 [(set (match_operand:SWI48 0 "register_operand" "=r")
12498 (zero_extract:SWI48
12499 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12500 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12501 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12502 (clobber (reg:CC FLAGS_REG))]
12505 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12506 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12508 [(set_attr "type" "bitmanip")
12509 (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_blcfill_<mode>"
12512 [(set (match_operand:SWI48 0 "register_operand" "=r")
12515 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12518 (clobber (reg:CC FLAGS_REG))]
12520 "blcfill\t{%1, %0|%0, %1}"
12521 [(set_attr "type" "bitmanip")
12522 (set_attr "mode" "<MODE>")])
12524 (define_insn "*tbm_blci_<mode>"
12525 [(set (match_operand:SWI48 0 "register_operand" "=r")
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12532 (clobber (reg:CC FLAGS_REG))]
12534 "blci\t{%1, %0|%0, %1}"
12535 [(set_attr "type" "bitmanip")
12536 (set_attr "mode" "<MODE>")])
12538 (define_insn "*tbm_blcic_<mode>"
12539 [(set (match_operand:SWI48 0 "register_operand" "=r")
12542 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12546 (clobber (reg:CC FLAGS_REG))]
12548 "blcic\t{%1, %0|%0, %1}"
12549 [(set_attr "type" "bitmanip")
12550 (set_attr "mode" "<MODE>")])
12552 (define_insn "*tbm_blcmsk_<mode>"
12553 [(set (match_operand:SWI48 0 "register_operand" "=r")
12556 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12559 (clobber (reg:CC FLAGS_REG))]
12561 "blcmsk\t{%1, %0|%0, %1}"
12562 [(set_attr "type" "bitmanip")
12563 (set_attr "mode" "<MODE>")])
12565 (define_insn "*tbm_blcs_<mode>"
12566 [(set (match_operand:SWI48 0 "register_operand" "=r")
12569 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12572 (clobber (reg:CC FLAGS_REG))]
12574 "blcs\t{%1, %0|%0, %1}"
12575 [(set_attr "type" "bitmanip")
12576 (set_attr "mode" "<MODE>")])
12578 (define_insn "*tbm_blsfill_<mode>"
12579 [(set (match_operand:SWI48 0 "register_operand" "=r")
12582 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12585 (clobber (reg:CC FLAGS_REG))]
12587 "blsfill\t{%1, %0|%0, %1}"
12588 [(set_attr "type" "bitmanip")
12589 (set_attr "mode" "<MODE>")])
12591 (define_insn "*tbm_blsic_<mode>"
12592 [(set (match_operand:SWI48 0 "register_operand" "=r")
12595 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12599 (clobber (reg:CC FLAGS_REG))]
12601 "blsic\t{%1, %0|%0, %1}"
12602 [(set_attr "type" "bitmanip")
12603 (set_attr "mode" "<MODE>")])
12605 (define_insn "*tbm_t1mskc_<mode>"
12606 [(set (match_operand:SWI48 0 "register_operand" "=r")
12609 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12613 (clobber (reg:CC FLAGS_REG))]
12615 "t1mskc\t{%1, %0|%0, %1}"
12616 [(set_attr "type" "bitmanip")
12617 (set_attr "mode" "<MODE>")])
12619 (define_insn "*tbm_tzmsk_<mode>"
12620 [(set (match_operand:SWI48 0 "register_operand" "=r")
12623 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12627 (clobber (reg:CC FLAGS_REG))]
12629 "tzmsk\t{%1, %0|%0, %1}"
12630 [(set_attr "type" "bitmanip")
12631 (set_attr "mode" "<MODE>")])
12633 (define_insn "bsr_rex64"
12634 [(set (match_operand:DI 0 "register_operand" "=r")
12635 (minus:DI (const_int 63)
12636 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12637 (clobber (reg:CC FLAGS_REG))]
12639 "bsr{q}\t{%1, %0|%0, %1}"
12640 [(set_attr "type" "alu1")
12641 (set_attr "prefix_0f" "1")
12642 (set_attr "mode" "DI")])
12645 [(set (match_operand:SI 0 "register_operand" "=r")
12646 (minus:SI (const_int 31)
12647 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12648 (clobber (reg:CC FLAGS_REG))]
12650 "bsr{l}\t{%1, %0|%0, %1}"
12651 [(set_attr "type" "alu1")
12652 (set_attr "prefix_0f" "1")
12653 (set_attr "mode" "SI")])
12655 (define_insn "*bsrhi"
12656 [(set (match_operand:HI 0 "register_operand" "=r")
12657 (minus:HI (const_int 15)
12658 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12659 (clobber (reg:CC FLAGS_REG))]
12661 "bsr{w}\t{%1, %0|%0, %1}"
12662 [(set_attr "type" "alu1")
12663 (set_attr "prefix_0f" "1")
12664 (set_attr "mode" "HI")])
12666 (define_expand "popcount<mode>2"
12668 [(set (match_operand:SWI248 0 "register_operand")
12670 (match_operand:SWI248 1 "nonimmediate_operand")))
12671 (clobber (reg:CC FLAGS_REG))])]
12674 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12675 [(set (match_operand:SWI48 0 "register_operand" "=r")
12677 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12678 (clobber (reg:CC FLAGS_REG))]
12680 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12682 "&& reload_completed"
12684 [(set (match_dup 0)
12685 (popcount:SWI48 (match_dup 1)))
12686 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12687 (clobber (reg:CC FLAGS_REG))])]
12689 if (!reg_mentioned_p (operands[0], operands[1]))
12690 ix86_expand_clear (operands[0]);
12693 (define_insn "*popcount<mode>2_falsedep"
12694 [(set (match_operand:SWI48 0 "register_operand" "=r")
12696 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12697 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12698 UNSPEC_INSN_FALSE_DEP)
12699 (clobber (reg:CC FLAGS_REG))]
12703 return "popcnt\t{%1, %0|%0, %1}";
12705 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12708 [(set_attr "prefix_rep" "1")
12709 (set_attr "type" "bitmanip")
12710 (set_attr "mode" "<MODE>")])
12712 (define_insn "*popcount<mode>2"
12713 [(set (match_operand:SWI248 0 "register_operand" "=r")
12715 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12716 (clobber (reg:CC FLAGS_REG))]
12720 return "popcnt\t{%1, %0|%0, %1}";
12722 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12725 [(set_attr "prefix_rep" "1")
12726 (set_attr "type" "bitmanip")
12727 (set_attr "mode" "<MODE>")])
12729 (define_expand "bswapdi2"
12730 [(set (match_operand:DI 0 "register_operand")
12731 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12735 operands[1] = force_reg (DImode, operands[1]);
12738 (define_expand "bswapsi2"
12739 [(set (match_operand:SI 0 "register_operand")
12740 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12745 else if (TARGET_BSWAP)
12746 operands[1] = force_reg (SImode, operands[1]);
12749 rtx x = operands[0];
12751 emit_move_insn (x, operands[1]);
12752 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12753 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12754 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12759 (define_insn "*bswap<mode>2_movbe"
12760 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12761 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12763 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12766 movbe\t{%1, %0|%0, %1}
12767 movbe\t{%1, %0|%0, %1}"
12768 [(set_attr "type" "bitmanip,imov,imov")
12769 (set_attr "modrm" "0,1,1")
12770 (set_attr "prefix_0f" "*,1,1")
12771 (set_attr "prefix_extra" "*,1,1")
12772 (set_attr "mode" "<MODE>")])
12774 (define_insn "*bswap<mode>2"
12775 [(set (match_operand:SWI48 0 "register_operand" "=r")
12776 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12779 [(set_attr "type" "bitmanip")
12780 (set_attr "modrm" "0")
12781 (set_attr "mode" "<MODE>")])
12783 (define_insn "*bswaphi_lowpart_1"
12784 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12785 (bswap:HI (match_dup 0)))
12786 (clobber (reg:CC FLAGS_REG))]
12787 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12789 xchg{b}\t{%h0, %b0|%b0, %h0}
12790 rol{w}\t{$8, %0|%0, 8}"
12791 [(set_attr "length" "2,4")
12792 (set_attr "mode" "QI,HI")])
12794 (define_insn "bswaphi_lowpart"
12795 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12796 (bswap:HI (match_dup 0)))
12797 (clobber (reg:CC FLAGS_REG))]
12799 "rol{w}\t{$8, %0|%0, 8}"
12800 [(set_attr "length" "4")
12801 (set_attr "mode" "HI")])
12803 (define_expand "paritydi2"
12804 [(set (match_operand:DI 0 "register_operand")
12805 (parity:DI (match_operand:DI 1 "register_operand")))]
12808 rtx scratch = gen_reg_rtx (QImode);
12811 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12812 NULL_RTX, operands[1]));
12814 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12815 gen_rtx_REG (CCmode, FLAGS_REG),
12817 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12820 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12823 rtx tmp = gen_reg_rtx (SImode);
12825 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12826 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12831 (define_expand "paritysi2"
12832 [(set (match_operand:SI 0 "register_operand")
12833 (parity:SI (match_operand:SI 1 "register_operand")))]
12836 rtx scratch = gen_reg_rtx (QImode);
12839 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12841 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12842 gen_rtx_REG (CCmode, FLAGS_REG),
12844 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12846 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12850 (define_insn_and_split "paritydi2_cmp"
12851 [(set (reg:CC FLAGS_REG)
12852 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12854 (clobber (match_scratch:DI 0 "=r"))
12855 (clobber (match_scratch:SI 1 "=&r"))
12856 (clobber (match_scratch:HI 2 "=Q"))]
12859 "&& reload_completed"
12861 [(set (match_dup 1)
12862 (xor:SI (match_dup 1) (match_dup 4)))
12863 (clobber (reg:CC FLAGS_REG))])
12865 [(set (reg:CC FLAGS_REG)
12866 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12867 (clobber (match_dup 1))
12868 (clobber (match_dup 2))])]
12870 operands[4] = gen_lowpart (SImode, operands[3]);
12874 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12875 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12878 operands[1] = gen_highpart (SImode, operands[3]);
12881 (define_insn_and_split "paritysi2_cmp"
12882 [(set (reg:CC FLAGS_REG)
12883 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12885 (clobber (match_scratch:SI 0 "=r"))
12886 (clobber (match_scratch:HI 1 "=&Q"))]
12889 "&& reload_completed"
12891 [(set (match_dup 1)
12892 (xor:HI (match_dup 1) (match_dup 3)))
12893 (clobber (reg:CC FLAGS_REG))])
12895 [(set (reg:CC FLAGS_REG)
12896 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12897 (clobber (match_dup 1))])]
12899 operands[3] = gen_lowpart (HImode, operands[2]);
12901 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12902 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12905 (define_insn "*parityhi2_cmp"
12906 [(set (reg:CC FLAGS_REG)
12907 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12909 (clobber (match_scratch:HI 0 "=Q"))]
12911 "xor{b}\t{%h0, %b0|%b0, %h0}"
12912 [(set_attr "length" "2")
12913 (set_attr "mode" "HI")])
12916 ;; Thread-local storage patterns for ELF.
12918 ;; Note that these code sequences must appear exactly as shown
12919 ;; in order to allow linker relaxation.
12921 (define_insn "*tls_global_dynamic_32_gnu"
12922 [(set (match_operand:SI 0 "register_operand" "=a")
12924 [(match_operand:SI 1 "register_operand" "b")
12925 (match_operand 2 "tls_symbolic_operand")
12926 (match_operand 3 "constant_call_address_operand" "Bz")
12929 (clobber (match_scratch:SI 4 "=d"))
12930 (clobber (match_scratch:SI 5 "=c"))
12931 (clobber (reg:CC FLAGS_REG))]
12932 "!TARGET_64BIT && TARGET_GNU_TLS"
12935 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12936 if (TARGET_SUN_TLS)
12937 #ifdef HAVE_AS_IX86_TLSGDPLT
12938 return "call\t%a2@tlsgdplt";
12940 return "call\t%p3@plt";
12942 return "call\t%P3";
12944 [(set_attr "type" "multi")
12945 (set_attr "length" "12")])
12947 (define_expand "tls_global_dynamic_32"
12949 [(set (match_operand:SI 0 "register_operand")
12950 (unspec:SI [(match_operand:SI 2 "register_operand")
12951 (match_operand 1 "tls_symbolic_operand")
12952 (match_operand 3 "constant_call_address_operand")
12955 (clobber (match_scratch:SI 4))
12956 (clobber (match_scratch:SI 5))
12957 (clobber (reg:CC FLAGS_REG))])]
12959 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12961 (define_insn "*tls_global_dynamic_64_<mode>"
12962 [(set (match_operand:P 0 "register_operand" "=a")
12964 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12965 (match_operand 3)))
12966 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12971 fputs (ASM_BYTE "0x66\n", asm_out_file);
12973 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12974 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12975 fputs ("\trex64\n", asm_out_file);
12976 if (TARGET_SUN_TLS)
12977 return "call\t%p2@plt";
12978 return "call\t%P2";
12980 [(set_attr "type" "multi")
12981 (set (attr "length")
12982 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12984 (define_insn "*tls_global_dynamic_64_largepic"
12985 [(set (match_operand:DI 0 "register_operand" "=a")
12987 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12988 (match_operand:DI 3 "immediate_operand" "i")))
12989 (match_operand 4)))
12990 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12992 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12993 && GET_CODE (operands[3]) == CONST
12994 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12995 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12998 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12999 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13000 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13001 return "call\t{*%%rax|rax}";
13003 [(set_attr "type" "multi")
13004 (set_attr "length" "22")])
13006 (define_expand "tls_global_dynamic_64_<mode>"
13008 [(set (match_operand:P 0 "register_operand")
13010 (mem:QI (match_operand 2))
13012 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13015 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13017 (define_insn "*tls_local_dynamic_base_32_gnu"
13018 [(set (match_operand:SI 0 "register_operand" "=a")
13020 [(match_operand:SI 1 "register_operand" "b")
13021 (match_operand 2 "constant_call_address_operand" "Bz")
13023 UNSPEC_TLS_LD_BASE))
13024 (clobber (match_scratch:SI 3 "=d"))
13025 (clobber (match_scratch:SI 4 "=c"))
13026 (clobber (reg:CC FLAGS_REG))]
13027 "!TARGET_64BIT && TARGET_GNU_TLS"
13030 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13031 if (TARGET_SUN_TLS)
13033 if (HAVE_AS_IX86_TLSLDMPLT)
13034 return "call\t%&@tlsldmplt";
13036 return "call\t%p2@plt";
13038 return "call\t%P2";
13040 [(set_attr "type" "multi")
13041 (set_attr "length" "11")])
13043 (define_expand "tls_local_dynamic_base_32"
13045 [(set (match_operand:SI 0 "register_operand")
13047 [(match_operand:SI 1 "register_operand")
13048 (match_operand 2 "constant_call_address_operand")
13050 UNSPEC_TLS_LD_BASE))
13051 (clobber (match_scratch:SI 3))
13052 (clobber (match_scratch:SI 4))
13053 (clobber (reg:CC FLAGS_REG))])]
13055 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13057 (define_insn "*tls_local_dynamic_base_64_<mode>"
13058 [(set (match_operand:P 0 "register_operand" "=a")
13060 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13061 (match_operand 2)))
13062 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13066 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13067 if (TARGET_SUN_TLS)
13068 return "call\t%p1@plt";
13069 return "call\t%P1";
13071 [(set_attr "type" "multi")
13072 (set_attr "length" "12")])
13074 (define_insn "*tls_local_dynamic_base_64_largepic"
13075 [(set (match_operand:DI 0 "register_operand" "=a")
13077 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13078 (match_operand:DI 2 "immediate_operand" "i")))
13079 (match_operand 3)))
13080 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13081 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13082 && GET_CODE (operands[2]) == CONST
13083 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13084 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13087 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13088 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13089 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13090 return "call\t{*%%rax|rax}";
13092 [(set_attr "type" "multi")
13093 (set_attr "length" "22")])
13095 (define_expand "tls_local_dynamic_base_64_<mode>"
13097 [(set (match_operand:P 0 "register_operand")
13099 (mem:QI (match_operand 1))
13101 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13103 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13105 ;; Local dynamic of a single variable is a lose. Show combine how
13106 ;; to convert that back to global dynamic.
13108 (define_insn_and_split "*tls_local_dynamic_32_once"
13109 [(set (match_operand:SI 0 "register_operand" "=a")
13111 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13112 (match_operand 2 "constant_call_address_operand" "Bz")
13114 UNSPEC_TLS_LD_BASE)
13115 (const:SI (unspec:SI
13116 [(match_operand 3 "tls_symbolic_operand")]
13118 (clobber (match_scratch:SI 4 "=d"))
13119 (clobber (match_scratch:SI 5 "=c"))
13120 (clobber (reg:CC FLAGS_REG))]
13125 [(set (match_dup 0)
13126 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13129 (clobber (match_dup 4))
13130 (clobber (match_dup 5))
13131 (clobber (reg:CC FLAGS_REG))])])
13133 ;; Segment register for the thread base ptr load
13134 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13136 ;; Load and add the thread base pointer from %<tp_seg>:0.
13137 (define_insn "*load_tp_x32"
13138 [(set (match_operand:SI 0 "register_operand" "=r")
13139 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13141 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13142 [(set_attr "type" "imov")
13143 (set_attr "modrm" "0")
13144 (set_attr "length" "7")
13145 (set_attr "memory" "load")
13146 (set_attr "imm_disp" "false")])
13148 (define_insn "*load_tp_x32_zext"
13149 [(set (match_operand:DI 0 "register_operand" "=r")
13150 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13152 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13153 [(set_attr "type" "imov")
13154 (set_attr "modrm" "0")
13155 (set_attr "length" "7")
13156 (set_attr "memory" "load")
13157 (set_attr "imm_disp" "false")])
13159 (define_insn "*load_tp_<mode>"
13160 [(set (match_operand:P 0 "register_operand" "=r")
13161 (unspec:P [(const_int 0)] UNSPEC_TP))]
13163 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13164 [(set_attr "type" "imov")
13165 (set_attr "modrm" "0")
13166 (set_attr "length" "7")
13167 (set_attr "memory" "load")
13168 (set_attr "imm_disp" "false")])
13170 (define_insn "*add_tp_x32"
13171 [(set (match_operand:SI 0 "register_operand" "=r")
13172 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13173 (match_operand:SI 1 "register_operand" "0")))
13174 (clobber (reg:CC FLAGS_REG))]
13176 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13177 [(set_attr "type" "alu")
13178 (set_attr "modrm" "0")
13179 (set_attr "length" "7")
13180 (set_attr "memory" "load")
13181 (set_attr "imm_disp" "false")])
13183 (define_insn "*add_tp_x32_zext"
13184 [(set (match_operand:DI 0 "register_operand" "=r")
13186 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13187 (match_operand:SI 1 "register_operand" "0"))))
13188 (clobber (reg:CC FLAGS_REG))]
13190 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13191 [(set_attr "type" "alu")
13192 (set_attr "modrm" "0")
13193 (set_attr "length" "7")
13194 (set_attr "memory" "load")
13195 (set_attr "imm_disp" "false")])
13197 (define_insn "*add_tp_<mode>"
13198 [(set (match_operand:P 0 "register_operand" "=r")
13199 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13200 (match_operand:P 1 "register_operand" "0")))
13201 (clobber (reg:CC FLAGS_REG))]
13203 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13204 [(set_attr "type" "alu")
13205 (set_attr "modrm" "0")
13206 (set_attr "length" "7")
13207 (set_attr "memory" "load")
13208 (set_attr "imm_disp" "false")])
13210 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13211 ;; %rax as destination of the initial executable code sequence.
13212 (define_insn "tls_initial_exec_64_sun"
13213 [(set (match_operand:DI 0 "register_operand" "=a")
13215 [(match_operand 1 "tls_symbolic_operand")]
13216 UNSPEC_TLS_IE_SUN))
13217 (clobber (reg:CC FLAGS_REG))]
13218 "TARGET_64BIT && TARGET_SUN_TLS"
13221 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13222 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13224 [(set_attr "type" "multi")])
13226 ;; GNU2 TLS patterns can be split.
13228 (define_expand "tls_dynamic_gnu2_32"
13229 [(set (match_dup 3)
13230 (plus:SI (match_operand:SI 2 "register_operand")
13232 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13235 [(set (match_operand:SI 0 "register_operand")
13236 (unspec:SI [(match_dup 1) (match_dup 3)
13237 (match_dup 2) (reg:SI SP_REG)]
13239 (clobber (reg:CC FLAGS_REG))])]
13240 "!TARGET_64BIT && TARGET_GNU2_TLS"
13242 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13243 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13246 (define_insn "*tls_dynamic_gnu2_lea_32"
13247 [(set (match_operand:SI 0 "register_operand" "=r")
13248 (plus:SI (match_operand:SI 1 "register_operand" "b")
13250 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13251 UNSPEC_TLSDESC))))]
13252 "!TARGET_64BIT && TARGET_GNU2_TLS"
13253 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13254 [(set_attr "type" "lea")
13255 (set_attr "mode" "SI")
13256 (set_attr "length" "6")
13257 (set_attr "length_address" "4")])
13259 (define_insn "*tls_dynamic_gnu2_call_32"
13260 [(set (match_operand:SI 0 "register_operand" "=a")
13261 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13262 (match_operand:SI 2 "register_operand" "0")
13263 ;; we have to make sure %ebx still points to the GOT
13264 (match_operand:SI 3 "register_operand" "b")
13267 (clobber (reg:CC FLAGS_REG))]
13268 "!TARGET_64BIT && TARGET_GNU2_TLS"
13269 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13270 [(set_attr "type" "call")
13271 (set_attr "length" "2")
13272 (set_attr "length_address" "0")])
13274 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13275 [(set (match_operand:SI 0 "register_operand" "=&a")
13277 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13278 (match_operand:SI 4)
13279 (match_operand:SI 2 "register_operand" "b")
13282 (const:SI (unspec:SI
13283 [(match_operand 1 "tls_symbolic_operand")]
13285 (clobber (reg:CC FLAGS_REG))]
13286 "!TARGET_64BIT && TARGET_GNU2_TLS"
13289 [(set (match_dup 0) (match_dup 5))]
13291 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13292 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13295 (define_expand "tls_dynamic_gnu2_64"
13296 [(set (match_dup 2)
13297 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13300 [(set (match_operand:DI 0 "register_operand")
13301 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13303 (clobber (reg:CC FLAGS_REG))])]
13304 "TARGET_64BIT && TARGET_GNU2_TLS"
13306 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13307 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13310 (define_insn "*tls_dynamic_gnu2_lea_64"
13311 [(set (match_operand:DI 0 "register_operand" "=r")
13312 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13314 "TARGET_64BIT && TARGET_GNU2_TLS"
13315 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13316 [(set_attr "type" "lea")
13317 (set_attr "mode" "DI")
13318 (set_attr "length" "7")
13319 (set_attr "length_address" "4")])
13321 (define_insn "*tls_dynamic_gnu2_call_64"
13322 [(set (match_operand:DI 0 "register_operand" "=a")
13323 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13324 (match_operand:DI 2 "register_operand" "0")
13327 (clobber (reg:CC FLAGS_REG))]
13328 "TARGET_64BIT && TARGET_GNU2_TLS"
13329 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13330 [(set_attr "type" "call")
13331 (set_attr "length" "2")
13332 (set_attr "length_address" "0")])
13334 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13335 [(set (match_operand:DI 0 "register_operand" "=&a")
13337 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13338 (match_operand:DI 3)
13341 (const:DI (unspec:DI
13342 [(match_operand 1 "tls_symbolic_operand")]
13344 (clobber (reg:CC FLAGS_REG))]
13345 "TARGET_64BIT && TARGET_GNU2_TLS"
13348 [(set (match_dup 0) (match_dup 4))]
13350 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13351 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13354 ;; These patterns match the binary 387 instructions for addM3, subM3,
13355 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13356 ;; SFmode. The first is the normal insn, the second the same insn but
13357 ;; with one operand a conversion, and the third the same insn but with
13358 ;; the other operand a conversion. The conversion may be SFmode or
13359 ;; SImode if the target mode DFmode, but only SImode if the target mode
13362 ;; Gcc is slightly more smart about handling normal two address instructions
13363 ;; so use special patterns for add and mull.
13365 (define_insn "*fop_<mode>_comm_mixed"
13366 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13367 (match_operator:MODEF 3 "binary_fp_operator"
13368 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13369 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13370 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13371 && COMMUTATIVE_ARITH_P (operands[3])
13372 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13373 "* return output_387_binary_op (insn, operands);"
13374 [(set (attr "type")
13375 (if_then_else (eq_attr "alternative" "1,2")
13376 (if_then_else (match_operand:MODEF 3 "mult_operator")
13377 (const_string "ssemul")
13378 (const_string "sseadd"))
13379 (if_then_else (match_operand:MODEF 3 "mult_operator")
13380 (const_string "fmul")
13381 (const_string "fop"))))
13382 (set_attr "isa" "*,noavx,avx")
13383 (set_attr "prefix" "orig,orig,vex")
13384 (set_attr "mode" "<MODE>")])
13386 (define_insn "*fop_<mode>_comm_sse"
13387 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13388 (match_operator:MODEF 3 "binary_fp_operator"
13389 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13390 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13392 && COMMUTATIVE_ARITH_P (operands[3])
13393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13394 "* return output_387_binary_op (insn, operands);"
13395 [(set (attr "type")
13396 (if_then_else (match_operand:MODEF 3 "mult_operator")
13397 (const_string "ssemul")
13398 (const_string "sseadd")))
13399 (set_attr "isa" "noavx,avx")
13400 (set_attr "prefix" "orig,vex")
13401 (set_attr "mode" "<MODE>")])
13403 (define_insn "*fop_<mode>_comm_i387"
13404 [(set (match_operand:MODEF 0 "register_operand" "=f")
13405 (match_operator:MODEF 3 "binary_fp_operator"
13406 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13407 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13408 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13409 && COMMUTATIVE_ARITH_P (operands[3])
13410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13411 "* return output_387_binary_op (insn, operands);"
13412 [(set (attr "type")
13413 (if_then_else (match_operand:MODEF 3 "mult_operator")
13414 (const_string "fmul")
13415 (const_string "fop")))
13416 (set_attr "mode" "<MODE>")])
13418 (define_insn "*fop_<mode>_1_mixed"
13419 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13420 (match_operator:MODEF 3 "binary_fp_operator"
13421 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13422 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13423 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13424 && !COMMUTATIVE_ARITH_P (operands[3])
13425 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13426 "* return output_387_binary_op (insn, operands);"
13427 [(set (attr "type")
13428 (cond [(and (eq_attr "alternative" "2,3")
13429 (match_operand:MODEF 3 "mult_operator"))
13430 (const_string "ssemul")
13431 (and (eq_attr "alternative" "2,3")
13432 (match_operand:MODEF 3 "div_operator"))
13433 (const_string "ssediv")
13434 (eq_attr "alternative" "2,3")
13435 (const_string "sseadd")
13436 (match_operand:MODEF 3 "mult_operator")
13437 (const_string "fmul")
13438 (match_operand:MODEF 3 "div_operator")
13439 (const_string "fdiv")
13441 (const_string "fop")))
13442 (set_attr "isa" "*,*,noavx,avx")
13443 (set_attr "prefix" "orig,orig,orig,vex")
13444 (set_attr "mode" "<MODE>")])
13446 (define_insn "*rcpsf2_sse"
13447 [(set (match_operand:SF 0 "register_operand" "=x")
13448 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13451 "%vrcpss\t{%1, %d0|%d0, %1}"
13452 [(set_attr "type" "sse")
13453 (set_attr "atom_sse_attr" "rcp")
13454 (set_attr "btver2_sse_attr" "rcp")
13455 (set_attr "prefix" "maybe_vex")
13456 (set_attr "mode" "SF")])
13458 (define_insn "*fop_<mode>_1_sse"
13459 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13460 (match_operator:MODEF 3 "binary_fp_operator"
13461 [(match_operand:MODEF 1 "register_operand" "0,x")
13462 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13463 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13464 && !COMMUTATIVE_ARITH_P (operands[3])"
13465 "* return output_387_binary_op (insn, operands);"
13466 [(set (attr "type")
13467 (cond [(match_operand:MODEF 3 "mult_operator")
13468 (const_string "ssemul")
13469 (match_operand:MODEF 3 "div_operator")
13470 (const_string "ssediv")
13472 (const_string "sseadd")))
13473 (set_attr "isa" "noavx,avx")
13474 (set_attr "prefix" "orig,vex")
13475 (set_attr "mode" "<MODE>")])
13477 ;; This pattern is not fully shadowed by the pattern above.
13478 (define_insn "*fop_<mode>_1_i387"
13479 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13480 (match_operator:MODEF 3 "binary_fp_operator"
13481 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13482 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13483 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13484 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13485 && !COMMUTATIVE_ARITH_P (operands[3])
13486 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13487 "* return output_387_binary_op (insn, operands);"
13488 [(set (attr "type")
13489 (cond [(match_operand:MODEF 3 "mult_operator")
13490 (const_string "fmul")
13491 (match_operand:MODEF 3 "div_operator")
13492 (const_string "fdiv")
13494 (const_string "fop")))
13495 (set_attr "mode" "<MODE>")])
13497 ;; ??? Add SSE splitters for these!
13498 (define_insn "*fop_<MODEF:mode>_2_i387"
13499 [(set (match_operand:MODEF 0 "register_operand" "=f")
13500 (match_operator:MODEF 3 "binary_fp_operator"
13502 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13503 (match_operand:MODEF 2 "register_operand" "0")]))]
13504 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13505 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13506 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13507 || optimize_function_for_size_p (cfun))"
13508 { return output_387_binary_op (insn, operands); }
13509 [(set (attr "type")
13510 (cond [(match_operand:MODEF 3 "mult_operator")
13511 (const_string "fmul")
13512 (match_operand:MODEF 3 "div_operator")
13513 (const_string "fdiv")
13515 (const_string "fop")))
13516 (set_attr "fp_int_src" "true")
13517 (set_attr "mode" "<SWI24:MODE>")])
13519 (define_insn "*fop_<MODEF:mode>_3_i387"
13520 [(set (match_operand:MODEF 0 "register_operand" "=f")
13521 (match_operator:MODEF 3 "binary_fp_operator"
13522 [(match_operand:MODEF 1 "register_operand" "0")
13524 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13525 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13526 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13527 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13528 || optimize_function_for_size_p (cfun))"
13529 { return output_387_binary_op (insn, operands); }
13530 [(set (attr "type")
13531 (cond [(match_operand:MODEF 3 "mult_operator")
13532 (const_string "fmul")
13533 (match_operand:MODEF 3 "div_operator")
13534 (const_string "fdiv")
13536 (const_string "fop")))
13537 (set_attr "fp_int_src" "true")
13538 (set_attr "mode" "<MODE>")])
13540 (define_insn "*fop_df_4_i387"
13541 [(set (match_operand:DF 0 "register_operand" "=f,f")
13542 (match_operator:DF 3 "binary_fp_operator"
13544 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13545 (match_operand:DF 2 "register_operand" "0,f")]))]
13546 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13547 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13548 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13549 "* return output_387_binary_op (insn, operands);"
13550 [(set (attr "type")
13551 (cond [(match_operand:DF 3 "mult_operator")
13552 (const_string "fmul")
13553 (match_operand:DF 3 "div_operator")
13554 (const_string "fdiv")
13556 (const_string "fop")))
13557 (set_attr "mode" "SF")])
13559 (define_insn "*fop_df_5_i387"
13560 [(set (match_operand:DF 0 "register_operand" "=f,f")
13561 (match_operator:DF 3 "binary_fp_operator"
13562 [(match_operand:DF 1 "register_operand" "0,f")
13564 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13565 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13566 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13567 "* return output_387_binary_op (insn, operands);"
13568 [(set (attr "type")
13569 (cond [(match_operand:DF 3 "mult_operator")
13570 (const_string "fmul")
13571 (match_operand:DF 3 "div_operator")
13572 (const_string "fdiv")
13574 (const_string "fop")))
13575 (set_attr "mode" "SF")])
13577 (define_insn "*fop_df_6_i387"
13578 [(set (match_operand:DF 0 "register_operand" "=f,f")
13579 (match_operator:DF 3 "binary_fp_operator"
13581 (match_operand:SF 1 "register_operand" "0,f"))
13583 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13584 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13585 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13586 "* return output_387_binary_op (insn, operands);"
13587 [(set (attr "type")
13588 (cond [(match_operand:DF 3 "mult_operator")
13589 (const_string "fmul")
13590 (match_operand:DF 3 "div_operator")
13591 (const_string "fdiv")
13593 (const_string "fop")))
13594 (set_attr "mode" "SF")])
13596 (define_insn "*fop_xf_comm_i387"
13597 [(set (match_operand:XF 0 "register_operand" "=f")
13598 (match_operator:XF 3 "binary_fp_operator"
13599 [(match_operand:XF 1 "register_operand" "%0")
13600 (match_operand:XF 2 "register_operand" "f")]))]
13602 && COMMUTATIVE_ARITH_P (operands[3])"
13603 "* return output_387_binary_op (insn, operands);"
13604 [(set (attr "type")
13605 (if_then_else (match_operand:XF 3 "mult_operator")
13606 (const_string "fmul")
13607 (const_string "fop")))
13608 (set_attr "mode" "XF")])
13610 (define_insn "*fop_xf_1_i387"
13611 [(set (match_operand:XF 0 "register_operand" "=f,f")
13612 (match_operator:XF 3 "binary_fp_operator"
13613 [(match_operand:XF 1 "register_operand" "0,f")
13614 (match_operand:XF 2 "register_operand" "f,0")]))]
13616 && !COMMUTATIVE_ARITH_P (operands[3])"
13617 "* return output_387_binary_op (insn, operands);"
13618 [(set (attr "type")
13619 (cond [(match_operand:XF 3 "mult_operator")
13620 (const_string "fmul")
13621 (match_operand:XF 3 "div_operator")
13622 (const_string "fdiv")
13624 (const_string "fop")))
13625 (set_attr "mode" "XF")])
13627 (define_insn "*fop_xf_2_i387"
13628 [(set (match_operand:XF 0 "register_operand" "=f")
13629 (match_operator:XF 3 "binary_fp_operator"
13631 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13632 (match_operand:XF 2 "register_operand" "0")]))]
13634 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13635 { return output_387_binary_op (insn, operands); }
13636 [(set (attr "type")
13637 (cond [(match_operand:XF 3 "mult_operator")
13638 (const_string "fmul")
13639 (match_operand:XF 3 "div_operator")
13640 (const_string "fdiv")
13642 (const_string "fop")))
13643 (set_attr "fp_int_src" "true")
13644 (set_attr "mode" "<MODE>")])
13646 (define_insn "*fop_xf_3_i387"
13647 [(set (match_operand:XF 0 "register_operand" "=f")
13648 (match_operator:XF 3 "binary_fp_operator"
13649 [(match_operand:XF 1 "register_operand" "0")
13651 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13653 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13654 { return output_387_binary_op (insn, operands); }
13655 [(set (attr "type")
13656 (cond [(match_operand:XF 3 "mult_operator")
13657 (const_string "fmul")
13658 (match_operand:XF 3 "div_operator")
13659 (const_string "fdiv")
13661 (const_string "fop")))
13662 (set_attr "fp_int_src" "true")
13663 (set_attr "mode" "<MODE>")])
13665 (define_insn "*fop_xf_4_i387"
13666 [(set (match_operand:XF 0 "register_operand" "=f,f")
13667 (match_operator:XF 3 "binary_fp_operator"
13669 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13670 (match_operand:XF 2 "register_operand" "0,f")]))]
13672 "* return output_387_binary_op (insn, operands);"
13673 [(set (attr "type")
13674 (cond [(match_operand:XF 3 "mult_operator")
13675 (const_string "fmul")
13676 (match_operand:XF 3 "div_operator")
13677 (const_string "fdiv")
13679 (const_string "fop")))
13680 (set_attr "mode" "<MODE>")])
13682 (define_insn "*fop_xf_5_i387"
13683 [(set (match_operand:XF 0 "register_operand" "=f,f")
13684 (match_operator:XF 3 "binary_fp_operator"
13685 [(match_operand:XF 1 "register_operand" "0,f")
13687 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13689 "* return output_387_binary_op (insn, operands);"
13690 [(set (attr "type")
13691 (cond [(match_operand:XF 3 "mult_operator")
13692 (const_string "fmul")
13693 (match_operand:XF 3 "div_operator")
13694 (const_string "fdiv")
13696 (const_string "fop")))
13697 (set_attr "mode" "<MODE>")])
13699 (define_insn "*fop_xf_6_i387"
13700 [(set (match_operand:XF 0 "register_operand" "=f,f")
13701 (match_operator:XF 3 "binary_fp_operator"
13703 (match_operand:MODEF 1 "register_operand" "0,f"))
13705 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13707 "* return output_387_binary_op (insn, operands);"
13708 [(set (attr "type")
13709 (cond [(match_operand:XF 3 "mult_operator")
13710 (const_string "fmul")
13711 (match_operand:XF 3 "div_operator")
13712 (const_string "fdiv")
13714 (const_string "fop")))
13715 (set_attr "mode" "<MODE>")])
13717 ;; FPU special functions.
13719 ;; This pattern implements a no-op XFmode truncation for
13720 ;; all fancy i386 XFmode math functions.
13722 (define_insn "truncxf<mode>2_i387_noop_unspec"
13723 [(set (match_operand:MODEF 0 "register_operand" "=f")
13724 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13725 UNSPEC_TRUNC_NOOP))]
13726 "TARGET_USE_FANCY_MATH_387"
13727 "* return output_387_reg_move (insn, operands);"
13728 [(set_attr "type" "fmov")
13729 (set_attr "mode" "<MODE>")])
13731 (define_insn "sqrtxf2"
13732 [(set (match_operand:XF 0 "register_operand" "=f")
13733 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13734 "TARGET_USE_FANCY_MATH_387"
13736 [(set_attr "type" "fpspc")
13737 (set_attr "mode" "XF")
13738 (set_attr "athlon_decode" "direct")
13739 (set_attr "amdfam10_decode" "direct")
13740 (set_attr "bdver1_decode" "direct")])
13742 (define_insn "sqrt_extend<mode>xf2_i387"
13743 [(set (match_operand:XF 0 "register_operand" "=f")
13746 (match_operand:MODEF 1 "register_operand" "0"))))]
13747 "TARGET_USE_FANCY_MATH_387"
13749 [(set_attr "type" "fpspc")
13750 (set_attr "mode" "XF")
13751 (set_attr "athlon_decode" "direct")
13752 (set_attr "amdfam10_decode" "direct")
13753 (set_attr "bdver1_decode" "direct")])
13755 (define_insn "*rsqrtsf2_sse"
13756 [(set (match_operand:SF 0 "register_operand" "=x")
13757 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13760 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13761 [(set_attr "type" "sse")
13762 (set_attr "atom_sse_attr" "rcp")
13763 (set_attr "btver2_sse_attr" "rcp")
13764 (set_attr "prefix" "maybe_vex")
13765 (set_attr "mode" "SF")])
13767 (define_expand "rsqrtsf2"
13768 [(set (match_operand:SF 0 "register_operand")
13769 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13773 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13777 (define_insn "*sqrt<mode>2_sse"
13778 [(set (match_operand:MODEF 0 "register_operand" "=x")
13780 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13781 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13782 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13783 [(set_attr "type" "sse")
13784 (set_attr "atom_sse_attr" "sqrt")
13785 (set_attr "btver2_sse_attr" "sqrt")
13786 (set_attr "prefix" "maybe_vex")
13787 (set_attr "mode" "<MODE>")
13788 (set_attr "athlon_decode" "*")
13789 (set_attr "amdfam10_decode" "*")
13790 (set_attr "bdver1_decode" "*")])
13792 (define_expand "sqrt<mode>2"
13793 [(set (match_operand:MODEF 0 "register_operand")
13795 (match_operand:MODEF 1 "nonimmediate_operand")))]
13796 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13797 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13799 if (<MODE>mode == SFmode
13801 && TARGET_RECIP_SQRT
13802 && !optimize_function_for_size_p (cfun)
13803 && flag_finite_math_only && !flag_trapping_math
13804 && flag_unsafe_math_optimizations)
13806 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13810 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13812 rtx op0 = gen_reg_rtx (XFmode);
13813 rtx op1 = force_reg (<MODE>mode, operands[1]);
13815 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13816 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13821 (define_insn "fpremxf4_i387"
13822 [(set (match_operand:XF 0 "register_operand" "=f")
13823 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13824 (match_operand:XF 3 "register_operand" "1")]
13826 (set (match_operand:XF 1 "register_operand" "=u")
13827 (unspec:XF [(match_dup 2) (match_dup 3)]
13829 (set (reg:CCFP FPSR_REG)
13830 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13832 "TARGET_USE_FANCY_MATH_387
13833 && flag_finite_math_only"
13835 [(set_attr "type" "fpspc")
13836 (set_attr "mode" "XF")])
13838 (define_expand "fmodxf3"
13839 [(use (match_operand:XF 0 "register_operand"))
13840 (use (match_operand:XF 1 "general_operand"))
13841 (use (match_operand:XF 2 "general_operand"))]
13842 "TARGET_USE_FANCY_MATH_387
13843 && flag_finite_math_only"
13845 rtx_code_label *label = gen_label_rtx ();
13847 rtx op1 = gen_reg_rtx (XFmode);
13848 rtx op2 = gen_reg_rtx (XFmode);
13850 emit_move_insn (op2, operands[2]);
13851 emit_move_insn (op1, operands[1]);
13853 emit_label (label);
13854 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13855 ix86_emit_fp_unordered_jump (label);
13856 LABEL_NUSES (label) = 1;
13858 emit_move_insn (operands[0], op1);
13862 (define_expand "fmod<mode>3"
13863 [(use (match_operand:MODEF 0 "register_operand"))
13864 (use (match_operand:MODEF 1 "general_operand"))
13865 (use (match_operand:MODEF 2 "general_operand"))]
13866 "TARGET_USE_FANCY_MATH_387
13867 && flag_finite_math_only"
13869 rtx (*gen_truncxf) (rtx, rtx);
13871 rtx_code_label *label = gen_label_rtx ();
13873 rtx op1 = gen_reg_rtx (XFmode);
13874 rtx op2 = gen_reg_rtx (XFmode);
13876 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13877 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13879 emit_label (label);
13880 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13881 ix86_emit_fp_unordered_jump (label);
13882 LABEL_NUSES (label) = 1;
13884 /* Truncate the result properly for strict SSE math. */
13885 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13886 && !TARGET_MIX_SSE_I387)
13887 gen_truncxf = gen_truncxf<mode>2;
13889 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13891 emit_insn (gen_truncxf (operands[0], op1));
13895 (define_insn "fprem1xf4_i387"
13896 [(set (match_operand:XF 0 "register_operand" "=f")
13897 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13898 (match_operand:XF 3 "register_operand" "1")]
13900 (set (match_operand:XF 1 "register_operand" "=u")
13901 (unspec:XF [(match_dup 2) (match_dup 3)]
13903 (set (reg:CCFP FPSR_REG)
13904 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_finite_math_only"
13909 [(set_attr "type" "fpspc")
13910 (set_attr "mode" "XF")])
13912 (define_expand "remainderxf3"
13913 [(use (match_operand:XF 0 "register_operand"))
13914 (use (match_operand:XF 1 "general_operand"))
13915 (use (match_operand:XF 2 "general_operand"))]
13916 "TARGET_USE_FANCY_MATH_387
13917 && flag_finite_math_only"
13919 rtx_code_label *label = gen_label_rtx ();
13921 rtx op1 = gen_reg_rtx (XFmode);
13922 rtx op2 = gen_reg_rtx (XFmode);
13924 emit_move_insn (op2, operands[2]);
13925 emit_move_insn (op1, operands[1]);
13927 emit_label (label);
13928 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13929 ix86_emit_fp_unordered_jump (label);
13930 LABEL_NUSES (label) = 1;
13932 emit_move_insn (operands[0], op1);
13936 (define_expand "remainder<mode>3"
13937 [(use (match_operand:MODEF 0 "register_operand"))
13938 (use (match_operand:MODEF 1 "general_operand"))
13939 (use (match_operand:MODEF 2 "general_operand"))]
13940 "TARGET_USE_FANCY_MATH_387
13941 && flag_finite_math_only"
13943 rtx (*gen_truncxf) (rtx, rtx);
13945 rtx_code_label *label = gen_label_rtx ();
13947 rtx op1 = gen_reg_rtx (XFmode);
13948 rtx op2 = gen_reg_rtx (XFmode);
13950 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13951 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13953 emit_label (label);
13955 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13956 ix86_emit_fp_unordered_jump (label);
13957 LABEL_NUSES (label) = 1;
13959 /* Truncate the result properly for strict SSE math. */
13960 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13961 && !TARGET_MIX_SSE_I387)
13962 gen_truncxf = gen_truncxf<mode>2;
13964 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13966 emit_insn (gen_truncxf (operands[0], op1));
13970 (define_int_iterator SINCOS
13974 (define_int_attr sincos
13975 [(UNSPEC_SIN "sin")
13976 (UNSPEC_COS "cos")])
13978 (define_insn "*<sincos>xf2_i387"
13979 [(set (match_operand:XF 0 "register_operand" "=f")
13980 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13982 "TARGET_USE_FANCY_MATH_387
13983 && flag_unsafe_math_optimizations"
13985 [(set_attr "type" "fpspc")
13986 (set_attr "mode" "XF")])
13988 (define_insn "*<sincos>_extend<mode>xf2_i387"
13989 [(set (match_operand:XF 0 "register_operand" "=f")
13990 (unspec:XF [(float_extend:XF
13991 (match_operand:MODEF 1 "register_operand" "0"))]
13993 "TARGET_USE_FANCY_MATH_387
13994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13995 || TARGET_MIX_SSE_I387)
13996 && flag_unsafe_math_optimizations"
13998 [(set_attr "type" "fpspc")
13999 (set_attr "mode" "XF")])
14001 ;; When sincos pattern is defined, sin and cos builtin functions will be
14002 ;; expanded to sincos pattern with one of its outputs left unused.
14003 ;; CSE pass will figure out if two sincos patterns can be combined,
14004 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14005 ;; depending on the unused output.
14007 (define_insn "sincosxf3"
14008 [(set (match_operand:XF 0 "register_operand" "=f")
14009 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14010 UNSPEC_SINCOS_COS))
14011 (set (match_operand:XF 1 "register_operand" "=u")
14012 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && flag_unsafe_math_optimizations"
14016 [(set_attr "type" "fpspc")
14017 (set_attr "mode" "XF")])
14020 [(set (match_operand:XF 0 "register_operand")
14021 (unspec:XF [(match_operand:XF 2 "register_operand")]
14022 UNSPEC_SINCOS_COS))
14023 (set (match_operand:XF 1 "register_operand")
14024 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14026 && can_create_pseudo_p ()"
14027 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14030 [(set (match_operand:XF 0 "register_operand")
14031 (unspec:XF [(match_operand:XF 2 "register_operand")]
14032 UNSPEC_SINCOS_COS))
14033 (set (match_operand:XF 1 "register_operand")
14034 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14035 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14036 && can_create_pseudo_p ()"
14037 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14039 (define_insn "sincos_extend<mode>xf3_i387"
14040 [(set (match_operand:XF 0 "register_operand" "=f")
14041 (unspec:XF [(float_extend:XF
14042 (match_operand:MODEF 2 "register_operand" "0"))]
14043 UNSPEC_SINCOS_COS))
14044 (set (match_operand:XF 1 "register_operand" "=u")
14045 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14046 "TARGET_USE_FANCY_MATH_387
14047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14048 || TARGET_MIX_SSE_I387)
14049 && flag_unsafe_math_optimizations"
14051 [(set_attr "type" "fpspc")
14052 (set_attr "mode" "XF")])
14055 [(set (match_operand:XF 0 "register_operand")
14056 (unspec:XF [(float_extend:XF
14057 (match_operand:MODEF 2 "register_operand"))]
14058 UNSPEC_SINCOS_COS))
14059 (set (match_operand:XF 1 "register_operand")
14060 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14061 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14062 && can_create_pseudo_p ()"
14063 [(set (match_dup 1)
14064 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14067 [(set (match_operand:XF 0 "register_operand")
14068 (unspec:XF [(float_extend:XF
14069 (match_operand:MODEF 2 "register_operand"))]
14070 UNSPEC_SINCOS_COS))
14071 (set (match_operand:XF 1 "register_operand")
14072 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14073 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14074 && can_create_pseudo_p ()"
14075 [(set (match_dup 0)
14076 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14078 (define_expand "sincos<mode>3"
14079 [(use (match_operand:MODEF 0 "register_operand"))
14080 (use (match_operand:MODEF 1 "register_operand"))
14081 (use (match_operand:MODEF 2 "register_operand"))]
14082 "TARGET_USE_FANCY_MATH_387
14083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14084 || TARGET_MIX_SSE_I387)
14085 && flag_unsafe_math_optimizations"
14087 rtx op0 = gen_reg_rtx (XFmode);
14088 rtx op1 = gen_reg_rtx (XFmode);
14090 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14096 (define_insn "fptanxf4_i387"
14097 [(set (match_operand:XF 0 "register_operand" "=f")
14098 (match_operand:XF 3 "const_double_operand" "F"))
14099 (set (match_operand:XF 1 "register_operand" "=u")
14100 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations
14104 && standard_80387_constant_p (operands[3]) == 2"
14106 [(set_attr "type" "fpspc")
14107 (set_attr "mode" "XF")])
14109 (define_insn "fptan_extend<mode>xf4_i387"
14110 [(set (match_operand:MODEF 0 "register_operand" "=f")
14111 (match_operand:MODEF 3 "const_double_operand" "F"))
14112 (set (match_operand:XF 1 "register_operand" "=u")
14113 (unspec:XF [(float_extend:XF
14114 (match_operand:MODEF 2 "register_operand" "0"))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations
14120 && standard_80387_constant_p (operands[3]) == 2"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14125 (define_expand "tanxf2"
14126 [(use (match_operand:XF 0 "register_operand"))
14127 (use (match_operand:XF 1 "register_operand"))]
14128 "TARGET_USE_FANCY_MATH_387
14129 && flag_unsafe_math_optimizations"
14131 rtx one = gen_reg_rtx (XFmode);
14132 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14134 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14138 (define_expand "tan<mode>2"
14139 [(use (match_operand:MODEF 0 "register_operand"))
14140 (use (match_operand:MODEF 1 "register_operand"))]
14141 "TARGET_USE_FANCY_MATH_387
14142 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14143 || TARGET_MIX_SSE_I387)
14144 && flag_unsafe_math_optimizations"
14146 rtx op0 = gen_reg_rtx (XFmode);
14148 rtx one = gen_reg_rtx (<MODE>mode);
14149 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14151 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14152 operands[1], op2));
14153 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14157 (define_insn "*fpatanxf3_i387"
14158 [(set (match_operand:XF 0 "register_operand" "=f")
14159 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14160 (match_operand:XF 2 "register_operand" "u")]
14162 (clobber (match_scratch:XF 3 "=2"))]
14163 "TARGET_USE_FANCY_MATH_387
14164 && flag_unsafe_math_optimizations"
14166 [(set_attr "type" "fpspc")
14167 (set_attr "mode" "XF")])
14169 (define_insn "fpatan_extend<mode>xf3_i387"
14170 [(set (match_operand:XF 0 "register_operand" "=f")
14171 (unspec:XF [(float_extend:XF
14172 (match_operand:MODEF 1 "register_operand" "0"))
14174 (match_operand:MODEF 2 "register_operand" "u"))]
14176 (clobber (match_scratch:XF 3 "=2"))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "XF")])
14185 (define_expand "atan2xf3"
14186 [(parallel [(set (match_operand:XF 0 "register_operand")
14187 (unspec:XF [(match_operand:XF 2 "register_operand")
14188 (match_operand:XF 1 "register_operand")]
14190 (clobber (match_scratch:XF 3))])]
14191 "TARGET_USE_FANCY_MATH_387
14192 && flag_unsafe_math_optimizations")
14194 (define_expand "atan2<mode>3"
14195 [(use (match_operand:MODEF 0 "register_operand"))
14196 (use (match_operand:MODEF 1 "register_operand"))
14197 (use (match_operand:MODEF 2 "register_operand"))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200 || TARGET_MIX_SSE_I387)
14201 && flag_unsafe_math_optimizations"
14203 rtx op0 = gen_reg_rtx (XFmode);
14205 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14206 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14210 (define_expand "atanxf2"
14211 [(parallel [(set (match_operand:XF 0 "register_operand")
14212 (unspec:XF [(match_dup 2)
14213 (match_operand:XF 1 "register_operand")]
14215 (clobber (match_scratch:XF 3))])]
14216 "TARGET_USE_FANCY_MATH_387
14217 && flag_unsafe_math_optimizations"
14219 operands[2] = gen_reg_rtx (XFmode);
14220 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14223 (define_expand "atan<mode>2"
14224 [(use (match_operand:MODEF 0 "register_operand"))
14225 (use (match_operand:MODEF 1 "register_operand"))]
14226 "TARGET_USE_FANCY_MATH_387
14227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14228 || TARGET_MIX_SSE_I387)
14229 && flag_unsafe_math_optimizations"
14231 rtx op0 = gen_reg_rtx (XFmode);
14233 rtx op2 = gen_reg_rtx (<MODE>mode);
14234 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14236 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14237 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14241 (define_expand "asinxf2"
14242 [(set (match_dup 2)
14243 (mult:XF (match_operand:XF 1 "register_operand")
14245 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14246 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14247 (parallel [(set (match_operand:XF 0 "register_operand")
14248 (unspec:XF [(match_dup 5) (match_dup 1)]
14250 (clobber (match_scratch:XF 6))])]
14251 "TARGET_USE_FANCY_MATH_387
14252 && flag_unsafe_math_optimizations"
14256 if (optimize_insn_for_size_p ())
14259 for (i = 2; i < 6; i++)
14260 operands[i] = gen_reg_rtx (XFmode);
14262 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14265 (define_expand "asin<mode>2"
14266 [(use (match_operand:MODEF 0 "register_operand"))
14267 (use (match_operand:MODEF 1 "general_operand"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14273 rtx op0 = gen_reg_rtx (XFmode);
14274 rtx op1 = gen_reg_rtx (XFmode);
14276 if (optimize_insn_for_size_p ())
14279 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14280 emit_insn (gen_asinxf2 (op0, op1));
14281 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14285 (define_expand "acosxf2"
14286 [(set (match_dup 2)
14287 (mult:XF (match_operand:XF 1 "register_operand")
14289 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14290 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14291 (parallel [(set (match_operand:XF 0 "register_operand")
14292 (unspec:XF [(match_dup 1) (match_dup 5)]
14294 (clobber (match_scratch:XF 6))])]
14295 "TARGET_USE_FANCY_MATH_387
14296 && flag_unsafe_math_optimizations"
14300 if (optimize_insn_for_size_p ())
14303 for (i = 2; i < 6; i++)
14304 operands[i] = gen_reg_rtx (XFmode);
14306 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14309 (define_expand "acos<mode>2"
14310 [(use (match_operand:MODEF 0 "register_operand"))
14311 (use (match_operand:MODEF 1 "general_operand"))]
14312 "TARGET_USE_FANCY_MATH_387
14313 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14314 || TARGET_MIX_SSE_I387)
14315 && flag_unsafe_math_optimizations"
14317 rtx op0 = gen_reg_rtx (XFmode);
14318 rtx op1 = gen_reg_rtx (XFmode);
14320 if (optimize_insn_for_size_p ())
14323 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14324 emit_insn (gen_acosxf2 (op0, op1));
14325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329 (define_insn "fyl2xxf3_i387"
14330 [(set (match_operand:XF 0 "register_operand" "=f")
14331 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14332 (match_operand:XF 2 "register_operand" "u")]
14334 (clobber (match_scratch:XF 3 "=2"))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && flag_unsafe_math_optimizations"
14338 [(set_attr "type" "fpspc")
14339 (set_attr "mode" "XF")])
14341 (define_insn "fyl2x_extend<mode>xf3_i387"
14342 [(set (match_operand:XF 0 "register_operand" "=f")
14343 (unspec:XF [(float_extend:XF
14344 (match_operand:MODEF 1 "register_operand" "0"))
14345 (match_operand:XF 2 "register_operand" "u")]
14347 (clobber (match_scratch:XF 3 "=2"))]
14348 "TARGET_USE_FANCY_MATH_387
14349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14350 || TARGET_MIX_SSE_I387)
14351 && flag_unsafe_math_optimizations"
14353 [(set_attr "type" "fpspc")
14354 (set_attr "mode" "XF")])
14356 (define_expand "logxf2"
14357 [(parallel [(set (match_operand:XF 0 "register_operand")
14358 (unspec:XF [(match_operand:XF 1 "register_operand")
14359 (match_dup 2)] UNSPEC_FYL2X))
14360 (clobber (match_scratch:XF 3))])]
14361 "TARGET_USE_FANCY_MATH_387
14362 && flag_unsafe_math_optimizations"
14364 operands[2] = gen_reg_rtx (XFmode);
14365 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14368 (define_expand "log<mode>2"
14369 [(use (match_operand:MODEF 0 "register_operand"))
14370 (use (match_operand:MODEF 1 "register_operand"))]
14371 "TARGET_USE_FANCY_MATH_387
14372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14373 || TARGET_MIX_SSE_I387)
14374 && flag_unsafe_math_optimizations"
14376 rtx op0 = gen_reg_rtx (XFmode);
14378 rtx op2 = gen_reg_rtx (XFmode);
14379 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14381 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14386 (define_expand "log10xf2"
14387 [(parallel [(set (match_operand:XF 0 "register_operand")
14388 (unspec:XF [(match_operand:XF 1 "register_operand")
14389 (match_dup 2)] UNSPEC_FYL2X))
14390 (clobber (match_scratch:XF 3))])]
14391 "TARGET_USE_FANCY_MATH_387
14392 && flag_unsafe_math_optimizations"
14394 operands[2] = gen_reg_rtx (XFmode);
14395 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14398 (define_expand "log10<mode>2"
14399 [(use (match_operand:MODEF 0 "register_operand"))
14400 (use (match_operand:MODEF 1 "register_operand"))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14403 || TARGET_MIX_SSE_I387)
14404 && flag_unsafe_math_optimizations"
14406 rtx op0 = gen_reg_rtx (XFmode);
14408 rtx op2 = gen_reg_rtx (XFmode);
14409 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14411 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14412 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14416 (define_expand "log2xf2"
14417 [(parallel [(set (match_operand:XF 0 "register_operand")
14418 (unspec:XF [(match_operand:XF 1 "register_operand")
14419 (match_dup 2)] UNSPEC_FYL2X))
14420 (clobber (match_scratch:XF 3))])]
14421 "TARGET_USE_FANCY_MATH_387
14422 && flag_unsafe_math_optimizations"
14424 operands[2] = gen_reg_rtx (XFmode);
14425 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14428 (define_expand "log2<mode>2"
14429 [(use (match_operand:MODEF 0 "register_operand"))
14430 (use (match_operand:MODEF 1 "register_operand"))]
14431 "TARGET_USE_FANCY_MATH_387
14432 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14433 || TARGET_MIX_SSE_I387)
14434 && flag_unsafe_math_optimizations"
14436 rtx op0 = gen_reg_rtx (XFmode);
14438 rtx op2 = gen_reg_rtx (XFmode);
14439 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14441 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14446 (define_insn "fyl2xp1xf3_i387"
14447 [(set (match_operand:XF 0 "register_operand" "=f")
14448 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14449 (match_operand:XF 2 "register_operand" "u")]
14451 (clobber (match_scratch:XF 3 "=2"))]
14452 "TARGET_USE_FANCY_MATH_387
14453 && flag_unsafe_math_optimizations"
14455 [(set_attr "type" "fpspc")
14456 (set_attr "mode" "XF")])
14458 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14459 [(set (match_operand:XF 0 "register_operand" "=f")
14460 (unspec:XF [(float_extend:XF
14461 (match_operand:MODEF 1 "register_operand" "0"))
14462 (match_operand:XF 2 "register_operand" "u")]
14464 (clobber (match_scratch:XF 3 "=2"))]
14465 "TARGET_USE_FANCY_MATH_387
14466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14467 || TARGET_MIX_SSE_I387)
14468 && flag_unsafe_math_optimizations"
14470 [(set_attr "type" "fpspc")
14471 (set_attr "mode" "XF")])
14473 (define_expand "log1pxf2"
14474 [(use (match_operand:XF 0 "register_operand"))
14475 (use (match_operand:XF 1 "register_operand"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && flag_unsafe_math_optimizations"
14479 if (optimize_insn_for_size_p ())
14482 ix86_emit_i387_log1p (operands[0], operands[1]);
14486 (define_expand "log1p<mode>2"
14487 [(use (match_operand:MODEF 0 "register_operand"))
14488 (use (match_operand:MODEF 1 "register_operand"))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491 || TARGET_MIX_SSE_I387)
14492 && flag_unsafe_math_optimizations"
14496 if (optimize_insn_for_size_p ())
14499 op0 = gen_reg_rtx (XFmode);
14501 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14503 ix86_emit_i387_log1p (op0, operands[1]);
14504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14508 (define_insn "fxtractxf3_i387"
14509 [(set (match_operand:XF 0 "register_operand" "=f")
14510 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14511 UNSPEC_XTRACT_FRACT))
14512 (set (match_operand:XF 1 "register_operand" "=u")
14513 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations"
14517 [(set_attr "type" "fpspc")
14518 (set_attr "mode" "XF")])
14520 (define_insn "fxtract_extend<mode>xf3_i387"
14521 [(set (match_operand:XF 0 "register_operand" "=f")
14522 (unspec:XF [(float_extend:XF
14523 (match_operand:MODEF 2 "register_operand" "0"))]
14524 UNSPEC_XTRACT_FRACT))
14525 (set (match_operand:XF 1 "register_operand" "=u")
14526 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14527 "TARGET_USE_FANCY_MATH_387
14528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14529 || TARGET_MIX_SSE_I387)
14530 && flag_unsafe_math_optimizations"
14532 [(set_attr "type" "fpspc")
14533 (set_attr "mode" "XF")])
14535 (define_expand "logbxf2"
14536 [(parallel [(set (match_dup 2)
14537 (unspec:XF [(match_operand:XF 1 "register_operand")]
14538 UNSPEC_XTRACT_FRACT))
14539 (set (match_operand:XF 0 "register_operand")
14540 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14541 "TARGET_USE_FANCY_MATH_387
14542 && flag_unsafe_math_optimizations"
14543 "operands[2] = gen_reg_rtx (XFmode);")
14545 (define_expand "logb<mode>2"
14546 [(use (match_operand:MODEF 0 "register_operand"))
14547 (use (match_operand:MODEF 1 "register_operand"))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550 || TARGET_MIX_SSE_I387)
14551 && flag_unsafe_math_optimizations"
14553 rtx op0 = gen_reg_rtx (XFmode);
14554 rtx op1 = gen_reg_rtx (XFmode);
14556 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14557 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14561 (define_expand "ilogbxf2"
14562 [(use (match_operand:SI 0 "register_operand"))
14563 (use (match_operand:XF 1 "register_operand"))]
14564 "TARGET_USE_FANCY_MATH_387
14565 && flag_unsafe_math_optimizations"
14569 if (optimize_insn_for_size_p ())
14572 op0 = gen_reg_rtx (XFmode);
14573 op1 = gen_reg_rtx (XFmode);
14575 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14576 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14580 (define_expand "ilogb<mode>2"
14581 [(use (match_operand:SI 0 "register_operand"))
14582 (use (match_operand:MODEF 1 "register_operand"))]
14583 "TARGET_USE_FANCY_MATH_387
14584 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14585 || TARGET_MIX_SSE_I387)
14586 && flag_unsafe_math_optimizations"
14590 if (optimize_insn_for_size_p ())
14593 op0 = gen_reg_rtx (XFmode);
14594 op1 = gen_reg_rtx (XFmode);
14596 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14597 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14601 (define_insn "*f2xm1xf2_i387"
14602 [(set (match_operand:XF 0 "register_operand" "=f")
14603 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14605 "TARGET_USE_FANCY_MATH_387
14606 && flag_unsafe_math_optimizations"
14608 [(set_attr "type" "fpspc")
14609 (set_attr "mode" "XF")])
14611 (define_insn "fscalexf4_i387"
14612 [(set (match_operand:XF 0 "register_operand" "=f")
14613 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14614 (match_operand:XF 3 "register_operand" "1")]
14615 UNSPEC_FSCALE_FRACT))
14616 (set (match_operand:XF 1 "register_operand" "=u")
14617 (unspec:XF [(match_dup 2) (match_dup 3)]
14618 UNSPEC_FSCALE_EXP))]
14619 "TARGET_USE_FANCY_MATH_387
14620 && flag_unsafe_math_optimizations"
14622 [(set_attr "type" "fpspc")
14623 (set_attr "mode" "XF")])
14625 (define_expand "expNcorexf3"
14626 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14627 (match_operand:XF 2 "register_operand")))
14628 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14629 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14630 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14631 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14632 (parallel [(set (match_operand:XF 0 "register_operand")
14633 (unspec:XF [(match_dup 8) (match_dup 4)]
14634 UNSPEC_FSCALE_FRACT))
14636 (unspec:XF [(match_dup 8) (match_dup 4)]
14637 UNSPEC_FSCALE_EXP))])]
14638 "TARGET_USE_FANCY_MATH_387
14639 && flag_unsafe_math_optimizations"
14643 if (optimize_insn_for_size_p ())
14646 for (i = 3; i < 10; i++)
14647 operands[i] = gen_reg_rtx (XFmode);
14649 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14652 (define_expand "expxf2"
14653 [(use (match_operand:XF 0 "register_operand"))
14654 (use (match_operand:XF 1 "register_operand"))]
14655 "TARGET_USE_FANCY_MATH_387
14656 && flag_unsafe_math_optimizations"
14660 if (optimize_insn_for_size_p ())
14663 op2 = gen_reg_rtx (XFmode);
14664 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14666 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14670 (define_expand "exp<mode>2"
14671 [(use (match_operand:MODEF 0 "register_operand"))
14672 (use (match_operand:MODEF 1 "general_operand"))]
14673 "TARGET_USE_FANCY_MATH_387
14674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675 || TARGET_MIX_SSE_I387)
14676 && flag_unsafe_math_optimizations"
14680 if (optimize_insn_for_size_p ())
14683 op0 = gen_reg_rtx (XFmode);
14684 op1 = gen_reg_rtx (XFmode);
14686 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14687 emit_insn (gen_expxf2 (op0, op1));
14688 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14692 (define_expand "exp10xf2"
14693 [(use (match_operand:XF 0 "register_operand"))
14694 (use (match_operand:XF 1 "register_operand"))]
14695 "TARGET_USE_FANCY_MATH_387
14696 && flag_unsafe_math_optimizations"
14700 if (optimize_insn_for_size_p ())
14703 op2 = gen_reg_rtx (XFmode);
14704 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14706 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14710 (define_expand "exp10<mode>2"
14711 [(use (match_operand:MODEF 0 "register_operand"))
14712 (use (match_operand:MODEF 1 "general_operand"))]
14713 "TARGET_USE_FANCY_MATH_387
14714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14715 || TARGET_MIX_SSE_I387)
14716 && flag_unsafe_math_optimizations"
14720 if (optimize_insn_for_size_p ())
14723 op0 = gen_reg_rtx (XFmode);
14724 op1 = gen_reg_rtx (XFmode);
14726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14727 emit_insn (gen_exp10xf2 (op0, op1));
14728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14732 (define_expand "exp2xf2"
14733 [(use (match_operand:XF 0 "register_operand"))
14734 (use (match_operand:XF 1 "register_operand"))]
14735 "TARGET_USE_FANCY_MATH_387
14736 && flag_unsafe_math_optimizations"
14740 if (optimize_insn_for_size_p ())
14743 op2 = gen_reg_rtx (XFmode);
14744 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14746 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14750 (define_expand "exp2<mode>2"
14751 [(use (match_operand:MODEF 0 "register_operand"))
14752 (use (match_operand:MODEF 1 "general_operand"))]
14753 "TARGET_USE_FANCY_MATH_387
14754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14755 || TARGET_MIX_SSE_I387)
14756 && flag_unsafe_math_optimizations"
14760 if (optimize_insn_for_size_p ())
14763 op0 = gen_reg_rtx (XFmode);
14764 op1 = gen_reg_rtx (XFmode);
14766 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14767 emit_insn (gen_exp2xf2 (op0, op1));
14768 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14772 (define_expand "expm1xf2"
14773 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14775 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14776 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14777 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14778 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14779 (parallel [(set (match_dup 7)
14780 (unspec:XF [(match_dup 6) (match_dup 4)]
14781 UNSPEC_FSCALE_FRACT))
14783 (unspec:XF [(match_dup 6) (match_dup 4)]
14784 UNSPEC_FSCALE_EXP))])
14785 (parallel [(set (match_dup 10)
14786 (unspec:XF [(match_dup 9) (match_dup 8)]
14787 UNSPEC_FSCALE_FRACT))
14788 (set (match_dup 11)
14789 (unspec:XF [(match_dup 9) (match_dup 8)]
14790 UNSPEC_FSCALE_EXP))])
14791 (set (match_dup 12) (minus:XF (match_dup 10)
14792 (float_extend:XF (match_dup 13))))
14793 (set (match_operand:XF 0 "register_operand")
14794 (plus:XF (match_dup 12) (match_dup 7)))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14800 if (optimize_insn_for_size_p ())
14803 for (i = 2; i < 13; i++)
14804 operands[i] = gen_reg_rtx (XFmode);
14807 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14809 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14812 (define_expand "expm1<mode>2"
14813 [(use (match_operand:MODEF 0 "register_operand"))
14814 (use (match_operand:MODEF 1 "general_operand"))]
14815 "TARGET_USE_FANCY_MATH_387
14816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14817 || TARGET_MIX_SSE_I387)
14818 && flag_unsafe_math_optimizations"
14822 if (optimize_insn_for_size_p ())
14825 op0 = gen_reg_rtx (XFmode);
14826 op1 = gen_reg_rtx (XFmode);
14828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14829 emit_insn (gen_expm1xf2 (op0, op1));
14830 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14834 (define_expand "ldexpxf3"
14835 [(match_operand:XF 0 "register_operand")
14836 (match_operand:XF 1 "register_operand")
14837 (match_operand:SI 2 "register_operand")]
14838 "TARGET_USE_FANCY_MATH_387
14839 && flag_unsafe_math_optimizations"
14842 if (optimize_insn_for_size_p ())
14845 tmp1 = gen_reg_rtx (XFmode);
14846 tmp2 = gen_reg_rtx (XFmode);
14848 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14849 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14850 operands[1], tmp1));
14854 (define_expand "ldexp<mode>3"
14855 [(use (match_operand:MODEF 0 "register_operand"))
14856 (use (match_operand:MODEF 1 "general_operand"))
14857 (use (match_operand:SI 2 "register_operand"))]
14858 "TARGET_USE_FANCY_MATH_387
14859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14860 || TARGET_MIX_SSE_I387)
14861 && flag_unsafe_math_optimizations"
14865 if (optimize_insn_for_size_p ())
14868 op0 = gen_reg_rtx (XFmode);
14869 op1 = gen_reg_rtx (XFmode);
14871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14872 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14877 (define_expand "scalbxf3"
14878 [(parallel [(set (match_operand:XF 0 " register_operand")
14879 (unspec:XF [(match_operand:XF 1 "register_operand")
14880 (match_operand:XF 2 "register_operand")]
14881 UNSPEC_FSCALE_FRACT))
14883 (unspec:XF [(match_dup 1) (match_dup 2)]
14884 UNSPEC_FSCALE_EXP))])]
14885 "TARGET_USE_FANCY_MATH_387
14886 && flag_unsafe_math_optimizations"
14888 if (optimize_insn_for_size_p ())
14891 operands[3] = gen_reg_rtx (XFmode);
14894 (define_expand "scalb<mode>3"
14895 [(use (match_operand:MODEF 0 "register_operand"))
14896 (use (match_operand:MODEF 1 "general_operand"))
14897 (use (match_operand:MODEF 2 "general_operand"))]
14898 "TARGET_USE_FANCY_MATH_387
14899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14900 || TARGET_MIX_SSE_I387)
14901 && flag_unsafe_math_optimizations"
14905 if (optimize_insn_for_size_p ())
14908 op0 = gen_reg_rtx (XFmode);
14909 op1 = gen_reg_rtx (XFmode);
14910 op2 = gen_reg_rtx (XFmode);
14912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14913 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14914 emit_insn (gen_scalbxf3 (op0, op1, op2));
14915 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14919 (define_expand "significandxf2"
14920 [(parallel [(set (match_operand:XF 0 "register_operand")
14921 (unspec:XF [(match_operand:XF 1 "register_operand")]
14922 UNSPEC_XTRACT_FRACT))
14924 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14925 "TARGET_USE_FANCY_MATH_387
14926 && flag_unsafe_math_optimizations"
14927 "operands[2] = gen_reg_rtx (XFmode);")
14929 (define_expand "significand<mode>2"
14930 [(use (match_operand:MODEF 0 "register_operand"))
14931 (use (match_operand:MODEF 1 "register_operand"))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14934 || TARGET_MIX_SSE_I387)
14935 && flag_unsafe_math_optimizations"
14937 rtx op0 = gen_reg_rtx (XFmode);
14938 rtx op1 = gen_reg_rtx (XFmode);
14940 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14941 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14946 (define_insn "sse4_1_round<mode>2"
14947 [(set (match_operand:MODEF 0 "register_operand" "=x")
14948 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14949 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14952 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14953 [(set_attr "type" "ssecvt")
14954 (set_attr "prefix_extra" "1")
14955 (set_attr "prefix" "maybe_vex")
14956 (set_attr "mode" "<MODE>")])
14958 (define_insn "rintxf2"
14959 [(set (match_operand:XF 0 "register_operand" "=f")
14960 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14962 "TARGET_USE_FANCY_MATH_387
14963 && flag_unsafe_math_optimizations"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "XF")])
14968 (define_expand "rint<mode>2"
14969 [(use (match_operand:MODEF 0 "register_operand"))
14970 (use (match_operand:MODEF 1 "register_operand"))]
14971 "(TARGET_USE_FANCY_MATH_387
14972 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14973 || TARGET_MIX_SSE_I387)
14974 && flag_unsafe_math_optimizations)
14975 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14976 && !flag_trapping_math)"
14978 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14979 && !flag_trapping_math)
14982 emit_insn (gen_sse4_1_round<mode>2
14983 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14984 else if (optimize_insn_for_size_p ())
14987 ix86_expand_rint (operands[0], operands[1]);
14991 rtx op0 = gen_reg_rtx (XFmode);
14992 rtx op1 = gen_reg_rtx (XFmode);
14994 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14995 emit_insn (gen_rintxf2 (op0, op1));
14997 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15002 (define_expand "round<mode>2"
15003 [(match_operand:X87MODEF 0 "register_operand")
15004 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15005 "(TARGET_USE_FANCY_MATH_387
15006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15007 || TARGET_MIX_SSE_I387)
15008 && flag_unsafe_math_optimizations)
15009 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15010 && !flag_trapping_math && !flag_rounding_math)"
15012 if (optimize_insn_for_size_p ())
15015 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15016 && !flag_trapping_math && !flag_rounding_math)
15020 operands[1] = force_reg (<MODE>mode, operands[1]);
15021 ix86_expand_round_sse4 (operands[0], operands[1]);
15023 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15024 ix86_expand_round (operands[0], operands[1]);
15026 ix86_expand_rounddf_32 (operands[0], operands[1]);
15030 operands[1] = force_reg (<MODE>mode, operands[1]);
15031 ix86_emit_i387_round (operands[0], operands[1]);
15036 (define_insn_and_split "*fistdi2_1"
15037 [(set (match_operand:DI 0 "nonimmediate_operand")
15038 (unspec:DI [(match_operand:XF 1 "register_operand")]
15040 "TARGET_USE_FANCY_MATH_387
15041 && can_create_pseudo_p ()"
15046 if (memory_operand (operands[0], VOIDmode))
15047 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15050 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15051 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15056 [(set_attr "type" "fpspc")
15057 (set_attr "mode" "DI")])
15059 (define_insn "fistdi2"
15060 [(set (match_operand:DI 0 "memory_operand" "=m")
15061 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15063 (clobber (match_scratch:XF 2 "=&1f"))]
15064 "TARGET_USE_FANCY_MATH_387"
15065 "* return output_fix_trunc (insn, operands, false);"
15066 [(set_attr "type" "fpspc")
15067 (set_attr "mode" "DI")])
15069 (define_insn "fistdi2_with_temp"
15070 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15071 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15073 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15074 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15075 "TARGET_USE_FANCY_MATH_387"
15077 [(set_attr "type" "fpspc")
15078 (set_attr "mode" "DI")])
15081 [(set (match_operand:DI 0 "register_operand")
15082 (unspec:DI [(match_operand:XF 1 "register_operand")]
15084 (clobber (match_operand:DI 2 "memory_operand"))
15085 (clobber (match_scratch 3))]
15087 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15088 (clobber (match_dup 3))])
15089 (set (match_dup 0) (match_dup 2))])
15092 [(set (match_operand:DI 0 "memory_operand")
15093 (unspec:DI [(match_operand:XF 1 "register_operand")]
15095 (clobber (match_operand:DI 2 "memory_operand"))
15096 (clobber (match_scratch 3))]
15098 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15099 (clobber (match_dup 3))])])
15101 (define_insn_and_split "*fist<mode>2_1"
15102 [(set (match_operand:SWI24 0 "register_operand")
15103 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15105 "TARGET_USE_FANCY_MATH_387
15106 && can_create_pseudo_p ()"
15111 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15112 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15116 [(set_attr "type" "fpspc")
15117 (set_attr "mode" "<MODE>")])
15119 (define_insn "fist<mode>2"
15120 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15121 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15123 "TARGET_USE_FANCY_MATH_387"
15124 "* return output_fix_trunc (insn, operands, false);"
15125 [(set_attr "type" "fpspc")
15126 (set_attr "mode" "<MODE>")])
15128 (define_insn "fist<mode>2_with_temp"
15129 [(set (match_operand:SWI24 0 "register_operand" "=r")
15130 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15132 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15133 "TARGET_USE_FANCY_MATH_387"
15135 [(set_attr "type" "fpspc")
15136 (set_attr "mode" "<MODE>")])
15139 [(set (match_operand:SWI24 0 "register_operand")
15140 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15142 (clobber (match_operand:SWI24 2 "memory_operand"))]
15144 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15145 (set (match_dup 0) (match_dup 2))])
15148 [(set (match_operand:SWI24 0 "memory_operand")
15149 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15151 (clobber (match_operand:SWI24 2 "memory_operand"))]
15153 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15155 (define_expand "lrintxf<mode>2"
15156 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15157 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15159 "TARGET_USE_FANCY_MATH_387")
15161 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15162 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15163 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15164 UNSPEC_FIX_NOTRUNC))]
15165 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15167 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15168 [(match_operand:SWI248x 0 "nonimmediate_operand")
15169 (match_operand:X87MODEF 1 "register_operand")]
15170 "(TARGET_USE_FANCY_MATH_387
15171 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15172 || TARGET_MIX_SSE_I387)
15173 && flag_unsafe_math_optimizations)
15174 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15175 && <SWI248x:MODE>mode != HImode
15176 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15177 && !flag_trapping_math && !flag_rounding_math)"
15179 if (optimize_insn_for_size_p ())
15182 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15183 && <SWI248x:MODE>mode != HImode
15184 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15185 && !flag_trapping_math && !flag_rounding_math)
15186 ix86_expand_lround (operands[0], operands[1]);
15188 ix86_emit_i387_round (operands[0], operands[1]);
15192 (define_int_iterator FRNDINT_ROUNDING
15193 [UNSPEC_FRNDINT_FLOOR
15194 UNSPEC_FRNDINT_CEIL
15195 UNSPEC_FRNDINT_TRUNC])
15197 (define_int_iterator FIST_ROUNDING
15201 ;; Base name for define_insn
15202 (define_int_attr rounding_insn
15203 [(UNSPEC_FRNDINT_FLOOR "floor")
15204 (UNSPEC_FRNDINT_CEIL "ceil")
15205 (UNSPEC_FRNDINT_TRUNC "btrunc")
15206 (UNSPEC_FIST_FLOOR "floor")
15207 (UNSPEC_FIST_CEIL "ceil")])
15209 (define_int_attr rounding
15210 [(UNSPEC_FRNDINT_FLOOR "floor")
15211 (UNSPEC_FRNDINT_CEIL "ceil")
15212 (UNSPEC_FRNDINT_TRUNC "trunc")
15213 (UNSPEC_FIST_FLOOR "floor")
15214 (UNSPEC_FIST_CEIL "ceil")])
15216 (define_int_attr ROUNDING
15217 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15218 (UNSPEC_FRNDINT_CEIL "CEIL")
15219 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15220 (UNSPEC_FIST_FLOOR "FLOOR")
15221 (UNSPEC_FIST_CEIL "CEIL")])
15223 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15224 (define_insn_and_split "frndintxf2_<rounding>"
15225 [(set (match_operand:XF 0 "register_operand")
15226 (unspec:XF [(match_operand:XF 1 "register_operand")]
15228 (clobber (reg:CC FLAGS_REG))]
15229 "TARGET_USE_FANCY_MATH_387
15230 && flag_unsafe_math_optimizations
15231 && can_create_pseudo_p ()"
15236 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15238 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15239 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15241 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15242 operands[2], operands[3]));
15245 [(set_attr "type" "frndint")
15246 (set_attr "i387_cw" "<rounding>")
15247 (set_attr "mode" "XF")])
15249 (define_insn "frndintxf2_<rounding>_i387"
15250 [(set (match_operand:XF 0 "register_operand" "=f")
15251 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15253 (use (match_operand:HI 2 "memory_operand" "m"))
15254 (use (match_operand:HI 3 "memory_operand" "m"))]
15255 "TARGET_USE_FANCY_MATH_387
15256 && flag_unsafe_math_optimizations"
15257 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15258 [(set_attr "type" "frndint")
15259 (set_attr "i387_cw" "<rounding>")
15260 (set_attr "mode" "XF")])
15262 (define_expand "<rounding_insn>xf2"
15263 [(parallel [(set (match_operand:XF 0 "register_operand")
15264 (unspec:XF [(match_operand:XF 1 "register_operand")]
15266 (clobber (reg:CC FLAGS_REG))])]
15267 "TARGET_USE_FANCY_MATH_387
15268 && flag_unsafe_math_optimizations
15269 && !optimize_insn_for_size_p ()")
15271 (define_expand "<rounding_insn><mode>2"
15272 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15273 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15275 (clobber (reg:CC FLAGS_REG))])]
15276 "(TARGET_USE_FANCY_MATH_387
15277 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15278 || TARGET_MIX_SSE_I387)
15279 && flag_unsafe_math_optimizations)
15280 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15281 && !flag_trapping_math)"
15283 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15284 && !flag_trapping_math)
15287 emit_insn (gen_sse4_1_round<mode>2
15288 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15289 else if (optimize_insn_for_size_p ())
15291 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15293 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15294 ix86_expand_floorceil (operands[0], operands[1], true);
15295 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15296 ix86_expand_floorceil (operands[0], operands[1], false);
15297 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15298 ix86_expand_trunc (operands[0], operands[1]);
15300 gcc_unreachable ();
15304 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15305 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15306 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15307 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15308 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15309 ix86_expand_truncdf_32 (operands[0], operands[1]);
15311 gcc_unreachable ();
15318 if (optimize_insn_for_size_p ())
15321 op0 = gen_reg_rtx (XFmode);
15322 op1 = gen_reg_rtx (XFmode);
15323 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15324 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15326 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15331 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15332 (define_insn_and_split "frndintxf2_mask_pm"
15333 [(set (match_operand:XF 0 "register_operand")
15334 (unspec:XF [(match_operand:XF 1 "register_operand")]
15335 UNSPEC_FRNDINT_MASK_PM))
15336 (clobber (reg:CC FLAGS_REG))]
15337 "TARGET_USE_FANCY_MATH_387
15338 && flag_unsafe_math_optimizations
15339 && can_create_pseudo_p ()"
15344 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15346 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15347 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15349 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15350 operands[2], operands[3]));
15353 [(set_attr "type" "frndint")
15354 (set_attr "i387_cw" "mask_pm")
15355 (set_attr "mode" "XF")])
15357 (define_insn "frndintxf2_mask_pm_i387"
15358 [(set (match_operand:XF 0 "register_operand" "=f")
15359 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15360 UNSPEC_FRNDINT_MASK_PM))
15361 (use (match_operand:HI 2 "memory_operand" "m"))
15362 (use (match_operand:HI 3 "memory_operand" "m"))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations"
15365 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15366 [(set_attr "type" "frndint")
15367 (set_attr "i387_cw" "mask_pm")
15368 (set_attr "mode" "XF")])
15370 (define_expand "nearbyintxf2"
15371 [(parallel [(set (match_operand:XF 0 "register_operand")
15372 (unspec:XF [(match_operand:XF 1 "register_operand")]
15373 UNSPEC_FRNDINT_MASK_PM))
15374 (clobber (reg:CC FLAGS_REG))])]
15375 "TARGET_USE_FANCY_MATH_387
15376 && flag_unsafe_math_optimizations")
15378 (define_expand "nearbyint<mode>2"
15379 [(use (match_operand:MODEF 0 "register_operand"))
15380 (use (match_operand:MODEF 1 "register_operand"))]
15381 "TARGET_USE_FANCY_MATH_387
15382 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15383 || TARGET_MIX_SSE_I387)
15384 && flag_unsafe_math_optimizations"
15386 rtx op0 = gen_reg_rtx (XFmode);
15387 rtx op1 = gen_reg_rtx (XFmode);
15389 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15390 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15392 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15396 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15397 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15398 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15399 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15401 (clobber (reg:CC FLAGS_REG))]
15402 "TARGET_USE_FANCY_MATH_387
15403 && flag_unsafe_math_optimizations
15404 && can_create_pseudo_p ()"
15409 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15411 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15412 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15413 if (memory_operand (operands[0], VOIDmode))
15414 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15415 operands[2], operands[3]));
15418 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15419 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15420 (operands[0], operands[1], operands[2],
15421 operands[3], operands[4]));
15425 [(set_attr "type" "fistp")
15426 (set_attr "i387_cw" "<rounding>")
15427 (set_attr "mode" "<MODE>")])
15429 (define_insn "fistdi2_<rounding>"
15430 [(set (match_operand:DI 0 "memory_operand" "=m")
15431 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15433 (use (match_operand:HI 2 "memory_operand" "m"))
15434 (use (match_operand:HI 3 "memory_operand" "m"))
15435 (clobber (match_scratch:XF 4 "=&1f"))]
15436 "TARGET_USE_FANCY_MATH_387
15437 && flag_unsafe_math_optimizations"
15438 "* return output_fix_trunc (insn, operands, false);"
15439 [(set_attr "type" "fistp")
15440 (set_attr "i387_cw" "<rounding>")
15441 (set_attr "mode" "DI")])
15443 (define_insn "fistdi2_<rounding>_with_temp"
15444 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15445 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15447 (use (match_operand:HI 2 "memory_operand" "m,m"))
15448 (use (match_operand:HI 3 "memory_operand" "m,m"))
15449 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15450 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15451 "TARGET_USE_FANCY_MATH_387
15452 && flag_unsafe_math_optimizations"
15454 [(set_attr "type" "fistp")
15455 (set_attr "i387_cw" "<rounding>")
15456 (set_attr "mode" "DI")])
15459 [(set (match_operand:DI 0 "register_operand")
15460 (unspec:DI [(match_operand:XF 1 "register_operand")]
15462 (use (match_operand:HI 2 "memory_operand"))
15463 (use (match_operand:HI 3 "memory_operand"))
15464 (clobber (match_operand:DI 4 "memory_operand"))
15465 (clobber (match_scratch 5))]
15467 [(parallel [(set (match_dup 4)
15468 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15469 (use (match_dup 2))
15470 (use (match_dup 3))
15471 (clobber (match_dup 5))])
15472 (set (match_dup 0) (match_dup 4))])
15475 [(set (match_operand:DI 0 "memory_operand")
15476 (unspec:DI [(match_operand:XF 1 "register_operand")]
15478 (use (match_operand:HI 2 "memory_operand"))
15479 (use (match_operand:HI 3 "memory_operand"))
15480 (clobber (match_operand:DI 4 "memory_operand"))
15481 (clobber (match_scratch 5))]
15483 [(parallel [(set (match_dup 0)
15484 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15485 (use (match_dup 2))
15486 (use (match_dup 3))
15487 (clobber (match_dup 5))])])
15489 (define_insn "fist<mode>2_<rounding>"
15490 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15491 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15493 (use (match_operand:HI 2 "memory_operand" "m"))
15494 (use (match_operand:HI 3 "memory_operand" "m"))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && flag_unsafe_math_optimizations"
15497 "* return output_fix_trunc (insn, operands, false);"
15498 [(set_attr "type" "fistp")
15499 (set_attr "i387_cw" "<rounding>")
15500 (set_attr "mode" "<MODE>")])
15502 (define_insn "fist<mode>2_<rounding>_with_temp"
15503 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15504 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15506 (use (match_operand:HI 2 "memory_operand" "m,m"))
15507 (use (match_operand:HI 3 "memory_operand" "m,m"))
15508 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15509 "TARGET_USE_FANCY_MATH_387
15510 && flag_unsafe_math_optimizations"
15512 [(set_attr "type" "fistp")
15513 (set_attr "i387_cw" "<rounding>")
15514 (set_attr "mode" "<MODE>")])
15517 [(set (match_operand:SWI24 0 "register_operand")
15518 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15520 (use (match_operand:HI 2 "memory_operand"))
15521 (use (match_operand:HI 3 "memory_operand"))
15522 (clobber (match_operand:SWI24 4 "memory_operand"))]
15524 [(parallel [(set (match_dup 4)
15525 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15526 (use (match_dup 2))
15527 (use (match_dup 3))])
15528 (set (match_dup 0) (match_dup 4))])
15531 [(set (match_operand:SWI24 0 "memory_operand")
15532 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15534 (use (match_operand:HI 2 "memory_operand"))
15535 (use (match_operand:HI 3 "memory_operand"))
15536 (clobber (match_operand:SWI24 4 "memory_operand"))]
15538 [(parallel [(set (match_dup 0)
15539 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15540 (use (match_dup 2))
15541 (use (match_dup 3))])])
15543 (define_expand "l<rounding_insn>xf<mode>2"
15544 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15545 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15547 (clobber (reg:CC FLAGS_REG))])]
15548 "TARGET_USE_FANCY_MATH_387
15549 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15550 && flag_unsafe_math_optimizations")
15552 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15553 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15554 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15556 (clobber (reg:CC FLAGS_REG))])]
15557 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15558 && !flag_trapping_math"
15560 if (TARGET_64BIT && optimize_insn_for_size_p ())
15563 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15564 ix86_expand_lfloorceil (operands[0], operands[1], true);
15565 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15566 ix86_expand_lfloorceil (operands[0], operands[1], false);
15568 gcc_unreachable ();
15573 (define_insn "fxam<mode>2_i387"
15574 [(set (match_operand:HI 0 "register_operand" "=a")
15576 [(match_operand:X87MODEF 1 "register_operand" "f")]
15578 "TARGET_USE_FANCY_MATH_387"
15579 "fxam\n\tfnstsw\t%0"
15580 [(set_attr "type" "multi")
15581 (set_attr "length" "4")
15582 (set_attr "unit" "i387")
15583 (set_attr "mode" "<MODE>")])
15585 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15586 [(set (match_operand:HI 0 "register_operand")
15588 [(match_operand:MODEF 1 "memory_operand")]
15590 "TARGET_USE_FANCY_MATH_387
15591 && can_create_pseudo_p ()"
15594 [(set (match_dup 2)(match_dup 1))
15596 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15598 operands[2] = gen_reg_rtx (<MODE>mode);
15600 MEM_VOLATILE_P (operands[1]) = 1;
15602 [(set_attr "type" "multi")
15603 (set_attr "unit" "i387")
15604 (set_attr "mode" "<MODE>")])
15606 (define_expand "isinfxf2"
15607 [(use (match_operand:SI 0 "register_operand"))
15608 (use (match_operand:XF 1 "register_operand"))]
15609 "TARGET_USE_FANCY_MATH_387
15610 && ix86_libc_has_function (function_c99_misc)"
15612 rtx mask = GEN_INT (0x45);
15613 rtx val = GEN_INT (0x05);
15617 rtx scratch = gen_reg_rtx (HImode);
15618 rtx res = gen_reg_rtx (QImode);
15620 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15622 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15623 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15624 cond = gen_rtx_fmt_ee (EQ, QImode,
15625 gen_rtx_REG (CCmode, FLAGS_REG),
15627 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15628 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15632 (define_expand "isinf<mode>2"
15633 [(use (match_operand:SI 0 "register_operand"))
15634 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15635 "TARGET_USE_FANCY_MATH_387
15636 && ix86_libc_has_function (function_c99_misc)
15637 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15639 rtx mask = GEN_INT (0x45);
15640 rtx val = GEN_INT (0x05);
15644 rtx scratch = gen_reg_rtx (HImode);
15645 rtx res = gen_reg_rtx (QImode);
15647 /* Remove excess precision by forcing value through memory. */
15648 if (memory_operand (operands[1], VOIDmode))
15649 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15652 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15654 emit_move_insn (temp, operands[1]);
15655 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15658 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15659 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15660 cond = gen_rtx_fmt_ee (EQ, QImode,
15661 gen_rtx_REG (CCmode, FLAGS_REG),
15663 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15664 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15668 (define_expand "signbitxf2"
15669 [(use (match_operand:SI 0 "register_operand"))
15670 (use (match_operand:XF 1 "register_operand"))]
15671 "TARGET_USE_FANCY_MATH_387"
15673 rtx scratch = gen_reg_rtx (HImode);
15675 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15676 emit_insn (gen_andsi3 (operands[0],
15677 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15681 (define_insn "movmsk_df"
15682 [(set (match_operand:SI 0 "register_operand" "=r")
15684 [(match_operand:DF 1 "register_operand" "x")]
15686 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15687 "%vmovmskpd\t{%1, %0|%0, %1}"
15688 [(set_attr "type" "ssemov")
15689 (set_attr "prefix" "maybe_vex")
15690 (set_attr "mode" "DF")])
15692 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15693 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15694 (define_expand "signbitdf2"
15695 [(use (match_operand:SI 0 "register_operand"))
15696 (use (match_operand:DF 1 "register_operand"))]
15697 "TARGET_USE_FANCY_MATH_387
15698 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15700 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15702 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15703 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15707 rtx scratch = gen_reg_rtx (HImode);
15709 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15710 emit_insn (gen_andsi3 (operands[0],
15711 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15716 (define_expand "signbitsf2"
15717 [(use (match_operand:SI 0 "register_operand"))
15718 (use (match_operand:SF 1 "register_operand"))]
15719 "TARGET_USE_FANCY_MATH_387
15720 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15722 rtx scratch = gen_reg_rtx (HImode);
15724 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15725 emit_insn (gen_andsi3 (operands[0],
15726 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15730 ;; Block operation instructions
15733 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15736 [(set_attr "length" "1")
15737 (set_attr "length_immediate" "0")
15738 (set_attr "modrm" "0")])
15740 (define_expand "movmem<mode>"
15741 [(use (match_operand:BLK 0 "memory_operand"))
15742 (use (match_operand:BLK 1 "memory_operand"))
15743 (use (match_operand:SWI48 2 "nonmemory_operand"))
15744 (use (match_operand:SWI48 3 "const_int_operand"))
15745 (use (match_operand:SI 4 "const_int_operand"))
15746 (use (match_operand:SI 5 "const_int_operand"))
15747 (use (match_operand:SI 6 ""))
15748 (use (match_operand:SI 7 ""))
15749 (use (match_operand:SI 8 ""))]
15752 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15753 operands[2], NULL, operands[3],
15754 operands[4], operands[5],
15755 operands[6], operands[7],
15756 operands[8], false))
15762 ;; Most CPUs don't like single string operations
15763 ;; Handle this case here to simplify previous expander.
15765 (define_expand "strmov"
15766 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15767 (set (match_operand 1 "memory_operand") (match_dup 4))
15768 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15769 (clobber (reg:CC FLAGS_REG))])
15770 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15771 (clobber (reg:CC FLAGS_REG))])]
15774 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15776 /* If .md ever supports :P for Pmode, these can be directly
15777 in the pattern above. */
15778 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15779 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15781 /* Can't use this if the user has appropriated esi or edi. */
15782 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15783 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15785 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15786 operands[2], operands[3],
15787 operands[5], operands[6]));
15791 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15794 (define_expand "strmov_singleop"
15795 [(parallel [(set (match_operand 1 "memory_operand")
15796 (match_operand 3 "memory_operand"))
15797 (set (match_operand 0 "register_operand")
15799 (set (match_operand 2 "register_operand")
15800 (match_operand 5))])]
15802 "ix86_current_function_needs_cld = 1;")
15804 (define_insn "*strmovdi_rex_1"
15805 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15806 (mem:DI (match_operand:P 3 "register_operand" "1")))
15807 (set (match_operand:P 0 "register_operand" "=D")
15808 (plus:P (match_dup 2)
15810 (set (match_operand:P 1 "register_operand" "=S")
15811 (plus:P (match_dup 3)
15814 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15816 [(set_attr "type" "str")
15817 (set_attr "memory" "both")
15818 (set_attr "mode" "DI")])
15820 (define_insn "*strmovsi_1"
15821 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15822 (mem:SI (match_operand:P 3 "register_operand" "1")))
15823 (set (match_operand:P 0 "register_operand" "=D")
15824 (plus:P (match_dup 2)
15826 (set (match_operand:P 1 "register_operand" "=S")
15827 (plus:P (match_dup 3)
15829 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15831 [(set_attr "type" "str")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "SI")])
15835 (define_insn "*strmovhi_1"
15836 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15837 (mem:HI (match_operand:P 3 "register_operand" "1")))
15838 (set (match_operand:P 0 "register_operand" "=D")
15839 (plus:P (match_dup 2)
15841 (set (match_operand:P 1 "register_operand" "=S")
15842 (plus:P (match_dup 3)
15844 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15846 [(set_attr "type" "str")
15847 (set_attr "memory" "both")
15848 (set_attr "mode" "HI")])
15850 (define_insn "*strmovqi_1"
15851 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15852 (mem:QI (match_operand:P 3 "register_operand" "1")))
15853 (set (match_operand:P 0 "register_operand" "=D")
15854 (plus:P (match_dup 2)
15856 (set (match_operand:P 1 "register_operand" "=S")
15857 (plus:P (match_dup 3)
15859 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15861 [(set_attr "type" "str")
15862 (set_attr "memory" "both")
15863 (set (attr "prefix_rex")
15865 (match_test "<P:MODE>mode == DImode")
15867 (const_string "*")))
15868 (set_attr "mode" "QI")])
15870 (define_expand "rep_mov"
15871 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15872 (set (match_operand 0 "register_operand")
15874 (set (match_operand 2 "register_operand")
15876 (set (match_operand 1 "memory_operand")
15877 (match_operand 3 "memory_operand"))
15878 (use (match_dup 4))])]
15880 "ix86_current_function_needs_cld = 1;")
15882 (define_insn "*rep_movdi_rex64"
15883 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15884 (set (match_operand:P 0 "register_operand" "=D")
15885 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15887 (match_operand:P 3 "register_operand" "0")))
15888 (set (match_operand:P 1 "register_operand" "=S")
15889 (plus:P (ashift:P (match_dup 5) (const_int 3))
15890 (match_operand:P 4 "register_operand" "1")))
15891 (set (mem:BLK (match_dup 3))
15892 (mem:BLK (match_dup 4)))
15893 (use (match_dup 5))]
15895 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15897 [(set_attr "type" "str")
15898 (set_attr "prefix_rep" "1")
15899 (set_attr "memory" "both")
15900 (set_attr "mode" "DI")])
15902 (define_insn "*rep_movsi"
15903 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15904 (set (match_operand:P 0 "register_operand" "=D")
15905 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15907 (match_operand:P 3 "register_operand" "0")))
15908 (set (match_operand:P 1 "register_operand" "=S")
15909 (plus:P (ashift:P (match_dup 5) (const_int 2))
15910 (match_operand:P 4 "register_operand" "1")))
15911 (set (mem:BLK (match_dup 3))
15912 (mem:BLK (match_dup 4)))
15913 (use (match_dup 5))]
15914 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15915 "%^rep{%;} movs{l|d}"
15916 [(set_attr "type" "str")
15917 (set_attr "prefix_rep" "1")
15918 (set_attr "memory" "both")
15919 (set_attr "mode" "SI")])
15921 (define_insn "*rep_movqi"
15922 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15923 (set (match_operand:P 0 "register_operand" "=D")
15924 (plus:P (match_operand:P 3 "register_operand" "0")
15925 (match_operand:P 5 "register_operand" "2")))
15926 (set (match_operand:P 1 "register_operand" "=S")
15927 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15928 (set (mem:BLK (match_dup 3))
15929 (mem:BLK (match_dup 4)))
15930 (use (match_dup 5))]
15931 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15933 [(set_attr "type" "str")
15934 (set_attr "prefix_rep" "1")
15935 (set_attr "memory" "both")
15936 (set_attr "mode" "QI")])
15938 (define_expand "setmem<mode>"
15939 [(use (match_operand:BLK 0 "memory_operand"))
15940 (use (match_operand:SWI48 1 "nonmemory_operand"))
15941 (use (match_operand:QI 2 "nonmemory_operand"))
15942 (use (match_operand 3 "const_int_operand"))
15943 (use (match_operand:SI 4 "const_int_operand"))
15944 (use (match_operand:SI 5 "const_int_operand"))
15945 (use (match_operand:SI 6 ""))
15946 (use (match_operand:SI 7 ""))
15947 (use (match_operand:SI 8 ""))]
15950 if (ix86_expand_set_or_movmem (operands[0], NULL,
15951 operands[1], operands[2],
15952 operands[3], operands[4],
15953 operands[5], operands[6],
15954 operands[7], operands[8], true))
15960 ;; Most CPUs don't like single string operations
15961 ;; Handle this case here to simplify previous expander.
15963 (define_expand "strset"
15964 [(set (match_operand 1 "memory_operand")
15965 (match_operand 2 "register_operand"))
15966 (parallel [(set (match_operand 0 "register_operand")
15968 (clobber (reg:CC FLAGS_REG))])]
15971 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15972 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15974 /* If .md ever supports :P for Pmode, this can be directly
15975 in the pattern above. */
15976 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15977 GEN_INT (GET_MODE_SIZE (GET_MODE
15979 /* Can't use this if the user has appropriated eax or edi. */
15980 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15981 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15983 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15989 (define_expand "strset_singleop"
15990 [(parallel [(set (match_operand 1 "memory_operand")
15991 (match_operand 2 "register_operand"))
15992 (set (match_operand 0 "register_operand")
15994 (unspec [(const_int 0)] UNSPEC_STOS)])]
15996 "ix86_current_function_needs_cld = 1;")
15998 (define_insn "*strsetdi_rex_1"
15999 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16000 (match_operand:DI 2 "register_operand" "a"))
16001 (set (match_operand:P 0 "register_operand" "=D")
16002 (plus:P (match_dup 1)
16004 (unspec [(const_int 0)] UNSPEC_STOS)]
16006 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16008 [(set_attr "type" "str")
16009 (set_attr "memory" "store")
16010 (set_attr "mode" "DI")])
16012 (define_insn "*strsetsi_1"
16013 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16014 (match_operand:SI 2 "register_operand" "a"))
16015 (set (match_operand:P 0 "register_operand" "=D")
16016 (plus:P (match_dup 1)
16018 (unspec [(const_int 0)] UNSPEC_STOS)]
16019 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16021 [(set_attr "type" "str")
16022 (set_attr "memory" "store")
16023 (set_attr "mode" "SI")])
16025 (define_insn "*strsethi_1"
16026 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16027 (match_operand:HI 2 "register_operand" "a"))
16028 (set (match_operand:P 0 "register_operand" "=D")
16029 (plus:P (match_dup 1)
16031 (unspec [(const_int 0)] UNSPEC_STOS)]
16032 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16034 [(set_attr "type" "str")
16035 (set_attr "memory" "store")
16036 (set_attr "mode" "HI")])
16038 (define_insn "*strsetqi_1"
16039 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16040 (match_operand:QI 2 "register_operand" "a"))
16041 (set (match_operand:P 0 "register_operand" "=D")
16042 (plus:P (match_dup 1)
16044 (unspec [(const_int 0)] UNSPEC_STOS)]
16045 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16047 [(set_attr "type" "str")
16048 (set_attr "memory" "store")
16049 (set (attr "prefix_rex")
16051 (match_test "<P:MODE>mode == DImode")
16053 (const_string "*")))
16054 (set_attr "mode" "QI")])
16056 (define_expand "rep_stos"
16057 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16058 (set (match_operand 0 "register_operand")
16060 (set (match_operand 2 "memory_operand") (const_int 0))
16061 (use (match_operand 3 "register_operand"))
16062 (use (match_dup 1))])]
16064 "ix86_current_function_needs_cld = 1;")
16066 (define_insn "*rep_stosdi_rex64"
16067 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16068 (set (match_operand:P 0 "register_operand" "=D")
16069 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16071 (match_operand:P 3 "register_operand" "0")))
16072 (set (mem:BLK (match_dup 3))
16074 (use (match_operand:DI 2 "register_operand" "a"))
16075 (use (match_dup 4))]
16077 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16079 [(set_attr "type" "str")
16080 (set_attr "prefix_rep" "1")
16081 (set_attr "memory" "store")
16082 (set_attr "mode" "DI")])
16084 (define_insn "*rep_stossi"
16085 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16086 (set (match_operand:P 0 "register_operand" "=D")
16087 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16089 (match_operand:P 3 "register_operand" "0")))
16090 (set (mem:BLK (match_dup 3))
16092 (use (match_operand:SI 2 "register_operand" "a"))
16093 (use (match_dup 4))]
16094 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16095 "%^rep{%;} stos{l|d}"
16096 [(set_attr "type" "str")
16097 (set_attr "prefix_rep" "1")
16098 (set_attr "memory" "store")
16099 (set_attr "mode" "SI")])
16101 (define_insn "*rep_stosqi"
16102 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16103 (set (match_operand:P 0 "register_operand" "=D")
16104 (plus:P (match_operand:P 3 "register_operand" "0")
16105 (match_operand:P 4 "register_operand" "1")))
16106 (set (mem:BLK (match_dup 3))
16108 (use (match_operand:QI 2 "register_operand" "a"))
16109 (use (match_dup 4))]
16110 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16112 [(set_attr "type" "str")
16113 (set_attr "prefix_rep" "1")
16114 (set_attr "memory" "store")
16115 (set (attr "prefix_rex")
16117 (match_test "<P:MODE>mode == DImode")
16119 (const_string "*")))
16120 (set_attr "mode" "QI")])
16122 (define_expand "cmpstrnsi"
16123 [(set (match_operand:SI 0 "register_operand")
16124 (compare:SI (match_operand:BLK 1 "general_operand")
16125 (match_operand:BLK 2 "general_operand")))
16126 (use (match_operand 3 "general_operand"))
16127 (use (match_operand 4 "immediate_operand"))]
16130 rtx addr1, addr2, out, outlow, count, countreg, align;
16132 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16135 /* Can't use this if the user has appropriated ecx, esi or edi. */
16136 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16141 out = gen_reg_rtx (SImode);
16143 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16144 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16145 if (addr1 != XEXP (operands[1], 0))
16146 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16147 if (addr2 != XEXP (operands[2], 0))
16148 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16150 count = operands[3];
16151 countreg = ix86_zero_extend_to_Pmode (count);
16153 /* %%% Iff we are testing strict equality, we can use known alignment
16154 to good advantage. This may be possible with combine, particularly
16155 once cc0 is dead. */
16156 align = operands[4];
16158 if (CONST_INT_P (count))
16160 if (INTVAL (count) == 0)
16162 emit_move_insn (operands[0], const0_rtx);
16165 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16166 operands[1], operands[2]));
16170 rtx (*gen_cmp) (rtx, rtx);
16172 gen_cmp = (TARGET_64BIT
16173 ? gen_cmpdi_1 : gen_cmpsi_1);
16175 emit_insn (gen_cmp (countreg, countreg));
16176 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16177 operands[1], operands[2]));
16180 outlow = gen_lowpart (QImode, out);
16181 emit_insn (gen_cmpintqi (outlow));
16182 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16184 if (operands[0] != out)
16185 emit_move_insn (operands[0], out);
16190 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16192 (define_expand "cmpintqi"
16193 [(set (match_dup 1)
16194 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16196 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16197 (parallel [(set (match_operand:QI 0 "register_operand")
16198 (minus:QI (match_dup 1)
16200 (clobber (reg:CC FLAGS_REG))])]
16203 operands[1] = gen_reg_rtx (QImode);
16204 operands[2] = gen_reg_rtx (QImode);
16207 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16208 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16210 (define_expand "cmpstrnqi_nz_1"
16211 [(parallel [(set (reg:CC FLAGS_REG)
16212 (compare:CC (match_operand 4 "memory_operand")
16213 (match_operand 5 "memory_operand")))
16214 (use (match_operand 2 "register_operand"))
16215 (use (match_operand:SI 3 "immediate_operand"))
16216 (clobber (match_operand 0 "register_operand"))
16217 (clobber (match_operand 1 "register_operand"))
16218 (clobber (match_dup 2))])]
16220 "ix86_current_function_needs_cld = 1;")
16222 (define_insn "*cmpstrnqi_nz_1"
16223 [(set (reg:CC FLAGS_REG)
16224 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16225 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16226 (use (match_operand:P 6 "register_operand" "2"))
16227 (use (match_operand:SI 3 "immediate_operand" "i"))
16228 (clobber (match_operand:P 0 "register_operand" "=S"))
16229 (clobber (match_operand:P 1 "register_operand" "=D"))
16230 (clobber (match_operand:P 2 "register_operand" "=c"))]
16231 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16233 [(set_attr "type" "str")
16234 (set_attr "mode" "QI")
16235 (set (attr "prefix_rex")
16237 (match_test "<P:MODE>mode == DImode")
16239 (const_string "*")))
16240 (set_attr "prefix_rep" "1")])
16242 ;; The same, but the count is not known to not be zero.
16244 (define_expand "cmpstrnqi_1"
16245 [(parallel [(set (reg:CC FLAGS_REG)
16246 (if_then_else:CC (ne (match_operand 2 "register_operand")
16248 (compare:CC (match_operand 4 "memory_operand")
16249 (match_operand 5 "memory_operand"))
16251 (use (match_operand:SI 3 "immediate_operand"))
16252 (use (reg:CC FLAGS_REG))
16253 (clobber (match_operand 0 "register_operand"))
16254 (clobber (match_operand 1 "register_operand"))
16255 (clobber (match_dup 2))])]
16257 "ix86_current_function_needs_cld = 1;")
16259 (define_insn "*cmpstrnqi_1"
16260 [(set (reg:CC FLAGS_REG)
16261 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16263 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16264 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16266 (use (match_operand:SI 3 "immediate_operand" "i"))
16267 (use (reg:CC FLAGS_REG))
16268 (clobber (match_operand:P 0 "register_operand" "=S"))
16269 (clobber (match_operand:P 1 "register_operand" "=D"))
16270 (clobber (match_operand:P 2 "register_operand" "=c"))]
16271 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16273 [(set_attr "type" "str")
16274 (set_attr "mode" "QI")
16275 (set (attr "prefix_rex")
16277 (match_test "<P:MODE>mode == DImode")
16279 (const_string "*")))
16280 (set_attr "prefix_rep" "1")])
16282 (define_expand "strlen<mode>"
16283 [(set (match_operand:P 0 "register_operand")
16284 (unspec:P [(match_operand:BLK 1 "general_operand")
16285 (match_operand:QI 2 "immediate_operand")
16286 (match_operand 3 "immediate_operand")]
16290 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16296 (define_expand "strlenqi_1"
16297 [(parallel [(set (match_operand 0 "register_operand")
16299 (clobber (match_operand 1 "register_operand"))
16300 (clobber (reg:CC FLAGS_REG))])]
16302 "ix86_current_function_needs_cld = 1;")
16304 (define_insn "*strlenqi_1"
16305 [(set (match_operand:P 0 "register_operand" "=&c")
16306 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16307 (match_operand:QI 2 "register_operand" "a")
16308 (match_operand:P 3 "immediate_operand" "i")
16309 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16310 (clobber (match_operand:P 1 "register_operand" "=D"))
16311 (clobber (reg:CC FLAGS_REG))]
16312 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16313 "%^repnz{%;} scasb"
16314 [(set_attr "type" "str")
16315 (set_attr "mode" "QI")
16316 (set (attr "prefix_rex")
16318 (match_test "<P:MODE>mode == DImode")
16320 (const_string "*")))
16321 (set_attr "prefix_rep" "1")])
16323 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16324 ;; handled in combine, but it is not currently up to the task.
16325 ;; When used for their truth value, the cmpstrn* expanders generate
16334 ;; The intermediate three instructions are unnecessary.
16336 ;; This one handles cmpstrn*_nz_1...
16339 (set (reg:CC FLAGS_REG)
16340 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16341 (mem:BLK (match_operand 5 "register_operand"))))
16342 (use (match_operand 6 "register_operand"))
16343 (use (match_operand:SI 3 "immediate_operand"))
16344 (clobber (match_operand 0 "register_operand"))
16345 (clobber (match_operand 1 "register_operand"))
16346 (clobber (match_operand 2 "register_operand"))])
16347 (set (match_operand:QI 7 "register_operand")
16348 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16349 (set (match_operand:QI 8 "register_operand")
16350 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16351 (set (reg FLAGS_REG)
16352 (compare (match_dup 7) (match_dup 8)))
16354 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16356 (set (reg:CC FLAGS_REG)
16357 (compare:CC (mem:BLK (match_dup 4))
16358 (mem:BLK (match_dup 5))))
16359 (use (match_dup 6))
16360 (use (match_dup 3))
16361 (clobber (match_dup 0))
16362 (clobber (match_dup 1))
16363 (clobber (match_dup 2))])])
16365 ;; ...and this one handles cmpstrn*_1.
16368 (set (reg:CC FLAGS_REG)
16369 (if_then_else:CC (ne (match_operand 6 "register_operand")
16371 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16372 (mem:BLK (match_operand 5 "register_operand")))
16374 (use (match_operand:SI 3 "immediate_operand"))
16375 (use (reg:CC FLAGS_REG))
16376 (clobber (match_operand 0 "register_operand"))
16377 (clobber (match_operand 1 "register_operand"))
16378 (clobber (match_operand 2 "register_operand"))])
16379 (set (match_operand:QI 7 "register_operand")
16380 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16381 (set (match_operand:QI 8 "register_operand")
16382 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16383 (set (reg FLAGS_REG)
16384 (compare (match_dup 7) (match_dup 8)))
16386 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16388 (set (reg:CC FLAGS_REG)
16389 (if_then_else:CC (ne (match_dup 6)
16391 (compare:CC (mem:BLK (match_dup 4))
16392 (mem:BLK (match_dup 5)))
16394 (use (match_dup 3))
16395 (use (reg:CC FLAGS_REG))
16396 (clobber (match_dup 0))
16397 (clobber (match_dup 1))
16398 (clobber (match_dup 2))])])
16400 ;; Conditional move instructions.
16402 (define_expand "mov<mode>cc"
16403 [(set (match_operand:SWIM 0 "register_operand")
16404 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16405 (match_operand:SWIM 2 "<general_operand>")
16406 (match_operand:SWIM 3 "<general_operand>")))]
16408 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16410 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16411 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16412 ;; So just document what we're doing explicitly.
16414 (define_expand "x86_mov<mode>cc_0_m1"
16416 [(set (match_operand:SWI48 0 "register_operand")
16417 (if_then_else:SWI48
16418 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16419 [(match_operand 1 "flags_reg_operand")
16423 (clobber (reg:CC FLAGS_REG))])])
16425 (define_insn "*x86_mov<mode>cc_0_m1"
16426 [(set (match_operand:SWI48 0 "register_operand" "=r")
16427 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16428 [(reg FLAGS_REG) (const_int 0)])
16431 (clobber (reg:CC FLAGS_REG))]
16433 "sbb{<imodesuffix>}\t%0, %0"
16434 ; Since we don't have the proper number of operands for an alu insn,
16435 ; fill in all the blanks.
16436 [(set_attr "type" "alu")
16437 (set_attr "use_carry" "1")
16438 (set_attr "pent_pair" "pu")
16439 (set_attr "memory" "none")
16440 (set_attr "imm_disp" "false")
16441 (set_attr "mode" "<MODE>")
16442 (set_attr "length_immediate" "0")])
16444 (define_insn "*x86_mov<mode>cc_0_m1_se"
16445 [(set (match_operand:SWI48 0 "register_operand" "=r")
16446 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16447 [(reg FLAGS_REG) (const_int 0)])
16450 (clobber (reg:CC FLAGS_REG))]
16452 "sbb{<imodesuffix>}\t%0, %0"
16453 [(set_attr "type" "alu")
16454 (set_attr "use_carry" "1")
16455 (set_attr "pent_pair" "pu")
16456 (set_attr "memory" "none")
16457 (set_attr "imm_disp" "false")
16458 (set_attr "mode" "<MODE>")
16459 (set_attr "length_immediate" "0")])
16461 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16462 [(set (match_operand:SWI48 0 "register_operand" "=r")
16463 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16464 [(reg FLAGS_REG) (const_int 0)])))
16465 (clobber (reg:CC FLAGS_REG))]
16467 "sbb{<imodesuffix>}\t%0, %0"
16468 [(set_attr "type" "alu")
16469 (set_attr "use_carry" "1")
16470 (set_attr "pent_pair" "pu")
16471 (set_attr "memory" "none")
16472 (set_attr "imm_disp" "false")
16473 (set_attr "mode" "<MODE>")
16474 (set_attr "length_immediate" "0")])
16476 (define_insn "*mov<mode>cc_noc"
16477 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16478 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16479 [(reg FLAGS_REG) (const_int 0)])
16480 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16481 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16482 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16484 cmov%O2%C1\t{%2, %0|%0, %2}
16485 cmov%O2%c1\t{%3, %0|%0, %3}"
16486 [(set_attr "type" "icmov")
16487 (set_attr "mode" "<MODE>")])
16489 ;; Don't do conditional moves with memory inputs. This splitter helps
16490 ;; register starved x86_32 by forcing inputs into registers before reload.
16492 [(set (match_operand:SWI248 0 "register_operand")
16493 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16494 [(reg FLAGS_REG) (const_int 0)])
16495 (match_operand:SWI248 2 "nonimmediate_operand")
16496 (match_operand:SWI248 3 "nonimmediate_operand")))]
16497 "!TARGET_64BIT && TARGET_CMOVE
16498 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16499 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16500 && can_create_pseudo_p ()
16501 && optimize_insn_for_speed_p ()"
16502 [(set (match_dup 0)
16503 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16505 if (MEM_P (operands[2]))
16506 operands[2] = force_reg (<MODE>mode, operands[2]);
16507 if (MEM_P (operands[3]))
16508 operands[3] = force_reg (<MODE>mode, operands[3]);
16511 (define_insn "*movqicc_noc"
16512 [(set (match_operand:QI 0 "register_operand" "=r,r")
16513 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16514 [(reg FLAGS_REG) (const_int 0)])
16515 (match_operand:QI 2 "register_operand" "r,0")
16516 (match_operand:QI 3 "register_operand" "0,r")))]
16517 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16519 [(set_attr "type" "icmov")
16520 (set_attr "mode" "QI")])
16523 [(set (match_operand:SWI12 0 "register_operand")
16524 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16525 [(reg FLAGS_REG) (const_int 0)])
16526 (match_operand:SWI12 2 "register_operand")
16527 (match_operand:SWI12 3 "register_operand")))]
16528 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16529 && reload_completed"
16530 [(set (match_dup 0)
16531 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16533 operands[0] = gen_lowpart (SImode, operands[0]);
16534 operands[2] = gen_lowpart (SImode, operands[2]);
16535 operands[3] = gen_lowpart (SImode, operands[3]);
16538 ;; Don't do conditional moves with memory inputs
16540 [(match_scratch:SWI248 2 "r")
16541 (set (match_operand:SWI248 0 "register_operand")
16542 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16543 [(reg FLAGS_REG) (const_int 0)])
16545 (match_operand:SWI248 3 "memory_operand")))]
16546 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16547 && optimize_insn_for_speed_p ()"
16548 [(set (match_dup 2) (match_dup 3))
16550 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16553 [(match_scratch:SWI248 2 "r")
16554 (set (match_operand:SWI248 0 "register_operand")
16555 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16556 [(reg FLAGS_REG) (const_int 0)])
16557 (match_operand:SWI248 3 "memory_operand")
16559 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16560 && optimize_insn_for_speed_p ()"
16561 [(set (match_dup 2) (match_dup 3))
16563 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16565 (define_expand "mov<mode>cc"
16566 [(set (match_operand:X87MODEF 0 "register_operand")
16567 (if_then_else:X87MODEF
16568 (match_operand 1 "comparison_operator")
16569 (match_operand:X87MODEF 2 "register_operand")
16570 (match_operand:X87MODEF 3 "register_operand")))]
16571 "(TARGET_80387 && TARGET_CMOVE)
16572 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16573 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16575 (define_insn "*movxfcc_1"
16576 [(set (match_operand:XF 0 "register_operand" "=f,f")
16577 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16578 [(reg FLAGS_REG) (const_int 0)])
16579 (match_operand:XF 2 "register_operand" "f,0")
16580 (match_operand:XF 3 "register_operand" "0,f")))]
16581 "TARGET_80387 && TARGET_CMOVE"
16583 fcmov%F1\t{%2, %0|%0, %2}
16584 fcmov%f1\t{%3, %0|%0, %3}"
16585 [(set_attr "type" "fcmov")
16586 (set_attr "mode" "XF")])
16588 (define_insn "*movdfcc_1"
16589 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16590 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16591 [(reg FLAGS_REG) (const_int 0)])
16592 (match_operand:DF 2 "nonimmediate_operand"
16594 (match_operand:DF 3 "nonimmediate_operand"
16595 "0 ,f,0 ,rm,0, rm")))]
16596 "TARGET_80387 && TARGET_CMOVE
16597 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16599 fcmov%F1\t{%2, %0|%0, %2}
16600 fcmov%f1\t{%3, %0|%0, %3}
16603 cmov%O2%C1\t{%2, %0|%0, %2}
16604 cmov%O2%c1\t{%3, %0|%0, %3}"
16605 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16606 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16607 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16610 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16611 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16612 [(reg FLAGS_REG) (const_int 0)])
16613 (match_operand:DF 2 "nonimmediate_operand")
16614 (match_operand:DF 3 "nonimmediate_operand")))]
16615 "!TARGET_64BIT && reload_completed"
16616 [(set (match_dup 2)
16617 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16619 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16621 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16622 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16625 (define_insn "*movsfcc_1_387"
16626 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16627 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16628 [(reg FLAGS_REG) (const_int 0)])
16629 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16630 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16631 "TARGET_80387 && TARGET_CMOVE
16632 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16634 fcmov%F1\t{%2, %0|%0, %2}
16635 fcmov%f1\t{%3, %0|%0, %3}
16636 cmov%O2%C1\t{%2, %0|%0, %2}
16637 cmov%O2%c1\t{%3, %0|%0, %3}"
16638 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16639 (set_attr "mode" "SF,SF,SI,SI")])
16641 ;; Don't do conditional moves with memory inputs. This splitter helps
16642 ;; register starved x86_32 by forcing inputs into registers before reload.
16644 [(set (match_operand:MODEF 0 "register_operand")
16645 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16646 [(reg FLAGS_REG) (const_int 0)])
16647 (match_operand:MODEF 2 "nonimmediate_operand")
16648 (match_operand:MODEF 3 "nonimmediate_operand")))]
16649 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16650 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16651 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16652 && can_create_pseudo_p ()
16653 && optimize_insn_for_speed_p ()"
16654 [(set (match_dup 0)
16655 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16657 if (MEM_P (operands[2]))
16658 operands[2] = force_reg (<MODE>mode, operands[2]);
16659 if (MEM_P (operands[3]))
16660 operands[3] = force_reg (<MODE>mode, operands[3]);
16663 ;; Don't do conditional moves with memory inputs
16665 [(match_scratch:MODEF 2 "r")
16666 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16667 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16668 [(reg FLAGS_REG) (const_int 0)])
16670 (match_operand:MODEF 3 "memory_operand")))]
16671 "(<MODE>mode != DFmode || TARGET_64BIT)
16672 && TARGET_80387 && TARGET_CMOVE
16673 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16674 && optimize_insn_for_speed_p ()"
16675 [(set (match_dup 2) (match_dup 3))
16677 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16680 [(match_scratch:MODEF 2 "r")
16681 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16682 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16683 [(reg FLAGS_REG) (const_int 0)])
16684 (match_operand:MODEF 3 "memory_operand")
16686 "(<MODE>mode != DFmode || TARGET_64BIT)
16687 && TARGET_80387 && TARGET_CMOVE
16688 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16689 && optimize_insn_for_speed_p ()"
16690 [(set (match_dup 2) (match_dup 3))
16692 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16694 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16695 ;; the scalar versions to have only XMM registers as operands.
16697 ;; XOP conditional move
16698 (define_insn "*xop_pcmov_<mode>"
16699 [(set (match_operand:MODEF 0 "register_operand" "=x")
16700 (if_then_else:MODEF
16701 (match_operand:MODEF 1 "register_operand" "x")
16702 (match_operand:MODEF 2 "register_operand" "x")
16703 (match_operand:MODEF 3 "register_operand" "x")))]
16705 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16706 [(set_attr "type" "sse4arg")])
16708 ;; These versions of the min/max patterns are intentionally ignorant of
16709 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16710 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16711 ;; are undefined in this condition, we're certain this is correct.
16713 (define_insn "<code><mode>3"
16714 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16716 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16717 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16718 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16720 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16721 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16722 [(set_attr "isa" "noavx,avx")
16723 (set_attr "prefix" "orig,vex")
16724 (set_attr "type" "sseadd")
16725 (set_attr "mode" "<MODE>")])
16727 ;; These versions of the min/max patterns implement exactly the operations
16728 ;; min = (op1 < op2 ? op1 : op2)
16729 ;; max = (!(op1 < op2) ? op1 : op2)
16730 ;; Their operands are not commutative, and thus they may be used in the
16731 ;; presence of -0.0 and NaN.
16733 (define_int_iterator IEEE_MAXMIN
16737 (define_int_attr ieee_maxmin
16738 [(UNSPEC_IEEE_MAX "max")
16739 (UNSPEC_IEEE_MIN "min")])
16741 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16742 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16744 [(match_operand:MODEF 1 "register_operand" "0,x")
16745 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16747 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16749 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16750 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16751 [(set_attr "isa" "noavx,avx")
16752 (set_attr "prefix" "orig,vex")
16753 (set_attr "type" "sseadd")
16754 (set_attr "mode" "<MODE>")])
16756 ;; Make two stack loads independent:
16758 ;; fld %st(0) -> fld bb
16759 ;; fmul bb fmul %st(1), %st
16761 ;; Actually we only match the last two instructions for simplicity.
16763 [(set (match_operand 0 "fp_register_operand")
16764 (match_operand 1 "fp_register_operand"))
16766 (match_operator 2 "binary_fp_operator"
16768 (match_operand 3 "memory_operand")]))]
16769 "REGNO (operands[0]) != REGNO (operands[1])"
16770 [(set (match_dup 0) (match_dup 3))
16771 (set (match_dup 0) (match_dup 4))]
16773 ;; The % modifier is not operational anymore in peephole2's, so we have to
16774 ;; swap the operands manually in the case of addition and multiplication.
16778 if (COMMUTATIVE_ARITH_P (operands[2]))
16779 op0 = operands[0], op1 = operands[1];
16781 op0 = operands[1], op1 = operands[0];
16783 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16784 GET_MODE (operands[2]),
16788 ;; Conditional addition patterns
16789 (define_expand "add<mode>cc"
16790 [(match_operand:SWI 0 "register_operand")
16791 (match_operand 1 "ordered_comparison_operator")
16792 (match_operand:SWI 2 "register_operand")
16793 (match_operand:SWI 3 "const_int_operand")]
16795 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16797 ;; Misc patterns (?)
16799 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16800 ;; Otherwise there will be nothing to keep
16802 ;; [(set (reg ebp) (reg esp))]
16803 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16804 ;; (clobber (eflags)]
16805 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16807 ;; in proper program order.
16809 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16810 [(set (match_operand:P 0 "register_operand" "=r,r")
16811 (plus:P (match_operand:P 1 "register_operand" "0,r")
16812 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16813 (clobber (reg:CC FLAGS_REG))
16814 (clobber (mem:BLK (scratch)))]
16817 switch (get_attr_type (insn))
16820 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16823 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16824 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16825 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16827 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16830 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16831 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16834 [(set (attr "type")
16835 (cond [(and (eq_attr "alternative" "0")
16836 (not (match_test "TARGET_OPT_AGU")))
16837 (const_string "alu")
16838 (match_operand:<MODE> 2 "const0_operand")
16839 (const_string "imov")
16841 (const_string "lea")))
16842 (set (attr "length_immediate")
16843 (cond [(eq_attr "type" "imov")
16845 (and (eq_attr "type" "alu")
16846 (match_operand 2 "const128_operand"))
16849 (const_string "*")))
16850 (set_attr "mode" "<MODE>")])
16852 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16853 [(set (match_operand:P 0 "register_operand" "=r")
16854 (minus:P (match_operand:P 1 "register_operand" "0")
16855 (match_operand:P 2 "register_operand" "r")))
16856 (clobber (reg:CC FLAGS_REG))
16857 (clobber (mem:BLK (scratch)))]
16859 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16860 [(set_attr "type" "alu")
16861 (set_attr "mode" "<MODE>")])
16863 (define_insn "allocate_stack_worker_probe_<mode>"
16864 [(set (match_operand:P 0 "register_operand" "=a")
16865 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16866 UNSPECV_STACK_PROBE))
16867 (clobber (reg:CC FLAGS_REG))]
16868 "ix86_target_stack_probe ()"
16869 "call\t___chkstk_ms"
16870 [(set_attr "type" "multi")
16871 (set_attr "length" "5")])
16873 (define_expand "allocate_stack"
16874 [(match_operand 0 "register_operand")
16875 (match_operand 1 "general_operand")]
16876 "ix86_target_stack_probe ()"
16880 #ifndef CHECK_STACK_LIMIT
16881 #define CHECK_STACK_LIMIT 0
16884 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16885 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16889 rtx (*insn) (rtx, rtx);
16891 x = copy_to_mode_reg (Pmode, operands[1]);
16893 insn = (TARGET_64BIT
16894 ? gen_allocate_stack_worker_probe_di
16895 : gen_allocate_stack_worker_probe_si);
16897 emit_insn (insn (x, x));
16900 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16901 stack_pointer_rtx, 0, OPTAB_DIRECT);
16903 if (x != stack_pointer_rtx)
16904 emit_move_insn (stack_pointer_rtx, x);
16906 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16910 ;; Use IOR for stack probes, this is shorter.
16911 (define_expand "probe_stack"
16912 [(match_operand 0 "memory_operand")]
16915 rtx (*gen_ior3) (rtx, rtx, rtx);
16917 gen_ior3 = (GET_MODE (operands[0]) == DImode
16918 ? gen_iordi3 : gen_iorsi3);
16920 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16924 (define_insn "adjust_stack_and_probe<mode>"
16925 [(set (match_operand:P 0 "register_operand" "=r")
16926 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16927 UNSPECV_PROBE_STACK_RANGE))
16928 (set (reg:P SP_REG)
16929 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16930 (clobber (reg:CC FLAGS_REG))
16931 (clobber (mem:BLK (scratch)))]
16933 "* return output_adjust_stack_and_probe (operands[0]);"
16934 [(set_attr "type" "multi")])
16936 (define_insn "probe_stack_range<mode>"
16937 [(set (match_operand:P 0 "register_operand" "=r")
16938 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16939 (match_operand:P 2 "const_int_operand" "n")]
16940 UNSPECV_PROBE_STACK_RANGE))
16941 (clobber (reg:CC FLAGS_REG))]
16943 "* return output_probe_stack_range (operands[0], operands[2]);"
16944 [(set_attr "type" "multi")])
16946 (define_expand "builtin_setjmp_receiver"
16947 [(label_ref (match_operand 0))]
16948 "!TARGET_64BIT && flag_pic"
16954 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16955 rtx_code_label *label_rtx = gen_label_rtx ();
16956 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16957 xops[0] = xops[1] = picreg;
16958 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16959 ix86_expand_binary_operator (MINUS, SImode, xops);
16963 emit_insn (gen_set_got (pic_offset_table_rtx));
16967 (define_insn_and_split "nonlocal_goto_receiver"
16968 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16969 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16971 "&& reload_completed"
16974 if (crtl->uses_pic_offset_table)
16977 rtx label_rtx = gen_label_rtx ();
16980 /* Get a new pic base. */
16981 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16982 /* Correct this with the offset from the new to the old. */
16983 xops[0] = xops[1] = pic_offset_table_rtx;
16984 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16985 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16986 UNSPEC_MACHOPIC_OFFSET);
16987 xops[2] = gen_rtx_CONST (Pmode, tmp);
16988 ix86_expand_binary_operator (MINUS, SImode, xops);
16991 /* No pic reg restore needed. */
16992 emit_note (NOTE_INSN_DELETED);
16997 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16998 ;; Do not split instructions with mask registers.
17000 [(set (match_operand 0 "general_reg_operand")
17001 (match_operator 3 "promotable_binary_operator"
17002 [(match_operand 1 "general_reg_operand")
17003 (match_operand 2 "aligned_operand")]))
17004 (clobber (reg:CC FLAGS_REG))]
17005 "! TARGET_PARTIAL_REG_STALL && reload_completed
17006 && ((GET_MODE (operands[0]) == HImode
17007 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17008 /* ??? next two lines just !satisfies_constraint_K (...) */
17009 || !CONST_INT_P (operands[2])
17010 || satisfies_constraint_K (operands[2])))
17011 || (GET_MODE (operands[0]) == QImode
17012 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17013 [(parallel [(set (match_dup 0)
17014 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17015 (clobber (reg:CC FLAGS_REG))])]
17017 operands[0] = gen_lowpart (SImode, operands[0]);
17018 operands[1] = gen_lowpart (SImode, operands[1]);
17019 if (GET_CODE (operands[3]) != ASHIFT)
17020 operands[2] = gen_lowpart (SImode, operands[2]);
17021 PUT_MODE (operands[3], SImode);
17024 ; Promote the QImode tests, as i386 has encoding of the AND
17025 ; instruction with 32-bit sign-extended immediate and thus the
17026 ; instruction size is unchanged, except in the %eax case for
17027 ; which it is increased by one byte, hence the ! optimize_size.
17029 [(set (match_operand 0 "flags_reg_operand")
17030 (match_operator 2 "compare_operator"
17031 [(and (match_operand 3 "aligned_operand")
17032 (match_operand 4 "const_int_operand"))
17034 (set (match_operand 1 "register_operand")
17035 (and (match_dup 3) (match_dup 4)))]
17036 "! TARGET_PARTIAL_REG_STALL && reload_completed
17037 && optimize_insn_for_speed_p ()
17038 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17039 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17040 /* Ensure that the operand will remain sign-extended immediate. */
17041 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17042 [(parallel [(set (match_dup 0)
17043 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17046 (and:SI (match_dup 3) (match_dup 4)))])]
17049 = gen_int_mode (INTVAL (operands[4])
17050 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17051 operands[1] = gen_lowpart (SImode, operands[1]);
17052 operands[3] = gen_lowpart (SImode, operands[3]);
17055 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17056 ; the TEST instruction with 32-bit sign-extended immediate and thus
17057 ; the instruction size would at least double, which is not what we
17058 ; want even with ! optimize_size.
17060 [(set (match_operand 0 "flags_reg_operand")
17061 (match_operator 1 "compare_operator"
17062 [(and (match_operand:HI 2 "aligned_operand")
17063 (match_operand:HI 3 "const_int_operand"))
17065 "! TARGET_PARTIAL_REG_STALL && reload_completed
17066 && ! TARGET_FAST_PREFIX
17067 && optimize_insn_for_speed_p ()
17068 /* Ensure that the operand will remain sign-extended immediate. */
17069 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17070 [(set (match_dup 0)
17071 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17075 = gen_int_mode (INTVAL (operands[3])
17076 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17077 operands[2] = gen_lowpart (SImode, operands[2]);
17081 [(set (match_operand 0 "register_operand")
17082 (neg (match_operand 1 "register_operand")))
17083 (clobber (reg:CC FLAGS_REG))]
17084 "! TARGET_PARTIAL_REG_STALL && reload_completed
17085 && (GET_MODE (operands[0]) == HImode
17086 || (GET_MODE (operands[0]) == QImode
17087 && (TARGET_PROMOTE_QImode
17088 || optimize_insn_for_size_p ())))"
17089 [(parallel [(set (match_dup 0)
17090 (neg:SI (match_dup 1)))
17091 (clobber (reg:CC FLAGS_REG))])]
17093 operands[0] = gen_lowpart (SImode, operands[0]);
17094 operands[1] = gen_lowpart (SImode, operands[1]);
17097 ;; Do not split instructions with mask regs.
17099 [(set (match_operand 0 "general_reg_operand")
17100 (not (match_operand 1 "general_reg_operand")))]
17101 "! TARGET_PARTIAL_REG_STALL && reload_completed
17102 && (GET_MODE (operands[0]) == HImode
17103 || (GET_MODE (operands[0]) == QImode
17104 && (TARGET_PROMOTE_QImode
17105 || optimize_insn_for_size_p ())))"
17106 [(set (match_dup 0)
17107 (not:SI (match_dup 1)))]
17109 operands[0] = gen_lowpart (SImode, operands[0]);
17110 operands[1] = gen_lowpart (SImode, operands[1]);
17113 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17114 ;; transform a complex memory operation into two memory to register operations.
17116 ;; Don't push memory operands
17118 [(set (match_operand:SWI 0 "push_operand")
17119 (match_operand:SWI 1 "memory_operand"))
17120 (match_scratch:SWI 2 "<r>")]
17121 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17122 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17123 [(set (match_dup 2) (match_dup 1))
17124 (set (match_dup 0) (match_dup 2))])
17126 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17129 [(set (match_operand:SF 0 "push_operand")
17130 (match_operand:SF 1 "memory_operand"))
17131 (match_scratch:SF 2 "r")]
17132 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17133 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17134 [(set (match_dup 2) (match_dup 1))
17135 (set (match_dup 0) (match_dup 2))])
17137 ;; Don't move an immediate directly to memory when the instruction
17138 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17140 [(match_scratch:SWI124 1 "<r>")
17141 (set (match_operand:SWI124 0 "memory_operand")
17143 "optimize_insn_for_speed_p ()
17144 && ((<MODE>mode == HImode
17145 && TARGET_LCP_STALL)
17146 || (!TARGET_USE_MOV0
17147 && TARGET_SPLIT_LONG_MOVES
17148 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17149 && peep2_regno_dead_p (0, FLAGS_REG)"
17150 [(parallel [(set (match_dup 2) (const_int 0))
17151 (clobber (reg:CC FLAGS_REG))])
17152 (set (match_dup 0) (match_dup 1))]
17153 "operands[2] = gen_lowpart (SImode, operands[1]);")
17156 [(match_scratch:SWI124 2 "<r>")
17157 (set (match_operand:SWI124 0 "memory_operand")
17158 (match_operand:SWI124 1 "immediate_operand"))]
17159 "optimize_insn_for_speed_p ()
17160 && ((<MODE>mode == HImode
17161 && TARGET_LCP_STALL)
17162 || (TARGET_SPLIT_LONG_MOVES
17163 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17164 [(set (match_dup 2) (match_dup 1))
17165 (set (match_dup 0) (match_dup 2))])
17167 ;; Don't compare memory with zero, load and use a test instead.
17169 [(set (match_operand 0 "flags_reg_operand")
17170 (match_operator 1 "compare_operator"
17171 [(match_operand:SI 2 "memory_operand")
17173 (match_scratch:SI 3 "r")]
17174 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17175 [(set (match_dup 3) (match_dup 2))
17176 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17178 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17179 ;; Don't split NOTs with a displacement operand, because resulting XOR
17180 ;; will not be pairable anyway.
17182 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17183 ;; represented using a modRM byte. The XOR replacement is long decoded,
17184 ;; so this split helps here as well.
17186 ;; Note: Can't do this as a regular split because we can't get proper
17187 ;; lifetime information then.
17190 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17191 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17192 "optimize_insn_for_speed_p ()
17193 && ((TARGET_NOT_UNPAIRABLE
17194 && (!MEM_P (operands[0])
17195 || !memory_displacement_operand (operands[0], <MODE>mode)))
17196 || (TARGET_NOT_VECTORMODE
17197 && long_memory_operand (operands[0], <MODE>mode)))
17198 && peep2_regno_dead_p (0, FLAGS_REG)"
17199 [(parallel [(set (match_dup 0)
17200 (xor:SWI124 (match_dup 1) (const_int -1)))
17201 (clobber (reg:CC FLAGS_REG))])])
17203 ;; Non pairable "test imm, reg" instructions can be translated to
17204 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17205 ;; byte opcode instead of two, have a short form for byte operands),
17206 ;; so do it for other CPUs as well. Given that the value was dead,
17207 ;; this should not create any new dependencies. Pass on the sub-word
17208 ;; versions if we're concerned about partial register stalls.
17211 [(set (match_operand 0 "flags_reg_operand")
17212 (match_operator 1 "compare_operator"
17213 [(and:SI (match_operand:SI 2 "register_operand")
17214 (match_operand:SI 3 "immediate_operand"))
17216 "ix86_match_ccmode (insn, CCNOmode)
17217 && (true_regnum (operands[2]) != AX_REG
17218 || satisfies_constraint_K (operands[3]))
17219 && peep2_reg_dead_p (1, operands[2])"
17221 [(set (match_dup 0)
17222 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17225 (and:SI (match_dup 2) (match_dup 3)))])])
17227 ;; We don't need to handle HImode case, because it will be promoted to SImode
17228 ;; on ! TARGET_PARTIAL_REG_STALL
17231 [(set (match_operand 0 "flags_reg_operand")
17232 (match_operator 1 "compare_operator"
17233 [(and:QI (match_operand:QI 2 "register_operand")
17234 (match_operand:QI 3 "immediate_operand"))
17236 "! TARGET_PARTIAL_REG_STALL
17237 && ix86_match_ccmode (insn, CCNOmode)
17238 && true_regnum (operands[2]) != AX_REG
17239 && peep2_reg_dead_p (1, operands[2])"
17241 [(set (match_dup 0)
17242 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17245 (and:QI (match_dup 2) (match_dup 3)))])])
17248 [(set (match_operand 0 "flags_reg_operand")
17249 (match_operator 1 "compare_operator"
17252 (match_operand 2 "ext_register_operand")
17255 (match_operand 3 "const_int_operand"))
17257 "! TARGET_PARTIAL_REG_STALL
17258 && ix86_match_ccmode (insn, CCNOmode)
17259 && true_regnum (operands[2]) != AX_REG
17260 && peep2_reg_dead_p (1, operands[2])"
17261 [(parallel [(set (match_dup 0)
17270 (set (zero_extract:SI (match_dup 2)
17278 (match_dup 3)))])])
17280 ;; Don't do logical operations with memory inputs.
17282 [(match_scratch:SI 2 "r")
17283 (parallel [(set (match_operand:SI 0 "register_operand")
17284 (match_operator:SI 3 "arith_or_logical_operator"
17286 (match_operand:SI 1 "memory_operand")]))
17287 (clobber (reg:CC FLAGS_REG))])]
17288 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17289 [(set (match_dup 2) (match_dup 1))
17290 (parallel [(set (match_dup 0)
17291 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17292 (clobber (reg:CC FLAGS_REG))])])
17295 [(match_scratch:SI 2 "r")
17296 (parallel [(set (match_operand:SI 0 "register_operand")
17297 (match_operator:SI 3 "arith_or_logical_operator"
17298 [(match_operand:SI 1 "memory_operand")
17300 (clobber (reg:CC FLAGS_REG))])]
17301 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17302 [(set (match_dup 2) (match_dup 1))
17303 (parallel [(set (match_dup 0)
17304 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17305 (clobber (reg:CC FLAGS_REG))])])
17307 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17308 ;; refers to the destination of the load!
17311 [(set (match_operand:SI 0 "register_operand")
17312 (match_operand:SI 1 "register_operand"))
17313 (parallel [(set (match_dup 0)
17314 (match_operator:SI 3 "commutative_operator"
17316 (match_operand:SI 2 "memory_operand")]))
17317 (clobber (reg:CC FLAGS_REG))])]
17318 "REGNO (operands[0]) != REGNO (operands[1])
17319 && GENERAL_REGNO_P (REGNO (operands[0]))
17320 && GENERAL_REGNO_P (REGNO (operands[1]))"
17321 [(set (match_dup 0) (match_dup 4))
17322 (parallel [(set (match_dup 0)
17323 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17324 (clobber (reg:CC FLAGS_REG))])]
17325 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17328 [(set (match_operand 0 "register_operand")
17329 (match_operand 1 "register_operand"))
17331 (match_operator 3 "commutative_operator"
17333 (match_operand 2 "memory_operand")]))]
17334 "REGNO (operands[0]) != REGNO (operands[1])
17335 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17336 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17337 [(set (match_dup 0) (match_dup 2))
17339 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17341 ; Don't do logical operations with memory outputs
17343 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17344 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17345 ; the same decoder scheduling characteristics as the original.
17348 [(match_scratch:SI 2 "r")
17349 (parallel [(set (match_operand:SI 0 "memory_operand")
17350 (match_operator:SI 3 "arith_or_logical_operator"
17352 (match_operand:SI 1 "nonmemory_operand")]))
17353 (clobber (reg:CC FLAGS_REG))])]
17354 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17355 /* Do not split stack checking probes. */
17356 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17357 [(set (match_dup 2) (match_dup 0))
17358 (parallel [(set (match_dup 2)
17359 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17360 (clobber (reg:CC FLAGS_REG))])
17361 (set (match_dup 0) (match_dup 2))])
17364 [(match_scratch:SI 2 "r")
17365 (parallel [(set (match_operand:SI 0 "memory_operand")
17366 (match_operator:SI 3 "arith_or_logical_operator"
17367 [(match_operand:SI 1 "nonmemory_operand")
17369 (clobber (reg:CC FLAGS_REG))])]
17370 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17371 /* Do not split stack checking probes. */
17372 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17373 [(set (match_dup 2) (match_dup 0))
17374 (parallel [(set (match_dup 2)
17375 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17376 (clobber (reg:CC FLAGS_REG))])
17377 (set (match_dup 0) (match_dup 2))])
17379 ;; Attempt to use arith or logical operations with memory outputs with
17380 ;; setting of flags.
17382 [(set (match_operand:SWI 0 "register_operand")
17383 (match_operand:SWI 1 "memory_operand"))
17384 (parallel [(set (match_dup 0)
17385 (match_operator:SWI 3 "plusminuslogic_operator"
17387 (match_operand:SWI 2 "<nonmemory_operand>")]))
17388 (clobber (reg:CC FLAGS_REG))])
17389 (set (match_dup 1) (match_dup 0))
17390 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17391 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17392 && peep2_reg_dead_p (4, operands[0])
17393 && !reg_overlap_mentioned_p (operands[0], operands[1])
17394 && !reg_overlap_mentioned_p (operands[0], operands[2])
17395 && (<MODE>mode != QImode
17396 || immediate_operand (operands[2], QImode)
17397 || q_regs_operand (operands[2], QImode))
17398 && ix86_match_ccmode (peep2_next_insn (3),
17399 (GET_CODE (operands[3]) == PLUS
17400 || GET_CODE (operands[3]) == MINUS)
17401 ? CCGOCmode : CCNOmode)"
17402 [(parallel [(set (match_dup 4) (match_dup 5))
17403 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17404 (match_dup 2)]))])]
17406 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17407 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17408 copy_rtx (operands[1]),
17409 copy_rtx (operands[2]));
17410 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17411 operands[5], const0_rtx);
17415 [(parallel [(set (match_operand:SWI 0 "register_operand")
17416 (match_operator:SWI 2 "plusminuslogic_operator"
17418 (match_operand:SWI 1 "memory_operand")]))
17419 (clobber (reg:CC FLAGS_REG))])
17420 (set (match_dup 1) (match_dup 0))
17421 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17422 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17423 && GET_CODE (operands[2]) != MINUS
17424 && peep2_reg_dead_p (3, operands[0])
17425 && !reg_overlap_mentioned_p (operands[0], operands[1])
17426 && ix86_match_ccmode (peep2_next_insn (2),
17427 GET_CODE (operands[2]) == PLUS
17428 ? CCGOCmode : CCNOmode)"
17429 [(parallel [(set (match_dup 3) (match_dup 4))
17430 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17431 (match_dup 0)]))])]
17433 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17434 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17435 copy_rtx (operands[1]),
17436 copy_rtx (operands[0]));
17437 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17438 operands[4], const0_rtx);
17442 [(set (match_operand:SWI12 0 "register_operand")
17443 (match_operand:SWI12 1 "memory_operand"))
17444 (parallel [(set (match_operand:SI 4 "register_operand")
17445 (match_operator:SI 3 "plusminuslogic_operator"
17447 (match_operand:SI 2 "nonmemory_operand")]))
17448 (clobber (reg:CC FLAGS_REG))])
17449 (set (match_dup 1) (match_dup 0))
17450 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17451 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17452 && REG_P (operands[0]) && REG_P (operands[4])
17453 && REGNO (operands[0]) == REGNO (operands[4])
17454 && peep2_reg_dead_p (4, operands[0])
17455 && (<MODE>mode != QImode
17456 || immediate_operand (operands[2], SImode)
17457 || q_regs_operand (operands[2], SImode))
17458 && !reg_overlap_mentioned_p (operands[0], operands[1])
17459 && !reg_overlap_mentioned_p (operands[0], operands[2])
17460 && ix86_match_ccmode (peep2_next_insn (3),
17461 (GET_CODE (operands[3]) == PLUS
17462 || GET_CODE (operands[3]) == MINUS)
17463 ? CCGOCmode : CCNOmode)"
17464 [(parallel [(set (match_dup 4) (match_dup 5))
17465 (set (match_dup 1) (match_dup 6))])]
17467 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17468 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17469 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17470 copy_rtx (operands[1]), operands[2]);
17471 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17472 operands[5], const0_rtx);
17473 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17474 copy_rtx (operands[1]),
17475 copy_rtx (operands[2]));
17478 ;; Attempt to always use XOR for zeroing registers.
17480 [(set (match_operand 0 "register_operand")
17481 (match_operand 1 "const0_operand"))]
17482 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17483 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17484 && GENERAL_REG_P (operands[0])
17485 && peep2_regno_dead_p (0, FLAGS_REG)"
17486 [(parallel [(set (match_dup 0) (const_int 0))
17487 (clobber (reg:CC FLAGS_REG))])]
17488 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17491 [(set (strict_low_part (match_operand 0 "register_operand"))
17493 "(GET_MODE (operands[0]) == QImode
17494 || GET_MODE (operands[0]) == HImode)
17495 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17496 && peep2_regno_dead_p (0, FLAGS_REG)"
17497 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17498 (clobber (reg:CC FLAGS_REG))])])
17500 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17502 [(set (match_operand:SWI248 0 "register_operand")
17504 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17505 && peep2_regno_dead_p (0, FLAGS_REG)"
17506 [(parallel [(set (match_dup 0) (const_int -1))
17507 (clobber (reg:CC FLAGS_REG))])]
17509 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17510 operands[0] = gen_lowpart (SImode, operands[0]);
17513 ;; Attempt to convert simple lea to add/shift.
17514 ;; These can be created by move expanders.
17515 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17516 ;; relevant lea instructions were already split.
17519 [(set (match_operand:SWI48 0 "register_operand")
17520 (plus:SWI48 (match_dup 0)
17521 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17523 && peep2_regno_dead_p (0, FLAGS_REG)"
17524 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17525 (clobber (reg:CC FLAGS_REG))])])
17528 [(set (match_operand:SWI48 0 "register_operand")
17529 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17532 && peep2_regno_dead_p (0, FLAGS_REG)"
17533 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17534 (clobber (reg:CC FLAGS_REG))])])
17537 [(set (match_operand:DI 0 "register_operand")
17539 (plus:SI (match_operand:SI 1 "register_operand")
17540 (match_operand:SI 2 "nonmemory_operand"))))]
17541 "TARGET_64BIT && !TARGET_OPT_AGU
17542 && REGNO (operands[0]) == REGNO (operands[1])
17543 && peep2_regno_dead_p (0, FLAGS_REG)"
17544 [(parallel [(set (match_dup 0)
17545 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17546 (clobber (reg:CC FLAGS_REG))])])
17549 [(set (match_operand:DI 0 "register_operand")
17551 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17552 (match_operand:SI 2 "register_operand"))))]
17553 "TARGET_64BIT && !TARGET_OPT_AGU
17554 && REGNO (operands[0]) == REGNO (operands[2])
17555 && peep2_regno_dead_p (0, FLAGS_REG)"
17556 [(parallel [(set (match_dup 0)
17557 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17558 (clobber (reg:CC FLAGS_REG))])])
17561 [(set (match_operand:SWI48 0 "register_operand")
17562 (mult:SWI48 (match_dup 0)
17563 (match_operand:SWI48 1 "const_int_operand")))]
17564 "exact_log2 (INTVAL (operands[1])) >= 0
17565 && peep2_regno_dead_p (0, FLAGS_REG)"
17566 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17567 (clobber (reg:CC FLAGS_REG))])]
17568 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17571 [(set (match_operand:DI 0 "register_operand")
17573 (mult:SI (match_operand:SI 1 "register_operand")
17574 (match_operand:SI 2 "const_int_operand"))))]
17576 && exact_log2 (INTVAL (operands[2])) >= 0
17577 && REGNO (operands[0]) == REGNO (operands[1])
17578 && peep2_regno_dead_p (0, FLAGS_REG)"
17579 [(parallel [(set (match_dup 0)
17580 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17581 (clobber (reg:CC FLAGS_REG))])]
17582 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17584 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17585 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17586 ;; On many CPUs it is also faster, since special hardware to avoid esp
17587 ;; dependencies is present.
17589 ;; While some of these conversions may be done using splitters, we use
17590 ;; peepholes in order to allow combine_stack_adjustments pass to see
17591 ;; nonobfuscated RTL.
17593 ;; Convert prologue esp subtractions to push.
17594 ;; We need register to push. In order to keep verify_flow_info happy we have
17596 ;; - use scratch and clobber it in order to avoid dependencies
17597 ;; - use already live register
17598 ;; We can't use the second way right now, since there is no reliable way how to
17599 ;; verify that given register is live. First choice will also most likely in
17600 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17601 ;; call clobbered registers are dead. We may want to use base pointer as an
17602 ;; alternative when no register is available later.
17605 [(match_scratch:W 1 "r")
17606 (parallel [(set (reg:P SP_REG)
17607 (plus:P (reg:P SP_REG)
17608 (match_operand:P 0 "const_int_operand")))
17609 (clobber (reg:CC FLAGS_REG))
17610 (clobber (mem:BLK (scratch)))])]
17611 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17612 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17613 [(clobber (match_dup 1))
17614 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17615 (clobber (mem:BLK (scratch)))])])
17618 [(match_scratch:W 1 "r")
17619 (parallel [(set (reg:P SP_REG)
17620 (plus:P (reg:P SP_REG)
17621 (match_operand:P 0 "const_int_operand")))
17622 (clobber (reg:CC FLAGS_REG))
17623 (clobber (mem:BLK (scratch)))])]
17624 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17625 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17626 [(clobber (match_dup 1))
17627 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17628 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17629 (clobber (mem:BLK (scratch)))])])
17631 ;; Convert esp subtractions to push.
17633 [(match_scratch:W 1 "r")
17634 (parallel [(set (reg:P SP_REG)
17635 (plus:P (reg:P SP_REG)
17636 (match_operand:P 0 "const_int_operand")))
17637 (clobber (reg:CC FLAGS_REG))])]
17638 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17639 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17640 [(clobber (match_dup 1))
17641 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17644 [(match_scratch:W 1 "r")
17645 (parallel [(set (reg:P SP_REG)
17646 (plus:P (reg:P SP_REG)
17647 (match_operand:P 0 "const_int_operand")))
17648 (clobber (reg:CC FLAGS_REG))])]
17649 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17650 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17651 [(clobber (match_dup 1))
17652 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17653 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17655 ;; Convert epilogue deallocator to pop.
17657 [(match_scratch:W 1 "r")
17658 (parallel [(set (reg:P SP_REG)
17659 (plus:P (reg:P SP_REG)
17660 (match_operand:P 0 "const_int_operand")))
17661 (clobber (reg:CC FLAGS_REG))
17662 (clobber (mem:BLK (scratch)))])]
17663 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17664 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17665 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17666 (clobber (mem:BLK (scratch)))])])
17668 ;; Two pops case is tricky, since pop causes dependency
17669 ;; on destination register. We use two registers if available.
17671 [(match_scratch:W 1 "r")
17672 (match_scratch:W 2 "r")
17673 (parallel [(set (reg:P SP_REG)
17674 (plus:P (reg:P SP_REG)
17675 (match_operand:P 0 "const_int_operand")))
17676 (clobber (reg:CC FLAGS_REG))
17677 (clobber (mem:BLK (scratch)))])]
17678 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17679 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17680 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17681 (clobber (mem:BLK (scratch)))])
17682 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17685 [(match_scratch:W 1 "r")
17686 (parallel [(set (reg:P SP_REG)
17687 (plus:P (reg:P SP_REG)
17688 (match_operand:P 0 "const_int_operand")))
17689 (clobber (reg:CC FLAGS_REG))
17690 (clobber (mem:BLK (scratch)))])]
17691 "optimize_insn_for_size_p ()
17692 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17693 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17694 (clobber (mem:BLK (scratch)))])
17695 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17697 ;; Convert esp additions to pop.
17699 [(match_scratch:W 1 "r")
17700 (parallel [(set (reg:P SP_REG)
17701 (plus:P (reg:P SP_REG)
17702 (match_operand:P 0 "const_int_operand")))
17703 (clobber (reg:CC FLAGS_REG))])]
17704 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17705 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17707 ;; Two pops case is tricky, since pop causes dependency
17708 ;; on destination register. We use two registers if available.
17710 [(match_scratch:W 1 "r")
17711 (match_scratch:W 2 "r")
17712 (parallel [(set (reg:P SP_REG)
17713 (plus:P (reg:P SP_REG)
17714 (match_operand:P 0 "const_int_operand")))
17715 (clobber (reg:CC FLAGS_REG))])]
17716 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17717 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17718 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17721 [(match_scratch:W 1 "r")
17722 (parallel [(set (reg:P SP_REG)
17723 (plus:P (reg:P SP_REG)
17724 (match_operand:P 0 "const_int_operand")))
17725 (clobber (reg:CC FLAGS_REG))])]
17726 "optimize_insn_for_size_p ()
17727 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17728 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17729 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17731 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17732 ;; required and register dies. Similarly for 128 to -128.
17734 [(set (match_operand 0 "flags_reg_operand")
17735 (match_operator 1 "compare_operator"
17736 [(match_operand 2 "register_operand")
17737 (match_operand 3 "const_int_operand")]))]
17738 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17739 && incdec_operand (operands[3], GET_MODE (operands[3])))
17740 || (!TARGET_FUSE_CMP_AND_BRANCH
17741 && INTVAL (operands[3]) == 128))
17742 && ix86_match_ccmode (insn, CCGCmode)
17743 && peep2_reg_dead_p (1, operands[2])"
17744 [(parallel [(set (match_dup 0)
17745 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17746 (clobber (match_dup 2))])])
17748 ;; Convert imul by three, five and nine into lea
17751 [(set (match_operand:SWI48 0 "register_operand")
17752 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17753 (match_operand:SWI48 2 "const359_operand")))
17754 (clobber (reg:CC FLAGS_REG))])]
17755 "!TARGET_PARTIAL_REG_STALL
17756 || <MODE>mode == SImode
17757 || optimize_function_for_size_p (cfun)"
17758 [(set (match_dup 0)
17759 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17761 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17765 [(set (match_operand:SWI48 0 "register_operand")
17766 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17767 (match_operand:SWI48 2 "const359_operand")))
17768 (clobber (reg:CC FLAGS_REG))])]
17769 "optimize_insn_for_speed_p ()
17770 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17771 [(set (match_dup 0) (match_dup 1))
17773 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17775 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17777 ;; imul $32bit_imm, mem, reg is vector decoded, while
17778 ;; imul $32bit_imm, reg, reg is direct decoded.
17780 [(match_scratch:SWI48 3 "r")
17781 (parallel [(set (match_operand:SWI48 0 "register_operand")
17782 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17783 (match_operand:SWI48 2 "immediate_operand")))
17784 (clobber (reg:CC FLAGS_REG))])]
17785 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17786 && !satisfies_constraint_K (operands[2])"
17787 [(set (match_dup 3) (match_dup 1))
17788 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17789 (clobber (reg:CC FLAGS_REG))])])
17792 [(match_scratch:SI 3 "r")
17793 (parallel [(set (match_operand:DI 0 "register_operand")
17795 (mult:SI (match_operand:SI 1 "memory_operand")
17796 (match_operand:SI 2 "immediate_operand"))))
17797 (clobber (reg:CC FLAGS_REG))])]
17799 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17800 && !satisfies_constraint_K (operands[2])"
17801 [(set (match_dup 3) (match_dup 1))
17802 (parallel [(set (match_dup 0)
17803 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17804 (clobber (reg:CC FLAGS_REG))])])
17806 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17807 ;; Convert it into imul reg, reg
17808 ;; It would be better to force assembler to encode instruction using long
17809 ;; immediate, but there is apparently no way to do so.
17811 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17813 (match_operand:SWI248 1 "nonimmediate_operand")
17814 (match_operand:SWI248 2 "const_int_operand")))
17815 (clobber (reg:CC FLAGS_REG))])
17816 (match_scratch:SWI248 3 "r")]
17817 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17818 && satisfies_constraint_K (operands[2])"
17819 [(set (match_dup 3) (match_dup 2))
17820 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17821 (clobber (reg:CC FLAGS_REG))])]
17823 if (!rtx_equal_p (operands[0], operands[1]))
17824 emit_move_insn (operands[0], operands[1]);
17827 ;; After splitting up read-modify operations, array accesses with memory
17828 ;; operands might end up in form:
17830 ;; movl 4(%esp), %edx
17832 ;; instead of pre-splitting:
17834 ;; addl 4(%esp), %eax
17836 ;; movl 4(%esp), %edx
17837 ;; leal (%edx,%eax,4), %eax
17840 [(match_scratch:W 5 "r")
17841 (parallel [(set (match_operand 0 "register_operand")
17842 (ashift (match_operand 1 "register_operand")
17843 (match_operand 2 "const_int_operand")))
17844 (clobber (reg:CC FLAGS_REG))])
17845 (parallel [(set (match_operand 3 "register_operand")
17846 (plus (match_dup 0)
17847 (match_operand 4 "x86_64_general_operand")))
17848 (clobber (reg:CC FLAGS_REG))])]
17849 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17850 /* Validate MODE for lea. */
17851 && ((!TARGET_PARTIAL_REG_STALL
17852 && (GET_MODE (operands[0]) == QImode
17853 || GET_MODE (operands[0]) == HImode))
17854 || GET_MODE (operands[0]) == SImode
17855 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17856 && (rtx_equal_p (operands[0], operands[3])
17857 || peep2_reg_dead_p (2, operands[0]))
17858 /* We reorder load and the shift. */
17859 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17860 [(set (match_dup 5) (match_dup 4))
17861 (set (match_dup 0) (match_dup 1))]
17863 machine_mode op1mode = GET_MODE (operands[1]);
17864 machine_mode mode = op1mode == DImode ? DImode : SImode;
17865 int scale = 1 << INTVAL (operands[2]);
17866 rtx index = gen_lowpart (word_mode, operands[1]);
17867 rtx base = gen_lowpart (word_mode, operands[5]);
17868 rtx dest = gen_lowpart (mode, operands[3]);
17870 operands[1] = gen_rtx_PLUS (word_mode, base,
17871 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17872 operands[5] = base;
17873 if (mode != word_mode)
17874 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17875 if (op1mode != word_mode)
17876 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17877 operands[0] = dest;
17880 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17881 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17882 ;; caught for use by garbage collectors and the like. Using an insn that
17883 ;; maps to SIGILL makes it more likely the program will rightfully die.
17884 ;; Keeping with tradition, "6" is in honor of #UD.
17885 (define_insn "trap"
17886 [(trap_if (const_int 1) (const_int 6))]
17889 #ifdef HAVE_AS_IX86_UD2
17892 return ASM_SHORT "0x0b0f";
17895 [(set_attr "length" "2")])
17897 (define_expand "prefetch"
17898 [(prefetch (match_operand 0 "address_operand")
17899 (match_operand:SI 1 "const_int_operand")
17900 (match_operand:SI 2 "const_int_operand"))]
17901 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17903 bool write = INTVAL (operands[1]) != 0;
17904 int locality = INTVAL (operands[2]);
17906 gcc_assert (IN_RANGE (locality, 0, 3));
17908 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17909 supported by SSE counterpart or the SSE prefetch is not available
17910 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17912 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17913 operands[2] = const2_rtx;
17914 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17915 operands[2] = GEN_INT (3);
17917 operands[1] = const0_rtx;
17920 (define_insn "*prefetch_sse"
17921 [(prefetch (match_operand 0 "address_operand" "p")
17923 (match_operand:SI 1 "const_int_operand"))]
17924 "TARGET_PREFETCH_SSE"
17926 static const char * const patterns[4] = {
17927 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17930 int locality = INTVAL (operands[1]);
17931 gcc_assert (IN_RANGE (locality, 0, 3));
17933 return patterns[locality];
17935 [(set_attr "type" "sse")
17936 (set_attr "atom_sse_attr" "prefetch")
17937 (set (attr "length_address")
17938 (symbol_ref "memory_address_length (operands[0], false)"))
17939 (set_attr "memory" "none")])
17941 (define_insn "*prefetch_3dnow"
17942 [(prefetch (match_operand 0 "address_operand" "p")
17943 (match_operand:SI 1 "const_int_operand" "n")
17947 if (INTVAL (operands[1]) == 0)
17948 return "prefetch\t%a0";
17950 return "prefetchw\t%a0";
17952 [(set_attr "type" "mmx")
17953 (set (attr "length_address")
17954 (symbol_ref "memory_address_length (operands[0], false)"))
17955 (set_attr "memory" "none")])
17957 (define_insn "*prefetch_prefetchwt1_<mode>"
17958 [(prefetch (match_operand:P 0 "address_operand" "p")
17961 "TARGET_PREFETCHWT1"
17962 "prefetchwt1\t%a0";
17963 [(set_attr "type" "sse")
17964 (set (attr "length_address")
17965 (symbol_ref "memory_address_length (operands[0], false)"))
17966 (set_attr "memory" "none")])
17968 (define_expand "stack_protect_set"
17969 [(match_operand 0 "memory_operand")
17970 (match_operand 1 "memory_operand")]
17971 "TARGET_SSP_TLS_GUARD"
17973 rtx (*insn)(rtx, rtx);
17975 #ifdef TARGET_THREAD_SSP_OFFSET
17976 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17977 insn = (TARGET_LP64
17978 ? gen_stack_tls_protect_set_di
17979 : gen_stack_tls_protect_set_si);
17981 insn = (TARGET_LP64
17982 ? gen_stack_protect_set_di
17983 : gen_stack_protect_set_si);
17986 emit_insn (insn (operands[0], operands[1]));
17990 (define_insn "stack_protect_set_<mode>"
17991 [(set (match_operand:PTR 0 "memory_operand" "=m")
17992 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17994 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17995 (clobber (reg:CC FLAGS_REG))]
17996 "TARGET_SSP_TLS_GUARD"
17997 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17998 [(set_attr "type" "multi")])
18000 (define_insn "stack_tls_protect_set_<mode>"
18001 [(set (match_operand:PTR 0 "memory_operand" "=m")
18002 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18003 UNSPEC_SP_TLS_SET))
18004 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18005 (clobber (reg:CC FLAGS_REG))]
18007 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18008 [(set_attr "type" "multi")])
18010 (define_expand "stack_protect_test"
18011 [(match_operand 0 "memory_operand")
18012 (match_operand 1 "memory_operand")
18014 "TARGET_SSP_TLS_GUARD"
18016 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18018 rtx (*insn)(rtx, rtx, rtx);
18020 #ifdef TARGET_THREAD_SSP_OFFSET
18021 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18022 insn = (TARGET_LP64
18023 ? gen_stack_tls_protect_test_di
18024 : gen_stack_tls_protect_test_si);
18026 insn = (TARGET_LP64
18027 ? gen_stack_protect_test_di
18028 : gen_stack_protect_test_si);
18031 emit_insn (insn (flags, operands[0], operands[1]));
18033 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18034 flags, const0_rtx, operands[2]));
18038 (define_insn "stack_protect_test_<mode>"
18039 [(set (match_operand:CCZ 0 "flags_reg_operand")
18040 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18041 (match_operand:PTR 2 "memory_operand" "m")]
18043 (clobber (match_scratch:PTR 3 "=&r"))]
18044 "TARGET_SSP_TLS_GUARD"
18045 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18046 [(set_attr "type" "multi")])
18048 (define_insn "stack_tls_protect_test_<mode>"
18049 [(set (match_operand:CCZ 0 "flags_reg_operand")
18050 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18051 (match_operand:PTR 2 "const_int_operand" "i")]
18052 UNSPEC_SP_TLS_TEST))
18053 (clobber (match_scratch:PTR 3 "=r"))]
18055 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18056 [(set_attr "type" "multi")])
18058 (define_insn "sse4_2_crc32<mode>"
18059 [(set (match_operand:SI 0 "register_operand" "=r")
18061 [(match_operand:SI 1 "register_operand" "0")
18062 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18064 "TARGET_SSE4_2 || TARGET_CRC32"
18065 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18066 [(set_attr "type" "sselog1")
18067 (set_attr "prefix_rep" "1")
18068 (set_attr "prefix_extra" "1")
18069 (set (attr "prefix_data16")
18070 (if_then_else (match_operand:HI 2)
18072 (const_string "*")))
18073 (set (attr "prefix_rex")
18074 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18076 (const_string "*")))
18077 (set_attr "mode" "SI")])
18079 (define_insn "sse4_2_crc32di"
18080 [(set (match_operand:DI 0 "register_operand" "=r")
18082 [(match_operand:DI 1 "register_operand" "0")
18083 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18085 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18086 "crc32{q}\t{%2, %0|%0, %2}"
18087 [(set_attr "type" "sselog1")
18088 (set_attr "prefix_rep" "1")
18089 (set_attr "prefix_extra" "1")
18090 (set_attr "mode" "DI")])
18092 (define_insn "rdpmc"
18093 [(set (match_operand:DI 0 "register_operand" "=A")
18094 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18098 [(set_attr "type" "other")
18099 (set_attr "length" "2")])
18101 (define_insn "rdpmc_rex64"
18102 [(set (match_operand:DI 0 "register_operand" "=a")
18103 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18105 (set (match_operand:DI 1 "register_operand" "=d")
18106 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18109 [(set_attr "type" "other")
18110 (set_attr "length" "2")])
18112 (define_insn "rdtsc"
18113 [(set (match_operand:DI 0 "register_operand" "=A")
18114 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18117 [(set_attr "type" "other")
18118 (set_attr "length" "2")])
18120 (define_insn "rdtsc_rex64"
18121 [(set (match_operand:DI 0 "register_operand" "=a")
18122 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18123 (set (match_operand:DI 1 "register_operand" "=d")
18124 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18127 [(set_attr "type" "other")
18128 (set_attr "length" "2")])
18130 (define_insn "rdtscp"
18131 [(set (match_operand:DI 0 "register_operand" "=A")
18132 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18133 (set (match_operand:SI 1 "register_operand" "=c")
18134 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18137 [(set_attr "type" "other")
18138 (set_attr "length" "3")])
18140 (define_insn "rdtscp_rex64"
18141 [(set (match_operand:DI 0 "register_operand" "=a")
18142 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18143 (set (match_operand:DI 1 "register_operand" "=d")
18144 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18145 (set (match_operand:SI 2 "register_operand" "=c")
18146 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18149 [(set_attr "type" "other")
18150 (set_attr "length" "3")])
18152 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18154 ;; FXSR, XSAVE and XSAVEOPT instructions
18156 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18158 (define_insn "fxsave"
18159 [(set (match_operand:BLK 0 "memory_operand" "=m")
18160 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18163 [(set_attr "type" "other")
18164 (set_attr "memory" "store")
18165 (set (attr "length")
18166 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18168 (define_insn "fxsave64"
18169 [(set (match_operand:BLK 0 "memory_operand" "=m")
18170 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18171 "TARGET_64BIT && TARGET_FXSR"
18173 [(set_attr "type" "other")
18174 (set_attr "memory" "store")
18175 (set (attr "length")
18176 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18178 (define_insn "fxrstor"
18179 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18183 [(set_attr "type" "other")
18184 (set_attr "memory" "load")
18185 (set (attr "length")
18186 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18188 (define_insn "fxrstor64"
18189 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18190 UNSPECV_FXRSTOR64)]
18191 "TARGET_64BIT && TARGET_FXSR"
18193 [(set_attr "type" "other")
18194 (set_attr "memory" "load")
18195 (set (attr "length")
18196 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18198 (define_int_iterator ANY_XSAVE
18200 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18201 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18202 (UNSPECV_XSAVES "TARGET_XSAVES")])
18204 (define_int_iterator ANY_XSAVE64
18206 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18207 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18208 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18210 (define_int_attr xsave
18211 [(UNSPECV_XSAVE "xsave")
18212 (UNSPECV_XSAVE64 "xsave64")
18213 (UNSPECV_XSAVEOPT "xsaveopt")
18214 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18215 (UNSPECV_XSAVEC "xsavec")
18216 (UNSPECV_XSAVEC64 "xsavec64")
18217 (UNSPECV_XSAVES "xsaves")
18218 (UNSPECV_XSAVES64 "xsaves64")])
18220 (define_int_iterator ANY_XRSTOR
18222 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18224 (define_int_iterator ANY_XRSTOR64
18226 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18228 (define_int_attr xrstor
18229 [(UNSPECV_XRSTOR "xrstor")
18230 (UNSPECV_XRSTOR64 "xrstor")
18231 (UNSPECV_XRSTORS "xrstors")
18232 (UNSPECV_XRSTORS64 "xrstors")])
18234 (define_insn "<xsave>"
18235 [(set (match_operand:BLK 0 "memory_operand" "=m")
18236 (unspec_volatile:BLK
18237 [(match_operand:DI 1 "register_operand" "A")]
18239 "!TARGET_64BIT && TARGET_XSAVE"
18241 [(set_attr "type" "other")
18242 (set_attr "memory" "store")
18243 (set (attr "length")
18244 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18246 (define_insn "<xsave>_rex64"
18247 [(set (match_operand:BLK 0 "memory_operand" "=m")
18248 (unspec_volatile:BLK
18249 [(match_operand:SI 1 "register_operand" "a")
18250 (match_operand:SI 2 "register_operand" "d")]
18252 "TARGET_64BIT && TARGET_XSAVE"
18254 [(set_attr "type" "other")
18255 (set_attr "memory" "store")
18256 (set (attr "length")
18257 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18259 (define_insn "<xsave>"
18260 [(set (match_operand:BLK 0 "memory_operand" "=m")
18261 (unspec_volatile:BLK
18262 [(match_operand:SI 1 "register_operand" "a")
18263 (match_operand:SI 2 "register_operand" "d")]
18265 "TARGET_64BIT && TARGET_XSAVE"
18267 [(set_attr "type" "other")
18268 (set_attr "memory" "store")
18269 (set (attr "length")
18270 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18272 (define_insn "<xrstor>"
18273 [(unspec_volatile:BLK
18274 [(match_operand:BLK 0 "memory_operand" "m")
18275 (match_operand:DI 1 "register_operand" "A")]
18277 "!TARGET_64BIT && TARGET_XSAVE"
18279 [(set_attr "type" "other")
18280 (set_attr "memory" "load")
18281 (set (attr "length")
18282 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18284 (define_insn "<xrstor>_rex64"
18285 [(unspec_volatile:BLK
18286 [(match_operand:BLK 0 "memory_operand" "m")
18287 (match_operand:SI 1 "register_operand" "a")
18288 (match_operand:SI 2 "register_operand" "d")]
18290 "TARGET_64BIT && TARGET_XSAVE"
18292 [(set_attr "type" "other")
18293 (set_attr "memory" "load")
18294 (set (attr "length")
18295 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18297 (define_insn "<xrstor>64"
18298 [(unspec_volatile:BLK
18299 [(match_operand:BLK 0 "memory_operand" "m")
18300 (match_operand:SI 1 "register_operand" "a")
18301 (match_operand:SI 2 "register_operand" "d")]
18303 "TARGET_64BIT && TARGET_XSAVE"
18305 [(set_attr "type" "other")
18306 (set_attr "memory" "load")
18307 (set (attr "length")
18308 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18310 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18312 ;; Floating-point instructions for atomic compound assignments
18314 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18316 ; Clobber all floating-point registers on environment save and restore
18317 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18318 (define_insn "fnstenv"
18319 [(set (match_operand:BLK 0 "memory_operand" "=m")
18320 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18321 (clobber (reg:HI FPCR_REG))
18322 (clobber (reg:XF ST0_REG))
18323 (clobber (reg:XF ST1_REG))
18324 (clobber (reg:XF ST2_REG))
18325 (clobber (reg:XF ST3_REG))
18326 (clobber (reg:XF ST4_REG))
18327 (clobber (reg:XF ST5_REG))
18328 (clobber (reg:XF ST6_REG))
18329 (clobber (reg:XF ST7_REG))]
18332 [(set_attr "type" "other")
18333 (set_attr "memory" "store")
18334 (set (attr "length")
18335 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18337 (define_insn "fldenv"
18338 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18340 (clobber (reg:CCFP FPSR_REG))
18341 (clobber (reg:HI FPCR_REG))
18342 (clobber (reg:XF ST0_REG))
18343 (clobber (reg:XF ST1_REG))
18344 (clobber (reg:XF ST2_REG))
18345 (clobber (reg:XF ST3_REG))
18346 (clobber (reg:XF ST4_REG))
18347 (clobber (reg:XF ST5_REG))
18348 (clobber (reg:XF ST6_REG))
18349 (clobber (reg:XF ST7_REG))]
18352 [(set_attr "type" "other")
18353 (set_attr "memory" "load")
18354 (set (attr "length")
18355 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18357 (define_insn "fnstsw"
18358 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18359 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18362 [(set_attr "type" "other,other")
18363 (set_attr "memory" "none,store")
18364 (set (attr "length")
18365 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18367 (define_insn "fnclex"
18368 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18371 [(set_attr "type" "other")
18372 (set_attr "memory" "none")
18373 (set_attr "length" "2")])
18375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18377 ;; LWP instructions
18379 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18381 (define_expand "lwp_llwpcb"
18382 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18383 UNSPECV_LLWP_INTRINSIC)]
18386 (define_insn "*lwp_llwpcb<mode>1"
18387 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18388 UNSPECV_LLWP_INTRINSIC)]
18391 [(set_attr "type" "lwp")
18392 (set_attr "mode" "<MODE>")
18393 (set_attr "length" "5")])
18395 (define_expand "lwp_slwpcb"
18396 [(set (match_operand 0 "register_operand" "=r")
18397 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18402 insn = (Pmode == DImode
18404 : gen_lwp_slwpcbsi);
18406 emit_insn (insn (operands[0]));
18410 (define_insn "lwp_slwpcb<mode>"
18411 [(set (match_operand:P 0 "register_operand" "=r")
18412 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18415 [(set_attr "type" "lwp")
18416 (set_attr "mode" "<MODE>")
18417 (set_attr "length" "5")])
18419 (define_expand "lwp_lwpval<mode>3"
18420 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18421 (match_operand:SI 2 "nonimmediate_operand" "rm")
18422 (match_operand:SI 3 "const_int_operand" "i")]
18423 UNSPECV_LWPVAL_INTRINSIC)]
18425 ;; Avoid unused variable warning.
18426 "(void) operands[0];")
18428 (define_insn "*lwp_lwpval<mode>3_1"
18429 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18430 (match_operand:SI 1 "nonimmediate_operand" "rm")
18431 (match_operand:SI 2 "const_int_operand" "i")]
18432 UNSPECV_LWPVAL_INTRINSIC)]
18434 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18435 [(set_attr "type" "lwp")
18436 (set_attr "mode" "<MODE>")
18437 (set (attr "length")
18438 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18440 (define_expand "lwp_lwpins<mode>3"
18441 [(set (reg:CCC FLAGS_REG)
18442 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18443 (match_operand:SI 2 "nonimmediate_operand" "rm")
18444 (match_operand:SI 3 "const_int_operand" "i")]
18445 UNSPECV_LWPINS_INTRINSIC))
18446 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18447 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18450 (define_insn "*lwp_lwpins<mode>3_1"
18451 [(set (reg:CCC FLAGS_REG)
18452 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18453 (match_operand:SI 1 "nonimmediate_operand" "rm")
18454 (match_operand:SI 2 "const_int_operand" "i")]
18455 UNSPECV_LWPINS_INTRINSIC))]
18457 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18458 [(set_attr "type" "lwp")
18459 (set_attr "mode" "<MODE>")
18460 (set (attr "length")
18461 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18463 (define_int_iterator RDFSGSBASE
18467 (define_int_iterator WRFSGSBASE
18471 (define_int_attr fsgs
18472 [(UNSPECV_RDFSBASE "fs")
18473 (UNSPECV_RDGSBASE "gs")
18474 (UNSPECV_WRFSBASE "fs")
18475 (UNSPECV_WRGSBASE "gs")])
18477 (define_insn "rd<fsgs>base<mode>"
18478 [(set (match_operand:SWI48 0 "register_operand" "=r")
18479 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18480 "TARGET_64BIT && TARGET_FSGSBASE"
18482 [(set_attr "type" "other")
18483 (set_attr "prefix_extra" "2")])
18485 (define_insn "wr<fsgs>base<mode>"
18486 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18488 "TARGET_64BIT && TARGET_FSGSBASE"
18490 [(set_attr "type" "other")
18491 (set_attr "prefix_extra" "2")])
18493 (define_insn "rdrand<mode>_1"
18494 [(set (match_operand:SWI248 0 "register_operand" "=r")
18495 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18496 (set (reg:CCC FLAGS_REG)
18497 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18500 [(set_attr "type" "other")
18501 (set_attr "prefix_extra" "1")])
18503 (define_insn "rdseed<mode>_1"
18504 [(set (match_operand:SWI248 0 "register_operand" "=r")
18505 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18506 (set (reg:CCC FLAGS_REG)
18507 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18510 [(set_attr "type" "other")
18511 (set_attr "prefix_extra" "1")])
18513 (define_expand "pause"
18514 [(set (match_dup 0)
18515 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18518 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18519 MEM_VOLATILE_P (operands[0]) = 1;
18522 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18523 ;; They have the same encoding.
18524 (define_insn "*pause"
18525 [(set (match_operand:BLK 0)
18526 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18529 [(set_attr "length" "2")
18530 (set_attr "memory" "unknown")])
18532 (define_expand "xbegin"
18533 [(set (match_operand:SI 0 "register_operand")
18534 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18537 rtx_code_label *label = gen_label_rtx ();
18539 /* xbegin is emitted as jump_insn, so reload won't be able
18540 to reload its operand. Force the value into AX hard register. */
18541 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18542 emit_move_insn (ax_reg, constm1_rtx);
18544 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18546 emit_label (label);
18547 LABEL_NUSES (label) = 1;
18549 emit_move_insn (operands[0], ax_reg);
18554 (define_insn "xbegin_1"
18556 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18558 (label_ref (match_operand 1))
18560 (set (match_operand:SI 0 "register_operand" "+a")
18561 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18564 [(set_attr "type" "other")
18565 (set_attr "length" "6")])
18567 (define_insn "xend"
18568 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18571 [(set_attr "type" "other")
18572 (set_attr "length" "3")])
18574 (define_insn "xabort"
18575 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18579 [(set_attr "type" "other")
18580 (set_attr "length" "3")])
18582 (define_expand "xtest"
18583 [(set (match_operand:QI 0 "register_operand")
18584 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18587 emit_insn (gen_xtest_1 ());
18589 ix86_expand_setcc (operands[0], NE,
18590 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18594 (define_insn "xtest_1"
18595 [(set (reg:CCZ FLAGS_REG)
18596 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18599 [(set_attr "type" "other")
18600 (set_attr "length" "3")])
18602 (define_insn "clflushopt"
18603 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18604 UNSPECV_CLFLUSHOPT)]
18605 "TARGET_CLFLUSHOPT"
18607 [(set_attr "type" "sse")
18608 (set_attr "atom_sse_attr" "fence")
18609 (set_attr "memory" "unknown")])
18613 (include "sync.md")