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 (define_insn "*pushtf"
2737 [(set (match_operand:TF 0 "push_operand" "=<,<")
2738 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2739 "TARGET_64BIT || TARGET_SSE"
2741 /* This insn should be already split before reg-stack. */
2744 [(set_attr "isa" "*,x64")
2745 (set_attr "type" "multi")
2746 (set_attr "unit" "sse,*")
2747 (set_attr "mode" "TF,DI")])
2749 ;; %%% Kill this when call knows how to work this out.
2751 [(set (match_operand:TF 0 "push_operand")
2752 (match_operand:TF 1 "sse_reg_operand"))]
2753 "TARGET_SSE && reload_completed"
2754 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2755 (set (match_dup 0) (match_dup 1))]
2757 /* Preserve memory attributes. */
2758 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2761 (define_insn "*pushxf"
2762 [(set (match_operand:XF 0 "push_operand" "=<,<")
2763 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2766 /* This insn should be already split before reg-stack. */
2769 [(set_attr "type" "multi")
2770 (set_attr "unit" "i387,*")
2772 (cond [(eq_attr "alternative" "1")
2773 (if_then_else (match_test "TARGET_64BIT")
2775 (const_string "SI"))
2777 (const_string "XF")))])
2779 ;; %%% Kill this when call knows how to work this out.
2781 [(set (match_operand:XF 0 "push_operand")
2782 (match_operand:XF 1 "fp_register_operand"))]
2784 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2785 (set (match_dup 0) (match_dup 1))]
2787 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2788 /* Preserve memory attributes. */
2789 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2792 (define_insn "*pushdf"
2793 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2794 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2797 /* This insn should be already split before reg-stack. */
2800 [(set_attr "isa" "*,nox64,x64,sse2")
2801 (set_attr "type" "multi")
2802 (set_attr "unit" "i387,*,*,sse")
2803 (set_attr "mode" "DF,SI,DI,DF")])
2805 ;; %%% Kill this when call knows how to work this out.
2807 [(set (match_operand:DF 0 "push_operand")
2808 (match_operand:DF 1 "any_fp_register_operand"))]
2810 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2811 (set (match_dup 0) (match_dup 1))]
2813 /* Preserve memory attributes. */
2814 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2817 (define_insn "*pushsf_rex64"
2818 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2819 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2822 /* Anything else should be already split before reg-stack. */
2823 gcc_assert (which_alternative == 1);
2824 return "push{q}\t%q1";
2826 [(set_attr "type" "multi,push,multi")
2827 (set_attr "unit" "i387,*,*")
2828 (set_attr "mode" "SF,DI,SF")])
2830 (define_insn "*pushsf"
2831 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2832 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2835 /* Anything else should be already split before reg-stack. */
2836 gcc_assert (which_alternative == 1);
2837 return "push{l}\t%1";
2839 [(set_attr "type" "multi,push,multi")
2840 (set_attr "unit" "i387,*,*")
2841 (set_attr "mode" "SF,SI,SF")])
2843 ;; %%% Kill this when call knows how to work this out.
2845 [(set (match_operand:SF 0 "push_operand")
2846 (match_operand:SF 1 "any_fp_register_operand"))]
2848 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2849 (set (match_dup 0) (match_dup 1))]
2851 rtx op = XEXP (operands[0], 0);
2852 if (GET_CODE (op) == PRE_DEC)
2854 gcc_assert (!TARGET_64BIT);
2859 op = XEXP (XEXP (op, 1), 1);
2860 gcc_assert (CONST_INT_P (op));
2863 /* Preserve memory attributes. */
2864 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2868 [(set (match_operand:SF 0 "push_operand")
2869 (match_operand:SF 1 "memory_operand"))]
2871 && (operands[2] = find_constant_src (insn))"
2872 [(set (match_dup 0) (match_dup 2))])
2875 [(set (match_operand 0 "push_operand")
2876 (match_operand 1 "general_operand"))]
2878 && (GET_MODE (operands[0]) == TFmode
2879 || GET_MODE (operands[0]) == XFmode
2880 || GET_MODE (operands[0]) == DFmode)
2881 && !ANY_FP_REG_P (operands[1])"
2883 "ix86_split_long_move (operands); DONE;")
2885 ;; Floating point move instructions.
2887 (define_expand "movtf"
2888 [(set (match_operand:TF 0 "nonimmediate_operand")
2889 (match_operand:TF 1 "nonimmediate_operand"))]
2890 "TARGET_64BIT || TARGET_SSE"
2891 "ix86_expand_move (TFmode, operands); DONE;")
2893 (define_expand "mov<mode>"
2894 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2895 (match_operand:X87MODEF 1 "general_operand"))]
2897 "ix86_expand_move (<MODE>mode, operands); DONE;")
2899 (define_insn "*movtf_internal"
2900 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2901 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2902 "(TARGET_64BIT || TARGET_SSE)
2903 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2904 && (!can_create_pseudo_p ()
2905 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2906 || GET_CODE (operands[1]) != CONST_DOUBLE
2907 || (optimize_function_for_size_p (cfun)
2908 && standard_sse_constant_p (operands[1])
2909 && !memory_operand (operands[0], TFmode))
2910 || (!TARGET_MEMORY_MISMATCH_STALL
2911 && memory_operand (operands[0], TFmode)))"
2913 switch (get_attr_type (insn))
2916 return standard_sse_constant_opcode (insn, operands[1]);
2919 /* Handle misaligned load/store since we
2920 don't have movmisaligntf pattern. */
2921 if (misaligned_operand (operands[0], TFmode)
2922 || misaligned_operand (operands[1], TFmode))
2924 if (get_attr_mode (insn) == MODE_V4SF)
2925 return "%vmovups\t{%1, %0|%0, %1}";
2927 return "%vmovdqu\t{%1, %0|%0, %1}";
2931 if (get_attr_mode (insn) == MODE_V4SF)
2932 return "%vmovaps\t{%1, %0|%0, %1}";
2934 return "%vmovdqa\t{%1, %0|%0, %1}";
2944 [(set_attr "isa" "*,*,*,x64,x64")
2945 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2946 (set (attr "prefix")
2947 (if_then_else (eq_attr "type" "sselog1,ssemov")
2948 (const_string "maybe_vex")
2949 (const_string "orig")))
2951 (cond [(eq_attr "alternative" "3,4")
2953 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2954 (const_string "V4SF")
2955 (and (eq_attr "alternative" "2")
2956 (match_test "TARGET_SSE_TYPELESS_STORES"))
2957 (const_string "V4SF")
2958 (match_test "TARGET_AVX")
2960 (ior (not (match_test "TARGET_SSE2"))
2961 (match_test "optimize_function_for_size_p (cfun)"))
2962 (const_string "V4SF")
2964 (const_string "TI")))])
2966 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2967 (define_insn "*movxf_internal"
2968 [(set (match_operand:XF 0 "nonimmediate_operand"
2969 "=f,m,f,?Yx*r ,!o ,!o")
2970 (match_operand:XF 1 "general_operand"
2971 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2972 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2973 && (!can_create_pseudo_p ()
2974 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2975 || GET_CODE (operands[1]) != CONST_DOUBLE
2976 || (optimize_function_for_size_p (cfun)
2977 && standard_80387_constant_p (operands[1]) > 0
2978 && !memory_operand (operands[0], XFmode))
2979 || (!TARGET_MEMORY_MISMATCH_STALL
2980 && memory_operand (operands[0], XFmode)))"
2982 switch (get_attr_type (insn))
2985 if (which_alternative == 2)
2986 return standard_80387_constant_opcode (operands[1]);
2987 return output_387_reg_move (insn, operands);
2996 [(set_attr "isa" "*,*,*,*,nox64,x64")
2997 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2999 (cond [(eq_attr "alternative" "3,4,5")
3000 (if_then_else (match_test "TARGET_64BIT")
3002 (const_string "SI"))
3004 (const_string "XF")))])
3006 ;; Possible store forwarding (partial memory) stall in alternative 4.
3007 (define_insn "*movdf_internal"
3008 [(set (match_operand:DF 0 "nonimmediate_operand"
3009 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3010 (match_operand:DF 1 "general_operand"
3011 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3012 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3013 && (!can_create_pseudo_p ()
3014 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3015 || GET_CODE (operands[1]) != CONST_DOUBLE
3016 || (optimize_function_for_size_p (cfun)
3017 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3018 && standard_80387_constant_p (operands[1]) > 0)
3019 || (TARGET_SSE2 && TARGET_SSE_MATH
3020 && standard_sse_constant_p (operands[1])))
3021 && !memory_operand (operands[0], DFmode))
3022 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3023 && memory_operand (operands[0], DFmode)))"
3025 switch (get_attr_type (insn))
3028 if (which_alternative == 2)
3029 return standard_80387_constant_opcode (operands[1]);
3030 return output_387_reg_move (insn, operands);
3036 if (get_attr_mode (insn) == MODE_SI)
3037 return "mov{l}\t{%1, %k0|%k0, %1}";
3038 else if (which_alternative == 8)
3039 return "movabs{q}\t{%1, %0|%0, %1}";
3041 return "mov{q}\t{%1, %0|%0, %1}";
3044 return standard_sse_constant_opcode (insn, operands[1]);
3047 switch (get_attr_mode (insn))
3050 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3051 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3052 return "%vmovsd\t{%1, %0|%0, %1}";
3055 return "%vmovaps\t{%1, %0|%0, %1}";
3057 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3059 return "%vmovapd\t{%1, %0|%0, %1}";
3062 gcc_assert (!TARGET_AVX);
3063 return "movlps\t{%1, %0|%0, %1}";
3065 gcc_assert (!TARGET_AVX);
3066 return "movlpd\t{%1, %0|%0, %1}";
3069 /* Handle broken assemblers that require movd instead of movq. */
3070 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3071 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3072 return "%vmovd\t{%1, %0|%0, %1}";
3073 return "%vmovq\t{%1, %0|%0, %1}";
3084 (cond [(eq_attr "alternative" "3,4")
3085 (const_string "nox64")
3086 (eq_attr "alternative" "5,6,7,8,17,18")
3087 (const_string "x64")
3088 (eq_attr "alternative" "9,10,11,12")
3089 (const_string "sse2")
3091 (const_string "*")))
3093 (cond [(eq_attr "alternative" "0,1,2")
3094 (const_string "fmov")
3095 (eq_attr "alternative" "3,4")
3096 (const_string "multi")
3097 (eq_attr "alternative" "5,6,7,8")
3098 (const_string "imov")
3099 (eq_attr "alternative" "9,13")
3100 (const_string "sselog1")
3102 (const_string "ssemov")))
3104 (if_then_else (eq_attr "alternative" "8")
3106 (const_string "*")))
3107 (set (attr "length_immediate")
3108 (if_then_else (eq_attr "alternative" "8")
3110 (const_string "*")))
3111 (set (attr "prefix")
3112 (if_then_else (eq_attr "type" "sselog1,ssemov")
3113 (const_string "maybe_vex")
3114 (const_string "orig")))
3115 (set (attr "prefix_data16")
3117 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3118 (eq_attr "mode" "V1DF"))
3120 (const_string "*")))
3122 (cond [(eq_attr "alternative" "3,4,7")
3124 (eq_attr "alternative" "5,6,8,17,18")
3127 /* xorps is one byte shorter for non-AVX targets. */
3128 (eq_attr "alternative" "9,13")
3129 (cond [(not (match_test "TARGET_SSE2"))
3130 (const_string "V4SF")
3131 (match_test "TARGET_AVX512F")
3133 (match_test "TARGET_AVX")
3134 (const_string "V2DF")
3135 (match_test "optimize_function_for_size_p (cfun)")
3136 (const_string "V4SF")
3137 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3140 (const_string "V2DF"))
3142 /* For architectures resolving dependencies on
3143 whole SSE registers use movapd to break dependency
3144 chains, otherwise use short move to avoid extra work. */
3146 /* movaps is one byte shorter for non-AVX targets. */
3147 (eq_attr "alternative" "10,14")
3148 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3149 (match_operand 1 "ext_sse_reg_operand"))
3150 (const_string "V8DF")
3151 (ior (not (match_test "TARGET_SSE2"))
3152 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3153 (const_string "V4SF")
3154 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3155 (const_string "V2DF")
3156 (match_test "TARGET_AVX")
3158 (match_test "optimize_function_for_size_p (cfun)")
3159 (const_string "V4SF")
3161 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3166 (eq_attr "alternative" "11,15")
3167 (cond [(not (match_test "TARGET_SSE2"))
3168 (const_string "V2SF")
3169 (match_test "TARGET_AVX")
3171 (match_test "TARGET_SSE_SPLIT_REGS")
3172 (const_string "V1DF")
3174 (const_string "DF"))
3176 (and (eq_attr "alternative" "12,16")
3177 (not (match_test "TARGET_SSE2")))
3178 (const_string "V2SF")
3180 (const_string "DF")))])
3182 (define_insn "*movsf_internal"
3183 [(set (match_operand:SF 0 "nonimmediate_operand"
3184 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3185 (match_operand:SF 1 "general_operand"
3186 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3187 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3188 && (!can_create_pseudo_p ()
3189 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3190 || GET_CODE (operands[1]) != CONST_DOUBLE
3191 || (optimize_function_for_size_p (cfun)
3192 && ((!TARGET_SSE_MATH
3193 && standard_80387_constant_p (operands[1]) > 0)
3195 && standard_sse_constant_p (operands[1]))))
3196 || memory_operand (operands[0], SFmode))"
3198 switch (get_attr_type (insn))
3201 if (which_alternative == 2)
3202 return standard_80387_constant_opcode (operands[1]);
3203 return output_387_reg_move (insn, operands);
3206 return "mov{l}\t{%1, %0|%0, %1}";
3209 return standard_sse_constant_opcode (insn, operands[1]);
3212 switch (get_attr_mode (insn))
3215 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3216 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3217 return "%vmovss\t{%1, %0|%0, %1}";
3220 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3222 return "%vmovaps\t{%1, %0|%0, %1}";
3225 return "%vmovd\t{%1, %0|%0, %1}";
3232 switch (get_attr_mode (insn))
3235 return "movq\t{%1, %0|%0, %1}";
3237 return "movd\t{%1, %0|%0, %1}";
3248 (cond [(eq_attr "alternative" "0,1,2")
3249 (const_string "fmov")
3250 (eq_attr "alternative" "3,4")
3251 (const_string "imov")
3252 (eq_attr "alternative" "5")
3253 (const_string "sselog1")
3254 (eq_attr "alternative" "11,12,13,14,15")
3255 (const_string "mmxmov")
3257 (const_string "ssemov")))
3258 (set (attr "prefix")
3259 (if_then_else (eq_attr "type" "sselog1,ssemov")
3260 (const_string "maybe_vex")
3261 (const_string "orig")))
3262 (set (attr "prefix_data16")
3263 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3265 (const_string "*")))
3267 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3269 (eq_attr "alternative" "11")
3271 (eq_attr "alternative" "5")
3272 (cond [(not (match_test "TARGET_SSE2"))
3273 (const_string "V4SF")
3274 (match_test "TARGET_AVX512F")
3275 (const_string "V16SF")
3276 (match_test "TARGET_AVX")
3277 (const_string "V4SF")
3278 (match_test "optimize_function_for_size_p (cfun)")
3279 (const_string "V4SF")
3280 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3283 (const_string "V4SF"))
3285 /* For architectures resolving dependencies on
3286 whole SSE registers use APS move to break dependency
3287 chains, otherwise use short move to avoid extra work.
3289 Do the same for architectures resolving dependencies on
3290 the parts. While in DF mode it is better to always handle
3291 just register parts, the SF mode is different due to lack
3292 of instructions to load just part of the register. It is
3293 better to maintain the whole registers in single format
3294 to avoid problems on using packed logical operations. */
3295 (eq_attr "alternative" "6")
3296 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3297 (match_operand 1 "ext_sse_reg_operand"))
3298 (const_string "V16SF")
3299 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3300 (match_test "TARGET_SSE_SPLIT_REGS"))
3301 (const_string "V4SF")
3303 (const_string "SF"))
3305 (const_string "SF")))])
3308 [(set (match_operand 0 "any_fp_register_operand")
3309 (match_operand 1 "memory_operand"))]
3311 && (GET_MODE (operands[0]) == TFmode
3312 || GET_MODE (operands[0]) == XFmode
3313 || GET_MODE (operands[0]) == DFmode
3314 || GET_MODE (operands[0]) == SFmode)
3315 && (operands[2] = find_constant_src (insn))"
3316 [(set (match_dup 0) (match_dup 2))]
3318 rtx c = operands[2];
3319 int r = REGNO (operands[0]);
3321 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3322 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3327 [(set (match_operand 0 "any_fp_register_operand")
3328 (float_extend (match_operand 1 "memory_operand")))]
3330 && (GET_MODE (operands[0]) == TFmode
3331 || GET_MODE (operands[0]) == XFmode
3332 || GET_MODE (operands[0]) == DFmode)
3333 && (operands[2] = find_constant_src (insn))"
3334 [(set (match_dup 0) (match_dup 2))]
3336 rtx c = operands[2];
3337 int r = REGNO (operands[0]);
3339 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3340 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3344 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3346 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3347 (match_operand:X87MODEF 1 "immediate_operand"))]
3349 && (standard_80387_constant_p (operands[1]) == 8
3350 || standard_80387_constant_p (operands[1]) == 9)"
3351 [(set (match_dup 0)(match_dup 1))
3353 (neg:X87MODEF (match_dup 0)))]
3357 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3358 if (real_isnegzero (&r))
3359 operands[1] = CONST0_RTX (<MODE>mode);
3361 operands[1] = CONST1_RTX (<MODE>mode);
3365 [(set (match_operand 0 "nonimmediate_operand")
3366 (match_operand 1 "general_operand"))]
3368 && (GET_MODE (operands[0]) == TFmode
3369 || GET_MODE (operands[0]) == XFmode
3370 || GET_MODE (operands[0]) == DFmode)
3371 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3373 "ix86_split_long_move (operands); DONE;")
3375 (define_insn "swapxf"
3376 [(set (match_operand:XF 0 "register_operand" "+f")
3377 (match_operand:XF 1 "register_operand" "+f"))
3382 if (STACK_TOP_P (operands[0]))
3387 [(set_attr "type" "fxch")
3388 (set_attr "mode" "XF")])
3390 (define_insn "*swap<mode>"
3391 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3392 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3395 "TARGET_80387 || reload_completed"
3397 if (STACK_TOP_P (operands[0]))
3402 [(set_attr "type" "fxch")
3403 (set_attr "mode" "<MODE>")])
3405 ;; Zero extension instructions
3407 (define_expand "zero_extendsidi2"
3408 [(set (match_operand:DI 0 "nonimmediate_operand")
3409 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3411 (define_insn "*zero_extendsidi2"
3412 [(set (match_operand:DI 0 "nonimmediate_operand"
3413 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3415 (match_operand:SI 1 "x86_64_zext_operand"
3416 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3419 switch (get_attr_type (insn))
3422 if (ix86_use_lea_for_mov (insn, operands))
3423 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3425 return "mov{l}\t{%1, %k0|%k0, %1}";
3431 return "movd\t{%1, %0|%0, %1}";
3434 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3437 if (GENERAL_REG_P (operands[0]))
3438 return "%vmovd\t{%1, %k0|%k0, %1}";
3440 return "%vmovd\t{%1, %0|%0, %1}";
3447 (cond [(eq_attr "alternative" "0,1,2")
3448 (const_string "nox64")
3449 (eq_attr "alternative" "3,7")
3450 (const_string "x64")
3451 (eq_attr "alternative" "8")
3452 (const_string "x64_sse4")
3453 (eq_attr "alternative" "10")
3454 (const_string "sse2")
3456 (const_string "*")))
3458 (cond [(eq_attr "alternative" "0,1,2,4")
3459 (const_string "multi")
3460 (eq_attr "alternative" "5,6")
3461 (const_string "mmxmov")
3462 (eq_attr "alternative" "7,9,10")
3463 (const_string "ssemov")
3464 (eq_attr "alternative" "8")
3465 (const_string "sselog1")
3467 (const_string "imovx")))
3468 (set (attr "prefix_extra")
3469 (if_then_else (eq_attr "alternative" "8")
3471 (const_string "*")))
3472 (set (attr "length_immediate")
3473 (if_then_else (eq_attr "alternative" "8")
3475 (const_string "*")))
3476 (set (attr "prefix")
3477 (if_then_else (eq_attr "type" "ssemov,sselog1")
3478 (const_string "maybe_vex")
3479 (const_string "orig")))
3480 (set (attr "prefix_0f")
3481 (if_then_else (eq_attr "type" "imovx")
3483 (const_string "*")))
3485 (cond [(eq_attr "alternative" "5,6")
3487 (eq_attr "alternative" "7,8,9")
3490 (const_string "SI")))])
3493 [(set (match_operand:DI 0 "memory_operand")
3494 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3496 [(set (match_dup 4) (const_int 0))]
3497 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3500 [(set (match_operand:DI 0 "register_operand")
3501 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3502 "!TARGET_64BIT && reload_completed
3503 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3504 && true_regnum (operands[0]) == true_regnum (operands[1])"
3505 [(set (match_dup 4) (const_int 0))]
3506 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3509 [(set (match_operand:DI 0 "nonimmediate_operand")
3510 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3511 "!TARGET_64BIT && reload_completed
3512 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3513 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3514 [(set (match_dup 3) (match_dup 1))
3515 (set (match_dup 4) (const_int 0))]
3516 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3518 (define_insn "zero_extend<mode>di2"
3519 [(set (match_operand:DI 0 "register_operand" "=r")
3521 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3523 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3524 [(set_attr "type" "imovx")
3525 (set_attr "mode" "SI")])
3527 (define_expand "zero_extend<mode>si2"
3528 [(set (match_operand:SI 0 "register_operand")
3529 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3532 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3534 operands[1] = force_reg (<MODE>mode, operands[1]);
3535 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3540 (define_insn_and_split "zero_extend<mode>si2_and"
3541 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3543 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3544 (clobber (reg:CC FLAGS_REG))]
3545 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3547 "&& reload_completed"
3548 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3549 (clobber (reg:CC FLAGS_REG))])]
3551 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3553 ix86_expand_clear (operands[0]);
3555 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3556 emit_insn (gen_movstrict<mode>
3557 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3561 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3563 [(set_attr "type" "alu1")
3564 (set_attr "mode" "SI")])
3566 (define_insn "*zero_extend<mode>si2"
3567 [(set (match_operand:SI 0 "register_operand" "=r")
3569 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3570 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3571 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3572 [(set_attr "type" "imovx")
3573 (set_attr "mode" "SI")])
3575 (define_expand "zero_extendqihi2"
3576 [(set (match_operand:HI 0 "register_operand")
3577 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3580 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3582 operands[1] = force_reg (QImode, operands[1]);
3583 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3588 (define_insn_and_split "zero_extendqihi2_and"
3589 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3590 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3591 (clobber (reg:CC FLAGS_REG))]
3592 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3594 "&& reload_completed"
3595 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3596 (clobber (reg:CC FLAGS_REG))])]
3598 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3600 ix86_expand_clear (operands[0]);
3602 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3603 emit_insn (gen_movstrictqi
3604 (gen_lowpart (QImode, operands[0]), operands[1]));
3608 operands[0] = gen_lowpart (SImode, operands[0]);
3610 [(set_attr "type" "alu1")
3611 (set_attr "mode" "SI")])
3613 ; zero extend to SImode to avoid partial register stalls
3614 (define_insn "*zero_extendqihi2"
3615 [(set (match_operand:HI 0 "register_operand" "=r")
3616 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3617 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3618 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3619 [(set_attr "type" "imovx")
3620 (set_attr "mode" "SI")])
3622 ;; Sign extension instructions
3624 (define_expand "extendsidi2"
3625 [(set (match_operand:DI 0 "register_operand")
3626 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3631 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3636 (define_insn "*extendsidi2_rex64"
3637 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3638 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3642 movs{lq|x}\t{%1, %0|%0, %1}"
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "DI")
3645 (set_attr "prefix_0f" "0")
3646 (set_attr "modrm" "0,1")])
3648 (define_insn "extendsidi2_1"
3649 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3650 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3651 (clobber (reg:CC FLAGS_REG))
3652 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3656 ;; Split the memory case. If the source register doesn't die, it will stay
3657 ;; this way, if it does die, following peephole2s take care of it.
3659 [(set (match_operand:DI 0 "memory_operand")
3660 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3661 (clobber (reg:CC FLAGS_REG))
3662 (clobber (match_operand:SI 2 "register_operand"))]
3666 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3668 emit_move_insn (operands[3], operands[1]);
3670 /* Generate a cltd if possible and doing so it profitable. */
3671 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3672 && true_regnum (operands[1]) == AX_REG
3673 && true_regnum (operands[2]) == DX_REG)
3675 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3679 emit_move_insn (operands[2], operands[1]);
3680 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3682 emit_move_insn (operands[4], operands[2]);
3686 ;; Peepholes for the case where the source register does die, after
3687 ;; being split with the above splitter.
3689 [(set (match_operand:SI 0 "memory_operand")
3690 (match_operand:SI 1 "register_operand"))
3691 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3692 (parallel [(set (match_dup 2)
3693 (ashiftrt:SI (match_dup 2) (const_int 31)))
3694 (clobber (reg:CC FLAGS_REG))])
3695 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3696 "REGNO (operands[1]) != REGNO (operands[2])
3697 && peep2_reg_dead_p (2, operands[1])
3698 && peep2_reg_dead_p (4, operands[2])
3699 && !reg_mentioned_p (operands[2], operands[3])"
3700 [(set (match_dup 0) (match_dup 1))
3701 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3702 (clobber (reg:CC FLAGS_REG))])
3703 (set (match_dup 3) (match_dup 1))])
3706 [(set (match_operand:SI 0 "memory_operand")
3707 (match_operand:SI 1 "register_operand"))
3708 (parallel [(set (match_operand:SI 2 "register_operand")
3709 (ashiftrt:SI (match_dup 1) (const_int 31)))
3710 (clobber (reg:CC FLAGS_REG))])
3711 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3712 "/* cltd is shorter than sarl $31, %eax */
3713 !optimize_function_for_size_p (cfun)
3714 && true_regnum (operands[1]) == AX_REG
3715 && true_regnum (operands[2]) == DX_REG
3716 && peep2_reg_dead_p (2, operands[1])
3717 && peep2_reg_dead_p (3, operands[2])
3718 && !reg_mentioned_p (operands[2], operands[3])"
3719 [(set (match_dup 0) (match_dup 1))
3720 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3721 (clobber (reg:CC FLAGS_REG))])
3722 (set (match_dup 3) (match_dup 1))])
3724 ;; Extend to register case. Optimize case where source and destination
3725 ;; registers match and cases where we can use cltd.
3727 [(set (match_operand:DI 0 "register_operand")
3728 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3729 (clobber (reg:CC FLAGS_REG))
3730 (clobber (match_scratch:SI 2))]
3734 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3736 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3737 emit_move_insn (operands[3], operands[1]);
3739 /* Generate a cltd if possible and doing so it profitable. */
3740 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3741 && true_regnum (operands[3]) == AX_REG
3742 && true_regnum (operands[4]) == DX_REG)
3744 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3748 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3749 emit_move_insn (operands[4], operands[1]);
3751 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3755 (define_insn "extend<mode>di2"
3756 [(set (match_operand:DI 0 "register_operand" "=r")
3758 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3760 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3761 [(set_attr "type" "imovx")
3762 (set_attr "mode" "DI")])
3764 (define_insn "extendhisi2"
3765 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3766 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3769 switch (get_attr_prefix_0f (insn))
3772 return "{cwtl|cwde}";
3774 return "movs{wl|x}\t{%1, %0|%0, %1}";
3777 [(set_attr "type" "imovx")
3778 (set_attr "mode" "SI")
3779 (set (attr "prefix_0f")
3780 ;; movsx is short decodable while cwtl is vector decoded.
3781 (if_then_else (and (eq_attr "cpu" "!k6")
3782 (eq_attr "alternative" "0"))
3784 (const_string "1")))
3786 (if_then_else (eq_attr "prefix_0f" "0")
3788 (const_string "1")))])
3790 (define_insn "*extendhisi2_zext"
3791 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3794 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3797 switch (get_attr_prefix_0f (insn))
3800 return "{cwtl|cwde}";
3802 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3805 [(set_attr "type" "imovx")
3806 (set_attr "mode" "SI")
3807 (set (attr "prefix_0f")
3808 ;; movsx is short decodable while cwtl is vector decoded.
3809 (if_then_else (and (eq_attr "cpu" "!k6")
3810 (eq_attr "alternative" "0"))
3812 (const_string "1")))
3814 (if_then_else (eq_attr "prefix_0f" "0")
3816 (const_string "1")))])
3818 (define_insn "extendqisi2"
3819 [(set (match_operand:SI 0 "register_operand" "=r")
3820 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3822 "movs{bl|x}\t{%1, %0|%0, %1}"
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")])
3826 (define_insn "*extendqisi2_zext"
3827 [(set (match_operand:DI 0 "register_operand" "=r")
3829 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3831 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3832 [(set_attr "type" "imovx")
3833 (set_attr "mode" "SI")])
3835 (define_insn "extendqihi2"
3836 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3837 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3840 switch (get_attr_prefix_0f (insn))
3843 return "{cbtw|cbw}";
3845 return "movs{bw|x}\t{%1, %0|%0, %1}";
3848 [(set_attr "type" "imovx")
3849 (set_attr "mode" "HI")
3850 (set (attr "prefix_0f")
3851 ;; movsx is short decodable while cwtl is vector decoded.
3852 (if_then_else (and (eq_attr "cpu" "!k6")
3853 (eq_attr "alternative" "0"))
3855 (const_string "1")))
3857 (if_then_else (eq_attr "prefix_0f" "0")
3859 (const_string "1")))])
3861 ;; Conversions between float and double.
3863 ;; These are all no-ops in the model used for the 80387.
3864 ;; So just emit moves.
3866 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3868 [(set (match_operand:DF 0 "push_operand")
3869 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3871 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3872 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3875 [(set (match_operand:XF 0 "push_operand")
3876 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3878 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3879 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3880 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3882 (define_expand "extendsfdf2"
3883 [(set (match_operand:DF 0 "nonimmediate_operand")
3884 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3885 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3887 /* ??? Needed for compress_float_constant since all fp constants
3888 are TARGET_LEGITIMATE_CONSTANT_P. */
3889 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3891 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3892 && standard_80387_constant_p (operands[1]) > 0)
3894 operands[1] = simplify_const_unary_operation
3895 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3896 emit_move_insn_1 (operands[0], operands[1]);
3899 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3903 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3905 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3907 We do the conversion post reload to avoid producing of 128bit spills
3908 that might lead to ICE on 32bit target. The sequence unlikely combine
3911 [(set (match_operand:DF 0 "register_operand")
3913 (match_operand:SF 1 "nonimmediate_operand")))]
3914 "TARGET_USE_VECTOR_FP_CONVERTS
3915 && optimize_insn_for_speed_p ()
3916 && reload_completed && SSE_REG_P (operands[0])"
3921 (parallel [(const_int 0) (const_int 1)]))))]
3923 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3924 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3925 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3926 Try to avoid move when unpacking can be done in source. */
3927 if (REG_P (operands[1]))
3929 /* If it is unsafe to overwrite upper half of source, we need
3930 to move to destination and unpack there. */
3931 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3932 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3933 && true_regnum (operands[0]) != true_regnum (operands[1]))
3935 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3936 emit_move_insn (tmp, operands[1]);
3939 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3940 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3944 emit_insn (gen_vec_setv4sf_0 (operands[3],
3945 CONST0_RTX (V4SFmode), operands[1]));
3948 ;; It's more profitable to split and then extend in the same register.
3950 [(set (match_operand:DF 0 "register_operand")
3952 (match_operand:SF 1 "memory_operand")))]
3953 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3954 && optimize_insn_for_speed_p ()
3955 && SSE_REG_P (operands[0])"
3956 [(set (match_dup 2) (match_dup 1))
3957 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3958 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3960 (define_insn "*extendsfdf2_mixed"
3961 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3963 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3964 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3966 switch (which_alternative)
3970 return output_387_reg_move (insn, operands);
3973 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3979 [(set_attr "type" "fmov,fmov,ssecvt")
3980 (set_attr "prefix" "orig,orig,maybe_vex")
3981 (set_attr "mode" "SF,XF,DF")])
3983 (define_insn "*extendsfdf2_sse"
3984 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3985 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3986 "TARGET_SSE2 && TARGET_SSE_MATH"
3987 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3988 [(set_attr "type" "ssecvt")
3989 (set_attr "prefix" "maybe_vex")
3990 (set_attr "mode" "DF")])
3992 (define_insn "*extendsfdf2_i387"
3993 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3994 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3996 "* return output_387_reg_move (insn, operands);"
3997 [(set_attr "type" "fmov")
3998 (set_attr "mode" "SF,XF")])
4000 (define_expand "extend<mode>xf2"
4001 [(set (match_operand:XF 0 "nonimmediate_operand")
4002 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4005 /* ??? Needed for compress_float_constant since all fp constants
4006 are TARGET_LEGITIMATE_CONSTANT_P. */
4007 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4009 if (standard_80387_constant_p (operands[1]) > 0)
4011 operands[1] = simplify_const_unary_operation
4012 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4013 emit_move_insn_1 (operands[0], operands[1]);
4016 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4020 (define_insn "*extend<mode>xf2_i387"
4021 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4023 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4025 "* return output_387_reg_move (insn, operands);"
4026 [(set_attr "type" "fmov")
4027 (set_attr "mode" "<MODE>,XF")])
4029 ;; %%% This seems bad bad news.
4030 ;; This cannot output into an f-reg because there is no way to be sure
4031 ;; of truncating in that case. Otherwise this is just like a simple move
4032 ;; insn. So we pretend we can output to a reg in order to get better
4033 ;; register preferencing, but we really use a stack slot.
4035 ;; Conversion from DFmode to SFmode.
4037 (define_expand "truncdfsf2"
4038 [(set (match_operand:SF 0 "nonimmediate_operand")
4040 (match_operand:DF 1 "nonimmediate_operand")))]
4041 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4043 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4045 else if (flag_unsafe_math_optimizations)
4049 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4050 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4055 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4057 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4059 We do the conversion post reload to avoid producing of 128bit spills
4060 that might lead to ICE on 32bit target. The sequence unlikely combine
4063 [(set (match_operand:SF 0 "register_operand")
4065 (match_operand:DF 1 "nonimmediate_operand")))]
4066 "TARGET_USE_VECTOR_FP_CONVERTS
4067 && optimize_insn_for_speed_p ()
4068 && reload_completed && SSE_REG_P (operands[0])"
4071 (float_truncate:V2SF
4075 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4076 operands[3] = CONST0_RTX (V2SFmode);
4077 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4078 /* Use movsd for loading from memory, unpcklpd for registers.
4079 Try to avoid move when unpacking can be done in source, or SSE3
4080 movddup is available. */
4081 if (REG_P (operands[1]))
4084 && true_regnum (operands[0]) != true_regnum (operands[1])
4085 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4086 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4088 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4089 emit_move_insn (tmp, operands[1]);
4092 else if (!TARGET_SSE3)
4093 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4094 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4097 emit_insn (gen_sse2_loadlpd (operands[4],
4098 CONST0_RTX (V2DFmode), operands[1]));
4101 ;; It's more profitable to split and then extend in the same register.
4103 [(set (match_operand:SF 0 "register_operand")
4105 (match_operand:DF 1 "memory_operand")))]
4106 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4107 && optimize_insn_for_speed_p ()
4108 && SSE_REG_P (operands[0])"
4109 [(set (match_dup 2) (match_dup 1))
4110 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4111 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4113 (define_expand "truncdfsf2_with_temp"
4114 [(parallel [(set (match_operand:SF 0)
4115 (float_truncate:SF (match_operand:DF 1)))
4116 (clobber (match_operand:SF 2))])])
4118 (define_insn "*truncdfsf_fast_mixed"
4119 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4121 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4122 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4124 switch (which_alternative)
4127 return output_387_reg_move (insn, operands);
4129 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4134 [(set_attr "type" "fmov,ssecvt")
4135 (set_attr "prefix" "orig,maybe_vex")
4136 (set_attr "mode" "SF")])
4138 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4139 ;; because nothing we do here is unsafe.
4140 (define_insn "*truncdfsf_fast_sse"
4141 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4143 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4144 "TARGET_SSE2 && TARGET_SSE_MATH"
4145 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4146 [(set_attr "type" "ssecvt")
4147 (set_attr "prefix" "maybe_vex")
4148 (set_attr "mode" "SF")])
4150 (define_insn "*truncdfsf_fast_i387"
4151 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4153 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4154 "TARGET_80387 && flag_unsafe_math_optimizations"
4155 "* return output_387_reg_move (insn, operands);"
4156 [(set_attr "type" "fmov")
4157 (set_attr "mode" "SF")])
4159 (define_insn "*truncdfsf_mixed"
4160 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4162 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4163 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4164 "TARGET_MIX_SSE_I387"
4166 switch (which_alternative)
4169 return output_387_reg_move (insn, operands);
4171 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4177 [(set_attr "isa" "*,sse2,*,*,*")
4178 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4179 (set_attr "unit" "*,*,i387,i387,i387")
4180 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4181 (set_attr "mode" "SF")])
4183 (define_insn "*truncdfsf_i387"
4184 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4186 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4187 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4190 switch (which_alternative)
4193 return output_387_reg_move (insn, operands);
4199 [(set_attr "type" "fmov,multi,multi,multi")
4200 (set_attr "unit" "*,i387,i387,i387")
4201 (set_attr "mode" "SF")])
4203 (define_insn "*truncdfsf2_i387_1"
4204 [(set (match_operand:SF 0 "memory_operand" "=m")
4206 (match_operand:DF 1 "register_operand" "f")))]
4208 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4209 && !TARGET_MIX_SSE_I387"
4210 "* return output_387_reg_move (insn, operands);"
4211 [(set_attr "type" "fmov")
4212 (set_attr "mode" "SF")])
4215 [(set (match_operand:SF 0 "register_operand")
4217 (match_operand:DF 1 "fp_register_operand")))
4218 (clobber (match_operand 2))]
4220 [(set (match_dup 2) (match_dup 1))
4221 (set (match_dup 0) (match_dup 2))]
4222 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4224 ;; Conversion from XFmode to {SF,DF}mode
4226 (define_expand "truncxf<mode>2"
4227 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4228 (float_truncate:MODEF
4229 (match_operand:XF 1 "register_operand")))
4230 (clobber (match_dup 2))])]
4233 if (flag_unsafe_math_optimizations)
4235 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4236 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4237 if (reg != operands[0])
4238 emit_move_insn (operands[0], reg);
4242 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4245 (define_insn "*truncxfsf2_mixed"
4246 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4248 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4249 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4252 gcc_assert (!which_alternative);
4253 return output_387_reg_move (insn, operands);
4255 [(set_attr "type" "fmov,multi,multi,multi")
4256 (set_attr "unit" "*,i387,i387,i387")
4257 (set_attr "mode" "SF")])
4259 (define_insn "*truncxfdf2_mixed"
4260 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4262 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4263 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4266 gcc_assert (!which_alternative);
4267 return output_387_reg_move (insn, operands);
4269 [(set_attr "isa" "*,*,sse2,*")
4270 (set_attr "type" "fmov,multi,multi,multi")
4271 (set_attr "unit" "*,i387,i387,i387")
4272 (set_attr "mode" "DF")])
4274 (define_insn "truncxf<mode>2_i387_noop"
4275 [(set (match_operand:MODEF 0 "register_operand" "=f")
4276 (float_truncate:MODEF
4277 (match_operand:XF 1 "register_operand" "f")))]
4278 "TARGET_80387 && flag_unsafe_math_optimizations"
4279 "* return output_387_reg_move (insn, operands);"
4280 [(set_attr "type" "fmov")
4281 (set_attr "mode" "<MODE>")])
4283 (define_insn "*truncxf<mode>2_i387"
4284 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4285 (float_truncate:MODEF
4286 (match_operand:XF 1 "register_operand" "f")))]
4288 "* return output_387_reg_move (insn, operands);"
4289 [(set_attr "type" "fmov")
4290 (set_attr "mode" "<MODE>")])
4293 [(set (match_operand:MODEF 0 "register_operand")
4294 (float_truncate:MODEF
4295 (match_operand:XF 1 "register_operand")))
4296 (clobber (match_operand:MODEF 2 "memory_operand"))]
4297 "TARGET_80387 && reload_completed"
4298 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4299 (set (match_dup 0) (match_dup 2))])
4302 [(set (match_operand:MODEF 0 "memory_operand")
4303 (float_truncate:MODEF
4304 (match_operand:XF 1 "register_operand")))
4305 (clobber (match_operand:MODEF 2 "memory_operand"))]
4307 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4309 ;; Signed conversion to DImode.
4311 (define_expand "fix_truncxfdi2"
4312 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4313 (fix:DI (match_operand:XF 1 "register_operand")))
4314 (clobber (reg:CC FLAGS_REG))])]
4319 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4324 (define_expand "fix_trunc<mode>di2"
4325 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4326 (fix:DI (match_operand:MODEF 1 "register_operand")))
4327 (clobber (reg:CC FLAGS_REG))])]
4328 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4333 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4336 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4338 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4339 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4340 if (out != operands[0])
4341 emit_move_insn (operands[0], out);
4346 ;; Signed conversion to SImode.
4348 (define_expand "fix_truncxfsi2"
4349 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4350 (fix:SI (match_operand:XF 1 "register_operand")))
4351 (clobber (reg:CC FLAGS_REG))])]
4356 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4361 (define_expand "fix_trunc<mode>si2"
4362 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4363 (fix:SI (match_operand:MODEF 1 "register_operand")))
4364 (clobber (reg:CC FLAGS_REG))])]
4365 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4368 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4370 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4373 if (SSE_FLOAT_MODE_P (<MODE>mode))
4375 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4376 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4377 if (out != operands[0])
4378 emit_move_insn (operands[0], out);
4383 ;; Signed conversion to HImode.
4385 (define_expand "fix_trunc<mode>hi2"
4386 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4387 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4388 (clobber (reg:CC FLAGS_REG))])]
4390 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4394 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4399 ;; Unsigned conversion to SImode.
4401 (define_expand "fixuns_trunc<mode>si2"
4403 [(set (match_operand:SI 0 "register_operand")
4405 (match_operand:MODEF 1 "nonimmediate_operand")))
4407 (clobber (match_scratch:<ssevecmode> 3))
4408 (clobber (match_scratch:<ssevecmode> 4))])]
4409 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4411 machine_mode mode = <MODE>mode;
4412 machine_mode vecmode = <ssevecmode>mode;
4413 REAL_VALUE_TYPE TWO31r;
4416 if (optimize_insn_for_size_p ())
4419 real_ldexp (&TWO31r, &dconst1, 31);
4420 two31 = const_double_from_real_value (TWO31r, mode);
4421 two31 = ix86_build_const_vector (vecmode, true, two31);
4422 operands[2] = force_reg (vecmode, two31);
4425 (define_insn_and_split "*fixuns_trunc<mode>_1"
4426 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4428 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4429 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4430 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4431 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4432 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4433 && optimize_function_for_speed_p (cfun)"
4435 "&& reload_completed"
4438 ix86_split_convert_uns_si_sse (operands);
4442 ;; Unsigned conversion to HImode.
4443 ;; Without these patterns, we'll try the unsigned SI conversion which
4444 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4446 (define_expand "fixuns_trunc<mode>hi2"
4448 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4449 (set (match_operand:HI 0 "nonimmediate_operand")
4450 (subreg:HI (match_dup 2) 0))]
4451 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4452 "operands[2] = gen_reg_rtx (SImode);")
4454 ;; When SSE is available, it is always faster to use it!
4455 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4456 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4457 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4458 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4459 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4460 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4461 [(set_attr "type" "sseicvt")
4462 (set_attr "prefix" "maybe_vex")
4463 (set (attr "prefix_rex")
4465 (match_test "<SWI48:MODE>mode == DImode")
4467 (const_string "*")))
4468 (set_attr "mode" "<MODEF:MODE>")
4469 (set_attr "athlon_decode" "double,vector")
4470 (set_attr "amdfam10_decode" "double,double")
4471 (set_attr "bdver1_decode" "double,double")])
4473 ;; Avoid vector decoded forms of the instruction.
4475 [(match_scratch:MODEF 2 "x")
4476 (set (match_operand:SWI48 0 "register_operand")
4477 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4478 "TARGET_AVOID_VECTOR_DECODE
4479 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4480 && optimize_insn_for_speed_p ()"
4481 [(set (match_dup 2) (match_dup 1))
4482 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4484 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4485 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4486 (fix:SWI248x (match_operand 1 "register_operand")))]
4487 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4489 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4490 && (TARGET_64BIT || <MODE>mode != DImode))
4492 && can_create_pseudo_p ()"
4497 if (memory_operand (operands[0], VOIDmode))
4498 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4501 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4502 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4508 [(set_attr "type" "fisttp")
4509 (set_attr "mode" "<MODE>")])
4511 (define_insn "fix_trunc<mode>_i387_fisttp"
4512 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4513 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4514 (clobber (match_scratch:XF 2 "=&1f"))]
4515 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4518 && (TARGET_64BIT || <MODE>mode != DImode))
4519 && TARGET_SSE_MATH)"
4520 "* return output_fix_trunc (insn, operands, true);"
4521 [(set_attr "type" "fisttp")
4522 (set_attr "mode" "<MODE>")])
4524 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4525 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4526 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4527 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4528 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4529 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && (TARGET_64BIT || <MODE>mode != DImode))
4533 && TARGET_SSE_MATH)"
4535 [(set_attr "type" "fisttp")
4536 (set_attr "mode" "<MODE>")])
4539 [(set (match_operand:SWI248x 0 "register_operand")
4540 (fix:SWI248x (match_operand 1 "register_operand")))
4541 (clobber (match_operand:SWI248x 2 "memory_operand"))
4542 (clobber (match_scratch 3))]
4544 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4545 (clobber (match_dup 3))])
4546 (set (match_dup 0) (match_dup 2))])
4549 [(set (match_operand:SWI248x 0 "memory_operand")
4550 (fix:SWI248x (match_operand 1 "register_operand")))
4551 (clobber (match_operand:SWI248x 2 "memory_operand"))
4552 (clobber (match_scratch 3))]
4554 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4555 (clobber (match_dup 3))])])
4557 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4558 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4559 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4560 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4561 ;; function in i386.c.
4562 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4563 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4564 (fix:SWI248x (match_operand 1 "register_operand")))
4565 (clobber (reg:CC FLAGS_REG))]
4566 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4569 && (TARGET_64BIT || <MODE>mode != DImode))
4570 && can_create_pseudo_p ()"
4575 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4577 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4578 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4579 if (memory_operand (operands[0], VOIDmode))
4580 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4581 operands[2], operands[3]));
4584 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4585 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4586 operands[2], operands[3],
4591 [(set_attr "type" "fistp")
4592 (set_attr "i387_cw" "trunc")
4593 (set_attr "mode" "<MODE>")])
4595 (define_insn "fix_truncdi_i387"
4596 [(set (match_operand:DI 0 "memory_operand" "=m")
4597 (fix:DI (match_operand 1 "register_operand" "f")))
4598 (use (match_operand:HI 2 "memory_operand" "m"))
4599 (use (match_operand:HI 3 "memory_operand" "m"))
4600 (clobber (match_scratch:XF 4 "=&1f"))]
4601 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4604 "* return output_fix_trunc (insn, operands, false);"
4605 [(set_attr "type" "fistp")
4606 (set_attr "i387_cw" "trunc")
4607 (set_attr "mode" "DI")])
4609 (define_insn "fix_truncdi_i387_with_temp"
4610 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4611 (fix:DI (match_operand 1 "register_operand" "f,f")))
4612 (use (match_operand:HI 2 "memory_operand" "m,m"))
4613 (use (match_operand:HI 3 "memory_operand" "m,m"))
4614 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4615 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4616 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4620 [(set_attr "type" "fistp")
4621 (set_attr "i387_cw" "trunc")
4622 (set_attr "mode" "DI")])
4625 [(set (match_operand:DI 0 "register_operand")
4626 (fix:DI (match_operand 1 "register_operand")))
4627 (use (match_operand:HI 2 "memory_operand"))
4628 (use (match_operand:HI 3 "memory_operand"))
4629 (clobber (match_operand:DI 4 "memory_operand"))
4630 (clobber (match_scratch 5))]
4632 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4635 (clobber (match_dup 5))])
4636 (set (match_dup 0) (match_dup 4))])
4639 [(set (match_operand:DI 0 "memory_operand")
4640 (fix:DI (match_operand 1 "register_operand")))
4641 (use (match_operand:HI 2 "memory_operand"))
4642 (use (match_operand:HI 3 "memory_operand"))
4643 (clobber (match_operand:DI 4 "memory_operand"))
4644 (clobber (match_scratch 5))]
4646 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4649 (clobber (match_dup 5))])])
4651 (define_insn "fix_trunc<mode>_i387"
4652 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4653 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4654 (use (match_operand:HI 2 "memory_operand" "m"))
4655 (use (match_operand:HI 3 "memory_operand" "m"))]
4656 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4658 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4659 "* return output_fix_trunc (insn, operands, false);"
4660 [(set_attr "type" "fistp")
4661 (set_attr "i387_cw" "trunc")
4662 (set_attr "mode" "<MODE>")])
4664 (define_insn "fix_trunc<mode>_i387_with_temp"
4665 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4666 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4667 (use (match_operand:HI 2 "memory_operand" "m,m"))
4668 (use (match_operand:HI 3 "memory_operand" "m,m"))
4669 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4670 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4672 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4674 [(set_attr "type" "fistp")
4675 (set_attr "i387_cw" "trunc")
4676 (set_attr "mode" "<MODE>")])
4679 [(set (match_operand:SWI24 0 "register_operand")
4680 (fix:SWI24 (match_operand 1 "register_operand")))
4681 (use (match_operand:HI 2 "memory_operand"))
4682 (use (match_operand:HI 3 "memory_operand"))
4683 (clobber (match_operand:SWI24 4 "memory_operand"))]
4685 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4687 (use (match_dup 3))])
4688 (set (match_dup 0) (match_dup 4))])
4691 [(set (match_operand:SWI24 0 "memory_operand")
4692 (fix:SWI24 (match_operand 1 "register_operand")))
4693 (use (match_operand:HI 2 "memory_operand"))
4694 (use (match_operand:HI 3 "memory_operand"))
4695 (clobber (match_operand:SWI24 4 "memory_operand"))]
4697 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4699 (use (match_dup 3))])])
4701 (define_insn "x86_fnstcw_1"
4702 [(set (match_operand:HI 0 "memory_operand" "=m")
4703 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4706 [(set (attr "length")
4707 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4708 (set_attr "mode" "HI")
4709 (set_attr "unit" "i387")
4710 (set_attr "bdver1_decode" "vector")])
4712 (define_insn "x86_fldcw_1"
4713 [(set (reg:HI FPCR_REG)
4714 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4717 [(set (attr "length")
4718 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4719 (set_attr "mode" "HI")
4720 (set_attr "unit" "i387")
4721 (set_attr "athlon_decode" "vector")
4722 (set_attr "amdfam10_decode" "vector")
4723 (set_attr "bdver1_decode" "vector")])
4725 ;; Conversion between fixed point and floating point.
4727 ;; Even though we only accept memory inputs, the backend _really_
4728 ;; wants to be able to do this between registers. Thankfully, LRA
4729 ;; will fix this up for us during register allocation.
4731 (define_insn "floathi<mode>2"
4732 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4733 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4736 || TARGET_MIX_SSE_I387)"
4738 [(set_attr "type" "fmov")
4739 (set_attr "mode" "<MODE>")
4740 (set_attr "fp_int_src" "true")])
4742 (define_insn "float<SWI48x:mode>xf2"
4743 [(set (match_operand:XF 0 "register_operand" "=f")
4744 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4747 [(set_attr "type" "fmov")
4748 (set_attr "mode" "XF")
4749 (set_attr "fp_int_src" "true")])
4751 (define_expand "float<SWI48:mode><MODEF:mode>2"
4752 [(set (match_operand:MODEF 0 "register_operand")
4753 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4754 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4756 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4757 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4759 rtx reg = gen_reg_rtx (XFmode);
4760 rtx (*insn)(rtx, rtx);
4762 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4764 if (<MODEF:MODE>mode == SFmode)
4765 insn = gen_truncxfsf2;
4766 else if (<MODEF:MODE>mode == DFmode)
4767 insn = gen_truncxfdf2;
4771 emit_insn (insn (operands[0], reg));
4776 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4777 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4779 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4780 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4783 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4784 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4785 [(set_attr "type" "fmov,sseicvt,sseicvt")
4786 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4787 (set_attr "mode" "<MODEF:MODE>")
4788 (set (attr "prefix_rex")
4790 (and (eq_attr "prefix" "maybe_vex")
4791 (match_test "<SWI48:MODE>mode == DImode"))
4793 (const_string "*")))
4794 (set_attr "unit" "i387,*,*")
4795 (set_attr "athlon_decode" "*,double,direct")
4796 (set_attr "amdfam10_decode" "*,vector,double")
4797 (set_attr "bdver1_decode" "*,double,direct")
4798 (set_attr "fp_int_src" "true")
4799 (set (attr "enabled")
4800 (cond [(eq_attr "alternative" "0")
4801 (symbol_ref "TARGET_MIX_SSE_I387
4802 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4805 (symbol_ref "true")))
4806 (set (attr "preferred_for_speed")
4807 (cond [(eq_attr "alternative" "1")
4808 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4809 (symbol_ref "true")))
4812 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4813 [(set (match_operand:MODEF 0 "register_operand" "=f")
4814 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4815 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4817 [(set_attr "type" "fmov")
4818 (set_attr "mode" "<MODEF:MODE>")
4819 (set_attr "fp_int_src" "true")])
4821 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4822 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4823 ;; alternative in sse2_loadld.
4825 [(set (match_operand:MODEF 0 "register_operand")
4826 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4827 "TARGET_SSE2 && TARGET_SSE_MATH
4828 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4829 && reload_completed && SSE_REG_P (operands[0])
4830 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4833 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4835 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4837 emit_insn (gen_sse2_loadld (operands[4],
4838 CONST0_RTX (V4SImode), operands[1]));
4840 if (<ssevecmode>mode == V4SFmode)
4841 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4843 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4847 ;; Avoid partial SSE register dependency stalls
4849 [(set (match_operand:MODEF 0 "register_operand")
4850 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4851 "TARGET_SSE2 && TARGET_SSE_MATH
4852 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4853 && optimize_function_for_speed_p (cfun)
4854 && reload_completed && SSE_REG_P (operands[0])"
4857 const machine_mode vmode = <MODEF:ssevecmode>mode;
4858 const machine_mode mode = <MODEF:MODE>mode;
4859 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4861 emit_move_insn (op0, CONST0_RTX (vmode));
4863 t = gen_rtx_FLOAT (mode, operands[1]);
4864 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4865 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4866 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4870 ;; Break partial reg stall for cvtsd2ss.
4873 [(set (match_operand:SF 0 "register_operand")
4875 (match_operand:DF 1 "nonimmediate_operand")))]
4876 "TARGET_SSE2 && TARGET_SSE_MATH
4877 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4878 && optimize_function_for_speed_p (cfun)
4879 && SSE_REG_P (operands[0])
4880 && (!SSE_REG_P (operands[1])
4881 || REGNO (operands[0]) != REGNO (operands[1]))"
4885 (float_truncate:V2SF
4890 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4892 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4894 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4897 ;; Break partial reg stall for cvtss2sd.
4900 [(set (match_operand:DF 0 "register_operand")
4902 (match_operand:SF 1 "nonimmediate_operand")))]
4903 "TARGET_SSE2 && TARGET_SSE_MATH
4904 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4905 && optimize_function_for_speed_p (cfun)
4906 && SSE_REG_P (operands[0])
4907 && (!SSE_REG_P (operands[1])
4908 || REGNO (operands[0]) != REGNO (operands[1]))"
4914 (parallel [(const_int 0) (const_int 1)])))
4918 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4920 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4922 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4925 ;; Avoid store forwarding (partial memory) stall penalty
4926 ;; by passing DImode value through XMM registers. */
4928 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4929 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4931 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4932 (clobber (match_scratch:V4SI 3 "=X,x"))
4933 (clobber (match_scratch:V4SI 4 "=X,x"))
4934 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4935 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4936 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4937 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4939 [(set_attr "type" "multi")
4940 (set_attr "mode" "<X87MODEF:MODE>")
4941 (set_attr "unit" "i387")
4942 (set_attr "fp_int_src" "true")])
4945 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4946 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4947 (clobber (match_scratch:V4SI 3))
4948 (clobber (match_scratch:V4SI 4))
4949 (clobber (match_operand:DI 2 "memory_operand"))]
4950 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4951 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4952 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4953 && reload_completed"
4954 [(set (match_dup 2) (match_dup 3))
4955 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4957 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4958 Assemble the 64-bit DImode value in an xmm register. */
4959 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4960 gen_rtx_SUBREG (SImode, operands[1], 0)));
4961 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4962 gen_rtx_SUBREG (SImode, operands[1], 4)));
4963 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4966 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4970 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4971 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4972 (clobber (match_scratch:V4SI 3))
4973 (clobber (match_scratch:V4SI 4))
4974 (clobber (match_operand:DI 2 "memory_operand"))]
4975 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4976 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4977 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4978 && reload_completed"
4979 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4981 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4982 [(set (match_operand:MODEF 0 "register_operand")
4983 (unsigned_float:MODEF
4984 (match_operand:SWI12 1 "nonimmediate_operand")))]
4986 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4988 operands[1] = convert_to_mode (SImode, operands[1], 1);
4989 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4993 ;; Avoid store forwarding (partial memory) stall penalty by extending
4994 ;; SImode value to DImode through XMM register instead of pushing two
4995 ;; SImode values to stack. Also note that fild loads from memory only.
4997 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
4998 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4999 (unsigned_float:X87MODEF
5000 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5001 (clobber (match_scratch:DI 3 "=x"))
5002 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5004 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5005 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5007 "&& reload_completed"
5008 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5009 (set (match_dup 2) (match_dup 3))
5011 (float:X87MODEF (match_dup 2)))]
5013 [(set_attr "type" "multi")
5014 (set_attr "mode" "<MODE>")])
5016 (define_expand "floatunssi<mode>2"
5018 [(set (match_operand:X87MODEF 0 "register_operand")
5019 (unsigned_float:X87MODEF
5020 (match_operand:SI 1 "nonimmediate_operand")))
5021 (clobber (match_scratch:DI 3))
5022 (clobber (match_dup 2))])]
5024 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5025 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5026 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5028 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5030 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5034 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5037 (define_expand "floatunsdisf2"
5038 [(use (match_operand:SF 0 "register_operand"))
5039 (use (match_operand:DI 1 "nonimmediate_operand"))]
5040 "TARGET_64BIT && TARGET_SSE_MATH"
5041 "x86_emit_floatuns (operands); DONE;")
5043 (define_expand "floatunsdidf2"
5044 [(use (match_operand:DF 0 "register_operand"))
5045 (use (match_operand:DI 1 "nonimmediate_operand"))]
5046 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5047 && TARGET_SSE2 && TARGET_SSE_MATH"
5050 x86_emit_floatuns (operands);
5052 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5056 ;; Load effective address instructions
5058 (define_insn_and_split "*lea<mode>"
5059 [(set (match_operand:SWI48 0 "register_operand" "=r")
5060 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5063 if (SImode_address_operand (operands[1], VOIDmode))
5065 gcc_assert (TARGET_64BIT);
5066 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5069 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5071 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5074 machine_mode mode = <MODE>mode;
5077 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5078 change operands[] array behind our back. */
5079 pat = PATTERN (curr_insn);
5081 operands[0] = SET_DEST (pat);
5082 operands[1] = SET_SRC (pat);
5084 /* Emit all operations in SImode for zero-extended addresses. */
5085 if (SImode_address_operand (operands[1], VOIDmode))
5088 ix86_split_lea_for_addr (curr_insn, operands, mode);
5090 /* Zero-extend return register to DImode for zero-extended addresses. */
5091 if (mode != <MODE>mode)
5092 emit_insn (gen_zero_extendsidi2
5093 (operands[0], gen_lowpart (mode, operands[0])));
5097 [(set_attr "type" "lea")
5100 (match_operand 1 "SImode_address_operand")
5102 (const_string "<MODE>")))])
5106 (define_expand "add<mode>3"
5107 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5108 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5109 (match_operand:SDWIM 2 "<general_operand>")))]
5111 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5113 (define_insn_and_split "*add<dwi>3_doubleword"
5114 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5116 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5117 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5118 (clobber (reg:CC FLAGS_REG))]
5119 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5122 [(parallel [(set (reg:CC FLAGS_REG)
5123 (unspec:CC [(match_dup 1) (match_dup 2)]
5126 (plus:DWIH (match_dup 1) (match_dup 2)))])
5127 (parallel [(set (match_dup 3)
5131 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5133 (clobber (reg:CC FLAGS_REG))])]
5134 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5136 (define_insn "*add<mode>3_cc"
5137 [(set (reg:CC FLAGS_REG)
5139 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5140 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5142 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5143 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5144 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5145 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5146 [(set_attr "type" "alu")
5147 (set_attr "mode" "<MODE>")])
5149 (define_insn "addqi3_cc"
5150 [(set (reg:CC FLAGS_REG)
5152 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5153 (match_operand:QI 2 "general_operand" "qn,qm")]
5155 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5156 (plus:QI (match_dup 1) (match_dup 2)))]
5157 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5158 "add{b}\t{%2, %0|%0, %2}"
5159 [(set_attr "type" "alu")
5160 (set_attr "mode" "QI")])
5162 (define_insn "*add<mode>_1"
5163 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5165 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5166 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5167 (clobber (reg:CC FLAGS_REG))]
5168 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5170 switch (get_attr_type (insn))
5176 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5177 if (operands[2] == const1_rtx)
5178 return "inc{<imodesuffix>}\t%0";
5181 gcc_assert (operands[2] == constm1_rtx);
5182 return "dec{<imodesuffix>}\t%0";
5186 /* For most processors, ADD is faster than LEA. This alternative
5187 was added to use ADD as much as possible. */
5188 if (which_alternative == 2)
5191 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5194 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5195 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5196 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5198 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5202 (cond [(eq_attr "alternative" "3")
5203 (const_string "lea")
5204 (match_operand:SWI48 2 "incdec_operand")
5205 (const_string "incdec")
5207 (const_string "alu")))
5208 (set (attr "length_immediate")
5210 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5212 (const_string "*")))
5213 (set_attr "mode" "<MODE>")])
5215 ;; It may seem that nonimmediate operand is proper one for operand 1.
5216 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5217 ;; we take care in ix86_binary_operator_ok to not allow two memory
5218 ;; operands so proper swapping will be done in reload. This allow
5219 ;; patterns constructed from addsi_1 to match.
5221 (define_insn "addsi_1_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5224 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5225 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5226 (clobber (reg:CC FLAGS_REG))]
5227 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5229 switch (get_attr_type (insn))
5235 if (operands[2] == const1_rtx)
5236 return "inc{l}\t%k0";
5239 gcc_assert (operands[2] == constm1_rtx);
5240 return "dec{l}\t%k0";
5244 /* For most processors, ADD is faster than LEA. This alternative
5245 was added to use ADD as much as possible. */
5246 if (which_alternative == 1)
5249 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5252 if (x86_maybe_negate_const_int (&operands[2], SImode))
5253 return "sub{l}\t{%2, %k0|%k0, %2}";
5255 return "add{l}\t{%2, %k0|%k0, %2}";
5259 (cond [(eq_attr "alternative" "2")
5260 (const_string "lea")
5261 (match_operand:SI 2 "incdec_operand")
5262 (const_string "incdec")
5264 (const_string "alu")))
5265 (set (attr "length_immediate")
5267 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5269 (const_string "*")))
5270 (set_attr "mode" "SI")])
5272 (define_insn "*addhi_1"
5273 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5274 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5275 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5276 (clobber (reg:CC FLAGS_REG))]
5277 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5279 switch (get_attr_type (insn))
5285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5286 if (operands[2] == const1_rtx)
5287 return "inc{w}\t%0";
5290 gcc_assert (operands[2] == constm1_rtx);
5291 return "dec{w}\t%0";
5295 /* For most processors, ADD is faster than LEA. This alternative
5296 was added to use ADD as much as possible. */
5297 if (which_alternative == 2)
5300 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5303 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5304 if (x86_maybe_negate_const_int (&operands[2], HImode))
5305 return "sub{w}\t{%2, %0|%0, %2}";
5307 return "add{w}\t{%2, %0|%0, %2}";
5311 (cond [(eq_attr "alternative" "3")
5312 (const_string "lea")
5313 (match_operand:HI 2 "incdec_operand")
5314 (const_string "incdec")
5316 (const_string "alu")))
5317 (set (attr "length_immediate")
5319 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5321 (const_string "*")))
5322 (set_attr "mode" "HI,HI,HI,SI")])
5324 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5325 (define_insn "*addqi_1"
5326 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5327 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5328 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5329 (clobber (reg:CC FLAGS_REG))]
5330 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5332 bool widen = (which_alternative == 3 || which_alternative == 4);
5334 switch (get_attr_type (insn))
5340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341 if (operands[2] == const1_rtx)
5342 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5345 gcc_assert (operands[2] == constm1_rtx);
5346 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5350 /* For most processors, ADD is faster than LEA. These alternatives
5351 were added to use ADD as much as possible. */
5352 if (which_alternative == 2 || which_alternative == 4)
5355 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359 if (x86_maybe_negate_const_int (&operands[2], QImode))
5362 return "sub{l}\t{%2, %k0|%k0, %2}";
5364 return "sub{b}\t{%2, %0|%0, %2}";
5367 return "add{l}\t{%k2, %k0|%k0, %k2}";
5369 return "add{b}\t{%2, %0|%0, %2}";
5373 (cond [(eq_attr "alternative" "5")
5374 (const_string "lea")
5375 (match_operand:QI 2 "incdec_operand")
5376 (const_string "incdec")
5378 (const_string "alu")))
5379 (set (attr "length_immediate")
5381 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5383 (const_string "*")))
5384 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5386 (define_insn "*addqi_1_slp"
5387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5388 (plus:QI (match_dup 0)
5389 (match_operand:QI 1 "general_operand" "qn,qm")))
5390 (clobber (reg:CC FLAGS_REG))]
5391 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5392 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5394 switch (get_attr_type (insn))
5397 if (operands[1] == const1_rtx)
5398 return "inc{b}\t%0";
5401 gcc_assert (operands[1] == constm1_rtx);
5402 return "dec{b}\t%0";
5406 if (x86_maybe_negate_const_int (&operands[1], QImode))
5407 return "sub{b}\t{%1, %0|%0, %1}";
5409 return "add{b}\t{%1, %0|%0, %1}";
5413 (if_then_else (match_operand:QI 1 "incdec_operand")
5414 (const_string "incdec")
5415 (const_string "alu1")))
5416 (set (attr "memory")
5417 (if_then_else (match_operand 1 "memory_operand")
5418 (const_string "load")
5419 (const_string "none")))
5420 (set_attr "mode" "QI")])
5422 ;; Split non destructive adds if we cannot use lea.
5424 [(set (match_operand:SWI48 0 "register_operand")
5425 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5426 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5427 (clobber (reg:CC FLAGS_REG))]
5428 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5429 [(set (match_dup 0) (match_dup 1))
5430 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5431 (clobber (reg:CC FLAGS_REG))])])
5433 ;; Convert add to the lea pattern to avoid flags dependency.
5435 [(set (match_operand:SWI 0 "register_operand")
5436 (plus:SWI (match_operand:SWI 1 "register_operand")
5437 (match_operand:SWI 2 "<nonmemory_operand>")))
5438 (clobber (reg:CC FLAGS_REG))]
5439 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5442 machine_mode mode = <MODE>mode;
5445 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5448 operands[0] = gen_lowpart (mode, operands[0]);
5449 operands[1] = gen_lowpart (mode, operands[1]);
5450 operands[2] = gen_lowpart (mode, operands[2]);
5453 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5455 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5459 ;; Split non destructive adds if we cannot use lea.
5461 [(set (match_operand:DI 0 "register_operand")
5463 (plus:SI (match_operand:SI 1 "register_operand")
5464 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5465 (clobber (reg:CC FLAGS_REG))]
5467 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5468 [(set (match_dup 3) (match_dup 1))
5469 (parallel [(set (match_dup 0)
5470 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5471 (clobber (reg:CC FLAGS_REG))])]
5472 "operands[3] = gen_lowpart (SImode, operands[0]);")
5474 ;; Convert add to the lea pattern to avoid flags dependency.
5476 [(set (match_operand:DI 0 "register_operand")
5478 (plus:SI (match_operand:SI 1 "register_operand")
5479 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5480 (clobber (reg:CC FLAGS_REG))]
5481 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5483 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5485 (define_insn "*add<mode>_2"
5486 [(set (reg FLAGS_REG)
5489 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5490 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5492 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5493 (plus:SWI (match_dup 1) (match_dup 2)))]
5494 "ix86_match_ccmode (insn, CCGOCmode)
5495 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5497 switch (get_attr_type (insn))
5500 if (operands[2] == const1_rtx)
5501 return "inc{<imodesuffix>}\t%0";
5504 gcc_assert (operands[2] == constm1_rtx);
5505 return "dec{<imodesuffix>}\t%0";
5509 if (which_alternative == 2)
5512 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5515 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5516 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5517 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5519 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5523 (if_then_else (match_operand:SWI 2 "incdec_operand")
5524 (const_string "incdec")
5525 (const_string "alu")))
5526 (set (attr "length_immediate")
5528 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5530 (const_string "*")))
5531 (set_attr "mode" "<MODE>")])
5533 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5534 (define_insn "*addsi_2_zext"
5535 [(set (reg FLAGS_REG)
5537 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5538 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5540 (set (match_operand:DI 0 "register_operand" "=r,r")
5541 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5542 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5543 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5545 switch (get_attr_type (insn))
5548 if (operands[2] == const1_rtx)
5549 return "inc{l}\t%k0";
5552 gcc_assert (operands[2] == constm1_rtx);
5553 return "dec{l}\t%k0";
5557 if (which_alternative == 1)
5560 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5563 if (x86_maybe_negate_const_int (&operands[2], SImode))
5564 return "sub{l}\t{%2, %k0|%k0, %2}";
5566 return "add{l}\t{%2, %k0|%k0, %2}";
5570 (if_then_else (match_operand:SI 2 "incdec_operand")
5571 (const_string "incdec")
5572 (const_string "alu")))
5573 (set (attr "length_immediate")
5575 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5577 (const_string "*")))
5578 (set_attr "mode" "SI")])
5580 (define_insn "*add<mode>_3"
5581 [(set (reg FLAGS_REG)
5583 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5584 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5585 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5586 "ix86_match_ccmode (insn, CCZmode)
5587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5589 switch (get_attr_type (insn))
5592 if (operands[2] == const1_rtx)
5593 return "inc{<imodesuffix>}\t%0";
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{<imodesuffix>}\t%0";
5601 if (which_alternative == 1)
5604 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5607 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5608 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5609 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5611 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5615 (if_then_else (match_operand:SWI 2 "incdec_operand")
5616 (const_string "incdec")
5617 (const_string "alu")))
5618 (set (attr "length_immediate")
5620 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5622 (const_string "*")))
5623 (set_attr "mode" "<MODE>")])
5625 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5626 (define_insn "*addsi_3_zext"
5627 [(set (reg FLAGS_REG)
5629 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5630 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5631 (set (match_operand:DI 0 "register_operand" "=r,r")
5632 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5633 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5634 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5636 switch (get_attr_type (insn))
5639 if (operands[2] == const1_rtx)
5640 return "inc{l}\t%k0";
5643 gcc_assert (operands[2] == constm1_rtx);
5644 return "dec{l}\t%k0";
5648 if (which_alternative == 1)
5651 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654 if (x86_maybe_negate_const_int (&operands[2], SImode))
5655 return "sub{l}\t{%2, %k0|%k0, %2}";
5657 return "add{l}\t{%2, %k0|%k0, %2}";
5661 (if_then_else (match_operand:SI 2 "incdec_operand")
5662 (const_string "incdec")
5663 (const_string "alu")))
5664 (set (attr "length_immediate")
5666 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5668 (const_string "*")))
5669 (set_attr "mode" "SI")])
5671 ; For comparisons against 1, -1 and 128, we may generate better code
5672 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5673 ; is matched then. We can't accept general immediate, because for
5674 ; case of overflows, the result is messed up.
5675 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5676 ; only for comparisons not depending on it.
5678 (define_insn "*adddi_4"
5679 [(set (reg FLAGS_REG)
5681 (match_operand:DI 1 "nonimmediate_operand" "0")
5682 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5683 (clobber (match_scratch:DI 0 "=rm"))]
5685 && ix86_match_ccmode (insn, CCGCmode)"
5687 switch (get_attr_type (insn))
5690 if (operands[2] == constm1_rtx)
5691 return "inc{q}\t%0";
5694 gcc_assert (operands[2] == const1_rtx);
5695 return "dec{q}\t%0";
5699 if (x86_maybe_negate_const_int (&operands[2], DImode))
5700 return "add{q}\t{%2, %0|%0, %2}";
5702 return "sub{q}\t{%2, %0|%0, %2}";
5706 (if_then_else (match_operand:DI 2 "incdec_operand")
5707 (const_string "incdec")
5708 (const_string "alu")))
5709 (set (attr "length_immediate")
5711 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5713 (const_string "*")))
5714 (set_attr "mode" "DI")])
5716 ; For comparisons against 1, -1 and 128, we may generate better code
5717 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5718 ; is matched then. We can't accept general immediate, because for
5719 ; case of overflows, the result is messed up.
5720 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5721 ; only for comparisons not depending on it.
5723 (define_insn "*add<mode>_4"
5724 [(set (reg FLAGS_REG)
5726 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5727 (match_operand:SWI124 2 "const_int_operand" "n")))
5728 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5729 "ix86_match_ccmode (insn, CCGCmode)"
5731 switch (get_attr_type (insn))
5734 if (operands[2] == constm1_rtx)
5735 return "inc{<imodesuffix>}\t%0";
5738 gcc_assert (operands[2] == const1_rtx);
5739 return "dec{<imodesuffix>}\t%0";
5743 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5744 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5746 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5750 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5751 (const_string "incdec")
5752 (const_string "alu")))
5753 (set (attr "length_immediate")
5755 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5757 (const_string "*")))
5758 (set_attr "mode" "<MODE>")])
5760 (define_insn "*add<mode>_5"
5761 [(set (reg FLAGS_REG)
5764 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5765 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5767 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5768 "ix86_match_ccmode (insn, CCGOCmode)
5769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5771 switch (get_attr_type (insn))
5774 if (operands[2] == const1_rtx)
5775 return "inc{<imodesuffix>}\t%0";
5778 gcc_assert (operands[2] == constm1_rtx);
5779 return "dec{<imodesuffix>}\t%0";
5783 if (which_alternative == 1)
5786 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5791 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5793 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5797 (if_then_else (match_operand:SWI 2 "incdec_operand")
5798 (const_string "incdec")
5799 (const_string "alu")))
5800 (set (attr "length_immediate")
5802 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5804 (const_string "*")))
5805 (set_attr "mode" "<MODE>")])
5807 (define_insn "addqi_ext_1"
5808 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5813 (match_operand 1 "ext_register_operand" "0,0")
5816 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5817 (clobber (reg:CC FLAGS_REG))]
5820 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{b}\t%h0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{b}\t%h0";
5832 return "add{b}\t{%2, %h0|%h0, %2}";
5835 [(set_attr "isa" "*,nox64")
5837 (if_then_else (match_operand:QI 2 "incdec_operand")
5838 (const_string "incdec")
5839 (const_string "alu")))
5840 (set_attr "modrm" "1")
5841 (set_attr "mode" "QI")])
5843 (define_insn "*addqi_ext_2"
5844 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5849 (match_operand 1 "ext_register_operand" "%0")
5853 (match_operand 2 "ext_register_operand" "Q")
5856 (clobber (reg:CC FLAGS_REG))]
5858 "add{b}\t{%h2, %h0|%h0, %h2}"
5859 [(set_attr "type" "alu")
5860 (set_attr "mode" "QI")])
5862 ;; Add with jump on overflow.
5863 (define_expand "addv<mode>4"
5864 [(parallel [(set (reg:CCO FLAGS_REG)
5867 (match_operand:SWI 1 "nonimmediate_operand"))
5870 (plus:SWI (match_dup 1)
5871 (match_operand:SWI 2
5872 "<general_operand>")))))
5873 (set (match_operand:SWI 0 "register_operand")
5874 (plus:SWI (match_dup 1) (match_dup 2)))])
5875 (set (pc) (if_then_else
5876 (eq (reg:CCO FLAGS_REG) (const_int 0))
5877 (label_ref (match_operand 3))
5881 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5882 if (CONST_INT_P (operands[2]))
5883 operands[4] = operands[2];
5885 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5888 (define_insn "*addv<mode>4"
5889 [(set (reg:CCO FLAGS_REG)
5892 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5894 (match_operand:SWI 2 "<general_sext_operand>"
5897 (plus:SWI (match_dup 1) (match_dup 2)))))
5898 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5899 (plus:SWI (match_dup 1) (match_dup 2)))]
5900 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5901 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5902 [(set_attr "type" "alu")
5903 (set_attr "mode" "<MODE>")])
5905 (define_insn "*addv<mode>4_1"
5906 [(set (reg:CCO FLAGS_REG)
5909 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5910 (match_operand:<DWI> 3 "const_int_operand" "i"))
5912 (plus:SWI (match_dup 1)
5913 (match_operand:SWI 2 "x86_64_immediate_operand"
5915 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5916 (plus:SWI (match_dup 1) (match_dup 2)))]
5917 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5918 && CONST_INT_P (operands[2])
5919 && INTVAL (operands[2]) == INTVAL (operands[3])"
5920 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5921 [(set_attr "type" "alu")
5922 (set_attr "mode" "<MODE>")
5923 (set (attr "length_immediate")
5924 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5926 (match_test "<MODE_SIZE> == 8")
5928 (const_string "<MODE_SIZE>")))])
5930 ;; The lea patterns for modes less than 32 bits need to be matched by
5931 ;; several insns converted to real lea by splitters.
5933 (define_insn_and_split "*lea_general_1"
5934 [(set (match_operand 0 "register_operand" "=r")
5935 (plus (plus (match_operand 1 "index_register_operand" "l")
5936 (match_operand 2 "register_operand" "r"))
5937 (match_operand 3 "immediate_operand" "i")))]
5938 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5939 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5940 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5941 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5942 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5943 || GET_MODE (operands[3]) == VOIDmode)"
5945 "&& reload_completed"
5948 machine_mode mode = SImode;
5951 operands[0] = gen_lowpart (mode, operands[0]);
5952 operands[1] = gen_lowpart (mode, operands[1]);
5953 operands[2] = gen_lowpart (mode, operands[2]);
5954 operands[3] = gen_lowpart (mode, operands[3]);
5956 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5959 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5962 [(set_attr "type" "lea")
5963 (set_attr "mode" "SI")])
5965 (define_insn_and_split "*lea_general_2"
5966 [(set (match_operand 0 "register_operand" "=r")
5967 (plus (mult (match_operand 1 "index_register_operand" "l")
5968 (match_operand 2 "const248_operand" "n"))
5969 (match_operand 3 "nonmemory_operand" "ri")))]
5970 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5971 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5972 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5973 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5974 || GET_MODE (operands[3]) == VOIDmode)"
5976 "&& reload_completed"
5979 machine_mode mode = SImode;
5982 operands[0] = gen_lowpart (mode, operands[0]);
5983 operands[1] = gen_lowpart (mode, operands[1]);
5984 operands[3] = gen_lowpart (mode, operands[3]);
5986 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5989 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5992 [(set_attr "type" "lea")
5993 (set_attr "mode" "SI")])
5995 (define_insn_and_split "*lea_general_3"
5996 [(set (match_operand 0 "register_operand" "=r")
5997 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5998 (match_operand 2 "const248_operand" "n"))
5999 (match_operand 3 "register_operand" "r"))
6000 (match_operand 4 "immediate_operand" "i")))]
6001 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6002 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6003 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6004 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6006 "&& reload_completed"
6009 machine_mode mode = SImode;
6012 operands[0] = gen_lowpart (mode, operands[0]);
6013 operands[1] = gen_lowpart (mode, operands[1]);
6014 operands[3] = gen_lowpart (mode, operands[3]);
6015 operands[4] = gen_lowpart (mode, operands[4]);
6017 pat = gen_rtx_PLUS (mode,
6019 gen_rtx_MULT (mode, operands[1],
6024 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6027 [(set_attr "type" "lea")
6028 (set_attr "mode" "SI")])
6030 (define_insn_and_split "*lea_general_4"
6031 [(set (match_operand 0 "register_operand" "=r")
6033 (match_operand 1 "index_register_operand" "l")
6034 (match_operand 2 "const_int_operand" "n"))
6035 (match_operand 3 "const_int_operand" "n")))]
6036 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6037 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6038 || GET_MODE (operands[0]) == SImode
6039 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6040 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6041 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6042 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6043 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6045 "&& reload_completed"
6048 machine_mode mode = GET_MODE (operands[0]);
6051 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6054 operands[0] = gen_lowpart (mode, operands[0]);
6055 operands[1] = gen_lowpart (mode, operands[1]);
6058 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6060 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6061 INTVAL (operands[3]));
6063 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6066 [(set_attr "type" "lea")
6068 (if_then_else (match_operand:DI 0)
6070 (const_string "SI")))])
6072 ;; Subtract instructions
6074 (define_expand "sub<mode>3"
6075 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6076 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6077 (match_operand:SDWIM 2 "<general_operand>")))]
6079 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6081 (define_insn_and_split "*sub<dwi>3_doubleword"
6082 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6084 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6085 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6086 (clobber (reg:CC FLAGS_REG))]
6087 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6090 [(parallel [(set (reg:CC FLAGS_REG)
6091 (compare:CC (match_dup 1) (match_dup 2)))
6093 (minus:DWIH (match_dup 1) (match_dup 2)))])
6094 (parallel [(set (match_dup 3)
6098 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6100 (clobber (reg:CC FLAGS_REG))])]
6101 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6103 (define_insn "*sub<mode>_1"
6104 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6106 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6107 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6108 (clobber (reg:CC FLAGS_REG))]
6109 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6110 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6111 [(set_attr "type" "alu")
6112 (set_attr "mode" "<MODE>")])
6114 (define_insn "*subsi_1_zext"
6115 [(set (match_operand:DI 0 "register_operand" "=r")
6117 (minus:SI (match_operand:SI 1 "register_operand" "0")
6118 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6119 (clobber (reg:CC FLAGS_REG))]
6120 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6121 "sub{l}\t{%2, %k0|%k0, %2}"
6122 [(set_attr "type" "alu")
6123 (set_attr "mode" "SI")])
6125 (define_insn "*subqi_1_slp"
6126 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6127 (minus:QI (match_dup 0)
6128 (match_operand:QI 1 "general_operand" "qn,qm")))
6129 (clobber (reg:CC FLAGS_REG))]
6130 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6131 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6132 "sub{b}\t{%1, %0|%0, %1}"
6133 [(set_attr "type" "alu1")
6134 (set_attr "mode" "QI")])
6136 (define_insn "*sub<mode>_2"
6137 [(set (reg FLAGS_REG)
6140 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6141 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6143 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6144 (minus:SWI (match_dup 1) (match_dup 2)))]
6145 "ix86_match_ccmode (insn, CCGOCmode)
6146 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6147 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6148 [(set_attr "type" "alu")
6149 (set_attr "mode" "<MODE>")])
6151 (define_insn "*subsi_2_zext"
6152 [(set (reg FLAGS_REG)
6154 (minus:SI (match_operand:SI 1 "register_operand" "0")
6155 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6157 (set (match_operand:DI 0 "register_operand" "=r")
6159 (minus:SI (match_dup 1)
6161 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6162 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6163 "sub{l}\t{%2, %k0|%k0, %2}"
6164 [(set_attr "type" "alu")
6165 (set_attr "mode" "SI")])
6167 ;; Subtract with jump on overflow.
6168 (define_expand "subv<mode>4"
6169 [(parallel [(set (reg:CCO FLAGS_REG)
6170 (eq:CCO (minus:<DWI>
6172 (match_operand:SWI 1 "nonimmediate_operand"))
6175 (minus:SWI (match_dup 1)
6176 (match_operand:SWI 2
6177 "<general_operand>")))))
6178 (set (match_operand:SWI 0 "register_operand")
6179 (minus:SWI (match_dup 1) (match_dup 2)))])
6180 (set (pc) (if_then_else
6181 (eq (reg:CCO FLAGS_REG) (const_int 0))
6182 (label_ref (match_operand 3))
6186 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6187 if (CONST_INT_P (operands[2]))
6188 operands[4] = operands[2];
6190 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6193 (define_insn "*subv<mode>4"
6194 [(set (reg:CCO FLAGS_REG)
6195 (eq:CCO (minus:<DWI>
6197 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6199 (match_operand:SWI 2 "<general_sext_operand>"
6202 (minus:SWI (match_dup 1) (match_dup 2)))))
6203 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6204 (minus:SWI (match_dup 1) (match_dup 2)))]
6205 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6206 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6207 [(set_attr "type" "alu")
6208 (set_attr "mode" "<MODE>")])
6210 (define_insn "*subv<mode>4_1"
6211 [(set (reg:CCO FLAGS_REG)
6212 (eq:CCO (minus:<DWI>
6214 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6215 (match_operand:<DWI> 3 "const_int_operand" "i"))
6217 (minus:SWI (match_dup 1)
6218 (match_operand:SWI 2 "x86_64_immediate_operand"
6220 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6221 (minus:SWI (match_dup 1) (match_dup 2)))]
6222 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6223 && CONST_INT_P (operands[2])
6224 && INTVAL (operands[2]) == INTVAL (operands[3])"
6225 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6226 [(set_attr "type" "alu")
6227 (set_attr "mode" "<MODE>")
6228 (set (attr "length_immediate")
6229 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6231 (match_test "<MODE_SIZE> == 8")
6233 (const_string "<MODE_SIZE>")))])
6235 (define_insn "*sub<mode>_3"
6236 [(set (reg FLAGS_REG)
6237 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6238 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6240 (minus:SWI (match_dup 1) (match_dup 2)))]
6241 "ix86_match_ccmode (insn, CCmode)
6242 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6243 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6244 [(set_attr "type" "alu")
6245 (set_attr "mode" "<MODE>")])
6247 (define_insn "*subsi_3_zext"
6248 [(set (reg FLAGS_REG)
6249 (compare (match_operand:SI 1 "register_operand" "0")
6250 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6251 (set (match_operand:DI 0 "register_operand" "=r")
6253 (minus:SI (match_dup 1)
6255 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6256 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6257 "sub{l}\t{%2, %1|%1, %2}"
6258 [(set_attr "type" "alu")
6259 (set_attr "mode" "SI")])
6261 ;; Add with carry and subtract with borrow
6263 (define_expand "<plusminus_insn><mode>3_carry"
6265 [(set (match_operand:SWI 0 "nonimmediate_operand")
6267 (match_operand:SWI 1 "nonimmediate_operand")
6268 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6269 [(match_operand 3 "flags_reg_operand")
6271 (match_operand:SWI 2 "<general_operand>"))))
6272 (clobber (reg:CC FLAGS_REG))])]
6273 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6275 (define_insn "*<plusminus_insn><mode>3_carry"
6276 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6278 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6280 (match_operator 3 "ix86_carry_flag_operator"
6281 [(reg FLAGS_REG) (const_int 0)])
6282 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6283 (clobber (reg:CC FLAGS_REG))]
6284 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6285 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6286 [(set_attr "type" "alu")
6287 (set_attr "use_carry" "1")
6288 (set_attr "pent_pair" "pu")
6289 (set_attr "mode" "<MODE>")])
6291 (define_insn "*addsi3_carry_zext"
6292 [(set (match_operand:DI 0 "register_operand" "=r")
6294 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6295 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6296 [(reg FLAGS_REG) (const_int 0)])
6297 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6298 (clobber (reg:CC FLAGS_REG))]
6299 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6300 "adc{l}\t{%2, %k0|%k0, %2}"
6301 [(set_attr "type" "alu")
6302 (set_attr "use_carry" "1")
6303 (set_attr "pent_pair" "pu")
6304 (set_attr "mode" "SI")])
6306 (define_insn "*subsi3_carry_zext"
6307 [(set (match_operand:DI 0 "register_operand" "=r")
6309 (minus:SI (match_operand:SI 1 "register_operand" "0")
6310 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6311 [(reg FLAGS_REG) (const_int 0)])
6312 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6313 (clobber (reg:CC FLAGS_REG))]
6314 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6315 "sbb{l}\t{%2, %k0|%k0, %2}"
6316 [(set_attr "type" "alu")
6317 (set_attr "pent_pair" "pu")
6318 (set_attr "mode" "SI")])
6322 (define_insn "adcx<mode>3"
6323 [(set (reg:CCC FLAGS_REG)
6326 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6328 (match_operator 4 "ix86_carry_flag_operator"
6329 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6330 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6332 (set (match_operand:SWI48 0 "register_operand" "=r")
6333 (plus:SWI48 (match_dup 1)
6334 (plus:SWI48 (match_op_dup 4
6335 [(match_dup 3) (const_int 0)])
6337 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6338 "adcx\t{%2, %0|%0, %2}"
6339 [(set_attr "type" "alu")
6340 (set_attr "use_carry" "1")
6341 (set_attr "mode" "<MODE>")])
6343 ;; Overflow setting add instructions
6345 (define_insn "*add<mode>3_cconly_overflow"
6346 [(set (reg:CCC FLAGS_REG)
6349 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6350 (match_operand:SWI 2 "<general_operand>" "<g>"))
6352 (clobber (match_scratch:SWI 0 "=<r>"))]
6353 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6354 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6355 [(set_attr "type" "alu")
6356 (set_attr "mode" "<MODE>")])
6358 (define_insn "*add<mode>3_cc_overflow"
6359 [(set (reg:CCC FLAGS_REG)
6362 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6363 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6365 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6366 (plus:SWI (match_dup 1) (match_dup 2)))]
6367 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6368 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6369 [(set_attr "type" "alu")
6370 (set_attr "mode" "<MODE>")])
6372 (define_insn "*addsi3_zext_cc_overflow"
6373 [(set (reg:CCC FLAGS_REG)
6376 (match_operand:SI 1 "nonimmediate_operand" "%0")
6377 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6379 (set (match_operand:DI 0 "register_operand" "=r")
6380 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6381 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6382 "add{l}\t{%2, %k0|%k0, %2}"
6383 [(set_attr "type" "alu")
6384 (set_attr "mode" "SI")])
6386 ;; The patterns that match these are at the end of this file.
6388 (define_expand "<plusminus_insn>xf3"
6389 [(set (match_operand:XF 0 "register_operand")
6391 (match_operand:XF 1 "register_operand")
6392 (match_operand:XF 2 "register_operand")))]
6395 (define_expand "<plusminus_insn><mode>3"
6396 [(set (match_operand:MODEF 0 "register_operand")
6398 (match_operand:MODEF 1 "register_operand")
6399 (match_operand:MODEF 2 "nonimmediate_operand")))]
6400 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6403 ;; Multiply instructions
6405 (define_expand "mul<mode>3"
6406 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6408 (match_operand:SWIM248 1 "register_operand")
6409 (match_operand:SWIM248 2 "<general_operand>")))
6410 (clobber (reg:CC FLAGS_REG))])])
6412 (define_expand "mulqi3"
6413 [(parallel [(set (match_operand:QI 0 "register_operand")
6415 (match_operand:QI 1 "register_operand")
6416 (match_operand:QI 2 "nonimmediate_operand")))
6417 (clobber (reg:CC FLAGS_REG))])]
6418 "TARGET_QIMODE_MATH")
6421 ;; IMUL reg32/64, reg32/64, imm8 Direct
6422 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6423 ;; IMUL reg32/64, reg32/64, imm32 Direct
6424 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6425 ;; IMUL reg32/64, reg32/64 Direct
6426 ;; IMUL reg32/64, mem32/64 Direct
6428 ;; On BDVER1, all above IMULs use DirectPath
6430 (define_insn "*mul<mode>3_1"
6431 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6433 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6434 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6435 (clobber (reg:CC FLAGS_REG))]
6436 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6438 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6439 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6440 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6441 [(set_attr "type" "imul")
6442 (set_attr "prefix_0f" "0,0,1")
6443 (set (attr "athlon_decode")
6444 (cond [(eq_attr "cpu" "athlon")
6445 (const_string "vector")
6446 (eq_attr "alternative" "1")
6447 (const_string "vector")
6448 (and (eq_attr "alternative" "2")
6449 (match_operand 1 "memory_operand"))
6450 (const_string "vector")]
6451 (const_string "direct")))
6452 (set (attr "amdfam10_decode")
6453 (cond [(and (eq_attr "alternative" "0,1")
6454 (match_operand 1 "memory_operand"))
6455 (const_string "vector")]
6456 (const_string "direct")))
6457 (set_attr "bdver1_decode" "direct")
6458 (set_attr "mode" "<MODE>")])
6460 (define_insn "*mulsi3_1_zext"
6461 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6463 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6464 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6465 (clobber (reg:CC FLAGS_REG))]
6467 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6469 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6470 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6471 imul{l}\t{%2, %k0|%k0, %2}"
6472 [(set_attr "type" "imul")
6473 (set_attr "prefix_0f" "0,0,1")
6474 (set (attr "athlon_decode")
6475 (cond [(eq_attr "cpu" "athlon")
6476 (const_string "vector")
6477 (eq_attr "alternative" "1")
6478 (const_string "vector")
6479 (and (eq_attr "alternative" "2")
6480 (match_operand 1 "memory_operand"))
6481 (const_string "vector")]
6482 (const_string "direct")))
6483 (set (attr "amdfam10_decode")
6484 (cond [(and (eq_attr "alternative" "0,1")
6485 (match_operand 1 "memory_operand"))
6486 (const_string "vector")]
6487 (const_string "direct")))
6488 (set_attr "bdver1_decode" "direct")
6489 (set_attr "mode" "SI")])
6492 ;; IMUL reg16, reg16, imm8 VectorPath
6493 ;; IMUL reg16, mem16, imm8 VectorPath
6494 ;; IMUL reg16, reg16, imm16 VectorPath
6495 ;; IMUL reg16, mem16, imm16 VectorPath
6496 ;; IMUL reg16, reg16 Direct
6497 ;; IMUL reg16, mem16 Direct
6499 ;; On BDVER1, all HI MULs use DoublePath
6501 (define_insn "*mulhi3_1"
6502 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6503 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6504 (match_operand:HI 2 "general_operand" "K,n,mr")))
6505 (clobber (reg:CC FLAGS_REG))]
6507 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6509 imul{w}\t{%2, %1, %0|%0, %1, %2}
6510 imul{w}\t{%2, %1, %0|%0, %1, %2}
6511 imul{w}\t{%2, %0|%0, %2}"
6512 [(set_attr "type" "imul")
6513 (set_attr "prefix_0f" "0,0,1")
6514 (set (attr "athlon_decode")
6515 (cond [(eq_attr "cpu" "athlon")
6516 (const_string "vector")
6517 (eq_attr "alternative" "1,2")
6518 (const_string "vector")]
6519 (const_string "direct")))
6520 (set (attr "amdfam10_decode")
6521 (cond [(eq_attr "alternative" "0,1")
6522 (const_string "vector")]
6523 (const_string "direct")))
6524 (set_attr "bdver1_decode" "double")
6525 (set_attr "mode" "HI")])
6527 ;;On AMDFAM10 and BDVER1
6531 (define_insn "*mulqi3_1"
6532 [(set (match_operand:QI 0 "register_operand" "=a")
6533 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6534 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6535 (clobber (reg:CC FLAGS_REG))]
6537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6539 [(set_attr "type" "imul")
6540 (set_attr "length_immediate" "0")
6541 (set (attr "athlon_decode")
6542 (if_then_else (eq_attr "cpu" "athlon")
6543 (const_string "vector")
6544 (const_string "direct")))
6545 (set_attr "amdfam10_decode" "direct")
6546 (set_attr "bdver1_decode" "direct")
6547 (set_attr "mode" "QI")])
6549 ;; Multiply with jump on overflow.
6550 (define_expand "mulv<mode>4"
6551 [(parallel [(set (reg:CCO FLAGS_REG)
6554 (match_operand:SWI48 1 "register_operand"))
6557 (mult:SWI48 (match_dup 1)
6558 (match_operand:SWI48 2
6559 "<general_operand>")))))
6560 (set (match_operand:SWI48 0 "register_operand")
6561 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6562 (set (pc) (if_then_else
6563 (eq (reg:CCO FLAGS_REG) (const_int 0))
6564 (label_ref (match_operand 3))
6568 if (CONST_INT_P (operands[2]))
6569 operands[4] = operands[2];
6571 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6574 (define_insn "*mulv<mode>4"
6575 [(set (reg:CCO FLAGS_REG)
6578 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6580 (match_operand:SWI48 2 "<general_sext_operand>"
6583 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6584 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6585 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6586 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6588 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6589 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6590 [(set_attr "type" "imul")
6591 (set_attr "prefix_0f" "0,1")
6592 (set (attr "athlon_decode")
6593 (cond [(eq_attr "cpu" "athlon")
6594 (const_string "vector")
6595 (eq_attr "alternative" "0")
6596 (const_string "vector")
6597 (and (eq_attr "alternative" "1")
6598 (match_operand 1 "memory_operand"))
6599 (const_string "vector")]
6600 (const_string "direct")))
6601 (set (attr "amdfam10_decode")
6602 (cond [(and (eq_attr "alternative" "1")
6603 (match_operand 1 "memory_operand"))
6604 (const_string "vector")]
6605 (const_string "direct")))
6606 (set_attr "bdver1_decode" "direct")
6607 (set_attr "mode" "<MODE>")])
6609 (define_insn "*mulv<mode>4_1"
6610 [(set (reg:CCO FLAGS_REG)
6613 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6614 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6616 (mult:SWI48 (match_dup 1)
6617 (match_operand:SWI 2 "x86_64_immediate_operand"
6619 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6620 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6621 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6622 && CONST_INT_P (operands[2])
6623 && INTVAL (operands[2]) == INTVAL (operands[3])"
6625 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6626 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6627 [(set_attr "type" "imul")
6628 (set (attr "athlon_decode")
6629 (cond [(eq_attr "cpu" "athlon")
6630 (const_string "vector")
6631 (eq_attr "alternative" "1")
6632 (const_string "vector")]
6633 (const_string "direct")))
6634 (set (attr "amdfam10_decode")
6635 (cond [(match_operand 1 "memory_operand")
6636 (const_string "vector")]
6637 (const_string "direct")))
6638 (set_attr "bdver1_decode" "direct")
6639 (set_attr "mode" "<MODE>")
6640 (set (attr "length_immediate")
6641 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6643 (match_test "<MODE_SIZE> == 8")
6645 (const_string "<MODE_SIZE>")))])
6647 (define_expand "<u>mul<mode><dwi>3"
6648 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6651 (match_operand:DWIH 1 "nonimmediate_operand"))
6653 (match_operand:DWIH 2 "register_operand"))))
6654 (clobber (reg:CC FLAGS_REG))])])
6656 (define_expand "<u>mulqihi3"
6657 [(parallel [(set (match_operand:HI 0 "register_operand")
6660 (match_operand:QI 1 "nonimmediate_operand"))
6662 (match_operand:QI 2 "register_operand"))))
6663 (clobber (reg:CC FLAGS_REG))])]
6664 "TARGET_QIMODE_MATH")
6666 (define_insn "*bmi2_umulditi3_1"
6667 [(set (match_operand:DI 0 "register_operand" "=r")
6669 (match_operand:DI 2 "nonimmediate_operand" "%d")
6670 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6671 (set (match_operand:DI 1 "register_operand" "=r")
6674 (mult:TI (zero_extend:TI (match_dup 2))
6675 (zero_extend:TI (match_dup 3)))
6677 "TARGET_64BIT && TARGET_BMI2
6678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679 "mulx\t{%3, %0, %1|%1, %0, %3}"
6680 [(set_attr "type" "imulx")
6681 (set_attr "prefix" "vex")
6682 (set_attr "mode" "DI")])
6684 (define_insn "*bmi2_umulsidi3_1"
6685 [(set (match_operand:SI 0 "register_operand" "=r")
6687 (match_operand:SI 2 "nonimmediate_operand" "%d")
6688 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6689 (set (match_operand:SI 1 "register_operand" "=r")
6692 (mult:DI (zero_extend:DI (match_dup 2))
6693 (zero_extend:DI (match_dup 3)))
6695 "!TARGET_64BIT && TARGET_BMI2
6696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6697 "mulx\t{%3, %0, %1|%1, %0, %3}"
6698 [(set_attr "type" "imulx")
6699 (set_attr "prefix" "vex")
6700 (set_attr "mode" "SI")])
6702 (define_insn "*umul<mode><dwi>3_1"
6703 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6706 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6708 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6709 (clobber (reg:CC FLAGS_REG))]
6710 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713 mul{<imodesuffix>}\t%2"
6714 [(set_attr "isa" "bmi2,*")
6715 (set_attr "type" "imulx,imul")
6716 (set_attr "length_immediate" "*,0")
6717 (set (attr "athlon_decode")
6718 (cond [(eq_attr "alternative" "1")
6719 (if_then_else (eq_attr "cpu" "athlon")
6720 (const_string "vector")
6721 (const_string "double"))]
6722 (const_string "*")))
6723 (set_attr "amdfam10_decode" "*,double")
6724 (set_attr "bdver1_decode" "*,direct")
6725 (set_attr "prefix" "vex,orig")
6726 (set_attr "mode" "<MODE>")])
6728 ;; Convert mul to the mulx pattern to avoid flags dependency.
6730 [(set (match_operand:<DWI> 0 "register_operand")
6733 (match_operand:DWIH 1 "register_operand"))
6735 (match_operand:DWIH 2 "nonimmediate_operand"))))
6736 (clobber (reg:CC FLAGS_REG))]
6737 "TARGET_BMI2 && reload_completed
6738 && true_regnum (operands[1]) == DX_REG"
6739 [(parallel [(set (match_dup 3)
6740 (mult:DWIH (match_dup 1) (match_dup 2)))
6744 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6745 (zero_extend:<DWI> (match_dup 2)))
6748 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6750 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6753 (define_insn "*mul<mode><dwi>3_1"
6754 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6757 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6759 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6760 (clobber (reg:CC FLAGS_REG))]
6761 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6762 "imul{<imodesuffix>}\t%2"
6763 [(set_attr "type" "imul")
6764 (set_attr "length_immediate" "0")
6765 (set (attr "athlon_decode")
6766 (if_then_else (eq_attr "cpu" "athlon")
6767 (const_string "vector")
6768 (const_string "double")))
6769 (set_attr "amdfam10_decode" "double")
6770 (set_attr "bdver1_decode" "direct")
6771 (set_attr "mode" "<MODE>")])
6773 (define_insn "*<u>mulqihi3_1"
6774 [(set (match_operand:HI 0 "register_operand" "=a")
6777 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6779 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6780 (clobber (reg:CC FLAGS_REG))]
6782 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6783 "<sgnprefix>mul{b}\t%2"
6784 [(set_attr "type" "imul")
6785 (set_attr "length_immediate" "0")
6786 (set (attr "athlon_decode")
6787 (if_then_else (eq_attr "cpu" "athlon")
6788 (const_string "vector")
6789 (const_string "direct")))
6790 (set_attr "amdfam10_decode" "direct")
6791 (set_attr "bdver1_decode" "direct")
6792 (set_attr "mode" "QI")])
6794 (define_expand "<s>mul<mode>3_highpart"
6795 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6800 (match_operand:SWI48 1 "nonimmediate_operand"))
6802 (match_operand:SWI48 2 "register_operand")))
6804 (clobber (match_scratch:SWI48 3))
6805 (clobber (reg:CC FLAGS_REG))])]
6807 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6809 (define_insn "*<s>muldi3_highpart_1"
6810 [(set (match_operand:DI 0 "register_operand" "=d")
6815 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6817 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6819 (clobber (match_scratch:DI 3 "=1"))
6820 (clobber (reg:CC FLAGS_REG))]
6822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823 "<sgnprefix>mul{q}\t%2"
6824 [(set_attr "type" "imul")
6825 (set_attr "length_immediate" "0")
6826 (set (attr "athlon_decode")
6827 (if_then_else (eq_attr "cpu" "athlon")
6828 (const_string "vector")
6829 (const_string "double")))
6830 (set_attr "amdfam10_decode" "double")
6831 (set_attr "bdver1_decode" "direct")
6832 (set_attr "mode" "DI")])
6834 (define_insn "*<s>mulsi3_highpart_1"
6835 [(set (match_operand:SI 0 "register_operand" "=d")
6840 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6842 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6844 (clobber (match_scratch:SI 3 "=1"))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6847 "<sgnprefix>mul{l}\t%2"
6848 [(set_attr "type" "imul")
6849 (set_attr "length_immediate" "0")
6850 (set (attr "athlon_decode")
6851 (if_then_else (eq_attr "cpu" "athlon")
6852 (const_string "vector")
6853 (const_string "double")))
6854 (set_attr "amdfam10_decode" "double")
6855 (set_attr "bdver1_decode" "direct")
6856 (set_attr "mode" "SI")])
6858 (define_insn "*<s>mulsi3_highpart_zext"
6859 [(set (match_operand:DI 0 "register_operand" "=d")
6860 (zero_extend:DI (truncate:SI
6862 (mult:DI (any_extend:DI
6863 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6865 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6867 (clobber (match_scratch:SI 3 "=1"))
6868 (clobber (reg:CC FLAGS_REG))]
6870 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6871 "<sgnprefix>mul{l}\t%2"
6872 [(set_attr "type" "imul")
6873 (set_attr "length_immediate" "0")
6874 (set (attr "athlon_decode")
6875 (if_then_else (eq_attr "cpu" "athlon")
6876 (const_string "vector")
6877 (const_string "double")))
6878 (set_attr "amdfam10_decode" "double")
6879 (set_attr "bdver1_decode" "direct")
6880 (set_attr "mode" "SI")])
6882 ;; The patterns that match these are at the end of this file.
6884 (define_expand "mulxf3"
6885 [(set (match_operand:XF 0 "register_operand")
6886 (mult:XF (match_operand:XF 1 "register_operand")
6887 (match_operand:XF 2 "register_operand")))]
6890 (define_expand "mul<mode>3"
6891 [(set (match_operand:MODEF 0 "register_operand")
6892 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6893 (match_operand:MODEF 2 "nonimmediate_operand")))]
6894 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6895 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6897 ;; Divide instructions
6899 ;; The patterns that match these are at the end of this file.
6901 (define_expand "divxf3"
6902 [(set (match_operand:XF 0 "register_operand")
6903 (div:XF (match_operand:XF 1 "register_operand")
6904 (match_operand:XF 2 "register_operand")))]
6907 (define_expand "divdf3"
6908 [(set (match_operand:DF 0 "register_operand")
6909 (div:DF (match_operand:DF 1 "register_operand")
6910 (match_operand:DF 2 "nonimmediate_operand")))]
6911 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6912 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6914 (define_expand "divsf3"
6915 [(set (match_operand:SF 0 "register_operand")
6916 (div:SF (match_operand:SF 1 "register_operand")
6917 (match_operand:SF 2 "nonimmediate_operand")))]
6918 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6923 && optimize_insn_for_speed_p ()
6924 && flag_finite_math_only && !flag_trapping_math
6925 && flag_unsafe_math_optimizations)
6927 ix86_emit_swdivsf (operands[0], operands[1],
6928 operands[2], SFmode);
6933 ;; Divmod instructions.
6935 (define_expand "divmod<mode>4"
6936 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6938 (match_operand:SWIM248 1 "register_operand")
6939 (match_operand:SWIM248 2 "nonimmediate_operand")))
6940 (set (match_operand:SWIM248 3 "register_operand")
6941 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6942 (clobber (reg:CC FLAGS_REG))])])
6944 ;; Split with 8bit unsigned divide:
6945 ;; if (dividend an divisor are in [0-255])
6946 ;; use 8bit unsigned integer divide
6948 ;; use original integer divide
6950 [(set (match_operand:SWI48 0 "register_operand")
6951 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6952 (match_operand:SWI48 3 "nonimmediate_operand")))
6953 (set (match_operand:SWI48 1 "register_operand")
6954 (mod:SWI48 (match_dup 2) (match_dup 3)))
6955 (clobber (reg:CC FLAGS_REG))]
6956 "TARGET_USE_8BIT_IDIV
6957 && TARGET_QIMODE_MATH
6958 && can_create_pseudo_p ()
6959 && !optimize_insn_for_size_p ()"
6961 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6963 (define_insn_and_split "divmod<mode>4_1"
6964 [(set (match_operand:SWI48 0 "register_operand" "=a")
6965 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6966 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6967 (set (match_operand:SWI48 1 "register_operand" "=&d")
6968 (mod:SWI48 (match_dup 2) (match_dup 3)))
6969 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6970 (clobber (reg:CC FLAGS_REG))]
6974 [(parallel [(set (match_dup 1)
6975 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6976 (clobber (reg:CC FLAGS_REG))])
6977 (parallel [(set (match_dup 0)
6978 (div:SWI48 (match_dup 2) (match_dup 3)))
6980 (mod:SWI48 (match_dup 2) (match_dup 3)))
6982 (clobber (reg:CC FLAGS_REG))])]
6984 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6986 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6987 operands[4] = operands[2];
6990 /* Avoid use of cltd in favor of a mov+shift. */
6991 emit_move_insn (operands[1], operands[2]);
6992 operands[4] = operands[1];
6995 [(set_attr "type" "multi")
6996 (set_attr "mode" "<MODE>")])
6998 (define_insn_and_split "*divmod<mode>4"
6999 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7000 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7001 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7002 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7003 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7004 (clobber (reg:CC FLAGS_REG))]
7008 [(parallel [(set (match_dup 1)
7009 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7010 (clobber (reg:CC FLAGS_REG))])
7011 (parallel [(set (match_dup 0)
7012 (div:SWIM248 (match_dup 2) (match_dup 3)))
7014 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7016 (clobber (reg:CC FLAGS_REG))])]
7018 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7020 if (<MODE>mode != HImode
7021 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7022 operands[4] = operands[2];
7025 /* Avoid use of cltd in favor of a mov+shift. */
7026 emit_move_insn (operands[1], operands[2]);
7027 operands[4] = operands[1];
7030 [(set_attr "type" "multi")
7031 (set_attr "mode" "<MODE>")])
7033 (define_insn "*divmod<mode>4_noext"
7034 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7035 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7036 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7037 (set (match_operand:SWIM248 1 "register_operand" "=d")
7038 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7039 (use (match_operand:SWIM248 4 "register_operand" "1"))
7040 (clobber (reg:CC FLAGS_REG))]
7042 "idiv{<imodesuffix>}\t%3"
7043 [(set_attr "type" "idiv")
7044 (set_attr "mode" "<MODE>")])
7046 (define_expand "divmodqi4"
7047 [(parallel [(set (match_operand:QI 0 "register_operand")
7049 (match_operand:QI 1 "register_operand")
7050 (match_operand:QI 2 "nonimmediate_operand")))
7051 (set (match_operand:QI 3 "register_operand")
7052 (mod:QI (match_dup 1) (match_dup 2)))
7053 (clobber (reg:CC FLAGS_REG))])]
7054 "TARGET_QIMODE_MATH"
7059 tmp0 = gen_reg_rtx (HImode);
7060 tmp1 = gen_reg_rtx (HImode);
7062 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7064 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7065 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7067 /* Extract remainder from AH. */
7068 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7069 insn = emit_move_insn (operands[3], tmp1);
7071 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7072 set_unique_reg_note (insn, REG_EQUAL, mod);
7074 /* Extract quotient from AL. */
7075 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7077 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7078 set_unique_reg_note (insn, REG_EQUAL, div);
7083 ;; Divide AX by r/m8, with result stored in
7086 ;; Change div/mod to HImode and extend the second argument to HImode
7087 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7088 ;; combine may fail.
7089 (define_insn "divmodhiqi3"
7090 [(set (match_operand:HI 0 "register_operand" "=a")
7095 (mod:HI (match_operand:HI 1 "register_operand" "0")
7097 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7101 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7102 (clobber (reg:CC FLAGS_REG))]
7103 "TARGET_QIMODE_MATH"
7105 [(set_attr "type" "idiv")
7106 (set_attr "mode" "QI")])
7108 (define_expand "udivmod<mode>4"
7109 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7111 (match_operand:SWIM248 1 "register_operand")
7112 (match_operand:SWIM248 2 "nonimmediate_operand")))
7113 (set (match_operand:SWIM248 3 "register_operand")
7114 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7115 (clobber (reg:CC FLAGS_REG))])])
7117 ;; Split with 8bit unsigned divide:
7118 ;; if (dividend an divisor are in [0-255])
7119 ;; use 8bit unsigned integer divide
7121 ;; use original integer divide
7123 [(set (match_operand:SWI48 0 "register_operand")
7124 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7125 (match_operand:SWI48 3 "nonimmediate_operand")))
7126 (set (match_operand:SWI48 1 "register_operand")
7127 (umod:SWI48 (match_dup 2) (match_dup 3)))
7128 (clobber (reg:CC FLAGS_REG))]
7129 "TARGET_USE_8BIT_IDIV
7130 && TARGET_QIMODE_MATH
7131 && can_create_pseudo_p ()
7132 && !optimize_insn_for_size_p ()"
7134 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7136 (define_insn_and_split "udivmod<mode>4_1"
7137 [(set (match_operand:SWI48 0 "register_operand" "=a")
7138 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7139 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7140 (set (match_operand:SWI48 1 "register_operand" "=&d")
7141 (umod:SWI48 (match_dup 2) (match_dup 3)))
7142 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7143 (clobber (reg:CC FLAGS_REG))]
7147 [(set (match_dup 1) (const_int 0))
7148 (parallel [(set (match_dup 0)
7149 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7151 (umod:SWI48 (match_dup 2) (match_dup 3)))
7153 (clobber (reg:CC FLAGS_REG))])]
7155 [(set_attr "type" "multi")
7156 (set_attr "mode" "<MODE>")])
7158 (define_insn_and_split "*udivmod<mode>4"
7159 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7160 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7161 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7162 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7163 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7164 (clobber (reg:CC FLAGS_REG))]
7168 [(set (match_dup 1) (const_int 0))
7169 (parallel [(set (match_dup 0)
7170 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7172 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7174 (clobber (reg:CC FLAGS_REG))])]
7176 [(set_attr "type" "multi")
7177 (set_attr "mode" "<MODE>")])
7179 (define_insn "*udivmod<mode>4_noext"
7180 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7181 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7182 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7183 (set (match_operand:SWIM248 1 "register_operand" "=d")
7184 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7185 (use (match_operand:SWIM248 4 "register_operand" "1"))
7186 (clobber (reg:CC FLAGS_REG))]
7188 "div{<imodesuffix>}\t%3"
7189 [(set_attr "type" "idiv")
7190 (set_attr "mode" "<MODE>")])
7192 (define_expand "udivmodqi4"
7193 [(parallel [(set (match_operand:QI 0 "register_operand")
7195 (match_operand:QI 1 "register_operand")
7196 (match_operand:QI 2 "nonimmediate_operand")))
7197 (set (match_operand:QI 3 "register_operand")
7198 (umod:QI (match_dup 1) (match_dup 2)))
7199 (clobber (reg:CC FLAGS_REG))])]
7200 "TARGET_QIMODE_MATH"
7205 tmp0 = gen_reg_rtx (HImode);
7206 tmp1 = gen_reg_rtx (HImode);
7208 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7210 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7211 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7213 /* Extract remainder from AH. */
7214 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7215 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7216 insn = emit_move_insn (operands[3], tmp1);
7218 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7219 set_unique_reg_note (insn, REG_EQUAL, mod);
7221 /* Extract quotient from AL. */
7222 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7224 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7225 set_unique_reg_note (insn, REG_EQUAL, div);
7230 (define_insn "udivmodhiqi3"
7231 [(set (match_operand:HI 0 "register_operand" "=a")
7236 (mod:HI (match_operand:HI 1 "register_operand" "0")
7238 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7242 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7243 (clobber (reg:CC FLAGS_REG))]
7244 "TARGET_QIMODE_MATH"
7246 [(set_attr "type" "idiv")
7247 (set_attr "mode" "QI")])
7249 ;; We cannot use div/idiv for double division, because it causes
7250 ;; "division by zero" on the overflow and that's not what we expect
7251 ;; from truncate. Because true (non truncating) double division is
7252 ;; never generated, we can't create this insn anyway.
7255 ; [(set (match_operand:SI 0 "register_operand" "=a")
7257 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7259 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7260 ; (set (match_operand:SI 3 "register_operand" "=d")
7262 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7263 ; (clobber (reg:CC FLAGS_REG))]
7265 ; "div{l}\t{%2, %0|%0, %2}"
7266 ; [(set_attr "type" "idiv")])
7268 ;;- Logical AND instructions
7270 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7271 ;; Note that this excludes ah.
7273 (define_expand "testsi_ccno_1"
7274 [(set (reg:CCNO FLAGS_REG)
7276 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7277 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7280 (define_expand "testqi_ccz_1"
7281 [(set (reg:CCZ FLAGS_REG)
7282 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7283 (match_operand:QI 1 "nonmemory_operand"))
7286 (define_expand "testdi_ccno_1"
7287 [(set (reg:CCNO FLAGS_REG)
7289 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7290 (match_operand:DI 1 "x86_64_szext_general_operand"))
7292 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7294 (define_insn "*testdi_1"
7295 [(set (reg FLAGS_REG)
7298 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7299 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7301 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7302 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7304 test{l}\t{%k1, %k0|%k0, %k1}
7305 test{l}\t{%k1, %k0|%k0, %k1}
7306 test{q}\t{%1, %0|%0, %1}
7307 test{q}\t{%1, %0|%0, %1}
7308 test{q}\t{%1, %0|%0, %1}"
7309 [(set_attr "type" "test")
7310 (set_attr "modrm" "0,1,0,1,1")
7311 (set_attr "mode" "SI,SI,DI,DI,DI")])
7313 (define_insn "*testqi_1_maybe_si"
7314 [(set (reg FLAGS_REG)
7317 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7318 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7320 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7321 && ix86_match_ccmode (insn,
7322 CONST_INT_P (operands[1])
7323 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7325 if (which_alternative == 3)
7327 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7328 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7329 return "test{l}\t{%1, %k0|%k0, %1}";
7331 return "test{b}\t{%1, %0|%0, %1}";
7333 [(set_attr "type" "test")
7334 (set_attr "modrm" "0,1,1,1")
7335 (set_attr "mode" "QI,QI,QI,SI")
7336 (set_attr "pent_pair" "uv,np,uv,np")])
7338 (define_insn "*test<mode>_1"
7339 [(set (reg FLAGS_REG)
7342 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7343 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7345 "ix86_match_ccmode (insn, CCNOmode)
7346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7347 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7348 [(set_attr "type" "test")
7349 (set_attr "modrm" "0,1,1")
7350 (set_attr "mode" "<MODE>")
7351 (set_attr "pent_pair" "uv,np,uv")])
7353 (define_expand "testqi_ext_ccno_0"
7354 [(set (reg:CCNO FLAGS_REG)
7358 (match_operand 0 "ext_register_operand")
7361 (match_operand 1 "const_int_operand"))
7364 (define_insn "*testqi_ext_0"
7365 [(set (reg FLAGS_REG)
7369 (match_operand 0 "ext_register_operand" "Q")
7372 (match_operand 1 "const_int_operand" "n"))
7374 "ix86_match_ccmode (insn, CCNOmode)"
7375 "test{b}\t{%1, %h0|%h0, %1}"
7376 [(set_attr "type" "test")
7377 (set_attr "mode" "QI")
7378 (set_attr "length_immediate" "1")
7379 (set_attr "modrm" "1")
7380 (set_attr "pent_pair" "np")])
7382 (define_insn "*testqi_ext_1"
7383 [(set (reg FLAGS_REG)
7387 (match_operand 0 "ext_register_operand" "Q,Q")
7391 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7393 "ix86_match_ccmode (insn, CCNOmode)"
7394 "test{b}\t{%1, %h0|%h0, %1}"
7395 [(set_attr "isa" "*,nox64")
7396 (set_attr "type" "test")
7397 (set_attr "mode" "QI")])
7399 (define_insn "*testqi_ext_2"
7400 [(set (reg FLAGS_REG)
7404 (match_operand 0 "ext_register_operand" "Q")
7408 (match_operand 1 "ext_register_operand" "Q")
7412 "ix86_match_ccmode (insn, CCNOmode)"
7413 "test{b}\t{%h1, %h0|%h0, %h1}"
7414 [(set_attr "type" "test")
7415 (set_attr "mode" "QI")])
7417 ;; Combine likes to form bit extractions for some tests. Humor it.
7418 (define_insn "*testqi_ext_3"
7419 [(set (reg FLAGS_REG)
7420 (compare (zero_extract:SWI48
7421 (match_operand 0 "nonimmediate_operand" "rm")
7422 (match_operand:SWI48 1 "const_int_operand")
7423 (match_operand:SWI48 2 "const_int_operand"))
7425 "ix86_match_ccmode (insn, CCNOmode)
7426 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7427 || GET_MODE (operands[0]) == SImode
7428 || GET_MODE (operands[0]) == HImode
7429 || GET_MODE (operands[0]) == QImode)
7430 /* Ensure that resulting mask is zero or sign extended operand. */
7431 && INTVAL (operands[2]) >= 0
7432 && ((INTVAL (operands[1]) > 0
7433 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7434 || (<MODE>mode == DImode
7435 && INTVAL (operands[1]) > 32
7436 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7440 [(set (match_operand 0 "flags_reg_operand")
7441 (match_operator 1 "compare_operator"
7443 (match_operand 2 "nonimmediate_operand")
7444 (match_operand 3 "const_int_operand")
7445 (match_operand 4 "const_int_operand"))
7447 "ix86_match_ccmode (insn, CCNOmode)"
7448 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7450 rtx val = operands[2];
7451 HOST_WIDE_INT len = INTVAL (operands[3]);
7452 HOST_WIDE_INT pos = INTVAL (operands[4]);
7454 machine_mode mode, submode;
7456 mode = GET_MODE (val);
7459 /* ??? Combine likes to put non-volatile mem extractions in QImode
7460 no matter the size of the test. So find a mode that works. */
7461 if (! MEM_VOLATILE_P (val))
7463 mode = smallest_mode_for_size (pos + len, MODE_INT);
7464 val = adjust_address (val, mode, 0);
7467 else if (GET_CODE (val) == SUBREG
7468 && (submode = GET_MODE (SUBREG_REG (val)),
7469 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7470 && pos + len <= GET_MODE_BITSIZE (submode)
7471 && GET_MODE_CLASS (submode) == MODE_INT)
7473 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7475 val = SUBREG_REG (val);
7477 else if (mode == HImode && pos + len <= 8)
7479 /* Small HImode tests can be converted to QImode. */
7481 val = gen_lowpart (QImode, val);
7484 if (len == HOST_BITS_PER_WIDE_INT)
7487 mask = ((HOST_WIDE_INT)1 << len) - 1;
7490 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7493 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7494 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7495 ;; this is relatively important trick.
7496 ;; Do the conversion only post-reload to avoid limiting of the register class
7499 [(set (match_operand 0 "flags_reg_operand")
7500 (match_operator 1 "compare_operator"
7501 [(and (match_operand 2 "register_operand")
7502 (match_operand 3 "const_int_operand"))
7505 && QI_REG_P (operands[2])
7506 && GET_MODE (operands[2]) != QImode
7507 && ((ix86_match_ccmode (insn, CCZmode)
7508 && !(INTVAL (operands[3]) & ~(255 << 8)))
7509 || (ix86_match_ccmode (insn, CCNOmode)
7510 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7513 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7517 operands[2] = gen_lowpart (SImode, operands[2]);
7518 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7522 [(set (match_operand 0 "flags_reg_operand")
7523 (match_operator 1 "compare_operator"
7524 [(and (match_operand 2 "nonimmediate_operand")
7525 (match_operand 3 "const_int_operand"))
7528 && GET_MODE (operands[2]) != QImode
7529 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7530 && ((ix86_match_ccmode (insn, CCZmode)
7531 && !(INTVAL (operands[3]) & ~255))
7532 || (ix86_match_ccmode (insn, CCNOmode)
7533 && !(INTVAL (operands[3]) & ~127)))"
7535 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7538 operands[2] = gen_lowpart (QImode, operands[2]);
7539 operands[3] = gen_lowpart (QImode, operands[3]);
7543 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7544 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7545 (match_operand:SWI1248x 2 "mask_reg_operand")))
7546 (clobber (reg:CC FLAGS_REG))]
7547 "TARGET_AVX512F && reload_completed"
7549 (any_logic:SWI1248x (match_dup 1)
7552 (define_insn "*k<logic><mode>"
7553 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7554 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7555 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7558 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7559 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7561 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7563 [(set_attr "mode" "<MODE>")
7564 (set_attr "type" "msklog")
7565 (set_attr "prefix" "vex")])
7567 ;; %%% This used to optimize known byte-wide and operations to memory,
7568 ;; and sometimes to QImode registers. If this is considered useful,
7569 ;; it should be done with splitters.
7571 (define_expand "and<mode>3"
7572 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7573 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7574 (match_operand:SWIM 2 "<general_szext_operand>")))]
7577 machine_mode mode = <MODE>mode;
7578 rtx (*insn) (rtx, rtx);
7580 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7582 HOST_WIDE_INT ival = INTVAL (operands[2]);
7584 if (ival == (HOST_WIDE_INT) 0xffffffff)
7586 else if (ival == 0xffff)
7588 else if (ival == 0xff)
7592 if (mode == <MODE>mode)
7594 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7598 if (<MODE>mode == DImode)
7599 insn = (mode == SImode)
7600 ? gen_zero_extendsidi2
7602 ? gen_zero_extendhidi2
7603 : gen_zero_extendqidi2;
7604 else if (<MODE>mode == SImode)
7605 insn = (mode == HImode)
7606 ? gen_zero_extendhisi2
7607 : gen_zero_extendqisi2;
7608 else if (<MODE>mode == HImode)
7609 insn = gen_zero_extendqihi2;
7613 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7617 (define_insn "*anddi_1"
7618 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7620 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7621 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7625 switch (get_attr_type (insn))
7631 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7634 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7635 if (get_attr_mode (insn) == MODE_SI)
7636 return "and{l}\t{%k2, %k0|%k0, %k2}";
7638 return "and{q}\t{%2, %0|%0, %2}";
7641 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7642 (set_attr "length_immediate" "*,*,*,0,0")
7643 (set (attr "prefix_rex")
7645 (and (eq_attr "type" "imovx")
7646 (and (match_test "INTVAL (operands[2]) == 0xff")
7647 (match_operand 1 "ext_QIreg_operand")))
7649 (const_string "*")))
7650 (set_attr "mode" "SI,DI,DI,SI,DI")])
7652 (define_insn "*andsi_1"
7653 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7654 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7655 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7656 (clobber (reg:CC FLAGS_REG))]
7657 "ix86_binary_operator_ok (AND, SImode, operands)"
7659 switch (get_attr_type (insn))
7665 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7669 return "and{l}\t{%2, %0|%0, %2}";
7672 [(set_attr "type" "alu,alu,imovx,msklog")
7673 (set (attr "prefix_rex")
7675 (and (eq_attr "type" "imovx")
7676 (and (match_test "INTVAL (operands[2]) == 0xff")
7677 (match_operand 1 "ext_QIreg_operand")))
7679 (const_string "*")))
7680 (set_attr "length_immediate" "*,*,0,0")
7681 (set_attr "mode" "SI")])
7683 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7684 (define_insn "*andsi_1_zext"
7685 [(set (match_operand:DI 0 "register_operand" "=r")
7687 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7688 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7689 (clobber (reg:CC FLAGS_REG))]
7690 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7691 "and{l}\t{%2, %k0|%k0, %2}"
7692 [(set_attr "type" "alu")
7693 (set_attr "mode" "SI")])
7695 (define_insn "*andhi_1"
7696 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7697 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7698 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7699 (clobber (reg:CC FLAGS_REG))]
7700 "ix86_binary_operator_ok (AND, HImode, operands)"
7702 switch (get_attr_type (insn))
7708 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7711 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7712 return "and{w}\t{%2, %0|%0, %2}";
7715 [(set_attr "type" "alu,alu,imovx,msklog")
7716 (set_attr "length_immediate" "*,*,0,*")
7717 (set (attr "prefix_rex")
7719 (and (eq_attr "type" "imovx")
7720 (match_operand 1 "ext_QIreg_operand"))
7722 (const_string "*")))
7723 (set_attr "mode" "HI,HI,SI,HI")])
7725 ;; %%% Potential partial reg stall on alternative 2. What to do?
7726 (define_insn "*andqi_1"
7727 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7728 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7729 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7730 (clobber (reg:CC FLAGS_REG))]
7731 "ix86_binary_operator_ok (AND, QImode, operands)"
7733 switch (which_alternative)
7737 return "and{b}\t{%2, %0|%0, %2}";
7739 return "and{l}\t{%k2, %k0|%k0, %k2}";
7741 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7742 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7747 [(set_attr "type" "alu,alu,alu,msklog")
7748 (set_attr "mode" "QI,QI,SI,HI")])
7750 (define_insn "*andqi_1_slp"
7751 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7752 (and:QI (match_dup 0)
7753 (match_operand:QI 1 "general_operand" "qn,qmn")))
7754 (clobber (reg:CC FLAGS_REG))]
7755 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7756 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7757 "and{b}\t{%1, %0|%0, %1}"
7758 [(set_attr "type" "alu1")
7759 (set_attr "mode" "QI")])
7761 (define_insn "kandn<mode>"
7762 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7765 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7766 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7767 (clobber (reg:CC FLAGS_REG))]
7770 switch (which_alternative)
7773 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7777 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7778 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7780 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7785 [(set_attr "isa" "bmi,*,avx512f")
7786 (set_attr "type" "bitmanip,*,msklog")
7787 (set_attr "prefix" "*,*,vex")
7788 (set_attr "btver2_decode" "direct,*,*")
7789 (set_attr "mode" "<MODE>")])
7792 [(set (match_operand:SWI12 0 "general_reg_operand")
7796 (match_operand:SWI12 1 "general_reg_operand")))
7797 (clobber (reg:CC FLAGS_REG))]
7798 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7800 (not:HI (match_dup 0)))
7801 (parallel [(set (match_dup 0)
7802 (and:HI (match_dup 0)
7804 (clobber (reg:CC FLAGS_REG))])])
7806 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7808 [(set (match_operand:DI 0 "register_operand")
7809 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7810 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7811 (clobber (reg:CC FLAGS_REG))]
7813 [(parallel [(set (match_dup 0)
7814 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7815 (clobber (reg:CC FLAGS_REG))])]
7816 "operands[2] = gen_lowpart (SImode, operands[2]);")
7819 [(set (match_operand:SWI248 0 "register_operand")
7820 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7821 (match_operand:SWI248 2 "const_int_operand")))
7822 (clobber (reg:CC FLAGS_REG))]
7824 && true_regnum (operands[0]) != true_regnum (operands[1])"
7827 HOST_WIDE_INT ival = INTVAL (operands[2]);
7829 rtx (*insn) (rtx, rtx);
7831 if (ival == (HOST_WIDE_INT) 0xffffffff)
7833 else if (ival == 0xffff)
7837 gcc_assert (ival == 0xff);
7841 if (<MODE>mode == DImode)
7842 insn = (mode == SImode)
7843 ? gen_zero_extendsidi2
7845 ? gen_zero_extendhidi2
7846 : gen_zero_extendqidi2;
7849 if (<MODE>mode != SImode)
7850 /* Zero extend to SImode to avoid partial register stalls. */
7851 operands[0] = gen_lowpart (SImode, operands[0]);
7853 insn = (mode == HImode)
7854 ? gen_zero_extendhisi2
7855 : gen_zero_extendqisi2;
7857 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7862 [(set (match_operand 0 "register_operand")
7864 (const_int -65536)))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7867 || optimize_function_for_size_p (cfun)"
7868 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7869 "operands[1] = gen_lowpart (HImode, operands[0]);")
7872 [(set (match_operand 0 "ext_register_operand")
7875 (clobber (reg:CC FLAGS_REG))]
7876 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7877 && reload_completed"
7878 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7879 "operands[1] = gen_lowpart (QImode, operands[0]);")
7882 [(set (match_operand 0 "ext_register_operand")
7884 (const_int -65281)))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7887 && reload_completed"
7888 [(parallel [(set (zero_extract:SI (match_dup 0)
7892 (zero_extract:SI (match_dup 0)
7895 (zero_extract:SI (match_dup 0)
7898 (clobber (reg:CC FLAGS_REG))])]
7899 "operands[0] = gen_lowpart (SImode, operands[0]);")
7901 (define_insn "*anddi_2"
7902 [(set (reg FLAGS_REG)
7905 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7906 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7908 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7909 (and:DI (match_dup 1) (match_dup 2)))]
7911 && ix86_match_ccmode
7913 /* If we are going to emit andl instead of andq, and the operands[2]
7914 constant might have the SImode sign bit set, make sure the sign
7915 flag isn't tested, because the instruction will set the sign flag
7916 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7917 conservatively assume it might have bit 31 set. */
7918 (satisfies_constraint_Z (operands[2])
7919 && (!CONST_INT_P (operands[2])
7920 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7921 ? CCZmode : CCNOmode)
7922 && ix86_binary_operator_ok (AND, DImode, operands)"
7924 and{l}\t{%k2, %k0|%k0, %k2}
7925 and{q}\t{%2, %0|%0, %2}
7926 and{q}\t{%2, %0|%0, %2}"
7927 [(set_attr "type" "alu")
7928 (set_attr "mode" "SI,DI,DI")])
7930 (define_insn "*andqi_2_maybe_si"
7931 [(set (reg FLAGS_REG)
7933 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7934 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7936 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7937 (and:QI (match_dup 1) (match_dup 2)))]
7938 "ix86_binary_operator_ok (AND, QImode, operands)
7939 && ix86_match_ccmode (insn,
7940 CONST_INT_P (operands[2])
7941 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7943 if (which_alternative == 2)
7945 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7946 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7947 return "and{l}\t{%2, %k0|%k0, %2}";
7949 return "and{b}\t{%2, %0|%0, %2}";
7951 [(set_attr "type" "alu")
7952 (set_attr "mode" "QI,QI,SI")])
7954 (define_insn "*and<mode>_2"
7955 [(set (reg FLAGS_REG)
7956 (compare (and:SWI124
7957 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7958 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7960 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7961 (and:SWI124 (match_dup 1) (match_dup 2)))]
7962 "ix86_match_ccmode (insn, CCNOmode)
7963 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7964 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "<MODE>")])
7968 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7969 (define_insn "*andsi_2_zext"
7970 [(set (reg FLAGS_REG)
7972 (match_operand:SI 1 "nonimmediate_operand" "%0")
7973 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7975 (set (match_operand:DI 0 "register_operand" "=r")
7976 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7977 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7978 && ix86_binary_operator_ok (AND, SImode, operands)"
7979 "and{l}\t{%2, %k0|%k0, %2}"
7980 [(set_attr "type" "alu")
7981 (set_attr "mode" "SI")])
7983 (define_insn "*andqi_2_slp"
7984 [(set (reg FLAGS_REG)
7986 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7987 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7989 (set (strict_low_part (match_dup 0))
7990 (and:QI (match_dup 0) (match_dup 1)))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && ix86_match_ccmode (insn, CCNOmode)
7993 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7994 "and{b}\t{%1, %0|%0, %1}"
7995 [(set_attr "type" "alu1")
7996 (set_attr "mode" "QI")])
7998 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7999 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8000 ;; for a QImode operand, which of course failed.
8001 (define_insn "andqi_ext_0"
8002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8007 (match_operand 1 "ext_register_operand" "0")
8010 (match_operand 2 "const_int_operand" "n")))
8011 (clobber (reg:CC FLAGS_REG))]
8013 "and{b}\t{%2, %h0|%h0, %2}"
8014 [(set_attr "type" "alu")
8015 (set_attr "length_immediate" "1")
8016 (set_attr "modrm" "1")
8017 (set_attr "mode" "QI")])
8019 ;; Generated by peephole translating test to and. This shows up
8020 ;; often in fp comparisons.
8021 (define_insn "*andqi_ext_0_cc"
8022 [(set (reg FLAGS_REG)
8026 (match_operand 1 "ext_register_operand" "0")
8029 (match_operand 2 "const_int_operand" "n"))
8031 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8040 "ix86_match_ccmode (insn, CCNOmode)"
8041 "and{b}\t{%2, %h0|%h0, %2}"
8042 [(set_attr "type" "alu")
8043 (set_attr "length_immediate" "1")
8044 (set_attr "modrm" "1")
8045 (set_attr "mode" "QI")])
8047 (define_insn "*andqi_ext_1"
8048 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8053 (match_operand 1 "ext_register_operand" "0,0")
8057 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8058 (clobber (reg:CC FLAGS_REG))]
8060 "and{b}\t{%2, %h0|%h0, %2}"
8061 [(set_attr "isa" "*,nox64")
8062 (set_attr "type" "alu")
8063 (set_attr "length_immediate" "0")
8064 (set_attr "mode" "QI")])
8066 (define_insn "*andqi_ext_2"
8067 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8072 (match_operand 1 "ext_register_operand" "%0")
8076 (match_operand 2 "ext_register_operand" "Q")
8079 (clobber (reg:CC FLAGS_REG))]
8081 "and{b}\t{%h2, %h0|%h0, %h2}"
8082 [(set_attr "type" "alu")
8083 (set_attr "length_immediate" "0")
8084 (set_attr "mode" "QI")])
8086 ;; Convert wide AND instructions with immediate operand to shorter QImode
8087 ;; equivalents when possible.
8088 ;; Don't do the splitting with memory operands, since it introduces risk
8089 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8090 ;; for size, but that can (should?) be handled by generic code instead.
8092 [(set (match_operand 0 "register_operand")
8093 (and (match_operand 1 "register_operand")
8094 (match_operand 2 "const_int_operand")))
8095 (clobber (reg:CC FLAGS_REG))]
8097 && QI_REG_P (operands[0])
8098 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099 && !(~INTVAL (operands[2]) & ~(255 << 8))
8100 && GET_MODE (operands[0]) != QImode"
8101 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8102 (and:SI (zero_extract:SI (match_dup 1)
8103 (const_int 8) (const_int 8))
8105 (clobber (reg:CC FLAGS_REG))])]
8107 operands[0] = gen_lowpart (SImode, operands[0]);
8108 operands[1] = gen_lowpart (SImode, operands[1]);
8109 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8112 ;; Since AND can be encoded with sign extended immediate, this is only
8113 ;; profitable when 7th bit is not set.
8115 [(set (match_operand 0 "register_operand")
8116 (and (match_operand 1 "general_operand")
8117 (match_operand 2 "const_int_operand")))
8118 (clobber (reg:CC FLAGS_REG))]
8120 && ANY_QI_REG_P (operands[0])
8121 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8122 && !(~INTVAL (operands[2]) & ~255)
8123 && !(INTVAL (operands[2]) & 128)
8124 && GET_MODE (operands[0]) != QImode"
8125 [(parallel [(set (strict_low_part (match_dup 0))
8126 (and:QI (match_dup 1)
8128 (clobber (reg:CC FLAGS_REG))])]
8130 operands[0] = gen_lowpart (QImode, operands[0]);
8131 operands[1] = gen_lowpart (QImode, operands[1]);
8132 operands[2] = gen_lowpart (QImode, operands[2]);
8135 ;; Logical inclusive and exclusive OR instructions
8137 ;; %%% This used to optimize known byte-wide and operations to memory.
8138 ;; If this is considered useful, it should be done with splitters.
8140 (define_expand "<code><mode>3"
8141 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8142 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8143 (match_operand:SWIM 2 "<general_operand>")))]
8145 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8147 (define_insn "*<code><mode>_1"
8148 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8150 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8151 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8152 (clobber (reg:CC FLAGS_REG))]
8153 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8155 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8156 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8157 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8158 [(set_attr "type" "alu,alu,msklog")
8159 (set_attr "mode" "<MODE>")])
8161 (define_insn "*<code>hi_1"
8162 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8164 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8165 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8169 <logic>{w}\t{%2, %0|%0, %2}
8170 <logic>{w}\t{%2, %0|%0, %2}
8171 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8172 [(set_attr "type" "alu,alu,msklog")
8173 (set_attr "mode" "HI")])
8175 ;; %%% Potential partial reg stall on alternative 2. What to do?
8176 (define_insn "*<code>qi_1"
8177 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8178 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8179 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8180 (clobber (reg:CC FLAGS_REG))]
8181 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8183 <logic>{b}\t{%2, %0|%0, %2}
8184 <logic>{b}\t{%2, %0|%0, %2}
8185 <logic>{l}\t{%k2, %k0|%k0, %k2}
8186 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8187 [(set_attr "type" "alu,alu,alu,msklog")
8188 (set_attr "mode" "QI,QI,SI,HI")])
8190 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191 (define_insn "*<code>si_1_zext"
8192 [(set (match_operand:DI 0 "register_operand" "=r")
8194 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8198 "<logic>{l}\t{%2, %k0|%k0, %2}"
8199 [(set_attr "type" "alu")
8200 (set_attr "mode" "SI")])
8202 (define_insn "*<code>si_1_zext_imm"
8203 [(set (match_operand:DI 0 "register_operand" "=r")
8205 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8206 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8207 (clobber (reg:CC FLAGS_REG))]
8208 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8209 "<logic>{l}\t{%2, %k0|%k0, %2}"
8210 [(set_attr "type" "alu")
8211 (set_attr "mode" "SI")])
8213 (define_insn "*<code>qi_1_slp"
8214 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8215 (any_or:QI (match_dup 0)
8216 (match_operand:QI 1 "general_operand" "qmn,qn")))
8217 (clobber (reg:CC FLAGS_REG))]
8218 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8219 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8220 "<logic>{b}\t{%1, %0|%0, %1}"
8221 [(set_attr "type" "alu1")
8222 (set_attr "mode" "QI")])
8224 (define_insn "*<code><mode>_2"
8225 [(set (reg FLAGS_REG)
8226 (compare (any_or:SWI
8227 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8228 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8230 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8231 (any_or:SWI (match_dup 1) (match_dup 2)))]
8232 "ix86_match_ccmode (insn, CCNOmode)
8233 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8234 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "<MODE>")])
8238 (define_insn "kxnor<mode>"
8239 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8242 (match_operand:SWI12 1 "register_operand" "0,k")
8243 (match_operand:SWI12 2 "register_operand" "r,k"))))
8244 (clobber (reg:CC FLAGS_REG))]
8247 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8248 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8249 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8251 [(set_attr "type" "*,msklog")
8252 (set_attr "prefix" "*,vex")
8253 (set_attr "mode" "<MODE>")])
8255 (define_insn "kxnor<mode>"
8256 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8259 (match_operand:SWI48x 1 "register_operand" "0,k")
8260 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8261 (clobber (reg:CC FLAGS_REG))]
8265 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8266 [(set_attr "type" "*,msklog")
8267 (set_attr "prefix" "*,vex")
8268 (set_attr "mode" "<MODE>")])
8271 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8275 (match_operand:SWI1248x 1 "general_reg_operand"))))
8276 (clobber (reg:CC FLAGS_REG))]
8277 "TARGET_AVX512F && reload_completed"
8278 [(parallel [(set (match_dup 0)
8279 (xor:HI (match_dup 0)
8281 (clobber (reg:CC FLAGS_REG))])
8283 (not:HI (match_dup 0)))])
8285 ;;There are kortrest[bdq] but no intrinsics for them.
8286 ;;We probably don't need to implement them.
8287 (define_insn "kortestzhi"
8288 [(set (reg:CCZ FLAGS_REG)
8291 (match_operand:HI 0 "register_operand" "k")
8292 (match_operand:HI 1 "register_operand" "k"))
8294 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8295 "kortestw\t{%1, %0|%0, %1}"
8296 [(set_attr "mode" "HI")
8297 (set_attr "type" "msklog")
8298 (set_attr "prefix" "vex")])
8300 (define_insn "kortestchi"
8301 [(set (reg:CCC 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, CCCmode)"
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 "kunpckhi"
8314 [(set (match_operand:HI 0 "register_operand" "=k")
8317 (match_operand:HI 1 "register_operand" "k")
8319 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8321 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8322 [(set_attr "mode" "HI")
8323 (set_attr "type" "msklog")
8324 (set_attr "prefix" "vex")])
8326 (define_insn "kunpcksi"
8327 [(set (match_operand:SI 0 "register_operand" "=k")
8330 (match_operand:SI 1 "register_operand" "k")
8332 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8334 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8335 [(set_attr "mode" "SI")])
8337 (define_insn "kunpckdi"
8338 [(set (match_operand:DI 0 "register_operand" "=k")
8341 (match_operand:DI 1 "register_operand" "k")
8343 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8345 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8346 [(set_attr "mode" "DI")])
8348 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8349 ;; ??? Special case for immediate operand is missing - it is tricky.
8350 (define_insn "*<code>si_2_zext"
8351 [(set (reg FLAGS_REG)
8352 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8353 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8355 (set (match_operand:DI 0 "register_operand" "=r")
8356 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8357 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8358 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8359 "<logic>{l}\t{%2, %k0|%k0, %2}"
8360 [(set_attr "type" "alu")
8361 (set_attr "mode" "SI")])
8363 (define_insn "*<code>si_2_zext_imm"
8364 [(set (reg FLAGS_REG)
8366 (match_operand:SI 1 "nonimmediate_operand" "%0")
8367 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8369 (set (match_operand:DI 0 "register_operand" "=r")
8370 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8371 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8372 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8373 "<logic>{l}\t{%2, %k0|%k0, %2}"
8374 [(set_attr "type" "alu")
8375 (set_attr "mode" "SI")])
8377 (define_insn "*<code>qi_2_slp"
8378 [(set (reg FLAGS_REG)
8379 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8380 (match_operand:QI 1 "general_operand" "qmn,qn"))
8382 (set (strict_low_part (match_dup 0))
8383 (any_or:QI (match_dup 0) (match_dup 1)))]
8384 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8385 && ix86_match_ccmode (insn, CCNOmode)
8386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8387 "<logic>{b}\t{%1, %0|%0, %1}"
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8391 (define_insn "*<code><mode>_3"
8392 [(set (reg FLAGS_REG)
8393 (compare (any_or:SWI
8394 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8395 (match_operand:SWI 2 "<general_operand>" "<g>"))
8397 (clobber (match_scratch:SWI 0 "=<r>"))]
8398 "ix86_match_ccmode (insn, CCNOmode)
8399 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8400 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8401 [(set_attr "type" "alu")
8402 (set_attr "mode" "<MODE>")])
8404 (define_insn "*<code>qi_ext_0"
8405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8410 (match_operand 1 "ext_register_operand" "0")
8413 (match_operand 2 "const_int_operand" "n")))
8414 (clobber (reg:CC FLAGS_REG))]
8415 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8416 "<logic>{b}\t{%2, %h0|%h0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "length_immediate" "1")
8419 (set_attr "modrm" "1")
8420 (set_attr "mode" "QI")])
8422 (define_insn "*<code>qi_ext_1"
8423 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8428 (match_operand 1 "ext_register_operand" "0,0")
8432 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8435 "<logic>{b}\t{%2, %h0|%h0, %2}"
8436 [(set_attr "isa" "*,nox64")
8437 (set_attr "type" "alu")
8438 (set_attr "length_immediate" "0")
8439 (set_attr "mode" "QI")])
8441 (define_insn "*<code>qi_ext_2"
8442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8446 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8449 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8452 (clobber (reg:CC FLAGS_REG))]
8453 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8454 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "0")
8457 (set_attr "mode" "QI")])
8460 [(set (match_operand 0 "register_operand")
8461 (any_or (match_operand 1 "register_operand")
8462 (match_operand 2 "const_int_operand")))
8463 (clobber (reg:CC FLAGS_REG))]
8465 && QI_REG_P (operands[0])
8466 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8467 && !(INTVAL (operands[2]) & ~(255 << 8))
8468 && GET_MODE (operands[0]) != QImode"
8469 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8470 (any_or:SI (zero_extract:SI (match_dup 1)
8471 (const_int 8) (const_int 8))
8473 (clobber (reg:CC FLAGS_REG))])]
8475 operands[0] = gen_lowpart (SImode, operands[0]);
8476 operands[1] = gen_lowpart (SImode, operands[1]);
8477 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8480 ;; Since OR can be encoded with sign extended immediate, this is only
8481 ;; profitable when 7th bit is set.
8483 [(set (match_operand 0 "register_operand")
8484 (any_or (match_operand 1 "general_operand")
8485 (match_operand 2 "const_int_operand")))
8486 (clobber (reg:CC FLAGS_REG))]
8488 && ANY_QI_REG_P (operands[0])
8489 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8490 && !(INTVAL (operands[2]) & ~255)
8491 && (INTVAL (operands[2]) & 128)
8492 && GET_MODE (operands[0]) != QImode"
8493 [(parallel [(set (strict_low_part (match_dup 0))
8494 (any_or:QI (match_dup 1)
8496 (clobber (reg:CC FLAGS_REG))])]
8498 operands[0] = gen_lowpart (QImode, operands[0]);
8499 operands[1] = gen_lowpart (QImode, operands[1]);
8500 operands[2] = gen_lowpart (QImode, operands[2]);
8503 (define_expand "xorqi_cc_ext_1"
8505 (set (reg:CCNO FLAGS_REG)
8509 (match_operand 1 "ext_register_operand")
8512 (match_operand:QI 2 "const_int_operand"))
8514 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8524 (define_insn "*xorqi_cc_ext_1"
8525 [(set (reg FLAGS_REG)
8529 (match_operand 1 "ext_register_operand" "0,0")
8532 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8534 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8543 "ix86_match_ccmode (insn, CCNOmode)"
8544 "xor{b}\t{%2, %h0|%h0, %2}"
8545 [(set_attr "isa" "*,nox64")
8546 (set_attr "type" "alu")
8547 (set_attr "modrm" "1")
8548 (set_attr "mode" "QI")])
8550 ;; Negation instructions
8552 (define_expand "neg<mode>2"
8553 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8554 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8556 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8558 (define_insn_and_split "*neg<dwi>2_doubleword"
8559 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8560 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8561 (clobber (reg:CC FLAGS_REG))]
8562 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8566 [(set (reg:CCZ FLAGS_REG)
8567 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8568 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8571 (plus:DWIH (match_dup 3)
8572 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8574 (clobber (reg:CC FLAGS_REG))])
8577 (neg:DWIH (match_dup 2)))
8578 (clobber (reg:CC FLAGS_REG))])]
8579 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8581 (define_insn "*neg<mode>2_1"
8582 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8583 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8584 (clobber (reg:CC FLAGS_REG))]
8585 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8586 "neg{<imodesuffix>}\t%0"
8587 [(set_attr "type" "negnot")
8588 (set_attr "mode" "<MODE>")])
8590 ;; Combine is quite creative about this pattern.
8591 (define_insn "*negsi2_1_zext"
8592 [(set (match_operand:DI 0 "register_operand" "=r")
8594 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8597 (clobber (reg:CC FLAGS_REG))]
8598 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8600 [(set_attr "type" "negnot")
8601 (set_attr "mode" "SI")])
8603 ;; The problem with neg is that it does not perform (compare x 0),
8604 ;; it really performs (compare 0 x), which leaves us with the zero
8605 ;; flag being the only useful item.
8607 (define_insn "*neg<mode>2_cmpz"
8608 [(set (reg:CCZ FLAGS_REG)
8610 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8612 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8613 (neg:SWI (match_dup 1)))]
8614 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8615 "neg{<imodesuffix>}\t%0"
8616 [(set_attr "type" "negnot")
8617 (set_attr "mode" "<MODE>")])
8619 (define_insn "*negsi2_cmpz_zext"
8620 [(set (reg:CCZ FLAGS_REG)
8624 (match_operand:DI 1 "register_operand" "0")
8628 (set (match_operand:DI 0 "register_operand" "=r")
8629 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8632 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8634 [(set_attr "type" "negnot")
8635 (set_attr "mode" "SI")])
8637 ;; Negate with jump on overflow.
8638 (define_expand "negv<mode>3"
8639 [(parallel [(set (reg:CCO FLAGS_REG)
8640 (ne:CCO (match_operand:SWI 1 "register_operand")
8642 (set (match_operand:SWI 0 "register_operand")
8643 (neg:SWI (match_dup 1)))])
8644 (set (pc) (if_then_else
8645 (eq (reg:CCO FLAGS_REG) (const_int 0))
8646 (label_ref (match_operand 2))
8651 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8655 (define_insn "*negv<mode>3"
8656 [(set (reg:CCO FLAGS_REG)
8657 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8658 (match_operand:SWI 2 "const_int_operand")))
8659 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8660 (neg:SWI (match_dup 1)))]
8661 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8662 && mode_signbit_p (<MODE>mode, operands[2])"
8663 "neg{<imodesuffix>}\t%0"
8664 [(set_attr "type" "negnot")
8665 (set_attr "mode" "<MODE>")])
8667 ;; Changing of sign for FP values is doable using integer unit too.
8669 (define_expand "<code><mode>2"
8670 [(set (match_operand:X87MODEF 0 "register_operand")
8671 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8672 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8673 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8675 (define_insn "*absneg<mode>2_mixed"
8676 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8677 (match_operator:MODEF 3 "absneg_operator"
8678 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8679 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8680 (clobber (reg:CC FLAGS_REG))]
8681 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8684 (define_insn "*absneg<mode>2_sse"
8685 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8686 (match_operator:MODEF 3 "absneg_operator"
8687 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8688 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8693 (define_insn "*absneg<mode>2_i387"
8694 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8695 (match_operator:X87MODEF 3 "absneg_operator"
8696 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8697 (use (match_operand 2))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8702 (define_expand "<code>tf2"
8703 [(set (match_operand:TF 0 "register_operand")
8704 (absneg:TF (match_operand:TF 1 "register_operand")))]
8706 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8708 (define_insn "*absnegtf2_sse"
8709 [(set (match_operand:TF 0 "register_operand" "=x,x")
8710 (match_operator:TF 3 "absneg_operator"
8711 [(match_operand:TF 1 "register_operand" "0,x")]))
8712 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8713 (clobber (reg:CC FLAGS_REG))]
8717 ;; Splitters for fp abs and neg.
8720 [(set (match_operand 0 "fp_register_operand")
8721 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8722 (use (match_operand 2))
8723 (clobber (reg:CC FLAGS_REG))]
8725 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8728 [(set (match_operand 0 "register_operand")
8729 (match_operator 3 "absneg_operator"
8730 [(match_operand 1 "register_operand")]))
8731 (use (match_operand 2 "nonimmediate_operand"))
8732 (clobber (reg:CC FLAGS_REG))]
8733 "reload_completed && SSE_REG_P (operands[0])"
8734 [(set (match_dup 0) (match_dup 3))]
8736 machine_mode mode = GET_MODE (operands[0]);
8737 machine_mode vmode = GET_MODE (operands[2]);
8740 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8741 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8742 if (operands_match_p (operands[0], operands[2]))
8745 operands[1] = operands[2];
8748 if (GET_CODE (operands[3]) == ABS)
8749 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8751 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8756 [(set (match_operand:SF 0 "register_operand")
8757 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8758 (use (match_operand:V4SF 2))
8759 (clobber (reg:CC FLAGS_REG))]
8761 [(parallel [(set (match_dup 0) (match_dup 1))
8762 (clobber (reg:CC FLAGS_REG))])]
8765 operands[0] = gen_lowpart (SImode, operands[0]);
8766 if (GET_CODE (operands[1]) == ABS)
8768 tmp = gen_int_mode (0x7fffffff, SImode);
8769 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8773 tmp = gen_int_mode (0x80000000, SImode);
8774 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8780 [(set (match_operand:DF 0 "register_operand")
8781 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8782 (use (match_operand 2))
8783 (clobber (reg:CC FLAGS_REG))]
8785 [(parallel [(set (match_dup 0) (match_dup 1))
8786 (clobber (reg:CC FLAGS_REG))])]
8791 tmp = gen_lowpart (DImode, operands[0]);
8792 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8795 if (GET_CODE (operands[1]) == ABS)
8798 tmp = gen_rtx_NOT (DImode, tmp);
8802 operands[0] = gen_highpart (SImode, operands[0]);
8803 if (GET_CODE (operands[1]) == ABS)
8805 tmp = gen_int_mode (0x7fffffff, SImode);
8806 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8810 tmp = gen_int_mode (0x80000000, SImode);
8811 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8818 [(set (match_operand:XF 0 "register_operand")
8819 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8820 (use (match_operand 2))
8821 (clobber (reg:CC FLAGS_REG))]
8823 [(parallel [(set (match_dup 0) (match_dup 1))
8824 (clobber (reg:CC FLAGS_REG))])]
8827 operands[0] = gen_rtx_REG (SImode,
8828 true_regnum (operands[0])
8829 + (TARGET_64BIT ? 1 : 2));
8830 if (GET_CODE (operands[1]) == ABS)
8832 tmp = GEN_INT (0x7fff);
8833 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8837 tmp = GEN_INT (0x8000);
8838 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8843 ;; Conditionalize these after reload. If they match before reload, we
8844 ;; lose the clobber and ability to use integer instructions.
8846 (define_insn "*<code><mode>2_1"
8847 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8848 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8850 && (reload_completed
8851 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8852 "f<absneg_mnemonic>"
8853 [(set_attr "type" "fsgn")
8854 (set_attr "mode" "<MODE>")])
8856 (define_insn "*<code>extendsfdf2"
8857 [(set (match_operand:DF 0 "register_operand" "=f")
8858 (absneg:DF (float_extend:DF
8859 (match_operand:SF 1 "register_operand" "0"))))]
8860 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8861 "f<absneg_mnemonic>"
8862 [(set_attr "type" "fsgn")
8863 (set_attr "mode" "DF")])
8865 (define_insn "*<code>extendsfxf2"
8866 [(set (match_operand:XF 0 "register_operand" "=f")
8867 (absneg:XF (float_extend:XF
8868 (match_operand:SF 1 "register_operand" "0"))))]
8870 "f<absneg_mnemonic>"
8871 [(set_attr "type" "fsgn")
8872 (set_attr "mode" "XF")])
8874 (define_insn "*<code>extenddfxf2"
8875 [(set (match_operand:XF 0 "register_operand" "=f")
8876 (absneg:XF (float_extend:XF
8877 (match_operand:DF 1 "register_operand" "0"))))]
8879 "f<absneg_mnemonic>"
8880 [(set_attr "type" "fsgn")
8881 (set_attr "mode" "XF")])
8883 ;; Copysign instructions
8885 (define_mode_iterator CSGNMODE [SF DF TF])
8886 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8888 (define_expand "copysign<mode>3"
8889 [(match_operand:CSGNMODE 0 "register_operand")
8890 (match_operand:CSGNMODE 1 "nonmemory_operand")
8891 (match_operand:CSGNMODE 2 "register_operand")]
8892 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8893 || (TARGET_SSE && (<MODE>mode == TFmode))"
8894 "ix86_expand_copysign (operands); DONE;")
8896 (define_insn_and_split "copysign<mode>3_const"
8897 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8899 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8900 (match_operand:CSGNMODE 2 "register_operand" "0")
8901 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8903 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8904 || (TARGET_SSE && (<MODE>mode == TFmode))"
8906 "&& reload_completed"
8908 "ix86_split_copysign_const (operands); DONE;")
8910 (define_insn "copysign<mode>3_var"
8911 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8913 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8914 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8915 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8916 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8918 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8919 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8920 || (TARGET_SSE && (<MODE>mode == TFmode))"
8924 [(set (match_operand:CSGNMODE 0 "register_operand")
8926 [(match_operand:CSGNMODE 2 "register_operand")
8927 (match_operand:CSGNMODE 3 "register_operand")
8928 (match_operand:<CSGNVMODE> 4)
8929 (match_operand:<CSGNVMODE> 5)]
8931 (clobber (match_scratch:<CSGNVMODE> 1))]
8932 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8933 || (TARGET_SSE && (<MODE>mode == TFmode)))
8934 && reload_completed"
8936 "ix86_split_copysign_var (operands); DONE;")
8938 ;; One complement instructions
8940 (define_expand "one_cmpl<mode>2"
8941 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8942 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8944 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8946 (define_insn "*one_cmpl<mode>2_1"
8947 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8948 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8949 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8951 not{<imodesuffix>}\t%0
8952 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8953 [(set_attr "isa" "*,avx512bw")
8954 (set_attr "type" "negnot,msklog")
8955 (set_attr "prefix" "*,vex")
8956 (set_attr "mode" "<MODE>")])
8958 (define_insn "*one_cmplhi2_1"
8959 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8960 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8961 "ix86_unary_operator_ok (NOT, HImode, operands)"
8964 knotw\t{%1, %0|%0, %1}"
8965 [(set_attr "isa" "*,avx512f")
8966 (set_attr "type" "negnot,msklog")
8967 (set_attr "prefix" "*,vex")
8968 (set_attr "mode" "HI")])
8970 ;; %%% Potential partial reg stall on alternative 1. What to do?
8971 (define_insn "*one_cmplqi2_1"
8972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8973 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8974 "ix86_unary_operator_ok (NOT, QImode, operands)"
8976 switch (which_alternative)
8979 return "not{b}\t%0";
8981 return "not{l}\t%k0";
8983 if (TARGET_AVX512DQ)
8984 return "knotb\t{%1, %0|%0, %1}";
8985 return "knotw\t{%1, %0|%0, %1}";
8990 [(set_attr "isa" "*,*,avx512f")
8991 (set_attr "type" "negnot,negnot,msklog")
8992 (set_attr "prefix" "*,*,vex")
8993 (set_attr "mode" "QI,SI,QI")])
8995 ;; ??? Currently never generated - xor is used instead.
8996 (define_insn "*one_cmplsi2_1_zext"
8997 [(set (match_operand:DI 0 "register_operand" "=r")
8999 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9000 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9002 [(set_attr "type" "negnot")
9003 (set_attr "mode" "SI")])
9005 (define_insn "*one_cmpl<mode>2_2"
9006 [(set (reg FLAGS_REG)
9007 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9009 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9010 (not:SWI (match_dup 1)))]
9011 "ix86_match_ccmode (insn, CCNOmode)
9012 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9014 [(set_attr "type" "alu1")
9015 (set_attr "mode" "<MODE>")])
9018 [(set (match_operand 0 "flags_reg_operand")
9019 (match_operator 2 "compare_operator"
9020 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9022 (set (match_operand:SWI 1 "nonimmediate_operand")
9023 (not:SWI (match_dup 3)))]
9024 "ix86_match_ccmode (insn, CCNOmode)"
9025 [(parallel [(set (match_dup 0)
9026 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9029 (xor:SWI (match_dup 3) (const_int -1)))])])
9031 ;; ??? Currently never generated - xor is used instead.
9032 (define_insn "*one_cmplsi2_2_zext"
9033 [(set (reg FLAGS_REG)
9034 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9036 (set (match_operand:DI 0 "register_operand" "=r")
9037 (zero_extend:DI (not:SI (match_dup 1))))]
9038 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9039 && ix86_unary_operator_ok (NOT, SImode, operands)"
9041 [(set_attr "type" "alu1")
9042 (set_attr "mode" "SI")])
9045 [(set (match_operand 0 "flags_reg_operand")
9046 (match_operator 2 "compare_operator"
9047 [(not:SI (match_operand:SI 3 "register_operand"))
9049 (set (match_operand:DI 1 "register_operand")
9050 (zero_extend:DI (not:SI (match_dup 3))))]
9051 "ix86_match_ccmode (insn, CCNOmode)"
9052 [(parallel [(set (match_dup 0)
9053 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9056 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9058 ;; Shift instructions
9060 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9061 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9062 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9063 ;; from the assembler input.
9065 ;; This instruction shifts the target reg/mem as usual, but instead of
9066 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9067 ;; is a left shift double, bits are taken from the high order bits of
9068 ;; reg, else if the insn is a shift right double, bits are taken from the
9069 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9070 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9072 ;; Since sh[lr]d does not change the `reg' operand, that is done
9073 ;; separately, making all shifts emit pairs of shift double and normal
9074 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9075 ;; support a 63 bit shift, each shift where the count is in a reg expands
9076 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9078 ;; If the shift count is a constant, we need never emit more than one
9079 ;; shift pair, instead using moves and sign extension for counts greater
9082 (define_expand "ashl<mode>3"
9083 [(set (match_operand:SDWIM 0 "<shift_operand>")
9084 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9085 (match_operand:QI 2 "nonmemory_operand")))]
9087 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9089 (define_insn "*ashl<mode>3_doubleword"
9090 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9091 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9092 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9093 (clobber (reg:CC FLAGS_REG))]
9096 [(set_attr "type" "multi")])
9099 [(set (match_operand:DWI 0 "register_operand")
9100 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9101 (match_operand:QI 2 "nonmemory_operand")))
9102 (clobber (reg:CC FLAGS_REG))]
9103 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9105 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9107 ;; By default we don't ask for a scratch register, because when DWImode
9108 ;; values are manipulated, registers are already at a premium. But if
9109 ;; we have one handy, we won't turn it away.
9112 [(match_scratch:DWIH 3 "r")
9113 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9115 (match_operand:<DWI> 1 "nonmemory_operand")
9116 (match_operand:QI 2 "nonmemory_operand")))
9117 (clobber (reg:CC FLAGS_REG))])
9121 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9123 (define_insn "x86_64_shld"
9124 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9125 (ior:DI (ashift:DI (match_dup 0)
9126 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9127 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9128 (minus:QI (const_int 64) (match_dup 2)))))
9129 (clobber (reg:CC FLAGS_REG))]
9131 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9132 [(set_attr "type" "ishift")
9133 (set_attr "prefix_0f" "1")
9134 (set_attr "mode" "DI")
9135 (set_attr "athlon_decode" "vector")
9136 (set_attr "amdfam10_decode" "vector")
9137 (set_attr "bdver1_decode" "vector")])
9139 (define_insn "x86_shld"
9140 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9141 (ior:SI (ashift:SI (match_dup 0)
9142 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9143 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9144 (minus:QI (const_int 32) (match_dup 2)))))
9145 (clobber (reg:CC FLAGS_REG))]
9147 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9148 [(set_attr "type" "ishift")
9149 (set_attr "prefix_0f" "1")
9150 (set_attr "mode" "SI")
9151 (set_attr "pent_pair" "np")
9152 (set_attr "athlon_decode" "vector")
9153 (set_attr "amdfam10_decode" "vector")
9154 (set_attr "bdver1_decode" "vector")])
9156 (define_expand "x86_shift<mode>_adj_1"
9157 [(set (reg:CCZ FLAGS_REG)
9158 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9161 (set (match_operand:SWI48 0 "register_operand")
9162 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9163 (match_operand:SWI48 1 "register_operand")
9166 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9167 (match_operand:SWI48 3 "register_operand")
9170 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9172 (define_expand "x86_shift<mode>_adj_2"
9173 [(use (match_operand:SWI48 0 "register_operand"))
9174 (use (match_operand:SWI48 1 "register_operand"))
9175 (use (match_operand:QI 2 "register_operand"))]
9178 rtx_code_label *label = gen_label_rtx ();
9181 emit_insn (gen_testqi_ccz_1 (operands[2],
9182 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9184 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9185 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9186 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9187 gen_rtx_LABEL_REF (VOIDmode, label),
9189 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9190 JUMP_LABEL (tmp) = label;
9192 emit_move_insn (operands[0], operands[1]);
9193 ix86_expand_clear (operands[1]);
9196 LABEL_NUSES (label) = 1;
9201 ;; Avoid useless masking of count operand.
9202 (define_insn "*ashl<mode>3_mask"
9203 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9205 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9208 (match_operand:SI 2 "register_operand" "c")
9209 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9210 (clobber (reg:CC FLAGS_REG))]
9211 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9212 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9213 == GET_MODE_BITSIZE (<MODE>mode)-1"
9215 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9217 [(set_attr "type" "ishift")
9218 (set_attr "mode" "<MODE>")])
9220 (define_insn "*bmi2_ashl<mode>3_1"
9221 [(set (match_operand:SWI48 0 "register_operand" "=r")
9222 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9223 (match_operand:SWI48 2 "register_operand" "r")))]
9225 "shlx\t{%2, %1, %0|%0, %1, %2}"
9226 [(set_attr "type" "ishiftx")
9227 (set_attr "mode" "<MODE>")])
9229 (define_insn "*ashl<mode>3_1"
9230 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9231 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9232 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9236 switch (get_attr_type (insn))
9243 gcc_assert (operands[2] == const1_rtx);
9244 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9245 return "add{<imodesuffix>}\t%0, %0";
9248 if (operands[2] == const1_rtx
9249 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9250 return "sal{<imodesuffix>}\t%0";
9252 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9255 [(set_attr "isa" "*,*,bmi2")
9257 (cond [(eq_attr "alternative" "1")
9258 (const_string "lea")
9259 (eq_attr "alternative" "2")
9260 (const_string "ishiftx")
9261 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9262 (match_operand 0 "register_operand"))
9263 (match_operand 2 "const1_operand"))
9264 (const_string "alu")
9266 (const_string "ishift")))
9267 (set (attr "length_immediate")
9269 (ior (eq_attr "type" "alu")
9270 (and (eq_attr "type" "ishift")
9271 (and (match_operand 2 "const1_operand")
9272 (ior (match_test "TARGET_SHIFT1")
9273 (match_test "optimize_function_for_size_p (cfun)")))))
9275 (const_string "*")))
9276 (set_attr "mode" "<MODE>")])
9278 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9280 [(set (match_operand:SWI48 0 "register_operand")
9281 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9282 (match_operand:QI 2 "register_operand")))
9283 (clobber (reg:CC FLAGS_REG))]
9284 "TARGET_BMI2 && reload_completed"
9286 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9287 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9289 (define_insn "*bmi2_ashlsi3_1_zext"
9290 [(set (match_operand:DI 0 "register_operand" "=r")
9292 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9293 (match_operand:SI 2 "register_operand" "r"))))]
9294 "TARGET_64BIT && TARGET_BMI2"
9295 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9296 [(set_attr "type" "ishiftx")
9297 (set_attr "mode" "SI")])
9299 (define_insn "*ashlsi3_1_zext"
9300 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9302 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9303 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9304 (clobber (reg:CC FLAGS_REG))]
9305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9307 switch (get_attr_type (insn))
9314 gcc_assert (operands[2] == const1_rtx);
9315 return "add{l}\t%k0, %k0";
9318 if (operands[2] == const1_rtx
9319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320 return "sal{l}\t%k0";
9322 return "sal{l}\t{%2, %k0|%k0, %2}";
9325 [(set_attr "isa" "*,*,bmi2")
9327 (cond [(eq_attr "alternative" "1")
9328 (const_string "lea")
9329 (eq_attr "alternative" "2")
9330 (const_string "ishiftx")
9331 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332 (match_operand 2 "const1_operand"))
9333 (const_string "alu")
9335 (const_string "ishift")))
9336 (set (attr "length_immediate")
9338 (ior (eq_attr "type" "alu")
9339 (and (eq_attr "type" "ishift")
9340 (and (match_operand 2 "const1_operand")
9341 (ior (match_test "TARGET_SHIFT1")
9342 (match_test "optimize_function_for_size_p (cfun)")))))
9344 (const_string "*")))
9345 (set_attr "mode" "SI")])
9347 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9349 [(set (match_operand:DI 0 "register_operand")
9351 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9352 (match_operand:QI 2 "register_operand"))))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9356 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9357 "operands[2] = gen_lowpart (SImode, operands[2]);")
9359 (define_insn "*ashlhi3_1"
9360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9361 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9362 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9366 switch (get_attr_type (insn))
9372 gcc_assert (operands[2] == const1_rtx);
9373 return "add{w}\t%0, %0";
9376 if (operands[2] == const1_rtx
9377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378 return "sal{w}\t%0";
9380 return "sal{w}\t{%2, %0|%0, %2}";
9384 (cond [(eq_attr "alternative" "1")
9385 (const_string "lea")
9386 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9387 (match_operand 0 "register_operand"))
9388 (match_operand 2 "const1_operand"))
9389 (const_string "alu")
9391 (const_string "ishift")))
9392 (set (attr "length_immediate")
9394 (ior (eq_attr "type" "alu")
9395 (and (eq_attr "type" "ishift")
9396 (and (match_operand 2 "const1_operand")
9397 (ior (match_test "TARGET_SHIFT1")
9398 (match_test "optimize_function_for_size_p (cfun)")))))
9400 (const_string "*")))
9401 (set_attr "mode" "HI,SI")])
9403 ;; %%% Potential partial reg stall on alternative 1. What to do?
9404 (define_insn "*ashlqi3_1"
9405 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9406 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9407 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9411 switch (get_attr_type (insn))
9417 gcc_assert (operands[2] == const1_rtx);
9418 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9419 return "add{l}\t%k0, %k0";
9421 return "add{b}\t%0, %0";
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9427 if (get_attr_mode (insn) == MODE_SI)
9428 return "sal{l}\t%k0";
9430 return "sal{b}\t%0";
9434 if (get_attr_mode (insn) == MODE_SI)
9435 return "sal{l}\t{%2, %k0|%k0, %2}";
9437 return "sal{b}\t{%2, %0|%0, %2}";
9442 (cond [(eq_attr "alternative" "2")
9443 (const_string "lea")
9444 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9445 (match_operand 0 "register_operand"))
9446 (match_operand 2 "const1_operand"))
9447 (const_string "alu")
9449 (const_string "ishift")))
9450 (set (attr "length_immediate")
9452 (ior (eq_attr "type" "alu")
9453 (and (eq_attr "type" "ishift")
9454 (and (match_operand 2 "const1_operand")
9455 (ior (match_test "TARGET_SHIFT1")
9456 (match_test "optimize_function_for_size_p (cfun)")))))
9458 (const_string "*")))
9459 (set_attr "mode" "QI,SI,SI")])
9461 (define_insn "*ashlqi3_1_slp"
9462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9463 (ashift:QI (match_dup 0)
9464 (match_operand:QI 1 "nonmemory_operand" "cI")))
9465 (clobber (reg:CC FLAGS_REG))]
9466 "(optimize_function_for_size_p (cfun)
9467 || !TARGET_PARTIAL_FLAG_REG_STALL
9468 || (operands[1] == const1_rtx
9470 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9472 switch (get_attr_type (insn))
9475 gcc_assert (operands[1] == const1_rtx);
9476 return "add{b}\t%0, %0";
9479 if (operands[1] == const1_rtx
9480 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9481 return "sal{b}\t%0";
9483 return "sal{b}\t{%1, %0|%0, %1}";
9487 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9488 (match_operand 0 "register_operand"))
9489 (match_operand 1 "const1_operand"))
9490 (const_string "alu")
9492 (const_string "ishift1")))
9493 (set (attr "length_immediate")
9495 (ior (eq_attr "type" "alu")
9496 (and (eq_attr "type" "ishift1")
9497 (and (match_operand 1 "const1_operand")
9498 (ior (match_test "TARGET_SHIFT1")
9499 (match_test "optimize_function_for_size_p (cfun)")))))
9501 (const_string "*")))
9502 (set_attr "mode" "QI")])
9504 ;; Convert ashift to the lea pattern to avoid flags dependency.
9506 [(set (match_operand 0 "register_operand")
9507 (ashift (match_operand 1 "index_register_operand")
9508 (match_operand:QI 2 "const_int_operand")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9512 && true_regnum (operands[0]) != true_regnum (operands[1])"
9515 machine_mode mode = GET_MODE (operands[0]);
9518 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9521 operands[0] = gen_lowpart (mode, operands[0]);
9522 operands[1] = gen_lowpart (mode, operands[1]);
9525 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9527 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9529 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9533 ;; Convert ashift to the lea pattern to avoid flags dependency.
9535 [(set (match_operand:DI 0 "register_operand")
9537 (ashift:SI (match_operand:SI 1 "index_register_operand")
9538 (match_operand:QI 2 "const_int_operand"))))
9539 (clobber (reg:CC FLAGS_REG))]
9540 "TARGET_64BIT && reload_completed
9541 && true_regnum (operands[0]) != true_regnum (operands[1])"
9543 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9545 operands[1] = gen_lowpart (SImode, operands[1]);
9546 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9549 ;; This pattern can't accept a variable shift count, since shifts by
9550 ;; zero don't affect the flags. We assume that shifts by constant
9551 ;; zero are optimized away.
9552 (define_insn "*ashl<mode>3_cmp"
9553 [(set (reg FLAGS_REG)
9555 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9556 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9558 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9559 (ashift:SWI (match_dup 1) (match_dup 2)))]
9560 "(optimize_function_for_size_p (cfun)
9561 || !TARGET_PARTIAL_FLAG_REG_STALL
9562 || (operands[2] == const1_rtx
9564 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9565 && ix86_match_ccmode (insn, CCGOCmode)
9566 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9568 switch (get_attr_type (insn))
9571 gcc_assert (operands[2] == const1_rtx);
9572 return "add{<imodesuffix>}\t%0, %0";
9575 if (operands[2] == const1_rtx
9576 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9577 return "sal{<imodesuffix>}\t%0";
9579 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9583 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584 (match_operand 0 "register_operand"))
9585 (match_operand 2 "const1_operand"))
9586 (const_string "alu")
9588 (const_string "ishift")))
9589 (set (attr "length_immediate")
9591 (ior (eq_attr "type" "alu")
9592 (and (eq_attr "type" "ishift")
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))))
9597 (const_string "*")))
9598 (set_attr "mode" "<MODE>")])
9600 (define_insn "*ashlsi3_cmp_zext"
9601 [(set (reg FLAGS_REG)
9603 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9606 (set (match_operand:DI 0 "register_operand" "=r")
9607 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9609 && (optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[2] == const1_rtx
9613 || TARGET_DOUBLE_WITH_ADD)))
9614 && ix86_match_ccmode (insn, CCGOCmode)
9615 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9617 switch (get_attr_type (insn))
9620 gcc_assert (operands[2] == const1_rtx);
9621 return "add{l}\t%k0, %k0";
9624 if (operands[2] == const1_rtx
9625 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9626 return "sal{l}\t%k0";
9628 return "sal{l}\t{%2, %k0|%k0, %2}";
9632 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9633 (match_operand 2 "const1_operand"))
9634 (const_string "alu")
9636 (const_string "ishift")))
9637 (set (attr "length_immediate")
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift")
9641 (and (match_operand 2 "const1_operand")
9642 (ior (match_test "TARGET_SHIFT1")
9643 (match_test "optimize_function_for_size_p (cfun)")))))
9645 (const_string "*")))
9646 (set_attr "mode" "SI")])
9648 (define_insn "*ashl<mode>3_cconly"
9649 [(set (reg FLAGS_REG)
9651 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9652 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9654 (clobber (match_scratch:SWI 0 "=<r>"))]
9655 "(optimize_function_for_size_p (cfun)
9656 || !TARGET_PARTIAL_FLAG_REG_STALL
9657 || (operands[2] == const1_rtx
9659 || TARGET_DOUBLE_WITH_ADD)))
9660 && ix86_match_ccmode (insn, CCGOCmode)"
9662 switch (get_attr_type (insn))
9665 gcc_assert (operands[2] == const1_rtx);
9666 return "add{<imodesuffix>}\t%0, %0";
9669 if (operands[2] == const1_rtx
9670 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9671 return "sal{<imodesuffix>}\t%0";
9673 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9677 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9678 (match_operand 0 "register_operand"))
9679 (match_operand 2 "const1_operand"))
9680 (const_string "alu")
9682 (const_string "ishift")))
9683 (set (attr "length_immediate")
9685 (ior (eq_attr "type" "alu")
9686 (and (eq_attr "type" "ishift")
9687 (and (match_operand 2 "const1_operand")
9688 (ior (match_test "TARGET_SHIFT1")
9689 (match_test "optimize_function_for_size_p (cfun)")))))
9691 (const_string "*")))
9692 (set_attr "mode" "<MODE>")])
9694 ;; See comment above `ashl<mode>3' about how this works.
9696 (define_expand "<shift_insn><mode>3"
9697 [(set (match_operand:SDWIM 0 "<shift_operand>")
9698 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9699 (match_operand:QI 2 "nonmemory_operand")))]
9701 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9703 ;; Avoid useless masking of count operand.
9704 (define_insn "*<shift_insn><mode>3_mask"
9705 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9707 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9710 (match_operand:SI 2 "register_operand" "c")
9711 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9715 == GET_MODE_BITSIZE (<MODE>mode)-1"
9717 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9719 [(set_attr "type" "ishift")
9720 (set_attr "mode" "<MODE>")])
9722 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9723 [(set (match_operand:DWI 0 "register_operand" "=r")
9724 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9725 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9726 (clobber (reg:CC FLAGS_REG))]
9729 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9731 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9732 [(set_attr "type" "multi")])
9734 ;; By default we don't ask for a scratch register, because when DWImode
9735 ;; values are manipulated, registers are already at a premium. But if
9736 ;; we have one handy, we won't turn it away.
9739 [(match_scratch:DWIH 3 "r")
9740 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9742 (match_operand:<DWI> 1 "register_operand")
9743 (match_operand:QI 2 "nonmemory_operand")))
9744 (clobber (reg:CC FLAGS_REG))])
9748 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9750 (define_insn "x86_64_shrd"
9751 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9752 (ior:DI (lshiftrt:DI (match_dup 0)
9753 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9754 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9755 (minus:QI (const_int 64) (match_dup 2)))))
9756 (clobber (reg:CC FLAGS_REG))]
9758 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9759 [(set_attr "type" "ishift")
9760 (set_attr "prefix_0f" "1")
9761 (set_attr "mode" "DI")
9762 (set_attr "athlon_decode" "vector")
9763 (set_attr "amdfam10_decode" "vector")
9764 (set_attr "bdver1_decode" "vector")])
9766 (define_insn "x86_shrd"
9767 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9768 (ior:SI (lshiftrt:SI (match_dup 0)
9769 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9770 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9771 (minus:QI (const_int 32) (match_dup 2)))))
9772 (clobber (reg:CC FLAGS_REG))]
9774 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9775 [(set_attr "type" "ishift")
9776 (set_attr "prefix_0f" "1")
9777 (set_attr "mode" "SI")
9778 (set_attr "pent_pair" "np")
9779 (set_attr "athlon_decode" "vector")
9780 (set_attr "amdfam10_decode" "vector")
9781 (set_attr "bdver1_decode" "vector")])
9783 (define_insn "ashrdi3_cvt"
9784 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9785 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9786 (match_operand:QI 2 "const_int_operand")))
9787 (clobber (reg:CC FLAGS_REG))]
9788 "TARGET_64BIT && INTVAL (operands[2]) == 63
9789 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9790 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9793 sar{q}\t{%2, %0|%0, %2}"
9794 [(set_attr "type" "imovx,ishift")
9795 (set_attr "prefix_0f" "0,*")
9796 (set_attr "length_immediate" "0,*")
9797 (set_attr "modrm" "0,1")
9798 (set_attr "mode" "DI")])
9800 (define_insn "ashrsi3_cvt"
9801 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9802 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9803 (match_operand:QI 2 "const_int_operand")))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "INTVAL (operands[2]) == 31
9806 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9807 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9810 sar{l}\t{%2, %0|%0, %2}"
9811 [(set_attr "type" "imovx,ishift")
9812 (set_attr "prefix_0f" "0,*")
9813 (set_attr "length_immediate" "0,*")
9814 (set_attr "modrm" "0,1")
9815 (set_attr "mode" "SI")])
9817 (define_insn "*ashrsi3_cvt_zext"
9818 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9820 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9821 (match_operand:QI 2 "const_int_operand"))))
9822 (clobber (reg:CC FLAGS_REG))]
9823 "TARGET_64BIT && INTVAL (operands[2]) == 31
9824 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9825 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9828 sar{l}\t{%2, %k0|%k0, %2}"
9829 [(set_attr "type" "imovx,ishift")
9830 (set_attr "prefix_0f" "0,*")
9831 (set_attr "length_immediate" "0,*")
9832 (set_attr "modrm" "0,1")
9833 (set_attr "mode" "SI")])
9835 (define_expand "x86_shift<mode>_adj_3"
9836 [(use (match_operand:SWI48 0 "register_operand"))
9837 (use (match_operand:SWI48 1 "register_operand"))
9838 (use (match_operand:QI 2 "register_operand"))]
9841 rtx_code_label *label = gen_label_rtx ();
9844 emit_insn (gen_testqi_ccz_1 (operands[2],
9845 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9847 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9848 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9849 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9850 gen_rtx_LABEL_REF (VOIDmode, label),
9852 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9853 JUMP_LABEL (tmp) = label;
9855 emit_move_insn (operands[0], operands[1]);
9856 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9857 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9859 LABEL_NUSES (label) = 1;
9864 (define_insn "*bmi2_<shift_insn><mode>3_1"
9865 [(set (match_operand:SWI48 0 "register_operand" "=r")
9866 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9867 (match_operand:SWI48 2 "register_operand" "r")))]
9869 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9870 [(set_attr "type" "ishiftx")
9871 (set_attr "mode" "<MODE>")])
9873 (define_insn "*<shift_insn><mode>3_1"
9874 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9876 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9877 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9878 (clobber (reg:CC FLAGS_REG))]
9879 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9881 switch (get_attr_type (insn))
9887 if (operands[2] == const1_rtx
9888 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9889 return "<shift>{<imodesuffix>}\t%0";
9891 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9894 [(set_attr "isa" "*,bmi2")
9895 (set_attr "type" "ishift,ishiftx")
9896 (set (attr "length_immediate")
9898 (and (match_operand 2 "const1_operand")
9899 (ior (match_test "TARGET_SHIFT1")
9900 (match_test "optimize_function_for_size_p (cfun)")))
9902 (const_string "*")))
9903 (set_attr "mode" "<MODE>")])
9905 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9907 [(set (match_operand:SWI48 0 "register_operand")
9908 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9909 (match_operand:QI 2 "register_operand")))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "TARGET_BMI2 && reload_completed"
9913 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9914 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9916 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9917 [(set (match_operand:DI 0 "register_operand" "=r")
9919 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9920 (match_operand:SI 2 "register_operand" "r"))))]
9921 "TARGET_64BIT && TARGET_BMI2"
9922 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9923 [(set_attr "type" "ishiftx")
9924 (set_attr "mode" "SI")])
9926 (define_insn "*<shift_insn>si3_1_zext"
9927 [(set (match_operand:DI 0 "register_operand" "=r,r")
9929 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9930 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9931 (clobber (reg:CC FLAGS_REG))]
9932 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9934 switch (get_attr_type (insn))
9940 if (operands[2] == const1_rtx
9941 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9942 return "<shift>{l}\t%k0";
9944 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9947 [(set_attr "isa" "*,bmi2")
9948 (set_attr "type" "ishift,ishiftx")
9949 (set (attr "length_immediate")
9951 (and (match_operand 2 "const1_operand")
9952 (ior (match_test "TARGET_SHIFT1")
9953 (match_test "optimize_function_for_size_p (cfun)")))
9955 (const_string "*")))
9956 (set_attr "mode" "SI")])
9958 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9960 [(set (match_operand:DI 0 "register_operand")
9962 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9963 (match_operand:QI 2 "register_operand"))))
9964 (clobber (reg:CC FLAGS_REG))]
9965 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9967 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9968 "operands[2] = gen_lowpart (SImode, operands[2]);")
9970 (define_insn "*<shift_insn><mode>3_1"
9971 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9973 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9974 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9975 (clobber (reg:CC FLAGS_REG))]
9976 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9978 if (operands[2] == const1_rtx
9979 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9980 return "<shift>{<imodesuffix>}\t%0";
9982 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9984 [(set_attr "type" "ishift")
9985 (set (attr "length_immediate")
9987 (and (match_operand 2 "const1_operand")
9988 (ior (match_test "TARGET_SHIFT1")
9989 (match_test "optimize_function_for_size_p (cfun)")))
9991 (const_string "*")))
9992 (set_attr "mode" "<MODE>")])
9994 (define_insn "*<shift_insn>qi3_1_slp"
9995 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9996 (any_shiftrt:QI (match_dup 0)
9997 (match_operand:QI 1 "nonmemory_operand" "cI")))
9998 (clobber (reg:CC FLAGS_REG))]
9999 "(optimize_function_for_size_p (cfun)
10000 || !TARGET_PARTIAL_REG_STALL
10001 || (operands[1] == const1_rtx
10002 && TARGET_SHIFT1))"
10004 if (operands[1] == const1_rtx
10005 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10006 return "<shift>{b}\t%0";
10008 return "<shift>{b}\t{%1, %0|%0, %1}";
10010 [(set_attr "type" "ishift1")
10011 (set (attr "length_immediate")
10013 (and (match_operand 1 "const1_operand")
10014 (ior (match_test "TARGET_SHIFT1")
10015 (match_test "optimize_function_for_size_p (cfun)")))
10017 (const_string "*")))
10018 (set_attr "mode" "QI")])
10020 ;; This pattern can't accept a variable shift count, since shifts by
10021 ;; zero don't affect the flags. We assume that shifts by constant
10022 ;; zero are optimized away.
10023 (define_insn "*<shift_insn><mode>3_cmp"
10024 [(set (reg FLAGS_REG)
10027 (match_operand:SWI 1 "nonimmediate_operand" "0")
10028 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10030 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10031 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10032 "(optimize_function_for_size_p (cfun)
10033 || !TARGET_PARTIAL_FLAG_REG_STALL
10034 || (operands[2] == const1_rtx
10036 && ix86_match_ccmode (insn, CCGOCmode)
10037 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10039 if (operands[2] == const1_rtx
10040 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10041 return "<shift>{<imodesuffix>}\t%0";
10043 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10045 [(set_attr "type" "ishift")
10046 (set (attr "length_immediate")
10048 (and (match_operand 2 "const1_operand")
10049 (ior (match_test "TARGET_SHIFT1")
10050 (match_test "optimize_function_for_size_p (cfun)")))
10052 (const_string "*")))
10053 (set_attr "mode" "<MODE>")])
10055 (define_insn "*<shift_insn>si3_cmp_zext"
10056 [(set (reg FLAGS_REG)
10058 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10059 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10061 (set (match_operand:DI 0 "register_operand" "=r")
10062 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10064 && (optimize_function_for_size_p (cfun)
10065 || !TARGET_PARTIAL_FLAG_REG_STALL
10066 || (operands[2] == const1_rtx
10068 && ix86_match_ccmode (insn, CCGOCmode)
10069 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10071 if (operands[2] == const1_rtx
10072 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10073 return "<shift>{l}\t%k0";
10075 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10077 [(set_attr "type" "ishift")
10078 (set (attr "length_immediate")
10080 (and (match_operand 2 "const1_operand")
10081 (ior (match_test "TARGET_SHIFT1")
10082 (match_test "optimize_function_for_size_p (cfun)")))
10084 (const_string "*")))
10085 (set_attr "mode" "SI")])
10087 (define_insn "*<shift_insn><mode>3_cconly"
10088 [(set (reg FLAGS_REG)
10091 (match_operand:SWI 1 "register_operand" "0")
10092 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10094 (clobber (match_scratch:SWI 0 "=<r>"))]
10095 "(optimize_function_for_size_p (cfun)
10096 || !TARGET_PARTIAL_FLAG_REG_STALL
10097 || (operands[2] == const1_rtx
10099 && ix86_match_ccmode (insn, CCGOCmode)"
10101 if (operands[2] == const1_rtx
10102 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10103 return "<shift>{<imodesuffix>}\t%0";
10105 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10107 [(set_attr "type" "ishift")
10108 (set (attr "length_immediate")
10110 (and (match_operand 2 "const1_operand")
10111 (ior (match_test "TARGET_SHIFT1")
10112 (match_test "optimize_function_for_size_p (cfun)")))
10114 (const_string "*")))
10115 (set_attr "mode" "<MODE>")])
10117 ;; Rotate instructions
10119 (define_expand "<rotate_insn>ti3"
10120 [(set (match_operand:TI 0 "register_operand")
10121 (any_rotate:TI (match_operand:TI 1 "register_operand")
10122 (match_operand:QI 2 "nonmemory_operand")))]
10125 if (const_1_to_63_operand (operands[2], VOIDmode))
10126 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10127 (operands[0], operands[1], operands[2]));
10134 (define_expand "<rotate_insn>di3"
10135 [(set (match_operand:DI 0 "shiftdi_operand")
10136 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10137 (match_operand:QI 2 "nonmemory_operand")))]
10141 ix86_expand_binary_operator (<CODE>, DImode, operands);
10142 else if (const_1_to_31_operand (operands[2], VOIDmode))
10143 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10144 (operands[0], operands[1], operands[2]));
10151 (define_expand "<rotate_insn><mode>3"
10152 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10153 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10154 (match_operand:QI 2 "nonmemory_operand")))]
10156 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10158 ;; Avoid useless masking of count operand.
10159 (define_insn "*<rotate_insn><mode>3_mask"
10160 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10162 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10165 (match_operand:SI 2 "register_operand" "c")
10166 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10167 (clobber (reg:CC FLAGS_REG))]
10168 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10169 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10170 == GET_MODE_BITSIZE (<MODE>mode)-1"
10172 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10174 [(set_attr "type" "rotate")
10175 (set_attr "mode" "<MODE>")])
10177 ;; Implement rotation using two double-precision
10178 ;; shift instructions and a scratch register.
10180 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10181 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10182 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10183 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10184 (clobber (reg:CC FLAGS_REG))
10185 (clobber (match_scratch:DWIH 3 "=&r"))]
10189 [(set (match_dup 3) (match_dup 4))
10191 [(set (match_dup 4)
10192 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10193 (lshiftrt:DWIH (match_dup 5)
10194 (minus:QI (match_dup 6) (match_dup 2)))))
10195 (clobber (reg:CC FLAGS_REG))])
10197 [(set (match_dup 5)
10198 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10199 (lshiftrt:DWIH (match_dup 3)
10200 (minus:QI (match_dup 6) (match_dup 2)))))
10201 (clobber (reg:CC FLAGS_REG))])]
10203 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10205 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10208 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10209 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10210 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10211 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10212 (clobber (reg:CC FLAGS_REG))
10213 (clobber (match_scratch:DWIH 3 "=&r"))]
10217 [(set (match_dup 3) (match_dup 4))
10219 [(set (match_dup 4)
10220 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10221 (ashift:DWIH (match_dup 5)
10222 (minus:QI (match_dup 6) (match_dup 2)))))
10223 (clobber (reg:CC FLAGS_REG))])
10225 [(set (match_dup 5)
10226 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10227 (ashift:DWIH (match_dup 3)
10228 (minus:QI (match_dup 6) (match_dup 2)))))
10229 (clobber (reg:CC FLAGS_REG))])]
10231 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10233 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10236 (define_insn "*bmi2_rorx<mode>3_1"
10237 [(set (match_operand:SWI48 0 "register_operand" "=r")
10238 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10239 (match_operand:QI 2 "immediate_operand" "<S>")))]
10241 "rorx\t{%2, %1, %0|%0, %1, %2}"
10242 [(set_attr "type" "rotatex")
10243 (set_attr "mode" "<MODE>")])
10245 (define_insn "*<rotate_insn><mode>3_1"
10246 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10248 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10249 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10250 (clobber (reg:CC FLAGS_REG))]
10251 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10253 switch (get_attr_type (insn))
10259 if (operands[2] == const1_rtx
10260 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10261 return "<rotate>{<imodesuffix>}\t%0";
10263 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10266 [(set_attr "isa" "*,bmi2")
10267 (set_attr "type" "rotate,rotatex")
10268 (set (attr "length_immediate")
10270 (and (eq_attr "type" "rotate")
10271 (and (match_operand 2 "const1_operand")
10272 (ior (match_test "TARGET_SHIFT1")
10273 (match_test "optimize_function_for_size_p (cfun)"))))
10275 (const_string "*")))
10276 (set_attr "mode" "<MODE>")])
10278 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10280 [(set (match_operand:SWI48 0 "register_operand")
10281 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10282 (match_operand:QI 2 "immediate_operand")))
10283 (clobber (reg:CC FLAGS_REG))]
10284 "TARGET_BMI2 && reload_completed"
10285 [(set (match_dup 0)
10286 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10289 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10293 [(set (match_operand:SWI48 0 "register_operand")
10294 (rotatert: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)))])
10301 (define_insn "*bmi2_rorxsi3_1_zext"
10302 [(set (match_operand:DI 0 "register_operand" "=r")
10304 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10305 (match_operand:QI 2 "immediate_operand" "I"))))]
10306 "TARGET_64BIT && TARGET_BMI2"
10307 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10308 [(set_attr "type" "rotatex")
10309 (set_attr "mode" "SI")])
10311 (define_insn "*<rotate_insn>si3_1_zext"
10312 [(set (match_operand:DI 0 "register_operand" "=r,r")
10314 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10315 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10316 (clobber (reg:CC FLAGS_REG))]
10317 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10319 switch (get_attr_type (insn))
10325 if (operands[2] == const1_rtx
10326 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10327 return "<rotate>{l}\t%k0";
10329 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10332 [(set_attr "isa" "*,bmi2")
10333 (set_attr "type" "rotate,rotatex")
10334 (set (attr "length_immediate")
10336 (and (eq_attr "type" "rotate")
10337 (and (match_operand 2 "const1_operand")
10338 (ior (match_test "TARGET_SHIFT1")
10339 (match_test "optimize_function_for_size_p (cfun)"))))
10341 (const_string "*")))
10342 (set_attr "mode" "SI")])
10344 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10346 [(set (match_operand:DI 0 "register_operand")
10348 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10349 (match_operand:QI 2 "immediate_operand"))))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10352 [(set (match_dup 0)
10353 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10356 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10360 [(set (match_operand:DI 0 "register_operand")
10362 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10363 (match_operand:QI 2 "immediate_operand"))))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10366 [(set (match_dup 0)
10367 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10369 (define_insn "*<rotate_insn><mode>3_1"
10370 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10371 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10372 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10373 (clobber (reg:CC FLAGS_REG))]
10374 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10376 if (operands[2] == const1_rtx
10377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10378 return "<rotate>{<imodesuffix>}\t%0";
10380 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10382 [(set_attr "type" "rotate")
10383 (set (attr "length_immediate")
10385 (and (match_operand 2 "const1_operand")
10386 (ior (match_test "TARGET_SHIFT1")
10387 (match_test "optimize_function_for_size_p (cfun)")))
10389 (const_string "*")))
10390 (set_attr "mode" "<MODE>")])
10392 (define_insn "*<rotate_insn>qi3_1_slp"
10393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10394 (any_rotate:QI (match_dup 0)
10395 (match_operand:QI 1 "nonmemory_operand" "cI")))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "(optimize_function_for_size_p (cfun)
10398 || !TARGET_PARTIAL_REG_STALL
10399 || (operands[1] == const1_rtx
10400 && TARGET_SHIFT1))"
10402 if (operands[1] == const1_rtx
10403 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10404 return "<rotate>{b}\t%0";
10406 return "<rotate>{b}\t{%1, %0|%0, %1}";
10408 [(set_attr "type" "rotate1")
10409 (set (attr "length_immediate")
10411 (and (match_operand 1 "const1_operand")
10412 (ior (match_test "TARGET_SHIFT1")
10413 (match_test "optimize_function_for_size_p (cfun)")))
10415 (const_string "*")))
10416 (set_attr "mode" "QI")])
10419 [(set (match_operand:HI 0 "register_operand")
10420 (any_rotate:HI (match_dup 0) (const_int 8)))
10421 (clobber (reg:CC FLAGS_REG))]
10423 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10424 [(parallel [(set (strict_low_part (match_dup 0))
10425 (bswap:HI (match_dup 0)))
10426 (clobber (reg:CC FLAGS_REG))])])
10428 ;; Bit set / bit test instructions
10430 (define_expand "extv"
10431 [(set (match_operand:SI 0 "register_operand")
10432 (sign_extract:SI (match_operand:SI 1 "register_operand")
10433 (match_operand:SI 2 "const8_operand")
10434 (match_operand:SI 3 "const8_operand")))]
10437 /* Handle extractions from %ah et al. */
10438 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10441 /* From mips.md: extract_bit_field doesn't verify that our source
10442 matches the predicate, so check it again here. */
10443 if (! ext_register_operand (operands[1], VOIDmode))
10447 (define_expand "extzv"
10448 [(set (match_operand:SI 0 "register_operand")
10449 (zero_extract:SI (match_operand 1 "ext_register_operand")
10450 (match_operand:SI 2 "const8_operand")
10451 (match_operand:SI 3 "const8_operand")))]
10454 /* Handle extractions from %ah et al. */
10455 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10458 /* From mips.md: extract_bit_field doesn't verify that our source
10459 matches the predicate, so check it again here. */
10460 if (! ext_register_operand (operands[1], VOIDmode))
10464 (define_expand "insv"
10465 [(set (zero_extract (match_operand 0 "register_operand")
10466 (match_operand 1 "const_int_operand")
10467 (match_operand 2 "const_int_operand"))
10468 (match_operand 3 "register_operand"))]
10471 rtx (*gen_mov_insv_1) (rtx, rtx);
10473 if (ix86_expand_pinsr (operands))
10476 /* Handle insertions to %ah et al. */
10477 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10480 /* From mips.md: insert_bit_field doesn't verify that our source
10481 matches the predicate, so check it again here. */
10482 if (! ext_register_operand (operands[0], VOIDmode))
10485 gen_mov_insv_1 = (TARGET_64BIT
10486 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10488 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10492 ;; %%% bts, btr, btc, bt.
10493 ;; In general these instructions are *slow* when applied to memory,
10494 ;; since they enforce atomic operation. When applied to registers,
10495 ;; it depends on the cpu implementation. They're never faster than
10496 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10497 ;; no point. But in 64-bit, we can't hold the relevant immediates
10498 ;; within the instruction itself, so operating on bits in the high
10499 ;; 32-bits of a register becomes easier.
10501 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10502 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10503 ;; negdf respectively, so they can never be disabled entirely.
10505 (define_insn "*btsq"
10506 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10508 (match_operand:DI 1 "const_0_to_63_operand"))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10512 "bts{q}\t{%1, %0|%0, %1}"
10513 [(set_attr "type" "alu1")
10514 (set_attr "prefix_0f" "1")
10515 (set_attr "mode" "DI")])
10517 (define_insn "*btrq"
10518 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10520 (match_operand:DI 1 "const_0_to_63_operand"))
10522 (clobber (reg:CC FLAGS_REG))]
10523 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10524 "btr{q}\t{%1, %0|%0, %1}"
10525 [(set_attr "type" "alu1")
10526 (set_attr "prefix_0f" "1")
10527 (set_attr "mode" "DI")])
10529 (define_insn "*btcq"
10530 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10532 (match_operand:DI 1 "const_0_to_63_operand"))
10533 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10534 (clobber (reg:CC FLAGS_REG))]
10535 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10536 "btc{q}\t{%1, %0|%0, %1}"
10537 [(set_attr "type" "alu1")
10538 (set_attr "prefix_0f" "1")
10539 (set_attr "mode" "DI")])
10541 ;; Allow Nocona to avoid these instructions if a register is available.
10544 [(match_scratch:DI 2 "r")
10545 (parallel [(set (zero_extract:DI
10546 (match_operand:DI 0 "register_operand")
10548 (match_operand:DI 1 "const_0_to_63_operand"))
10550 (clobber (reg:CC FLAGS_REG))])]
10551 "TARGET_64BIT && !TARGET_USE_BT"
10554 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10557 if (HOST_BITS_PER_WIDE_INT >= 64)
10558 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10559 else if (i < HOST_BITS_PER_WIDE_INT)
10560 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10564 op1 = immed_double_const (lo, hi, DImode);
10567 emit_move_insn (operands[2], op1);
10571 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10576 [(match_scratch:DI 2 "r")
10577 (parallel [(set (zero_extract:DI
10578 (match_operand:DI 0 "register_operand")
10580 (match_operand:DI 1 "const_0_to_63_operand"))
10582 (clobber (reg:CC FLAGS_REG))])]
10583 "TARGET_64BIT && !TARGET_USE_BT"
10586 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10589 if (HOST_BITS_PER_WIDE_INT >= 64)
10590 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10591 else if (i < HOST_BITS_PER_WIDE_INT)
10592 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10594 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10596 op1 = immed_double_const (~lo, ~hi, DImode);
10599 emit_move_insn (operands[2], op1);
10603 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10608 [(match_scratch:DI 2 "r")
10609 (parallel [(set (zero_extract:DI
10610 (match_operand:DI 0 "register_operand")
10612 (match_operand:DI 1 "const_0_to_63_operand"))
10613 (not:DI (zero_extract:DI
10614 (match_dup 0) (const_int 1) (match_dup 1))))
10615 (clobber (reg:CC FLAGS_REG))])]
10616 "TARGET_64BIT && !TARGET_USE_BT"
10619 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10622 if (HOST_BITS_PER_WIDE_INT >= 64)
10623 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10624 else if (i < HOST_BITS_PER_WIDE_INT)
10625 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10627 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10629 op1 = immed_double_const (lo, hi, DImode);
10632 emit_move_insn (operands[2], op1);
10636 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10640 (define_insn "*bt<mode>"
10641 [(set (reg:CCC FLAGS_REG)
10643 (zero_extract:SWI48
10644 (match_operand:SWI48 0 "register_operand" "r")
10646 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10648 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10649 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10650 [(set_attr "type" "alu1")
10651 (set_attr "prefix_0f" "1")
10652 (set_attr "mode" "<MODE>")])
10654 ;; Store-flag instructions.
10656 ;; For all sCOND expanders, also expand the compare or test insn that
10657 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10659 (define_insn_and_split "*setcc_di_1"
10660 [(set (match_operand:DI 0 "register_operand" "=q")
10661 (match_operator:DI 1 "ix86_comparison_operator"
10662 [(reg FLAGS_REG) (const_int 0)]))]
10663 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10665 "&& reload_completed"
10666 [(set (match_dup 2) (match_dup 1))
10667 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10669 PUT_MODE (operands[1], QImode);
10670 operands[2] = gen_lowpart (QImode, operands[0]);
10673 (define_insn_and_split "*setcc_si_1_and"
10674 [(set (match_operand:SI 0 "register_operand" "=q")
10675 (match_operator:SI 1 "ix86_comparison_operator"
10676 [(reg FLAGS_REG) (const_int 0)]))
10677 (clobber (reg:CC FLAGS_REG))]
10678 "!TARGET_PARTIAL_REG_STALL
10679 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10681 "&& reload_completed"
10682 [(set (match_dup 2) (match_dup 1))
10683 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10684 (clobber (reg:CC FLAGS_REG))])]
10686 PUT_MODE (operands[1], QImode);
10687 operands[2] = gen_lowpart (QImode, operands[0]);
10690 (define_insn_and_split "*setcc_si_1_movzbl"
10691 [(set (match_operand:SI 0 "register_operand" "=q")
10692 (match_operator:SI 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)]))]
10694 "!TARGET_PARTIAL_REG_STALL
10695 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10697 "&& reload_completed"
10698 [(set (match_dup 2) (match_dup 1))
10699 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10701 PUT_MODE (operands[1], QImode);
10702 operands[2] = gen_lowpart (QImode, operands[0]);
10705 (define_insn "*setcc_qi"
10706 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10707 (match_operator:QI 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)]))]
10711 [(set_attr "type" "setcc")
10712 (set_attr "mode" "QI")])
10714 (define_insn "*setcc_qi_slp"
10715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10716 (match_operator:QI 1 "ix86_comparison_operator"
10717 [(reg FLAGS_REG) (const_int 0)]))]
10720 [(set_attr "type" "setcc")
10721 (set_attr "mode" "QI")])
10723 ;; In general it is not safe to assume too much about CCmode registers,
10724 ;; so simplify-rtx stops when it sees a second one. Under certain
10725 ;; conditions this is safe on x86, so help combine not create
10732 [(set (match_operand:QI 0 "nonimmediate_operand")
10733 (ne:QI (match_operator 1 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)])
10737 [(set (match_dup 0) (match_dup 1))]
10738 "PUT_MODE (operands[1], QImode);")
10741 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10742 (ne:QI (match_operator 1 "ix86_comparison_operator"
10743 [(reg FLAGS_REG) (const_int 0)])
10746 [(set (match_dup 0) (match_dup 1))]
10747 "PUT_MODE (operands[1], QImode);")
10750 [(set (match_operand:QI 0 "nonimmediate_operand")
10751 (eq:QI (match_operator 1 "ix86_comparison_operator"
10752 [(reg FLAGS_REG) (const_int 0)])
10755 [(set (match_dup 0) (match_dup 1))]
10757 rtx new_op1 = copy_rtx (operands[1]);
10758 operands[1] = new_op1;
10759 PUT_MODE (new_op1, QImode);
10760 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10761 GET_MODE (XEXP (new_op1, 0))));
10763 /* Make sure that (a) the CCmode we have for the flags is strong
10764 enough for the reversed compare or (b) we have a valid FP compare. */
10765 if (! ix86_comparison_operator (new_op1, VOIDmode))
10770 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10771 (eq:QI (match_operator 1 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)])
10775 [(set (match_dup 0) (match_dup 1))]
10777 rtx new_op1 = copy_rtx (operands[1]);
10778 operands[1] = new_op1;
10779 PUT_MODE (new_op1, QImode);
10780 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10781 GET_MODE (XEXP (new_op1, 0))));
10783 /* Make sure that (a) the CCmode we have for the flags is strong
10784 enough for the reversed compare or (b) we have a valid FP compare. */
10785 if (! ix86_comparison_operator (new_op1, VOIDmode))
10789 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10790 ;; subsequent logical operations are used to imitate conditional moves.
10791 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10794 (define_insn "setcc_<mode>_sse"
10795 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10796 (match_operator:MODEF 3 "sse_comparison_operator"
10797 [(match_operand:MODEF 1 "register_operand" "0,x")
10798 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10799 "SSE_FLOAT_MODE_P (<MODE>mode)"
10801 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10802 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10803 [(set_attr "isa" "noavx,avx")
10804 (set_attr "type" "ssecmp")
10805 (set_attr "length_immediate" "1")
10806 (set_attr "prefix" "orig,vex")
10807 (set_attr "mode" "<MODE>")])
10809 ;; Basic conditional jump instructions.
10810 ;; We ignore the overflow flag for signed branch instructions.
10812 (define_insn "*jcc_1"
10814 (if_then_else (match_operator 1 "ix86_comparison_operator"
10815 [(reg FLAGS_REG) (const_int 0)])
10816 (label_ref (match_operand 0))
10820 [(set_attr "type" "ibr")
10821 (set_attr "modrm" "0")
10822 (set (attr "length")
10823 (if_then_else (and (ge (minus (match_dup 0) (pc))
10825 (lt (minus (match_dup 0) (pc))
10830 (define_insn "*jcc_2"
10832 (if_then_else (match_operator 1 "ix86_comparison_operator"
10833 [(reg FLAGS_REG) (const_int 0)])
10835 (label_ref (match_operand 0))))]
10838 [(set_attr "type" "ibr")
10839 (set_attr "modrm" "0")
10840 (set (attr "length")
10841 (if_then_else (and (ge (minus (match_dup 0) (pc))
10843 (lt (minus (match_dup 0) (pc))
10848 ;; In general it is not safe to assume too much about CCmode registers,
10849 ;; so simplify-rtx stops when it sees a second one. Under certain
10850 ;; conditions this is safe on x86, so help combine not create
10858 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10859 [(reg FLAGS_REG) (const_int 0)])
10861 (label_ref (match_operand 1))
10865 (if_then_else (match_dup 0)
10866 (label_ref (match_dup 1))
10868 "PUT_MODE (operands[0], VOIDmode);")
10872 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10873 [(reg FLAGS_REG) (const_int 0)])
10875 (label_ref (match_operand 1))
10879 (if_then_else (match_dup 0)
10880 (label_ref (match_dup 1))
10883 rtx new_op0 = copy_rtx (operands[0]);
10884 operands[0] = new_op0;
10885 PUT_MODE (new_op0, VOIDmode);
10886 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10887 GET_MODE (XEXP (new_op0, 0))));
10889 /* Make sure that (a) the CCmode we have for the flags is strong
10890 enough for the reversed compare or (b) we have a valid FP compare. */
10891 if (! ix86_comparison_operator (new_op0, VOIDmode))
10895 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10896 ;; pass generates from shift insn with QImode operand. Actually, the mode
10897 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10898 ;; appropriate modulo of the bit offset value.
10900 (define_insn_and_split "*jcc_bt<mode>"
10902 (if_then_else (match_operator 0 "bt_comparison_operator"
10903 [(zero_extract:SWI48
10904 (match_operand:SWI48 1 "register_operand" "r")
10907 (match_operand:QI 2 "register_operand" "r")))
10909 (label_ref (match_operand 3))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10915 [(set (reg:CCC FLAGS_REG)
10917 (zero_extract:SWI48
10923 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10924 (label_ref (match_dup 3))
10927 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10929 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10932 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10933 ;; zero extended to SImode.
10934 (define_insn_and_split "*jcc_bt<mode>_1"
10936 (if_then_else (match_operator 0 "bt_comparison_operator"
10937 [(zero_extract:SWI48
10938 (match_operand:SWI48 1 "register_operand" "r")
10940 (match_operand:SI 2 "register_operand" "r"))
10942 (label_ref (match_operand 3))
10944 (clobber (reg:CC FLAGS_REG))]
10945 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10948 [(set (reg:CCC FLAGS_REG)
10950 (zero_extract:SWI48
10956 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10957 (label_ref (match_dup 3))
10960 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10962 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10965 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10966 ;; also for DImode, this is what combine produces.
10967 (define_insn_and_split "*jcc_bt<mode>_mask"
10969 (if_then_else (match_operator 0 "bt_comparison_operator"
10970 [(zero_extract:SWI48
10971 (match_operand:SWI48 1 "register_operand" "r")
10974 (match_operand:SI 2 "register_operand" "r")
10975 (match_operand:SI 3 "const_int_operand" "n")))])
10976 (label_ref (match_operand 4))
10978 (clobber (reg:CC FLAGS_REG))]
10979 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10980 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10981 == GET_MODE_BITSIZE (<MODE>mode)-1"
10984 [(set (reg:CCC FLAGS_REG)
10986 (zero_extract:SWI48
10992 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10993 (label_ref (match_dup 4))
10996 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10998 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11001 (define_insn_and_split "*jcc_btsi_1"
11003 (if_then_else (match_operator 0 "bt_comparison_operator"
11006 (match_operand:SI 1 "register_operand" "r")
11007 (match_operand:QI 2 "register_operand" "r"))
11010 (label_ref (match_operand 3))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11016 [(set (reg:CCC FLAGS_REG)
11024 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11025 (label_ref (match_dup 3))
11028 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11030 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11033 ;; avoid useless masking of bit offset operand
11034 (define_insn_and_split "*jcc_btsi_mask_1"
11037 (match_operator 0 "bt_comparison_operator"
11040 (match_operand:SI 1 "register_operand" "r")
11043 (match_operand:SI 2 "register_operand" "r")
11044 (match_operand:SI 3 "const_int_operand" "n")) 0))
11047 (label_ref (match_operand 4))
11049 (clobber (reg:CC FLAGS_REG))]
11050 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11051 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11054 [(set (reg:CCC FLAGS_REG)
11062 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11063 (label_ref (match_dup 4))
11065 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11067 ;; Define combination compare-and-branch fp compare instructions to help
11070 (define_insn "*jcc<mode>_0_i387"
11072 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11073 [(match_operand:X87MODEF 1 "register_operand" "f")
11074 (match_operand:X87MODEF 2 "const0_operand")])
11075 (label_ref (match_operand 3))
11077 (clobber (reg:CCFP FPSR_REG))
11078 (clobber (reg:CCFP FLAGS_REG))
11079 (clobber (match_scratch:HI 4 "=a"))]
11080 "TARGET_80387 && !TARGET_CMOVE"
11083 (define_insn "*jcc<mode>_0_r_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")])
11089 (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 "*jccxf_i387"
11098 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11099 [(match_operand:XF 1 "register_operand" "f")
11100 (match_operand:XF 2 "register_operand" "f")])
11101 (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_r_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")])
11115 (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 "*jcc<mode>_i387"
11124 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11125 [(match_operand:MODEF 1 "register_operand" "f")
11126 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11127 (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>_r_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")])
11141 (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 "*jccu<mode>_i387"
11150 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11151 [(match_operand:X87MODEF 1 "register_operand" "f")
11152 (match_operand:X87MODEF 2 "register_operand" "f")])
11153 (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>_r_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")])
11167 (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"
11176 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11177 [(match_operand:X87MODEF 1 "register_operand")
11178 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11180 (match_operand 4)))
11181 (clobber (reg:CCFP FPSR_REG))
11182 (clobber (reg:CCFP FLAGS_REG))]
11183 "TARGET_80387 && !TARGET_CMOVE
11184 && reload_completed"
11187 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11188 operands[3], operands[4], NULL_RTX);
11194 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11195 [(match_operand:X87MODEF 1 "register_operand")
11196 (match_operand:X87MODEF 2 "general_operand")])
11198 (match_operand 4)))
11199 (clobber (reg:CCFP FPSR_REG))
11200 (clobber (reg:CCFP FLAGS_REG))
11201 (clobber (match_scratch:HI 5))]
11202 "TARGET_80387 && !TARGET_CMOVE
11203 && reload_completed"
11206 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11207 operands[3], operands[4], operands[5]);
11211 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11212 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11213 ;; with a precedence over other operators and is always put in the first
11214 ;; place. Swap condition and operands to match ficom instruction.
11216 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11219 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11220 [(match_operator:X87MODEF 1 "float_operator"
11221 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11222 (match_operand:X87MODEF 3 "register_operand" "f")])
11223 (label_ref (match_operand 4))
11225 (clobber (reg:CCFP FPSR_REG))
11226 (clobber (reg:CCFP FLAGS_REG))
11227 (clobber (match_scratch:HI 5 "=a"))]
11228 "TARGET_80387 && !TARGET_CMOVE
11229 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11230 || optimize_function_for_size_p (cfun))"
11233 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11236 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11237 [(match_operator:X87MODEF 1 "float_operator"
11238 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11239 (match_operand:X87MODEF 3 "register_operand" "f")])
11241 (label_ref (match_operand 4))))
11242 (clobber (reg:CCFP FPSR_REG))
11243 (clobber (reg:CCFP FLAGS_REG))
11244 (clobber (match_scratch:HI 5 "=a"))]
11245 "TARGET_80387 && !TARGET_CMOVE
11246 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11247 || optimize_function_for_size_p (cfun))"
11253 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11254 [(match_operator:X87MODEF 1 "float_operator"
11255 [(match_operand:SWI24 2 "memory_operand")])
11256 (match_operand:X87MODEF 3 "register_operand")])
11258 (match_operand 5)))
11259 (clobber (reg:CCFP FPSR_REG))
11260 (clobber (reg:CCFP FLAGS_REG))
11261 (clobber (match_scratch:HI 6))]
11262 "TARGET_80387 && !TARGET_CMOVE
11263 && reload_completed"
11266 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11267 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11268 operands[4], operands[5], operands[6]);
11272 ;; Unconditional and other jump instructions
11274 (define_insn "jump"
11276 (label_ref (match_operand 0)))]
11279 [(set_attr "type" "ibr")
11280 (set (attr "length")
11281 (if_then_else (and (ge (minus (match_dup 0) (pc))
11283 (lt (minus (match_dup 0) (pc))
11287 (set_attr "modrm" "0")])
11289 (define_expand "indirect_jump"
11290 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11294 operands[0] = convert_memory_address (word_mode, operands[0]);
11297 (define_insn "*indirect_jump"
11298 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11301 [(set_attr "type" "ibr")
11302 (set_attr "length_immediate" "0")])
11304 (define_expand "tablejump"
11305 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11306 (use (label_ref (match_operand 1)))])]
11309 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11310 relative. Convert the relative address to an absolute address. */
11314 enum rtx_code code;
11316 /* We can't use @GOTOFF for text labels on VxWorks;
11317 see gotoff_operand. */
11318 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11322 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11324 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11328 op1 = pic_offset_table_rtx;
11333 op0 = pic_offset_table_rtx;
11337 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11342 operands[0] = convert_memory_address (word_mode, operands[0]);
11345 (define_insn "*tablejump_1"
11346 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11347 (use (label_ref (match_operand 1)))]
11350 [(set_attr "type" "ibr")
11351 (set_attr "length_immediate" "0")])
11353 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11356 [(set (reg FLAGS_REG) (match_operand 0))
11357 (set (match_operand:QI 1 "register_operand")
11358 (match_operator:QI 2 "ix86_comparison_operator"
11359 [(reg FLAGS_REG) (const_int 0)]))
11360 (set (match_operand 3 "q_regs_operand")
11361 (zero_extend (match_dup 1)))]
11362 "(peep2_reg_dead_p (3, operands[1])
11363 || operands_match_p (operands[1], operands[3]))
11364 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11365 [(set (match_dup 4) (match_dup 0))
11366 (set (strict_low_part (match_dup 5))
11369 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11370 operands[5] = gen_lowpart (QImode, operands[3]);
11371 ix86_expand_clear (operands[3]);
11375 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11376 (match_operand 4)])
11377 (set (match_operand:QI 1 "register_operand")
11378 (match_operator:QI 2 "ix86_comparison_operator"
11379 [(reg FLAGS_REG) (const_int 0)]))
11380 (set (match_operand 3 "q_regs_operand")
11381 (zero_extend (match_dup 1)))]
11382 "(peep2_reg_dead_p (3, operands[1])
11383 || operands_match_p (operands[1], operands[3]))
11384 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11385 [(parallel [(set (match_dup 5) (match_dup 0))
11387 (set (strict_low_part (match_dup 6))
11390 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11391 operands[6] = gen_lowpart (QImode, operands[3]);
11392 ix86_expand_clear (operands[3]);
11395 ;; Similar, but match zero extend with andsi3.
11398 [(set (reg FLAGS_REG) (match_operand 0))
11399 (set (match_operand:QI 1 "register_operand")
11400 (match_operator:QI 2 "ix86_comparison_operator"
11401 [(reg FLAGS_REG) (const_int 0)]))
11402 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11403 (and:SI (match_dup 3) (const_int 255)))
11404 (clobber (reg:CC FLAGS_REG))])]
11405 "REGNO (operands[1]) == REGNO (operands[3])
11406 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11407 [(set (match_dup 4) (match_dup 0))
11408 (set (strict_low_part (match_dup 5))
11411 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11412 operands[5] = gen_lowpart (QImode, operands[3]);
11413 ix86_expand_clear (operands[3]);
11417 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11418 (match_operand 4)])
11419 (set (match_operand:QI 1 "register_operand")
11420 (match_operator:QI 2 "ix86_comparison_operator"
11421 [(reg FLAGS_REG) (const_int 0)]))
11422 (parallel [(set (match_operand 3 "q_regs_operand")
11423 (zero_extend (match_dup 1)))
11424 (clobber (reg:CC FLAGS_REG))])]
11425 "(peep2_reg_dead_p (3, operands[1])
11426 || operands_match_p (operands[1], operands[3]))
11427 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11428 [(parallel [(set (match_dup 5) (match_dup 0))
11430 (set (strict_low_part (match_dup 6))
11433 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11434 operands[6] = gen_lowpart (QImode, operands[3]);
11435 ix86_expand_clear (operands[3]);
11438 ;; Call instructions.
11440 ;; The predicates normally associated with named expanders are not properly
11441 ;; checked for calls. This is a bug in the generic code, but it isn't that
11442 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11444 ;; P6 processors will jump to the address after the decrement when %esp
11445 ;; is used as a call operand, so they will execute return address as a code.
11446 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11448 ;; Register constraint for call instruction.
11449 (define_mode_attr c [(SI "l") (DI "r")])
11451 ;; Call subroutine returning no value.
11453 (define_expand "call"
11454 [(call (match_operand:QI 0)
11456 (use (match_operand 2))]
11459 ix86_expand_call (NULL, operands[0], operands[1],
11460 operands[2], NULL, false);
11464 (define_expand "sibcall"
11465 [(call (match_operand:QI 0)
11467 (use (match_operand 2))]
11470 ix86_expand_call (NULL, operands[0], operands[1],
11471 operands[2], NULL, true);
11475 (define_insn "*call"
11476 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11477 (match_operand 1))]
11478 "!SIBLING_CALL_P (insn)"
11479 "* return ix86_output_call_insn (insn, operands[0]);"
11480 [(set_attr "type" "call")])
11482 (define_insn "*sibcall"
11483 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11484 (match_operand 1))]
11485 "SIBLING_CALL_P (insn)"
11486 "* return ix86_output_call_insn (insn, operands[0]);"
11487 [(set_attr "type" "call")])
11489 (define_insn "*sibcall_memory"
11490 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11492 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11494 "* return ix86_output_call_insn (insn, operands[0]);"
11495 [(set_attr "type" "call")])
11498 [(set (match_operand:W 0 "register_operand")
11499 (match_operand:W 1 "memory_operand"))
11500 (call (mem:QI (match_dup 0))
11501 (match_operand 3))]
11502 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11503 && peep2_reg_dead_p (2, operands[0])"
11504 [(parallel [(call (mem:QI (match_dup 1))
11506 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11509 [(set (match_operand:W 0 "register_operand")
11510 (match_operand:W 1 "memory_operand"))
11511 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11512 (call (mem:QI (match_dup 0))
11513 (match_operand 3))]
11514 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11515 && peep2_reg_dead_p (3, operands[0])"
11516 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11517 (parallel [(call (mem:QI (match_dup 1))
11519 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11521 (define_expand "call_pop"
11522 [(parallel [(call (match_operand:QI 0)
11523 (match_operand:SI 1))
11524 (set (reg:SI SP_REG)
11525 (plus:SI (reg:SI SP_REG)
11526 (match_operand:SI 3)))])]
11529 ix86_expand_call (NULL, operands[0], operands[1],
11530 operands[2], operands[3], false);
11534 (define_insn "*call_pop"
11535 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11537 (set (reg:SI SP_REG)
11538 (plus:SI (reg:SI SP_REG)
11539 (match_operand:SI 2 "immediate_operand" "i")))]
11540 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11541 "* return ix86_output_call_insn (insn, operands[0]);"
11542 [(set_attr "type" "call")])
11544 (define_insn "*sibcall_pop"
11545 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11547 (set (reg:SI SP_REG)
11548 (plus:SI (reg:SI SP_REG)
11549 (match_operand:SI 2 "immediate_operand" "i")))]
11550 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11551 "* return ix86_output_call_insn (insn, operands[0]);"
11552 [(set_attr "type" "call")])
11554 (define_insn "*sibcall_pop_memory"
11555 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11557 (set (reg:SI SP_REG)
11558 (plus:SI (reg:SI SP_REG)
11559 (match_operand:SI 2 "immediate_operand" "i")))
11560 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11562 "* return ix86_output_call_insn (insn, operands[0]);"
11563 [(set_attr "type" "call")])
11566 [(set (match_operand:SI 0 "register_operand")
11567 (match_operand:SI 1 "memory_operand"))
11568 (parallel [(call (mem:QI (match_dup 0))
11570 (set (reg:SI SP_REG)
11571 (plus:SI (reg:SI SP_REG)
11572 (match_operand:SI 4 "immediate_operand")))])]
11573 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11574 && peep2_reg_dead_p (2, operands[0])"
11575 [(parallel [(call (mem:QI (match_dup 1))
11577 (set (reg:SI SP_REG)
11578 (plus:SI (reg:SI SP_REG)
11580 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11583 [(set (match_operand:SI 0 "register_operand")
11584 (match_operand:SI 1 "memory_operand"))
11585 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11586 (parallel [(call (mem:QI (match_dup 0))
11588 (set (reg:SI SP_REG)
11589 (plus:SI (reg:SI SP_REG)
11590 (match_operand:SI 4 "immediate_operand")))])]
11591 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11592 && peep2_reg_dead_p (3, operands[0])"
11593 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11594 (parallel [(call (mem:QI (match_dup 1))
11596 (set (reg:SI SP_REG)
11597 (plus:SI (reg:SI SP_REG)
11599 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11601 ;; Combining simple memory jump instruction
11604 [(set (match_operand:W 0 "register_operand")
11605 (match_operand:W 1 "memory_operand"))
11606 (set (pc) (match_dup 0))]
11607 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11608 [(set (pc) (match_dup 1))])
11610 ;; Call subroutine, returning value in operand 0
11612 (define_expand "call_value"
11613 [(set (match_operand 0)
11614 (call (match_operand:QI 1)
11615 (match_operand 2)))
11616 (use (match_operand 3))]
11619 ix86_expand_call (operands[0], operands[1], operands[2],
11620 operands[3], NULL, false);
11624 (define_expand "sibcall_value"
11625 [(set (match_operand 0)
11626 (call (match_operand:QI 1)
11627 (match_operand 2)))
11628 (use (match_operand 3))]
11631 ix86_expand_call (operands[0], operands[1], operands[2],
11632 operands[3], NULL, true);
11636 (define_insn "*call_value"
11637 [(set (match_operand 0)
11638 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11639 (match_operand 2)))]
11640 "!SIBLING_CALL_P (insn)"
11641 "* return ix86_output_call_insn (insn, operands[1]);"
11642 [(set_attr "type" "callv")])
11644 (define_insn "*sibcall_value"
11645 [(set (match_operand 0)
11646 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11647 (match_operand 2)))]
11648 "SIBLING_CALL_P (insn)"
11649 "* return ix86_output_call_insn (insn, operands[1]);"
11650 [(set_attr "type" "callv")])
11652 (define_insn "*sibcall_value_memory"
11653 [(set (match_operand 0)
11654 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11655 (match_operand 2)))
11656 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11658 "* return ix86_output_call_insn (insn, operands[1]);"
11659 [(set_attr "type" "callv")])
11662 [(set (match_operand:W 0 "register_operand")
11663 (match_operand:W 1 "memory_operand"))
11664 (set (match_operand 2)
11665 (call (mem:QI (match_dup 0))
11666 (match_operand 3)))]
11667 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11668 && peep2_reg_dead_p (2, operands[0])"
11669 [(parallel [(set (match_dup 2)
11670 (call (mem:QI (match_dup 1))
11672 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11675 [(set (match_operand:W 0 "register_operand")
11676 (match_operand:W 1 "memory_operand"))
11677 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11678 (set (match_operand 2)
11679 (call (mem:QI (match_dup 0))
11680 (match_operand 3)))]
11681 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11682 && peep2_reg_dead_p (3, operands[0])"
11683 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11684 (parallel [(set (match_dup 2)
11685 (call (mem:QI (match_dup 1))
11687 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11689 (define_expand "call_value_pop"
11690 [(parallel [(set (match_operand 0)
11691 (call (match_operand:QI 1)
11692 (match_operand:SI 2)))
11693 (set (reg:SI SP_REG)
11694 (plus:SI (reg:SI SP_REG)
11695 (match_operand:SI 4)))])]
11698 ix86_expand_call (operands[0], operands[1], operands[2],
11699 operands[3], operands[4], false);
11703 (define_insn "*call_value_pop"
11704 [(set (match_operand 0)
11705 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11706 (match_operand 2)))
11707 (set (reg:SI SP_REG)
11708 (plus:SI (reg:SI SP_REG)
11709 (match_operand:SI 3 "immediate_operand" "i")))]
11710 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11711 "* return ix86_output_call_insn (insn, operands[1]);"
11712 [(set_attr "type" "callv")])
11714 (define_insn "*sibcall_value_pop"
11715 [(set (match_operand 0)
11716 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11717 (match_operand 2)))
11718 (set (reg:SI SP_REG)
11719 (plus:SI (reg:SI SP_REG)
11720 (match_operand:SI 3 "immediate_operand" "i")))]
11721 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11722 "* return ix86_output_call_insn (insn, operands[1]);"
11723 [(set_attr "type" "callv")])
11725 (define_insn "*sibcall_value_pop_memory"
11726 [(set (match_operand 0)
11727 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11728 (match_operand 2)))
11729 (set (reg:SI SP_REG)
11730 (plus:SI (reg:SI SP_REG)
11731 (match_operand:SI 3 "immediate_operand" "i")))
11732 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11734 "* return ix86_output_call_insn (insn, operands[1]);"
11735 [(set_attr "type" "callv")])
11738 [(set (match_operand:SI 0 "register_operand")
11739 (match_operand:SI 1 "memory_operand"))
11740 (parallel [(set (match_operand 2)
11741 (call (mem:QI (match_dup 0))
11742 (match_operand 3)))
11743 (set (reg:SI SP_REG)
11744 (plus:SI (reg:SI SP_REG)
11745 (match_operand:SI 4 "immediate_operand")))])]
11746 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11747 && peep2_reg_dead_p (2, operands[0])"
11748 [(parallel [(set (match_dup 2)
11749 (call (mem:QI (match_dup 1))
11751 (set (reg:SI SP_REG)
11752 (plus:SI (reg:SI SP_REG)
11754 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11757 [(set (match_operand:SI 0 "register_operand")
11758 (match_operand:SI 1 "memory_operand"))
11759 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11760 (parallel [(set (match_operand 2)
11761 (call (mem:QI (match_dup 0))
11762 (match_operand 3)))
11763 (set (reg:SI SP_REG)
11764 (plus:SI (reg:SI SP_REG)
11765 (match_operand:SI 4 "immediate_operand")))])]
11766 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11767 && peep2_reg_dead_p (3, operands[0])"
11768 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11769 (parallel [(set (match_dup 2)
11770 (call (mem:QI (match_dup 1))
11772 (set (reg:SI SP_REG)
11773 (plus:SI (reg:SI SP_REG)
11775 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11777 ;; Call subroutine returning any type.
11779 (define_expand "untyped_call"
11780 [(parallel [(call (match_operand 0)
11783 (match_operand 2)])]
11788 /* In order to give reg-stack an easier job in validating two
11789 coprocessor registers as containing a possible return value,
11790 simply pretend the untyped call returns a complex long double
11793 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11794 and should have the default ABI. */
11796 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11797 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11798 operands[0], const0_rtx,
11799 GEN_INT ((TARGET_64BIT
11800 ? (ix86_abi == SYSV_ABI
11801 ? X86_64_SSE_REGPARM_MAX
11802 : X86_64_MS_SSE_REGPARM_MAX)
11803 : X86_32_SSE_REGPARM_MAX)
11807 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11809 rtx set = XVECEXP (operands[2], 0, i);
11810 emit_move_insn (SET_DEST (set), SET_SRC (set));
11813 /* The optimizer does not know that the call sets the function value
11814 registers we stored in the result block. We avoid problems by
11815 claiming that all hard registers are used and clobbered at this
11817 emit_insn (gen_blockage ());
11822 ;; Prologue and epilogue instructions
11824 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11825 ;; all of memory. This blocks insns from being moved across this point.
11827 (define_insn "blockage"
11828 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11831 [(set_attr "length" "0")])
11833 ;; Do not schedule instructions accessing memory across this point.
11835 (define_expand "memory_blockage"
11836 [(set (match_dup 0)
11837 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11840 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11841 MEM_VOLATILE_P (operands[0]) = 1;
11844 (define_insn "*memory_blockage"
11845 [(set (match_operand:BLK 0)
11846 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11849 [(set_attr "length" "0")])
11851 ;; As USE insns aren't meaningful after reload, this is used instead
11852 ;; to prevent deleting instructions setting registers for PIC code
11853 (define_insn "prologue_use"
11854 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11857 [(set_attr "length" "0")])
11859 ;; Insn emitted into the body of a function to return from a function.
11860 ;; This is only done if the function's epilogue is known to be simple.
11861 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11863 (define_expand "return"
11865 "ix86_can_use_return_insn_p ()"
11867 if (crtl->args.pops_args)
11869 rtx popc = GEN_INT (crtl->args.pops_args);
11870 emit_jump_insn (gen_simple_return_pop_internal (popc));
11875 ;; We need to disable this for TARGET_SEH, as otherwise
11876 ;; shrink-wrapped prologue gets enabled too. This might exceed
11877 ;; the maximum size of prologue in unwind information.
11879 (define_expand "simple_return"
11883 if (crtl->args.pops_args)
11885 rtx popc = GEN_INT (crtl->args.pops_args);
11886 emit_jump_insn (gen_simple_return_pop_internal (popc));
11891 (define_insn "simple_return_internal"
11895 [(set_attr "length" "1")
11896 (set_attr "atom_unit" "jeu")
11897 (set_attr "length_immediate" "0")
11898 (set_attr "modrm" "0")])
11900 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11901 ;; instruction Athlon and K8 have.
11903 (define_insn "simple_return_internal_long"
11905 (unspec [(const_int 0)] UNSPEC_REP)]
11908 [(set_attr "length" "2")
11909 (set_attr "atom_unit" "jeu")
11910 (set_attr "length_immediate" "0")
11911 (set_attr "prefix_rep" "1")
11912 (set_attr "modrm" "0")])
11914 (define_insn "simple_return_pop_internal"
11916 (use (match_operand:SI 0 "const_int_operand"))]
11919 [(set_attr "length" "3")
11920 (set_attr "atom_unit" "jeu")
11921 (set_attr "length_immediate" "2")
11922 (set_attr "modrm" "0")])
11924 (define_insn "simple_return_indirect_internal"
11926 (use (match_operand:SI 0 "register_operand" "r"))]
11929 [(set_attr "type" "ibr")
11930 (set_attr "length_immediate" "0")])
11936 [(set_attr "length" "1")
11937 (set_attr "length_immediate" "0")
11938 (set_attr "modrm" "0")])
11940 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11941 (define_insn "nops"
11942 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11946 int num = INTVAL (operands[0]);
11948 gcc_assert (IN_RANGE (num, 1, 8));
11951 fputs ("\tnop\n", asm_out_file);
11955 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11956 (set_attr "length_immediate" "0")
11957 (set_attr "modrm" "0")])
11959 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11960 ;; branch prediction penalty for the third jump in a 16-byte
11964 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11967 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11968 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11970 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11971 The align insn is used to avoid 3 jump instructions in the row to improve
11972 branch prediction and the benefits hardly outweigh the cost of extra 8
11973 nops on the average inserted by full alignment pseudo operation. */
11977 [(set_attr "length" "16")])
11979 (define_expand "prologue"
11982 "ix86_expand_prologue (); DONE;")
11984 (define_insn "set_got"
11985 [(set (match_operand:SI 0 "register_operand" "=r")
11986 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11987 (clobber (reg:CC FLAGS_REG))]
11989 "* return output_set_got (operands[0], NULL_RTX);"
11990 [(set_attr "type" "multi")
11991 (set_attr "length" "12")])
11993 (define_insn "set_got_labelled"
11994 [(set (match_operand:SI 0 "register_operand" "=r")
11995 (unspec:SI [(label_ref (match_operand 1))]
11997 (clobber (reg:CC FLAGS_REG))]
11999 "* return output_set_got (operands[0], operands[1]);"
12000 [(set_attr "type" "multi")
12001 (set_attr "length" "12")])
12003 (define_insn "set_got_rex64"
12004 [(set (match_operand:DI 0 "register_operand" "=r")
12005 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12007 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12008 [(set_attr "type" "lea")
12009 (set_attr "length_address" "4")
12010 (set_attr "mode" "DI")])
12012 (define_insn "set_rip_rex64"
12013 [(set (match_operand:DI 0 "register_operand" "=r")
12014 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12016 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12017 [(set_attr "type" "lea")
12018 (set_attr "length_address" "4")
12019 (set_attr "mode" "DI")])
12021 (define_insn "set_got_offset_rex64"
12022 [(set (match_operand:DI 0 "register_operand" "=r")
12024 [(label_ref (match_operand 1))]
12025 UNSPEC_SET_GOT_OFFSET))]
12027 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12028 [(set_attr "type" "imov")
12029 (set_attr "length_immediate" "0")
12030 (set_attr "length_address" "8")
12031 (set_attr "mode" "DI")])
12033 (define_expand "epilogue"
12036 "ix86_expand_epilogue (1); DONE;")
12038 (define_expand "sibcall_epilogue"
12041 "ix86_expand_epilogue (0); DONE;")
12043 (define_expand "eh_return"
12044 [(use (match_operand 0 "register_operand"))]
12047 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12049 /* Tricky bit: we write the address of the handler to which we will
12050 be returning into someone else's stack frame, one word below the
12051 stack address we wish to restore. */
12052 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12053 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12054 tmp = gen_rtx_MEM (Pmode, tmp);
12055 emit_move_insn (tmp, ra);
12057 emit_jump_insn (gen_eh_return_internal ());
12062 (define_insn_and_split "eh_return_internal"
12066 "epilogue_completed"
12068 "ix86_expand_epilogue (2); DONE;")
12070 (define_insn "leave"
12071 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12072 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12073 (clobber (mem:BLK (scratch)))]
12076 [(set_attr "type" "leave")])
12078 (define_insn "leave_rex64"
12079 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12080 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12081 (clobber (mem:BLK (scratch)))]
12084 [(set_attr "type" "leave")])
12086 ;; Handle -fsplit-stack.
12088 (define_expand "split_stack_prologue"
12092 ix86_expand_split_stack_prologue ();
12096 ;; In order to support the call/return predictor, we use a return
12097 ;; instruction which the middle-end doesn't see.
12098 (define_insn "split_stack_return"
12099 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12100 UNSPECV_SPLIT_STACK_RETURN)]
12103 if (operands[0] == const0_rtx)
12108 [(set_attr "atom_unit" "jeu")
12109 (set_attr "modrm" "0")
12110 (set (attr "length")
12111 (if_then_else (match_operand:SI 0 "const0_operand")
12114 (set (attr "length_immediate")
12115 (if_then_else (match_operand:SI 0 "const0_operand")
12119 ;; If there are operand 0 bytes available on the stack, jump to
12122 (define_expand "split_stack_space_check"
12123 [(set (pc) (if_then_else
12124 (ltu (minus (reg SP_REG)
12125 (match_operand 0 "register_operand"))
12126 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12127 (label_ref (match_operand 1))
12131 rtx reg, size, limit;
12133 reg = gen_reg_rtx (Pmode);
12134 size = force_reg (Pmode, operands[0]);
12135 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12136 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12137 UNSPEC_STACK_CHECK);
12138 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12139 ix86_expand_branch (GEU, reg, limit, operands[1]);
12144 ;; Bit manipulation instructions.
12146 (define_expand "ffs<mode>2"
12147 [(set (match_dup 2) (const_int -1))
12148 (parallel [(set (match_dup 3) (match_dup 4))
12149 (set (match_operand:SWI48 0 "register_operand")
12151 (match_operand:SWI48 1 "nonimmediate_operand")))])
12152 (set (match_dup 0) (if_then_else:SWI48
12153 (eq (match_dup 3) (const_int 0))
12156 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12157 (clobber (reg:CC FLAGS_REG))])]
12160 machine_mode flags_mode;
12162 if (<MODE>mode == SImode && !TARGET_CMOVE)
12164 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12169 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12171 operands[2] = gen_reg_rtx (<MODE>mode);
12172 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12173 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12176 (define_insn_and_split "ffssi2_no_cmove"
12177 [(set (match_operand:SI 0 "register_operand" "=r")
12178 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12179 (clobber (match_scratch:SI 2 "=&q"))
12180 (clobber (reg:CC FLAGS_REG))]
12183 "&& reload_completed"
12184 [(parallel [(set (match_dup 4) (match_dup 5))
12185 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12186 (set (strict_low_part (match_dup 3))
12187 (eq:QI (match_dup 4) (const_int 0)))
12188 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12189 (clobber (reg:CC FLAGS_REG))])
12190 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12191 (clobber (reg:CC FLAGS_REG))])
12192 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12193 (clobber (reg:CC FLAGS_REG))])]
12195 machine_mode flags_mode
12196 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12198 operands[3] = gen_lowpart (QImode, operands[2]);
12199 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12200 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12202 ix86_expand_clear (operands[2]);
12205 (define_insn "*tzcnt<mode>_1"
12206 [(set (reg:CCC FLAGS_REG)
12207 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12209 (set (match_operand:SWI48 0 "register_operand" "=r")
12210 (ctz:SWI48 (match_dup 1)))]
12211 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12212 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12213 [(set_attr "type" "alu1")
12214 (set_attr "prefix_0f" "1")
12215 (set_attr "prefix_rep" "1")
12216 (set_attr "btver2_decode" "double")
12217 (set_attr "mode" "<MODE>")])
12219 (define_insn "*bsf<mode>_1"
12220 [(set (reg:CCZ FLAGS_REG)
12221 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12223 (set (match_operand:SWI48 0 "register_operand" "=r")
12224 (ctz:SWI48 (match_dup 1)))]
12226 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "alu1")
12228 (set_attr "prefix_0f" "1")
12229 (set_attr "btver2_decode" "double")
12230 (set_attr "mode" "<MODE>")])
12232 (define_expand "ctz<mode>2"
12234 [(set (match_operand:SWI248 0 "register_operand")
12236 (match_operand:SWI248 1 "nonimmediate_operand")))
12237 (clobber (reg:CC FLAGS_REG))])])
12239 ; False dependency happens when destination is only updated by tzcnt,
12240 ; lzcnt or popcnt. There is no false dependency when destination is
12241 ; also used in source.
12242 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12243 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12246 (clobber (reg:CC FLAGS_REG))]
12247 "(TARGET_BMI || TARGET_GENERIC)
12248 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12250 "&& reload_completed"
12252 [(set (match_dup 0)
12253 (ctz:SWI48 (match_dup 1)))
12254 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12255 (clobber (reg:CC FLAGS_REG))])]
12257 if (!reg_mentioned_p (operands[0], operands[1]))
12258 ix86_expand_clear (operands[0]);
12261 (define_insn "*ctz<mode>2_falsedep"
12262 [(set (match_operand:SWI48 0 "register_operand" "=r")
12264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12265 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12266 UNSPEC_INSN_FALSE_DEP)
12267 (clobber (reg:CC FLAGS_REG))]
12271 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12272 else if (TARGET_GENERIC)
12273 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12274 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12276 gcc_unreachable ();
12278 [(set_attr "type" "alu1")
12279 (set_attr "prefix_0f" "1")
12280 (set_attr "prefix_rep" "1")
12281 (set_attr "mode" "<MODE>")])
12283 (define_insn "*ctz<mode>2"
12284 [(set (match_operand:SWI248 0 "register_operand" "=r")
12285 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12286 (clobber (reg:CC FLAGS_REG))]
12290 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12291 else if (optimize_function_for_size_p (cfun))
12293 else if (TARGET_GENERIC)
12294 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12295 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12297 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12299 [(set_attr "type" "alu1")
12300 (set_attr "prefix_0f" "1")
12301 (set (attr "prefix_rep")
12303 (ior (match_test "TARGET_BMI")
12304 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12305 (match_test "TARGET_GENERIC")))
12307 (const_string "0")))
12308 (set_attr "mode" "<MODE>")])
12310 (define_expand "clz<mode>2"
12312 [(set (match_operand:SWI248 0 "register_operand")
12315 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12316 (clobber (reg:CC FLAGS_REG))])
12318 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12319 (clobber (reg:CC FLAGS_REG))])]
12324 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12327 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12330 (define_expand "clz<mode>2_lzcnt"
12332 [(set (match_operand:SWI248 0 "register_operand")
12334 (match_operand:SWI248 1 "nonimmediate_operand")))
12335 (clobber (reg:CC FLAGS_REG))])]
12338 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12339 [(set (match_operand:SWI48 0 "register_operand" "=r")
12341 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12342 (clobber (reg:CC FLAGS_REG))]
12344 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12346 "&& reload_completed"
12348 [(set (match_dup 0)
12349 (clz:SWI48 (match_dup 1)))
12350 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12351 (clobber (reg:CC FLAGS_REG))])]
12353 if (!reg_mentioned_p (operands[0], operands[1]))
12354 ix86_expand_clear (operands[0]);
12357 (define_insn "*clz<mode>2_lzcnt_falsedep"
12358 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12361 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12362 UNSPEC_INSN_FALSE_DEP)
12363 (clobber (reg:CC FLAGS_REG))]
12365 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12366 [(set_attr "prefix_rep" "1")
12367 (set_attr "type" "bitmanip")
12368 (set_attr "mode" "<MODE>")])
12370 (define_insn "*clz<mode>2_lzcnt"
12371 [(set (match_operand:SWI248 0 "register_operand" "=r")
12372 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12373 (clobber (reg:CC FLAGS_REG))]
12375 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12376 [(set_attr "prefix_rep" "1")
12377 (set_attr "type" "bitmanip")
12378 (set_attr "mode" "<MODE>")])
12380 ;; BMI instructions.
12381 (define_insn "*bmi_andn_<mode>"
12382 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12385 (match_operand:SWI48 1 "register_operand" "r,r"))
12386 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12387 (clobber (reg:CC FLAGS_REG))]
12389 "andn\t{%2, %1, %0|%0, %1, %2}"
12390 [(set_attr "type" "bitmanip")
12391 (set_attr "btver2_decode" "direct, double")
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "bmi_bextr_<mode>"
12395 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12396 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12397 (match_operand:SWI48 2 "register_operand" "r,r")]
12399 (clobber (reg:CC FLAGS_REG))]
12401 "bextr\t{%2, %1, %0|%0, %1, %2}"
12402 [(set_attr "type" "bitmanip")
12403 (set_attr "btver2_decode" "direct, double")
12404 (set_attr "mode" "<MODE>")])
12406 (define_insn "*bmi_blsi_<mode>"
12407 [(set (match_operand:SWI48 0 "register_operand" "=r")
12410 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12412 (clobber (reg:CC FLAGS_REG))]
12414 "blsi\t{%1, %0|%0, %1}"
12415 [(set_attr "type" "bitmanip")
12416 (set_attr "btver2_decode" "double")
12417 (set_attr "mode" "<MODE>")])
12419 (define_insn "*bmi_blsmsk_<mode>"
12420 [(set (match_operand:SWI48 0 "register_operand" "=r")
12423 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12426 (clobber (reg:CC FLAGS_REG))]
12428 "blsmsk\t{%1, %0|%0, %1}"
12429 [(set_attr "type" "bitmanip")
12430 (set_attr "btver2_decode" "double")
12431 (set_attr "mode" "<MODE>")])
12433 (define_insn "*bmi_blsr_<mode>"
12434 [(set (match_operand:SWI48 0 "register_operand" "=r")
12437 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12440 (clobber (reg:CC FLAGS_REG))]
12442 "blsr\t{%1, %0|%0, %1}"
12443 [(set_attr "type" "bitmanip")
12444 (set_attr "btver2_decode" "double")
12445 (set_attr "mode" "<MODE>")])
12447 ;; BMI2 instructions.
12448 (define_insn "bmi2_bzhi_<mode>3"
12449 [(set (match_operand:SWI48 0 "register_operand" "=r")
12450 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12451 (match_operand:SWI48 2 "register_operand" "r"))
12452 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12453 (clobber (reg:CC FLAGS_REG))]
12455 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12456 [(set_attr "type" "bitmanip")
12457 (set_attr "prefix" "vex")
12458 (set_attr "mode" "<MODE>")])
12460 (define_insn "bmi2_pdep_<mode>3"
12461 [(set (match_operand:SWI48 0 "register_operand" "=r")
12462 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12463 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12466 "pdep\t{%2, %1, %0|%0, %1, %2}"
12467 [(set_attr "type" "bitmanip")
12468 (set_attr "prefix" "vex")
12469 (set_attr "mode" "<MODE>")])
12471 (define_insn "bmi2_pext_<mode>3"
12472 [(set (match_operand:SWI48 0 "register_operand" "=r")
12473 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12474 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12477 "pext\t{%2, %1, %0|%0, %1, %2}"
12478 [(set_attr "type" "bitmanip")
12479 (set_attr "prefix" "vex")
12480 (set_attr "mode" "<MODE>")])
12482 ;; TBM instructions.
12483 (define_insn "tbm_bextri_<mode>"
12484 [(set (match_operand:SWI48 0 "register_operand" "=r")
12485 (zero_extract:SWI48
12486 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12487 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12488 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12489 (clobber (reg:CC FLAGS_REG))]
12492 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12493 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12495 [(set_attr "type" "bitmanip")
12496 (set_attr "mode" "<MODE>")])
12498 (define_insn "*tbm_blcfill_<mode>"
12499 [(set (match_operand:SWI48 0 "register_operand" "=r")
12502 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12505 (clobber (reg:CC FLAGS_REG))]
12507 "blcfill\t{%1, %0|%0, %1}"
12508 [(set_attr "type" "bitmanip")
12509 (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_blci_<mode>"
12512 [(set (match_operand:SWI48 0 "register_operand" "=r")
12516 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12519 (clobber (reg:CC FLAGS_REG))]
12521 "blci\t{%1, %0|%0, %1}"
12522 [(set_attr "type" "bitmanip")
12523 (set_attr "mode" "<MODE>")])
12525 (define_insn "*tbm_blcic_<mode>"
12526 [(set (match_operand:SWI48 0 "register_operand" "=r")
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12533 (clobber (reg:CC FLAGS_REG))]
12535 "blcic\t{%1, %0|%0, %1}"
12536 [(set_attr "type" "bitmanip")
12537 (set_attr "mode" "<MODE>")])
12539 (define_insn "*tbm_blcmsk_<mode>"
12540 [(set (match_operand:SWI48 0 "register_operand" "=r")
12543 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12546 (clobber (reg:CC FLAGS_REG))]
12548 "blcmsk\t{%1, %0|%0, %1}"
12549 [(set_attr "type" "bitmanip")
12550 (set_attr "mode" "<MODE>")])
12552 (define_insn "*tbm_blcs_<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 "blcs\t{%1, %0|%0, %1}"
12562 [(set_attr "type" "bitmanip")
12563 (set_attr "mode" "<MODE>")])
12565 (define_insn "*tbm_blsfill_<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 "blsfill\t{%1, %0|%0, %1}"
12575 [(set_attr "type" "bitmanip")
12576 (set_attr "mode" "<MODE>")])
12578 (define_insn "*tbm_blsic_<mode>"
12579 [(set (match_operand:SWI48 0 "register_operand" "=r")
12582 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12586 (clobber (reg:CC FLAGS_REG))]
12588 "blsic\t{%1, %0|%0, %1}"
12589 [(set_attr "type" "bitmanip")
12590 (set_attr "mode" "<MODE>")])
12592 (define_insn "*tbm_t1mskc_<mode>"
12593 [(set (match_operand:SWI48 0 "register_operand" "=r")
12596 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12600 (clobber (reg:CC FLAGS_REG))]
12602 "t1mskc\t{%1, %0|%0, %1}"
12603 [(set_attr "type" "bitmanip")
12604 (set_attr "mode" "<MODE>")])
12606 (define_insn "*tbm_tzmsk_<mode>"
12607 [(set (match_operand:SWI48 0 "register_operand" "=r")
12610 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12614 (clobber (reg:CC FLAGS_REG))]
12616 "tzmsk\t{%1, %0|%0, %1}"
12617 [(set_attr "type" "bitmanip")
12618 (set_attr "mode" "<MODE>")])
12620 (define_insn "bsr_rex64"
12621 [(set (match_operand:DI 0 "register_operand" "=r")
12622 (minus:DI (const_int 63)
12623 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12624 (clobber (reg:CC FLAGS_REG))]
12626 "bsr{q}\t{%1, %0|%0, %1}"
12627 [(set_attr "type" "alu1")
12628 (set_attr "prefix_0f" "1")
12629 (set_attr "mode" "DI")])
12632 [(set (match_operand:SI 0 "register_operand" "=r")
12633 (minus:SI (const_int 31)
12634 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12635 (clobber (reg:CC FLAGS_REG))]
12637 "bsr{l}\t{%1, %0|%0, %1}"
12638 [(set_attr "type" "alu1")
12639 (set_attr "prefix_0f" "1")
12640 (set_attr "mode" "SI")])
12642 (define_insn "*bsrhi"
12643 [(set (match_operand:HI 0 "register_operand" "=r")
12644 (minus:HI (const_int 15)
12645 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12646 (clobber (reg:CC FLAGS_REG))]
12648 "bsr{w}\t{%1, %0|%0, %1}"
12649 [(set_attr "type" "alu1")
12650 (set_attr "prefix_0f" "1")
12651 (set_attr "mode" "HI")])
12653 (define_expand "popcount<mode>2"
12655 [(set (match_operand:SWI248 0 "register_operand")
12657 (match_operand:SWI248 1 "nonimmediate_operand")))
12658 (clobber (reg:CC FLAGS_REG))])]
12661 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12662 [(set (match_operand:SWI48 0 "register_operand" "=r")
12664 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12665 (clobber (reg:CC FLAGS_REG))]
12667 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12669 "&& reload_completed"
12671 [(set (match_dup 0)
12672 (popcount:SWI48 (match_dup 1)))
12673 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12674 (clobber (reg:CC FLAGS_REG))])]
12676 if (!reg_mentioned_p (operands[0], operands[1]))
12677 ix86_expand_clear (operands[0]);
12680 (define_insn "*popcount<mode>2_falsedep"
12681 [(set (match_operand:SWI48 0 "register_operand" "=r")
12683 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12684 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12685 UNSPEC_INSN_FALSE_DEP)
12686 (clobber (reg:CC FLAGS_REG))]
12690 return "popcnt\t{%1, %0|%0, %1}";
12692 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12695 [(set_attr "prefix_rep" "1")
12696 (set_attr "type" "bitmanip")
12697 (set_attr "mode" "<MODE>")])
12699 (define_insn "*popcount<mode>2"
12700 [(set (match_operand:SWI248 0 "register_operand" "=r")
12702 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12703 (clobber (reg:CC FLAGS_REG))]
12707 return "popcnt\t{%1, %0|%0, %1}";
12709 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12712 [(set_attr "prefix_rep" "1")
12713 (set_attr "type" "bitmanip")
12714 (set_attr "mode" "<MODE>")])
12716 (define_expand "bswapdi2"
12717 [(set (match_operand:DI 0 "register_operand")
12718 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12722 operands[1] = force_reg (DImode, operands[1]);
12725 (define_expand "bswapsi2"
12726 [(set (match_operand:SI 0 "register_operand")
12727 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12732 else if (TARGET_BSWAP)
12733 operands[1] = force_reg (SImode, operands[1]);
12736 rtx x = operands[0];
12738 emit_move_insn (x, operands[1]);
12739 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12740 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12741 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12746 (define_insn "*bswap<mode>2_movbe"
12747 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12748 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12750 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12753 movbe\t{%1, %0|%0, %1}
12754 movbe\t{%1, %0|%0, %1}"
12755 [(set_attr "type" "bitmanip,imov,imov")
12756 (set_attr "modrm" "0,1,1")
12757 (set_attr "prefix_0f" "*,1,1")
12758 (set_attr "prefix_extra" "*,1,1")
12759 (set_attr "mode" "<MODE>")])
12761 (define_insn "*bswap<mode>2"
12762 [(set (match_operand:SWI48 0 "register_operand" "=r")
12763 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12766 [(set_attr "type" "bitmanip")
12767 (set_attr "modrm" "0")
12768 (set_attr "mode" "<MODE>")])
12770 (define_insn "*bswaphi_lowpart_1"
12771 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12772 (bswap:HI (match_dup 0)))
12773 (clobber (reg:CC FLAGS_REG))]
12774 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12776 xchg{b}\t{%h0, %b0|%b0, %h0}
12777 rol{w}\t{$8, %0|%0, 8}"
12778 [(set_attr "length" "2,4")
12779 (set_attr "mode" "QI,HI")])
12781 (define_insn "bswaphi_lowpart"
12782 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12783 (bswap:HI (match_dup 0)))
12784 (clobber (reg:CC FLAGS_REG))]
12786 "rol{w}\t{$8, %0|%0, 8}"
12787 [(set_attr "length" "4")
12788 (set_attr "mode" "HI")])
12790 (define_expand "paritydi2"
12791 [(set (match_operand:DI 0 "register_operand")
12792 (parity:DI (match_operand:DI 1 "register_operand")))]
12795 rtx scratch = gen_reg_rtx (QImode);
12798 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12799 NULL_RTX, operands[1]));
12801 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12802 gen_rtx_REG (CCmode, FLAGS_REG),
12804 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12807 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12810 rtx tmp = gen_reg_rtx (SImode);
12812 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12813 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12818 (define_expand "paritysi2"
12819 [(set (match_operand:SI 0 "register_operand")
12820 (parity:SI (match_operand:SI 1 "register_operand")))]
12823 rtx scratch = gen_reg_rtx (QImode);
12826 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12828 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12829 gen_rtx_REG (CCmode, FLAGS_REG),
12831 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12833 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12837 (define_insn_and_split "paritydi2_cmp"
12838 [(set (reg:CC FLAGS_REG)
12839 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12841 (clobber (match_scratch:DI 0 "=r"))
12842 (clobber (match_scratch:SI 1 "=&r"))
12843 (clobber (match_scratch:HI 2 "=Q"))]
12846 "&& reload_completed"
12848 [(set (match_dup 1)
12849 (xor:SI (match_dup 1) (match_dup 4)))
12850 (clobber (reg:CC FLAGS_REG))])
12852 [(set (reg:CC FLAGS_REG)
12853 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12854 (clobber (match_dup 1))
12855 (clobber (match_dup 2))])]
12857 operands[4] = gen_lowpart (SImode, operands[3]);
12861 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12862 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12865 operands[1] = gen_highpart (SImode, operands[3]);
12868 (define_insn_and_split "paritysi2_cmp"
12869 [(set (reg:CC FLAGS_REG)
12870 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12872 (clobber (match_scratch:SI 0 "=r"))
12873 (clobber (match_scratch:HI 1 "=&Q"))]
12876 "&& reload_completed"
12878 [(set (match_dup 1)
12879 (xor:HI (match_dup 1) (match_dup 3)))
12880 (clobber (reg:CC FLAGS_REG))])
12882 [(set (reg:CC FLAGS_REG)
12883 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12884 (clobber (match_dup 1))])]
12886 operands[3] = gen_lowpart (HImode, operands[2]);
12888 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12889 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12892 (define_insn "*parityhi2_cmp"
12893 [(set (reg:CC FLAGS_REG)
12894 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12896 (clobber (match_scratch:HI 0 "=Q"))]
12898 "xor{b}\t{%h0, %b0|%b0, %h0}"
12899 [(set_attr "length" "2")
12900 (set_attr "mode" "HI")])
12903 ;; Thread-local storage patterns for ELF.
12905 ;; Note that these code sequences must appear exactly as shown
12906 ;; in order to allow linker relaxation.
12908 (define_insn "*tls_global_dynamic_32_gnu"
12909 [(set (match_operand:SI 0 "register_operand" "=a")
12911 [(match_operand:SI 1 "register_operand" "b")
12912 (match_operand 2 "tls_symbolic_operand")
12913 (match_operand 3 "constant_call_address_operand" "Bz")
12916 (clobber (match_scratch:SI 4 "=d"))
12917 (clobber (match_scratch:SI 5 "=c"))
12918 (clobber (reg:CC FLAGS_REG))]
12919 "!TARGET_64BIT && TARGET_GNU_TLS"
12922 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12923 if (TARGET_SUN_TLS)
12924 #ifdef HAVE_AS_IX86_TLSGDPLT
12925 return "call\t%a2@tlsgdplt";
12927 return "call\t%p3@plt";
12929 return "call\t%P3";
12931 [(set_attr "type" "multi")
12932 (set_attr "length" "12")])
12934 (define_expand "tls_global_dynamic_32"
12936 [(set (match_operand:SI 0 "register_operand")
12937 (unspec:SI [(match_operand:SI 2 "register_operand")
12938 (match_operand 1 "tls_symbolic_operand")
12939 (match_operand 3 "constant_call_address_operand")
12942 (clobber (match_scratch:SI 4))
12943 (clobber (match_scratch:SI 5))
12944 (clobber (reg:CC FLAGS_REG))])]
12946 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12948 (define_insn "*tls_global_dynamic_64_<mode>"
12949 [(set (match_operand:P 0 "register_operand" "=a")
12951 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12952 (match_operand 3)))
12953 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12958 fputs (ASM_BYTE "0x66\n", asm_out_file);
12960 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12961 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12962 fputs ("\trex64\n", asm_out_file);
12963 if (TARGET_SUN_TLS)
12964 return "call\t%p2@plt";
12965 return "call\t%P2";
12967 [(set_attr "type" "multi")
12968 (set (attr "length")
12969 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12971 (define_insn "*tls_global_dynamic_64_largepic"
12972 [(set (match_operand:DI 0 "register_operand" "=a")
12974 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12975 (match_operand:DI 3 "immediate_operand" "i")))
12976 (match_operand 4)))
12977 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12979 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12980 && GET_CODE (operands[3]) == CONST
12981 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12982 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12985 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12986 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12987 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12988 return "call\t{*%%rax|rax}";
12990 [(set_attr "type" "multi")
12991 (set_attr "length" "22")])
12993 (define_expand "tls_global_dynamic_64_<mode>"
12995 [(set (match_operand:P 0 "register_operand")
12997 (mem:QI (match_operand 2))
12999 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13002 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13004 (define_insn "*tls_local_dynamic_base_32_gnu"
13005 [(set (match_operand:SI 0 "register_operand" "=a")
13007 [(match_operand:SI 1 "register_operand" "b")
13008 (match_operand 2 "constant_call_address_operand" "Bz")
13010 UNSPEC_TLS_LD_BASE))
13011 (clobber (match_scratch:SI 3 "=d"))
13012 (clobber (match_scratch:SI 4 "=c"))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "!TARGET_64BIT && TARGET_GNU_TLS"
13017 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13018 if (TARGET_SUN_TLS)
13020 if (HAVE_AS_IX86_TLSLDMPLT)
13021 return "call\t%&@tlsldmplt";
13023 return "call\t%p2@plt";
13025 return "call\t%P2";
13027 [(set_attr "type" "multi")
13028 (set_attr "length" "11")])
13030 (define_expand "tls_local_dynamic_base_32"
13032 [(set (match_operand:SI 0 "register_operand")
13034 [(match_operand:SI 1 "register_operand")
13035 (match_operand 2 "constant_call_address_operand")
13037 UNSPEC_TLS_LD_BASE))
13038 (clobber (match_scratch:SI 3))
13039 (clobber (match_scratch:SI 4))
13040 (clobber (reg:CC FLAGS_REG))])]
13042 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13044 (define_insn "*tls_local_dynamic_base_64_<mode>"
13045 [(set (match_operand:P 0 "register_operand" "=a")
13047 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13048 (match_operand 2)))
13049 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13053 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13054 if (TARGET_SUN_TLS)
13055 return "call\t%p1@plt";
13056 return "call\t%P1";
13058 [(set_attr "type" "multi")
13059 (set_attr "length" "12")])
13061 (define_insn "*tls_local_dynamic_base_64_largepic"
13062 [(set (match_operand:DI 0 "register_operand" "=a")
13064 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13065 (match_operand:DI 2 "immediate_operand" "i")))
13066 (match_operand 3)))
13067 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13068 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13069 && GET_CODE (operands[2]) == CONST
13070 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13071 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13074 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13075 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13076 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13077 return "call\t{*%%rax|rax}";
13079 [(set_attr "type" "multi")
13080 (set_attr "length" "22")])
13082 (define_expand "tls_local_dynamic_base_64_<mode>"
13084 [(set (match_operand:P 0 "register_operand")
13086 (mem:QI (match_operand 1))
13088 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13090 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13092 ;; Local dynamic of a single variable is a lose. Show combine how
13093 ;; to convert that back to global dynamic.
13095 (define_insn_and_split "*tls_local_dynamic_32_once"
13096 [(set (match_operand:SI 0 "register_operand" "=a")
13098 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13099 (match_operand 2 "constant_call_address_operand" "Bz")
13101 UNSPEC_TLS_LD_BASE)
13102 (const:SI (unspec:SI
13103 [(match_operand 3 "tls_symbolic_operand")]
13105 (clobber (match_scratch:SI 4 "=d"))
13106 (clobber (match_scratch:SI 5 "=c"))
13107 (clobber (reg:CC FLAGS_REG))]
13112 [(set (match_dup 0)
13113 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13116 (clobber (match_dup 4))
13117 (clobber (match_dup 5))
13118 (clobber (reg:CC FLAGS_REG))])])
13120 ;; Segment register for the thread base ptr load
13121 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13123 ;; Load and add the thread base pointer from %<tp_seg>:0.
13124 (define_insn "*load_tp_x32"
13125 [(set (match_operand:SI 0 "register_operand" "=r")
13126 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13128 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13129 [(set_attr "type" "imov")
13130 (set_attr "modrm" "0")
13131 (set_attr "length" "7")
13132 (set_attr "memory" "load")
13133 (set_attr "imm_disp" "false")])
13135 (define_insn "*load_tp_x32_zext"
13136 [(set (match_operand:DI 0 "register_operand" "=r")
13137 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13139 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13140 [(set_attr "type" "imov")
13141 (set_attr "modrm" "0")
13142 (set_attr "length" "7")
13143 (set_attr "memory" "load")
13144 (set_attr "imm_disp" "false")])
13146 (define_insn "*load_tp_<mode>"
13147 [(set (match_operand:P 0 "register_operand" "=r")
13148 (unspec:P [(const_int 0)] UNSPEC_TP))]
13150 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13151 [(set_attr "type" "imov")
13152 (set_attr "modrm" "0")
13153 (set_attr "length" "7")
13154 (set_attr "memory" "load")
13155 (set_attr "imm_disp" "false")])
13157 (define_insn "*add_tp_x32"
13158 [(set (match_operand:SI 0 "register_operand" "=r")
13159 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13160 (match_operand:SI 1 "register_operand" "0")))
13161 (clobber (reg:CC FLAGS_REG))]
13163 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13164 [(set_attr "type" "alu")
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_zext"
13171 [(set (match_operand:DI 0 "register_operand" "=r")
13173 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13174 (match_operand:SI 1 "register_operand" "0"))))
13175 (clobber (reg:CC FLAGS_REG))]
13177 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13178 [(set_attr "type" "alu")
13179 (set_attr "modrm" "0")
13180 (set_attr "length" "7")
13181 (set_attr "memory" "load")
13182 (set_attr "imm_disp" "false")])
13184 (define_insn "*add_tp_<mode>"
13185 [(set (match_operand:P 0 "register_operand" "=r")
13186 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13187 (match_operand:P 1 "register_operand" "0")))
13188 (clobber (reg:CC FLAGS_REG))]
13190 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>: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 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13198 ;; %rax as destination of the initial executable code sequence.
13199 (define_insn "tls_initial_exec_64_sun"
13200 [(set (match_operand:DI 0 "register_operand" "=a")
13202 [(match_operand 1 "tls_symbolic_operand")]
13203 UNSPEC_TLS_IE_SUN))
13204 (clobber (reg:CC FLAGS_REG))]
13205 "TARGET_64BIT && TARGET_SUN_TLS"
13208 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13209 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13211 [(set_attr "type" "multi")])
13213 ;; GNU2 TLS patterns can be split.
13215 (define_expand "tls_dynamic_gnu2_32"
13216 [(set (match_dup 3)
13217 (plus:SI (match_operand:SI 2 "register_operand")
13219 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13222 [(set (match_operand:SI 0 "register_operand")
13223 (unspec:SI [(match_dup 1) (match_dup 3)
13224 (match_dup 2) (reg:SI SP_REG)]
13226 (clobber (reg:CC FLAGS_REG))])]
13227 "!TARGET_64BIT && TARGET_GNU2_TLS"
13229 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13230 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13233 (define_insn "*tls_dynamic_gnu2_lea_32"
13234 [(set (match_operand:SI 0 "register_operand" "=r")
13235 (plus:SI (match_operand:SI 1 "register_operand" "b")
13237 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13238 UNSPEC_TLSDESC))))]
13239 "!TARGET_64BIT && TARGET_GNU2_TLS"
13240 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13241 [(set_attr "type" "lea")
13242 (set_attr "mode" "SI")
13243 (set_attr "length" "6")
13244 (set_attr "length_address" "4")])
13246 (define_insn "*tls_dynamic_gnu2_call_32"
13247 [(set (match_operand:SI 0 "register_operand" "=a")
13248 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13249 (match_operand:SI 2 "register_operand" "0")
13250 ;; we have to make sure %ebx still points to the GOT
13251 (match_operand:SI 3 "register_operand" "b")
13254 (clobber (reg:CC FLAGS_REG))]
13255 "!TARGET_64BIT && TARGET_GNU2_TLS"
13256 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13257 [(set_attr "type" "call")
13258 (set_attr "length" "2")
13259 (set_attr "length_address" "0")])
13261 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13262 [(set (match_operand:SI 0 "register_operand" "=&a")
13264 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13265 (match_operand:SI 4)
13266 (match_operand:SI 2 "register_operand" "b")
13269 (const:SI (unspec:SI
13270 [(match_operand 1 "tls_symbolic_operand")]
13272 (clobber (reg:CC FLAGS_REG))]
13273 "!TARGET_64BIT && TARGET_GNU2_TLS"
13276 [(set (match_dup 0) (match_dup 5))]
13278 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13279 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13282 (define_expand "tls_dynamic_gnu2_64"
13283 [(set (match_dup 2)
13284 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13287 [(set (match_operand:DI 0 "register_operand")
13288 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13290 (clobber (reg:CC FLAGS_REG))])]
13291 "TARGET_64BIT && TARGET_GNU2_TLS"
13293 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13294 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13297 (define_insn "*tls_dynamic_gnu2_lea_64"
13298 [(set (match_operand:DI 0 "register_operand" "=r")
13299 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13301 "TARGET_64BIT && TARGET_GNU2_TLS"
13302 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13303 [(set_attr "type" "lea")
13304 (set_attr "mode" "DI")
13305 (set_attr "length" "7")
13306 (set_attr "length_address" "4")])
13308 (define_insn "*tls_dynamic_gnu2_call_64"
13309 [(set (match_operand:DI 0 "register_operand" "=a")
13310 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13311 (match_operand:DI 2 "register_operand" "0")
13314 (clobber (reg:CC FLAGS_REG))]
13315 "TARGET_64BIT && TARGET_GNU2_TLS"
13316 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13317 [(set_attr "type" "call")
13318 (set_attr "length" "2")
13319 (set_attr "length_address" "0")])
13321 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13322 [(set (match_operand:DI 0 "register_operand" "=&a")
13324 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13325 (match_operand:DI 3)
13328 (const:DI (unspec:DI
13329 [(match_operand 1 "tls_symbolic_operand")]
13331 (clobber (reg:CC FLAGS_REG))]
13332 "TARGET_64BIT && TARGET_GNU2_TLS"
13335 [(set (match_dup 0) (match_dup 4))]
13337 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13338 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13341 ;; These patterns match the binary 387 instructions for addM3, subM3,
13342 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13343 ;; SFmode. The first is the normal insn, the second the same insn but
13344 ;; with one operand a conversion, and the third the same insn but with
13345 ;; the other operand a conversion. The conversion may be SFmode or
13346 ;; SImode if the target mode DFmode, but only SImode if the target mode
13349 ;; Gcc is slightly more smart about handling normal two address instructions
13350 ;; so use special patterns for add and mull.
13352 (define_insn "*fop_<mode>_comm_mixed"
13353 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13354 (match_operator:MODEF 3 "binary_fp_operator"
13355 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13356 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13357 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13358 && COMMUTATIVE_ARITH_P (operands[3])
13359 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13360 "* return output_387_binary_op (insn, operands);"
13361 [(set (attr "type")
13362 (if_then_else (eq_attr "alternative" "1,2")
13363 (if_then_else (match_operand:MODEF 3 "mult_operator")
13364 (const_string "ssemul")
13365 (const_string "sseadd"))
13366 (if_then_else (match_operand:MODEF 3 "mult_operator")
13367 (const_string "fmul")
13368 (const_string "fop"))))
13369 (set_attr "isa" "*,noavx,avx")
13370 (set_attr "prefix" "orig,orig,vex")
13371 (set_attr "mode" "<MODE>")])
13373 (define_insn "*fop_<mode>_comm_sse"
13374 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13375 (match_operator:MODEF 3 "binary_fp_operator"
13376 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13377 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13378 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13379 && COMMUTATIVE_ARITH_P (operands[3])
13380 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13381 "* return output_387_binary_op (insn, operands);"
13382 [(set (attr "type")
13383 (if_then_else (match_operand:MODEF 3 "mult_operator")
13384 (const_string "ssemul")
13385 (const_string "sseadd")))
13386 (set_attr "isa" "noavx,avx")
13387 (set_attr "prefix" "orig,vex")
13388 (set_attr "mode" "<MODE>")])
13390 (define_insn "*fop_<mode>_comm_i387"
13391 [(set (match_operand:MODEF 0 "register_operand" "=f")
13392 (match_operator:MODEF 3 "binary_fp_operator"
13393 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13394 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13395 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13396 && COMMUTATIVE_ARITH_P (operands[3])
13397 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13398 "* return output_387_binary_op (insn, operands);"
13399 [(set (attr "type")
13400 (if_then_else (match_operand:MODEF 3 "mult_operator")
13401 (const_string "fmul")
13402 (const_string "fop")))
13403 (set_attr "mode" "<MODE>")])
13405 (define_insn "*fop_<mode>_1_mixed"
13406 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13407 (match_operator:MODEF 3 "binary_fp_operator"
13408 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13409 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13410 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13411 && !COMMUTATIVE_ARITH_P (operands[3])
13412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13413 "* return output_387_binary_op (insn, operands);"
13414 [(set (attr "type")
13415 (cond [(and (eq_attr "alternative" "2,3")
13416 (match_operand:MODEF 3 "mult_operator"))
13417 (const_string "ssemul")
13418 (and (eq_attr "alternative" "2,3")
13419 (match_operand:MODEF 3 "div_operator"))
13420 (const_string "ssediv")
13421 (eq_attr "alternative" "2,3")
13422 (const_string "sseadd")
13423 (match_operand:MODEF 3 "mult_operator")
13424 (const_string "fmul")
13425 (match_operand:MODEF 3 "div_operator")
13426 (const_string "fdiv")
13428 (const_string "fop")))
13429 (set_attr "isa" "*,*,noavx,avx")
13430 (set_attr "prefix" "orig,orig,orig,vex")
13431 (set_attr "mode" "<MODE>")])
13433 (define_insn "*rcpsf2_sse"
13434 [(set (match_operand:SF 0 "register_operand" "=x")
13435 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13438 "%vrcpss\t{%1, %d0|%d0, %1}"
13439 [(set_attr "type" "sse")
13440 (set_attr "atom_sse_attr" "rcp")
13441 (set_attr "btver2_sse_attr" "rcp")
13442 (set_attr "prefix" "maybe_vex")
13443 (set_attr "mode" "SF")])
13445 (define_insn "*fop_<mode>_1_sse"
13446 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13447 (match_operator:MODEF 3 "binary_fp_operator"
13448 [(match_operand:MODEF 1 "register_operand" "0,x")
13449 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13450 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13451 && !COMMUTATIVE_ARITH_P (operands[3])"
13452 "* return output_387_binary_op (insn, operands);"
13453 [(set (attr "type")
13454 (cond [(match_operand:MODEF 3 "mult_operator")
13455 (const_string "ssemul")
13456 (match_operand:MODEF 3 "div_operator")
13457 (const_string "ssediv")
13459 (const_string "sseadd")))
13460 (set_attr "isa" "noavx,avx")
13461 (set_attr "prefix" "orig,vex")
13462 (set_attr "mode" "<MODE>")])
13464 ;; This pattern is not fully shadowed by the pattern above.
13465 (define_insn "*fop_<mode>_1_i387"
13466 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13467 (match_operator:MODEF 3 "binary_fp_operator"
13468 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13469 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13470 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13471 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13472 && !COMMUTATIVE_ARITH_P (operands[3])
13473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13474 "* return output_387_binary_op (insn, operands);"
13475 [(set (attr "type")
13476 (cond [(match_operand:MODEF 3 "mult_operator")
13477 (const_string "fmul")
13478 (match_operand:MODEF 3 "div_operator")
13479 (const_string "fdiv")
13481 (const_string "fop")))
13482 (set_attr "mode" "<MODE>")])
13484 ;; ??? Add SSE splitters for these!
13485 (define_insn "*fop_<MODEF:mode>_2_i387"
13486 [(set (match_operand:MODEF 0 "register_operand" "=f")
13487 (match_operator:MODEF 3 "binary_fp_operator"
13489 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13490 (match_operand:MODEF 2 "register_operand" "0")]))]
13491 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13492 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13493 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13494 || optimize_function_for_size_p (cfun))"
13495 { return output_387_binary_op (insn, operands); }
13496 [(set (attr "type")
13497 (cond [(match_operand:MODEF 3 "mult_operator")
13498 (const_string "fmul")
13499 (match_operand:MODEF 3 "div_operator")
13500 (const_string "fdiv")
13502 (const_string "fop")))
13503 (set_attr "fp_int_src" "true")
13504 (set_attr "mode" "<SWI24:MODE>")])
13506 (define_insn "*fop_<MODEF:mode>_3_i387"
13507 [(set (match_operand:MODEF 0 "register_operand" "=f")
13508 (match_operator:MODEF 3 "binary_fp_operator"
13509 [(match_operand:MODEF 1 "register_operand" "0")
13511 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13512 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13513 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13514 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13515 || optimize_function_for_size_p (cfun))"
13516 { return output_387_binary_op (insn, operands); }
13517 [(set (attr "type")
13518 (cond [(match_operand:MODEF 3 "mult_operator")
13519 (const_string "fmul")
13520 (match_operand:MODEF 3 "div_operator")
13521 (const_string "fdiv")
13523 (const_string "fop")))
13524 (set_attr "fp_int_src" "true")
13525 (set_attr "mode" "<MODE>")])
13527 (define_insn "*fop_df_4_i387"
13528 [(set (match_operand:DF 0 "register_operand" "=f,f")
13529 (match_operator:DF 3 "binary_fp_operator"
13531 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13532 (match_operand:DF 2 "register_operand" "0,f")]))]
13533 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13534 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13535 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13536 "* return output_387_binary_op (insn, operands);"
13537 [(set (attr "type")
13538 (cond [(match_operand:DF 3 "mult_operator")
13539 (const_string "fmul")
13540 (match_operand:DF 3 "div_operator")
13541 (const_string "fdiv")
13543 (const_string "fop")))
13544 (set_attr "mode" "SF")])
13546 (define_insn "*fop_df_5_i387"
13547 [(set (match_operand:DF 0 "register_operand" "=f,f")
13548 (match_operator:DF 3 "binary_fp_operator"
13549 [(match_operand:DF 1 "register_operand" "0,f")
13551 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13552 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13553 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13554 "* return output_387_binary_op (insn, operands);"
13555 [(set (attr "type")
13556 (cond [(match_operand:DF 3 "mult_operator")
13557 (const_string "fmul")
13558 (match_operand:DF 3 "div_operator")
13559 (const_string "fdiv")
13561 (const_string "fop")))
13562 (set_attr "mode" "SF")])
13564 (define_insn "*fop_df_6_i387"
13565 [(set (match_operand:DF 0 "register_operand" "=f,f")
13566 (match_operator:DF 3 "binary_fp_operator"
13568 (match_operand:SF 1 "register_operand" "0,f"))
13570 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13571 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13572 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13573 "* return output_387_binary_op (insn, operands);"
13574 [(set (attr "type")
13575 (cond [(match_operand:DF 3 "mult_operator")
13576 (const_string "fmul")
13577 (match_operand:DF 3 "div_operator")
13578 (const_string "fdiv")
13580 (const_string "fop")))
13581 (set_attr "mode" "SF")])
13583 (define_insn "*fop_xf_comm_i387"
13584 [(set (match_operand:XF 0 "register_operand" "=f")
13585 (match_operator:XF 3 "binary_fp_operator"
13586 [(match_operand:XF 1 "register_operand" "%0")
13587 (match_operand:XF 2 "register_operand" "f")]))]
13589 && COMMUTATIVE_ARITH_P (operands[3])"
13590 "* return output_387_binary_op (insn, operands);"
13591 [(set (attr "type")
13592 (if_then_else (match_operand:XF 3 "mult_operator")
13593 (const_string "fmul")
13594 (const_string "fop")))
13595 (set_attr "mode" "XF")])
13597 (define_insn "*fop_xf_1_i387"
13598 [(set (match_operand:XF 0 "register_operand" "=f,f")
13599 (match_operator:XF 3 "binary_fp_operator"
13600 [(match_operand:XF 1 "register_operand" "0,f")
13601 (match_operand:XF 2 "register_operand" "f,0")]))]
13603 && !COMMUTATIVE_ARITH_P (operands[3])"
13604 "* return output_387_binary_op (insn, operands);"
13605 [(set (attr "type")
13606 (cond [(match_operand:XF 3 "mult_operator")
13607 (const_string "fmul")
13608 (match_operand:XF 3 "div_operator")
13609 (const_string "fdiv")
13611 (const_string "fop")))
13612 (set_attr "mode" "XF")])
13614 (define_insn "*fop_xf_2_i387"
13615 [(set (match_operand:XF 0 "register_operand" "=f")
13616 (match_operator:XF 3 "binary_fp_operator"
13618 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13619 (match_operand:XF 2 "register_operand" "0")]))]
13621 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13622 { return output_387_binary_op (insn, operands); }
13623 [(set (attr "type")
13624 (cond [(match_operand:XF 3 "mult_operator")
13625 (const_string "fmul")
13626 (match_operand:XF 3 "div_operator")
13627 (const_string "fdiv")
13629 (const_string "fop")))
13630 (set_attr "fp_int_src" "true")
13631 (set_attr "mode" "<MODE>")])
13633 (define_insn "*fop_xf_3_i387"
13634 [(set (match_operand:XF 0 "register_operand" "=f")
13635 (match_operator:XF 3 "binary_fp_operator"
13636 [(match_operand:XF 1 "register_operand" "0")
13638 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13640 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13641 { return output_387_binary_op (insn, operands); }
13642 [(set (attr "type")
13643 (cond [(match_operand:XF 3 "mult_operator")
13644 (const_string "fmul")
13645 (match_operand:XF 3 "div_operator")
13646 (const_string "fdiv")
13648 (const_string "fop")))
13649 (set_attr "fp_int_src" "true")
13650 (set_attr "mode" "<MODE>")])
13652 (define_insn "*fop_xf_4_i387"
13653 [(set (match_operand:XF 0 "register_operand" "=f,f")
13654 (match_operator:XF 3 "binary_fp_operator"
13656 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13657 (match_operand:XF 2 "register_operand" "0,f")]))]
13659 "* return output_387_binary_op (insn, operands);"
13660 [(set (attr "type")
13661 (cond [(match_operand:XF 3 "mult_operator")
13662 (const_string "fmul")
13663 (match_operand:XF 3 "div_operator")
13664 (const_string "fdiv")
13666 (const_string "fop")))
13667 (set_attr "mode" "<MODE>")])
13669 (define_insn "*fop_xf_5_i387"
13670 [(set (match_operand:XF 0 "register_operand" "=f,f")
13671 (match_operator:XF 3 "binary_fp_operator"
13672 [(match_operand:XF 1 "register_operand" "0,f")
13674 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13676 "* return output_387_binary_op (insn, operands);"
13677 [(set (attr "type")
13678 (cond [(match_operand:XF 3 "mult_operator")
13679 (const_string "fmul")
13680 (match_operand:XF 3 "div_operator")
13681 (const_string "fdiv")
13683 (const_string "fop")))
13684 (set_attr "mode" "<MODE>")])
13686 (define_insn "*fop_xf_6_i387"
13687 [(set (match_operand:XF 0 "register_operand" "=f,f")
13688 (match_operator:XF 3 "binary_fp_operator"
13690 (match_operand:MODEF 1 "register_operand" "0,f"))
13692 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13694 "* return output_387_binary_op (insn, operands);"
13695 [(set (attr "type")
13696 (cond [(match_operand:XF 3 "mult_operator")
13697 (const_string "fmul")
13698 (match_operand:XF 3 "div_operator")
13699 (const_string "fdiv")
13701 (const_string "fop")))
13702 (set_attr "mode" "<MODE>")])
13704 ;; FPU special functions.
13706 ;; This pattern implements a no-op XFmode truncation for
13707 ;; all fancy i386 XFmode math functions.
13709 (define_insn "truncxf<mode>2_i387_noop_unspec"
13710 [(set (match_operand:MODEF 0 "register_operand" "=f")
13711 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13712 UNSPEC_TRUNC_NOOP))]
13713 "TARGET_USE_FANCY_MATH_387"
13714 "* return output_387_reg_move (insn, operands);"
13715 [(set_attr "type" "fmov")
13716 (set_attr "mode" "<MODE>")])
13718 (define_insn "sqrtxf2"
13719 [(set (match_operand:XF 0 "register_operand" "=f")
13720 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13721 "TARGET_USE_FANCY_MATH_387"
13723 [(set_attr "type" "fpspc")
13724 (set_attr "mode" "XF")
13725 (set_attr "athlon_decode" "direct")
13726 (set_attr "amdfam10_decode" "direct")
13727 (set_attr "bdver1_decode" "direct")])
13729 (define_insn "sqrt_extend<mode>xf2_i387"
13730 [(set (match_operand:XF 0 "register_operand" "=f")
13733 (match_operand:MODEF 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 "*rsqrtsf2_sse"
13743 [(set (match_operand:SF 0 "register_operand" "=x")
13744 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13747 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13748 [(set_attr "type" "sse")
13749 (set_attr "atom_sse_attr" "rcp")
13750 (set_attr "btver2_sse_attr" "rcp")
13751 (set_attr "prefix" "maybe_vex")
13752 (set_attr "mode" "SF")])
13754 (define_expand "rsqrtsf2"
13755 [(set (match_operand:SF 0 "register_operand")
13756 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13760 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13764 (define_insn "*sqrt<mode>2_sse"
13765 [(set (match_operand:MODEF 0 "register_operand" "=x")
13767 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13768 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13769 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13770 [(set_attr "type" "sse")
13771 (set_attr "atom_sse_attr" "sqrt")
13772 (set_attr "btver2_sse_attr" "sqrt")
13773 (set_attr "prefix" "maybe_vex")
13774 (set_attr "mode" "<MODE>")
13775 (set_attr "athlon_decode" "*")
13776 (set_attr "amdfam10_decode" "*")
13777 (set_attr "bdver1_decode" "*")])
13779 (define_expand "sqrt<mode>2"
13780 [(set (match_operand:MODEF 0 "register_operand")
13782 (match_operand:MODEF 1 "nonimmediate_operand")))]
13783 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13784 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13786 if (<MODE>mode == SFmode
13788 && TARGET_RECIP_SQRT
13789 && !optimize_function_for_size_p (cfun)
13790 && flag_finite_math_only && !flag_trapping_math
13791 && flag_unsafe_math_optimizations)
13793 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13797 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13799 rtx op0 = gen_reg_rtx (XFmode);
13800 rtx op1 = force_reg (<MODE>mode, operands[1]);
13802 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13803 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13808 (define_insn "fpremxf4_i387"
13809 [(set (match_operand:XF 0 "register_operand" "=f")
13810 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13811 (match_operand:XF 3 "register_operand" "1")]
13813 (set (match_operand:XF 1 "register_operand" "=u")
13814 (unspec:XF [(match_dup 2) (match_dup 3)]
13816 (set (reg:CCFP FPSR_REG)
13817 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13819 "TARGET_USE_FANCY_MATH_387
13820 && flag_finite_math_only"
13822 [(set_attr "type" "fpspc")
13823 (set_attr "mode" "XF")])
13825 (define_expand "fmodxf3"
13826 [(use (match_operand:XF 0 "register_operand"))
13827 (use (match_operand:XF 1 "general_operand"))
13828 (use (match_operand:XF 2 "general_operand"))]
13829 "TARGET_USE_FANCY_MATH_387
13830 && flag_finite_math_only"
13832 rtx_code_label *label = gen_label_rtx ();
13834 rtx op1 = gen_reg_rtx (XFmode);
13835 rtx op2 = gen_reg_rtx (XFmode);
13837 emit_move_insn (op2, operands[2]);
13838 emit_move_insn (op1, operands[1]);
13840 emit_label (label);
13841 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13842 ix86_emit_fp_unordered_jump (label);
13843 LABEL_NUSES (label) = 1;
13845 emit_move_insn (operands[0], op1);
13849 (define_expand "fmod<mode>3"
13850 [(use (match_operand:MODEF 0 "register_operand"))
13851 (use (match_operand:MODEF 1 "general_operand"))
13852 (use (match_operand:MODEF 2 "general_operand"))]
13853 "TARGET_USE_FANCY_MATH_387
13854 && flag_finite_math_only"
13856 rtx (*gen_truncxf) (rtx, rtx);
13858 rtx_code_label *label = gen_label_rtx ();
13860 rtx op1 = gen_reg_rtx (XFmode);
13861 rtx op2 = gen_reg_rtx (XFmode);
13863 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13866 emit_label (label);
13867 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13868 ix86_emit_fp_unordered_jump (label);
13869 LABEL_NUSES (label) = 1;
13871 /* Truncate the result properly for strict SSE math. */
13872 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13873 && !TARGET_MIX_SSE_I387)
13874 gen_truncxf = gen_truncxf<mode>2;
13876 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13878 emit_insn (gen_truncxf (operands[0], op1));
13882 (define_insn "fprem1xf4_i387"
13883 [(set (match_operand:XF 0 "register_operand" "=f")
13884 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13885 (match_operand:XF 3 "register_operand" "1")]
13887 (set (match_operand:XF 1 "register_operand" "=u")
13888 (unspec:XF [(match_dup 2) (match_dup 3)]
13890 (set (reg:CCFP FPSR_REG)
13891 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13893 "TARGET_USE_FANCY_MATH_387
13894 && flag_finite_math_only"
13896 [(set_attr "type" "fpspc")
13897 (set_attr "mode" "XF")])
13899 (define_expand "remainderxf3"
13900 [(use (match_operand:XF 0 "register_operand"))
13901 (use (match_operand:XF 1 "general_operand"))
13902 (use (match_operand:XF 2 "general_operand"))]
13903 "TARGET_USE_FANCY_MATH_387
13904 && flag_finite_math_only"
13906 rtx_code_label *label = gen_label_rtx ();
13908 rtx op1 = gen_reg_rtx (XFmode);
13909 rtx op2 = gen_reg_rtx (XFmode);
13911 emit_move_insn (op2, operands[2]);
13912 emit_move_insn (op1, operands[1]);
13914 emit_label (label);
13915 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13916 ix86_emit_fp_unordered_jump (label);
13917 LABEL_NUSES (label) = 1;
13919 emit_move_insn (operands[0], op1);
13923 (define_expand "remainder<mode>3"
13924 [(use (match_operand:MODEF 0 "register_operand"))
13925 (use (match_operand:MODEF 1 "general_operand"))
13926 (use (match_operand:MODEF 2 "general_operand"))]
13927 "TARGET_USE_FANCY_MATH_387
13928 && flag_finite_math_only"
13930 rtx (*gen_truncxf) (rtx, rtx);
13932 rtx_code_label *label = gen_label_rtx ();
13934 rtx op1 = gen_reg_rtx (XFmode);
13935 rtx op2 = gen_reg_rtx (XFmode);
13937 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13938 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13940 emit_label (label);
13942 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13943 ix86_emit_fp_unordered_jump (label);
13944 LABEL_NUSES (label) = 1;
13946 /* Truncate the result properly for strict SSE math. */
13947 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13948 && !TARGET_MIX_SSE_I387)
13949 gen_truncxf = gen_truncxf<mode>2;
13951 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13953 emit_insn (gen_truncxf (operands[0], op1));
13957 (define_int_iterator SINCOS
13961 (define_int_attr sincos
13962 [(UNSPEC_SIN "sin")
13963 (UNSPEC_COS "cos")])
13965 (define_insn "*<sincos>xf2_i387"
13966 [(set (match_operand:XF 0 "register_operand" "=f")
13967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13975 (define_insn "*<sincos>_extend<mode>xf2_i387"
13976 [(set (match_operand:XF 0 "register_operand" "=f")
13977 (unspec:XF [(float_extend:XF
13978 (match_operand:MODEF 1 "register_operand" "0"))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982 || TARGET_MIX_SSE_I387)
13983 && flag_unsafe_math_optimizations"
13985 [(set_attr "type" "fpspc")
13986 (set_attr "mode" "XF")])
13988 ;; When sincos pattern is defined, sin and cos builtin functions will be
13989 ;; expanded to sincos pattern with one of its outputs left unused.
13990 ;; CSE pass will figure out if two sincos patterns can be combined,
13991 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13992 ;; depending on the unused output.
13994 (define_insn "sincosxf3"
13995 [(set (match_operand:XF 0 "register_operand" "=f")
13996 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13997 UNSPEC_SINCOS_COS))
13998 (set (match_operand:XF 1 "register_operand" "=u")
13999 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14007 [(set (match_operand:XF 0 "register_operand")
14008 (unspec:XF [(match_operand:XF 2 "register_operand")]
14009 UNSPEC_SINCOS_COS))
14010 (set (match_operand:XF 1 "register_operand")
14011 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14012 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14013 && can_create_pseudo_p ()"
14014 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14017 [(set (match_operand:XF 0 "register_operand")
14018 (unspec:XF [(match_operand:XF 2 "register_operand")]
14019 UNSPEC_SINCOS_COS))
14020 (set (match_operand:XF 1 "register_operand")
14021 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14022 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14023 && can_create_pseudo_p ()"
14024 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14026 (define_insn "sincos_extend<mode>xf3_i387"
14027 [(set (match_operand:XF 0 "register_operand" "=f")
14028 (unspec:XF [(float_extend:XF
14029 (match_operand:MODEF 2 "register_operand" "0"))]
14030 UNSPEC_SINCOS_COS))
14031 (set (match_operand:XF 1 "register_operand" "=u")
14032 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14033 "TARGET_USE_FANCY_MATH_387
14034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14035 || TARGET_MIX_SSE_I387)
14036 && flag_unsafe_math_optimizations"
14038 [(set_attr "type" "fpspc")
14039 (set_attr "mode" "XF")])
14042 [(set (match_operand:XF 0 "register_operand")
14043 (unspec:XF [(float_extend:XF
14044 (match_operand:MODEF 2 "register_operand"))]
14045 UNSPEC_SINCOS_COS))
14046 (set (match_operand:XF 1 "register_operand")
14047 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14048 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14049 && can_create_pseudo_p ()"
14050 [(set (match_dup 1)
14051 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14054 [(set (match_operand:XF 0 "register_operand")
14055 (unspec:XF [(float_extend:XF
14056 (match_operand:MODEF 2 "register_operand"))]
14057 UNSPEC_SINCOS_COS))
14058 (set (match_operand:XF 1 "register_operand")
14059 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14060 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14061 && can_create_pseudo_p ()"
14062 [(set (match_dup 0)
14063 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14065 (define_expand "sincos<mode>3"
14066 [(use (match_operand:MODEF 0 "register_operand"))
14067 (use (match_operand:MODEF 1 "register_operand"))
14068 (use (match_operand:MODEF 2 "register_operand"))]
14069 "TARGET_USE_FANCY_MATH_387
14070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14071 || TARGET_MIX_SSE_I387)
14072 && flag_unsafe_math_optimizations"
14074 rtx op0 = gen_reg_rtx (XFmode);
14075 rtx op1 = gen_reg_rtx (XFmode);
14077 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14078 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14083 (define_insn "fptanxf4_i387"
14084 [(set (match_operand:XF 0 "register_operand" "=f")
14085 (match_operand:XF 3 "const_double_operand" "F"))
14086 (set (match_operand:XF 1 "register_operand" "=u")
14087 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14089 "TARGET_USE_FANCY_MATH_387
14090 && flag_unsafe_math_optimizations
14091 && standard_80387_constant_p (operands[3]) == 2"
14093 [(set_attr "type" "fpspc")
14094 (set_attr "mode" "XF")])
14096 (define_insn "fptan_extend<mode>xf4_i387"
14097 [(set (match_operand:MODEF 0 "register_operand" "=f")
14098 (match_operand:MODEF 3 "const_double_operand" "F"))
14099 (set (match_operand:XF 1 "register_operand" "=u")
14100 (unspec:XF [(float_extend:XF
14101 (match_operand:MODEF 2 "register_operand" "0"))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105 || TARGET_MIX_SSE_I387)
14106 && flag_unsafe_math_optimizations
14107 && standard_80387_constant_p (operands[3]) == 2"
14109 [(set_attr "type" "fpspc")
14110 (set_attr "mode" "XF")])
14112 (define_expand "tanxf2"
14113 [(use (match_operand:XF 0 "register_operand"))
14114 (use (match_operand:XF 1 "register_operand"))]
14115 "TARGET_USE_FANCY_MATH_387
14116 && flag_unsafe_math_optimizations"
14118 rtx one = gen_reg_rtx (XFmode);
14119 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14121 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14125 (define_expand "tan<mode>2"
14126 [(use (match_operand:MODEF 0 "register_operand"))
14127 (use (match_operand:MODEF 1 "register_operand"))]
14128 "TARGET_USE_FANCY_MATH_387
14129 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14130 || TARGET_MIX_SSE_I387)
14131 && flag_unsafe_math_optimizations"
14133 rtx op0 = gen_reg_rtx (XFmode);
14135 rtx one = gen_reg_rtx (<MODE>mode);
14136 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14138 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14139 operands[1], op2));
14140 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14144 (define_insn "*fpatanxf3_i387"
14145 [(set (match_operand:XF 0 "register_operand" "=f")
14146 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14147 (match_operand:XF 2 "register_operand" "u")]
14149 (clobber (match_scratch:XF 3 "=2"))]
14150 "TARGET_USE_FANCY_MATH_387
14151 && flag_unsafe_math_optimizations"
14153 [(set_attr "type" "fpspc")
14154 (set_attr "mode" "XF")])
14156 (define_insn "fpatan_extend<mode>xf3_i387"
14157 [(set (match_operand:XF 0 "register_operand" "=f")
14158 (unspec:XF [(float_extend:XF
14159 (match_operand:MODEF 1 "register_operand" "0"))
14161 (match_operand:MODEF 2 "register_operand" "u"))]
14163 (clobber (match_scratch:XF 3 "=2"))]
14164 "TARGET_USE_FANCY_MATH_387
14165 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14166 || TARGET_MIX_SSE_I387)
14167 && flag_unsafe_math_optimizations"
14169 [(set_attr "type" "fpspc")
14170 (set_attr "mode" "XF")])
14172 (define_expand "atan2xf3"
14173 [(parallel [(set (match_operand:XF 0 "register_operand")
14174 (unspec:XF [(match_operand:XF 2 "register_operand")
14175 (match_operand:XF 1 "register_operand")]
14177 (clobber (match_scratch:XF 3))])]
14178 "TARGET_USE_FANCY_MATH_387
14179 && flag_unsafe_math_optimizations")
14181 (define_expand "atan2<mode>3"
14182 [(use (match_operand:MODEF 0 "register_operand"))
14183 (use (match_operand:MODEF 1 "register_operand"))
14184 (use (match_operand:MODEF 2 "register_operand"))]
14185 "TARGET_USE_FANCY_MATH_387
14186 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14187 || TARGET_MIX_SSE_I387)
14188 && flag_unsafe_math_optimizations"
14190 rtx op0 = gen_reg_rtx (XFmode);
14192 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14193 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14197 (define_expand "atanxf2"
14198 [(parallel [(set (match_operand:XF 0 "register_operand")
14199 (unspec:XF [(match_dup 2)
14200 (match_operand:XF 1 "register_operand")]
14202 (clobber (match_scratch:XF 3))])]
14203 "TARGET_USE_FANCY_MATH_387
14204 && flag_unsafe_math_optimizations"
14206 operands[2] = gen_reg_rtx (XFmode);
14207 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14210 (define_expand "atan<mode>2"
14211 [(use (match_operand:MODEF 0 "register_operand"))
14212 (use (match_operand:MODEF 1 "register_operand"))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215 || TARGET_MIX_SSE_I387)
14216 && flag_unsafe_math_optimizations"
14218 rtx op0 = gen_reg_rtx (XFmode);
14220 rtx op2 = gen_reg_rtx (<MODE>mode);
14221 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14223 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14228 (define_expand "asinxf2"
14229 [(set (match_dup 2)
14230 (mult:XF (match_operand:XF 1 "register_operand")
14232 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14233 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14234 (parallel [(set (match_operand:XF 0 "register_operand")
14235 (unspec:XF [(match_dup 5) (match_dup 1)]
14237 (clobber (match_scratch:XF 6))])]
14238 "TARGET_USE_FANCY_MATH_387
14239 && flag_unsafe_math_optimizations"
14243 if (optimize_insn_for_size_p ())
14246 for (i = 2; i < 6; i++)
14247 operands[i] = gen_reg_rtx (XFmode);
14249 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14252 (define_expand "asin<mode>2"
14253 [(use (match_operand:MODEF 0 "register_operand"))
14254 (use (match_operand:MODEF 1 "general_operand"))]
14255 "TARGET_USE_FANCY_MATH_387
14256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14257 || TARGET_MIX_SSE_I387)
14258 && flag_unsafe_math_optimizations"
14260 rtx op0 = gen_reg_rtx (XFmode);
14261 rtx op1 = gen_reg_rtx (XFmode);
14263 if (optimize_insn_for_size_p ())
14266 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14267 emit_insn (gen_asinxf2 (op0, op1));
14268 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14272 (define_expand "acosxf2"
14273 [(set (match_dup 2)
14274 (mult:XF (match_operand:XF 1 "register_operand")
14276 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14277 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14278 (parallel [(set (match_operand:XF 0 "register_operand")
14279 (unspec:XF [(match_dup 1) (match_dup 5)]
14281 (clobber (match_scratch:XF 6))])]
14282 "TARGET_USE_FANCY_MATH_387
14283 && flag_unsafe_math_optimizations"
14287 if (optimize_insn_for_size_p ())
14290 for (i = 2; i < 6; i++)
14291 operands[i] = gen_reg_rtx (XFmode);
14293 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14296 (define_expand "acos<mode>2"
14297 [(use (match_operand:MODEF 0 "register_operand"))
14298 (use (match_operand:MODEF 1 "general_operand"))]
14299 "TARGET_USE_FANCY_MATH_387
14300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14301 || TARGET_MIX_SSE_I387)
14302 && flag_unsafe_math_optimizations"
14304 rtx op0 = gen_reg_rtx (XFmode);
14305 rtx op1 = gen_reg_rtx (XFmode);
14307 if (optimize_insn_for_size_p ())
14310 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14311 emit_insn (gen_acosxf2 (op0, op1));
14312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14316 (define_insn "fyl2xxf3_i387"
14317 [(set (match_operand:XF 0 "register_operand" "=f")
14318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14319 (match_operand:XF 2 "register_operand" "u")]
14321 (clobber (match_scratch:XF 3 "=2"))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations"
14325 [(set_attr "type" "fpspc")
14326 (set_attr "mode" "XF")])
14328 (define_insn "fyl2x_extend<mode>xf3_i387"
14329 [(set (match_operand:XF 0 "register_operand" "=f")
14330 (unspec:XF [(float_extend:XF
14331 (match_operand:MODEF 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 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337 || TARGET_MIX_SSE_I387)
14338 && flag_unsafe_math_optimizations"
14340 [(set_attr "type" "fpspc")
14341 (set_attr "mode" "XF")])
14343 (define_expand "logxf2"
14344 [(parallel [(set (match_operand:XF 0 "register_operand")
14345 (unspec:XF [(match_operand:XF 1 "register_operand")
14346 (match_dup 2)] UNSPEC_FYL2X))
14347 (clobber (match_scratch:XF 3))])]
14348 "TARGET_USE_FANCY_MATH_387
14349 && flag_unsafe_math_optimizations"
14351 operands[2] = gen_reg_rtx (XFmode);
14352 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14355 (define_expand "log<mode>2"
14356 [(use (match_operand:MODEF 0 "register_operand"))
14357 (use (match_operand:MODEF 1 "register_operand"))]
14358 "TARGET_USE_FANCY_MATH_387
14359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14360 || TARGET_MIX_SSE_I387)
14361 && flag_unsafe_math_optimizations"
14363 rtx op0 = gen_reg_rtx (XFmode);
14365 rtx op2 = gen_reg_rtx (XFmode);
14366 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14368 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14373 (define_expand "log10xf2"
14374 [(parallel [(set (match_operand:XF 0 "register_operand")
14375 (unspec:XF [(match_operand:XF 1 "register_operand")
14376 (match_dup 2)] UNSPEC_FYL2X))
14377 (clobber (match_scratch:XF 3))])]
14378 "TARGET_USE_FANCY_MATH_387
14379 && flag_unsafe_math_optimizations"
14381 operands[2] = gen_reg_rtx (XFmode);
14382 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14385 (define_expand "log10<mode>2"
14386 [(use (match_operand:MODEF 0 "register_operand"))
14387 (use (match_operand:MODEF 1 "register_operand"))]
14388 "TARGET_USE_FANCY_MATH_387
14389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14390 || TARGET_MIX_SSE_I387)
14391 && flag_unsafe_math_optimizations"
14393 rtx op0 = gen_reg_rtx (XFmode);
14395 rtx op2 = gen_reg_rtx (XFmode);
14396 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14398 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14403 (define_expand "log2xf2"
14404 [(parallel [(set (match_operand:XF 0 "register_operand")
14405 (unspec:XF [(match_operand:XF 1 "register_operand")
14406 (match_dup 2)] UNSPEC_FYL2X))
14407 (clobber (match_scratch:XF 3))])]
14408 "TARGET_USE_FANCY_MATH_387
14409 && flag_unsafe_math_optimizations"
14411 operands[2] = gen_reg_rtx (XFmode);
14412 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14415 (define_expand "log2<mode>2"
14416 [(use (match_operand:MODEF 0 "register_operand"))
14417 (use (match_operand:MODEF 1 "register_operand"))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14423 rtx op0 = gen_reg_rtx (XFmode);
14425 rtx op2 = gen_reg_rtx (XFmode);
14426 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14428 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14429 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14433 (define_insn "fyl2xp1xf3_i387"
14434 [(set (match_operand:XF 0 "register_operand" "=f")
14435 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14436 (match_operand:XF 2 "register_operand" "u")]
14438 (clobber (match_scratch:XF 3 "=2"))]
14439 "TARGET_USE_FANCY_MATH_387
14440 && flag_unsafe_math_optimizations"
14442 [(set_attr "type" "fpspc")
14443 (set_attr "mode" "XF")])
14445 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14446 [(set (match_operand:XF 0 "register_operand" "=f")
14447 (unspec:XF [(float_extend:XF
14448 (match_operand:MODEF 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 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14454 || TARGET_MIX_SSE_I387)
14455 && flag_unsafe_math_optimizations"
14457 [(set_attr "type" "fpspc")
14458 (set_attr "mode" "XF")])
14460 (define_expand "log1pxf2"
14461 [(use (match_operand:XF 0 "register_operand"))
14462 (use (match_operand:XF 1 "register_operand"))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations"
14466 if (optimize_insn_for_size_p ())
14469 ix86_emit_i387_log1p (operands[0], operands[1]);
14473 (define_expand "log1p<mode>2"
14474 [(use (match_operand:MODEF 0 "register_operand"))
14475 (use (match_operand:MODEF 1 "register_operand"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478 || TARGET_MIX_SSE_I387)
14479 && flag_unsafe_math_optimizations"
14483 if (optimize_insn_for_size_p ())
14486 op0 = gen_reg_rtx (XFmode);
14488 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14490 ix86_emit_i387_log1p (op0, operands[1]);
14491 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14495 (define_insn "fxtractxf3_i387"
14496 [(set (match_operand:XF 0 "register_operand" "=f")
14497 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14498 UNSPEC_XTRACT_FRACT))
14499 (set (match_operand:XF 1 "register_operand" "=u")
14500 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14501 "TARGET_USE_FANCY_MATH_387
14502 && flag_unsafe_math_optimizations"
14504 [(set_attr "type" "fpspc")
14505 (set_attr "mode" "XF")])
14507 (define_insn "fxtract_extend<mode>xf3_i387"
14508 [(set (match_operand:XF 0 "register_operand" "=f")
14509 (unspec:XF [(float_extend:XF
14510 (match_operand:MODEF 2 "register_operand" "0"))]
14511 UNSPEC_XTRACT_FRACT))
14512 (set (match_operand:XF 1 "register_operand" "=u")
14513 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14514 "TARGET_USE_FANCY_MATH_387
14515 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14516 || TARGET_MIX_SSE_I387)
14517 && flag_unsafe_math_optimizations"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "XF")])
14522 (define_expand "logbxf2"
14523 [(parallel [(set (match_dup 2)
14524 (unspec:XF [(match_operand:XF 1 "register_operand")]
14525 UNSPEC_XTRACT_FRACT))
14526 (set (match_operand:XF 0 "register_operand")
14527 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14528 "TARGET_USE_FANCY_MATH_387
14529 && flag_unsafe_math_optimizations"
14530 "operands[2] = gen_reg_rtx (XFmode);")
14532 (define_expand "logb<mode>2"
14533 [(use (match_operand:MODEF 0 "register_operand"))
14534 (use (match_operand:MODEF 1 "register_operand"))]
14535 "TARGET_USE_FANCY_MATH_387
14536 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14537 || TARGET_MIX_SSE_I387)
14538 && flag_unsafe_math_optimizations"
14540 rtx op0 = gen_reg_rtx (XFmode);
14541 rtx op1 = gen_reg_rtx (XFmode);
14543 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14544 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14548 (define_expand "ilogbxf2"
14549 [(use (match_operand:SI 0 "register_operand"))
14550 (use (match_operand:XF 1 "register_operand"))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14556 if (optimize_insn_for_size_p ())
14559 op0 = gen_reg_rtx (XFmode);
14560 op1 = gen_reg_rtx (XFmode);
14562 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14563 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14567 (define_expand "ilogb<mode>2"
14568 [(use (match_operand:SI 0 "register_operand"))
14569 (use (match_operand:MODEF 1 "register_operand"))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572 || TARGET_MIX_SSE_I387)
14573 && flag_unsafe_math_optimizations"
14577 if (optimize_insn_for_size_p ())
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14583 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14584 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14588 (define_insn "*f2xm1xf2_i387"
14589 [(set (match_operand:XF 0 "register_operand" "=f")
14590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14595 [(set_attr "type" "fpspc")
14596 (set_attr "mode" "XF")])
14598 (define_insn "fscalexf4_i387"
14599 [(set (match_operand:XF 0 "register_operand" "=f")
14600 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14601 (match_operand:XF 3 "register_operand" "1")]
14602 UNSPEC_FSCALE_FRACT))
14603 (set (match_operand:XF 1 "register_operand" "=u")
14604 (unspec:XF [(match_dup 2) (match_dup 3)]
14605 UNSPEC_FSCALE_EXP))]
14606 "TARGET_USE_FANCY_MATH_387
14607 && flag_unsafe_math_optimizations"
14609 [(set_attr "type" "fpspc")
14610 (set_attr "mode" "XF")])
14612 (define_expand "expNcorexf3"
14613 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14614 (match_operand:XF 2 "register_operand")))
14615 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14616 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14617 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14618 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14619 (parallel [(set (match_operand:XF 0 "register_operand")
14620 (unspec:XF [(match_dup 8) (match_dup 4)]
14621 UNSPEC_FSCALE_FRACT))
14623 (unspec:XF [(match_dup 8) (match_dup 4)]
14624 UNSPEC_FSCALE_EXP))])]
14625 "TARGET_USE_FANCY_MATH_387
14626 && flag_unsafe_math_optimizations"
14630 if (optimize_insn_for_size_p ())
14633 for (i = 3; i < 10; i++)
14634 operands[i] = gen_reg_rtx (XFmode);
14636 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14639 (define_expand "expxf2"
14640 [(use (match_operand:XF 0 "register_operand"))
14641 (use (match_operand:XF 1 "register_operand"))]
14642 "TARGET_USE_FANCY_MATH_387
14643 && flag_unsafe_math_optimizations"
14647 if (optimize_insn_for_size_p ())
14650 op2 = gen_reg_rtx (XFmode);
14651 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14653 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14657 (define_expand "exp<mode>2"
14658 [(use (match_operand:MODEF 0 "register_operand"))
14659 (use (match_operand:MODEF 1 "general_operand"))]
14660 "TARGET_USE_FANCY_MATH_387
14661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14662 || TARGET_MIX_SSE_I387)
14663 && flag_unsafe_math_optimizations"
14667 if (optimize_insn_for_size_p ())
14670 op0 = gen_reg_rtx (XFmode);
14671 op1 = gen_reg_rtx (XFmode);
14673 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14674 emit_insn (gen_expxf2 (op0, op1));
14675 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14679 (define_expand "exp10xf2"
14680 [(use (match_operand:XF 0 "register_operand"))
14681 (use (match_operand:XF 1 "register_operand"))]
14682 "TARGET_USE_FANCY_MATH_387
14683 && flag_unsafe_math_optimizations"
14687 if (optimize_insn_for_size_p ())
14690 op2 = gen_reg_rtx (XFmode);
14691 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14693 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14697 (define_expand "exp10<mode>2"
14698 [(use (match_operand:MODEF 0 "register_operand"))
14699 (use (match_operand:MODEF 1 "general_operand"))]
14700 "TARGET_USE_FANCY_MATH_387
14701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14702 || TARGET_MIX_SSE_I387)
14703 && flag_unsafe_math_optimizations"
14707 if (optimize_insn_for_size_p ())
14710 op0 = gen_reg_rtx (XFmode);
14711 op1 = gen_reg_rtx (XFmode);
14713 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14714 emit_insn (gen_exp10xf2 (op0, op1));
14715 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14719 (define_expand "exp2xf2"
14720 [(use (match_operand:XF 0 "register_operand"))
14721 (use (match_operand:XF 1 "register_operand"))]
14722 "TARGET_USE_FANCY_MATH_387
14723 && flag_unsafe_math_optimizations"
14727 if (optimize_insn_for_size_p ())
14730 op2 = gen_reg_rtx (XFmode);
14731 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14733 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14737 (define_expand "exp2<mode>2"
14738 [(use (match_operand:MODEF 0 "register_operand"))
14739 (use (match_operand:MODEF 1 "general_operand"))]
14740 "TARGET_USE_FANCY_MATH_387
14741 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14742 || TARGET_MIX_SSE_I387)
14743 && flag_unsafe_math_optimizations"
14747 if (optimize_insn_for_size_p ())
14750 op0 = gen_reg_rtx (XFmode);
14751 op1 = gen_reg_rtx (XFmode);
14753 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14754 emit_insn (gen_exp2xf2 (op0, op1));
14755 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14759 (define_expand "expm1xf2"
14760 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14762 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14763 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14764 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14765 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14766 (parallel [(set (match_dup 7)
14767 (unspec:XF [(match_dup 6) (match_dup 4)]
14768 UNSPEC_FSCALE_FRACT))
14770 (unspec:XF [(match_dup 6) (match_dup 4)]
14771 UNSPEC_FSCALE_EXP))])
14772 (parallel [(set (match_dup 10)
14773 (unspec:XF [(match_dup 9) (match_dup 8)]
14774 UNSPEC_FSCALE_FRACT))
14775 (set (match_dup 11)
14776 (unspec:XF [(match_dup 9) (match_dup 8)]
14777 UNSPEC_FSCALE_EXP))])
14778 (set (match_dup 12) (minus:XF (match_dup 10)
14779 (float_extend:XF (match_dup 13))))
14780 (set (match_operand:XF 0 "register_operand")
14781 (plus:XF (match_dup 12) (match_dup 7)))]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14787 if (optimize_insn_for_size_p ())
14790 for (i = 2; i < 13; i++)
14791 operands[i] = gen_reg_rtx (XFmode);
14794 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14796 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14799 (define_expand "expm1<mode>2"
14800 [(use (match_operand:MODEF 0 "register_operand"))
14801 (use (match_operand:MODEF 1 "general_operand"))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14804 || TARGET_MIX_SSE_I387)
14805 && flag_unsafe_math_optimizations"
14809 if (optimize_insn_for_size_p ())
14812 op0 = gen_reg_rtx (XFmode);
14813 op1 = gen_reg_rtx (XFmode);
14815 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14816 emit_insn (gen_expm1xf2 (op0, op1));
14817 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14821 (define_expand "ldexpxf3"
14822 [(match_operand:XF 0 "register_operand")
14823 (match_operand:XF 1 "register_operand")
14824 (match_operand:SI 2 "register_operand")]
14825 "TARGET_USE_FANCY_MATH_387
14826 && flag_unsafe_math_optimizations"
14829 if (optimize_insn_for_size_p ())
14832 tmp1 = gen_reg_rtx (XFmode);
14833 tmp2 = gen_reg_rtx (XFmode);
14835 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14836 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14837 operands[1], tmp1));
14841 (define_expand "ldexp<mode>3"
14842 [(use (match_operand:MODEF 0 "register_operand"))
14843 (use (match_operand:MODEF 1 "general_operand"))
14844 (use (match_operand:SI 2 "register_operand"))]
14845 "TARGET_USE_FANCY_MATH_387
14846 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14847 || TARGET_MIX_SSE_I387)
14848 && flag_unsafe_math_optimizations"
14852 if (optimize_insn_for_size_p ())
14855 op0 = gen_reg_rtx (XFmode);
14856 op1 = gen_reg_rtx (XFmode);
14858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14859 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14860 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14864 (define_expand "scalbxf3"
14865 [(parallel [(set (match_operand:XF 0 " register_operand")
14866 (unspec:XF [(match_operand:XF 1 "register_operand")
14867 (match_operand:XF 2 "register_operand")]
14868 UNSPEC_FSCALE_FRACT))
14870 (unspec:XF [(match_dup 1) (match_dup 2)]
14871 UNSPEC_FSCALE_EXP))])]
14872 "TARGET_USE_FANCY_MATH_387
14873 && flag_unsafe_math_optimizations"
14875 if (optimize_insn_for_size_p ())
14878 operands[3] = gen_reg_rtx (XFmode);
14881 (define_expand "scalb<mode>3"
14882 [(use (match_operand:MODEF 0 "register_operand"))
14883 (use (match_operand:MODEF 1 "general_operand"))
14884 (use (match_operand:MODEF 2 "general_operand"))]
14885 "TARGET_USE_FANCY_MATH_387
14886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14887 || TARGET_MIX_SSE_I387)
14888 && flag_unsafe_math_optimizations"
14892 if (optimize_insn_for_size_p ())
14895 op0 = gen_reg_rtx (XFmode);
14896 op1 = gen_reg_rtx (XFmode);
14897 op2 = gen_reg_rtx (XFmode);
14899 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14900 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14901 emit_insn (gen_scalbxf3 (op0, op1, op2));
14902 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14906 (define_expand "significandxf2"
14907 [(parallel [(set (match_operand:XF 0 "register_operand")
14908 (unspec:XF [(match_operand:XF 1 "register_operand")]
14909 UNSPEC_XTRACT_FRACT))
14911 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 "operands[2] = gen_reg_rtx (XFmode);")
14916 (define_expand "significand<mode>2"
14917 [(use (match_operand:MODEF 0 "register_operand"))
14918 (use (match_operand:MODEF 1 "register_operand"))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14921 || TARGET_MIX_SSE_I387)
14922 && flag_unsafe_math_optimizations"
14924 rtx op0 = gen_reg_rtx (XFmode);
14925 rtx op1 = gen_reg_rtx (XFmode);
14927 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14933 (define_insn "sse4_1_round<mode>2"
14934 [(set (match_operand:MODEF 0 "register_operand" "=x")
14935 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14936 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14939 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14940 [(set_attr "type" "ssecvt")
14941 (set_attr "prefix_extra" "1")
14942 (set_attr "prefix" "maybe_vex")
14943 (set_attr "mode" "<MODE>")])
14945 (define_insn "rintxf2"
14946 [(set (match_operand:XF 0 "register_operand" "=f")
14947 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14949 "TARGET_USE_FANCY_MATH_387
14950 && flag_unsafe_math_optimizations"
14952 [(set_attr "type" "fpspc")
14953 (set_attr "mode" "XF")])
14955 (define_expand "rint<mode>2"
14956 [(use (match_operand:MODEF 0 "register_operand"))
14957 (use (match_operand:MODEF 1 "register_operand"))]
14958 "(TARGET_USE_FANCY_MATH_387
14959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14960 || TARGET_MIX_SSE_I387)
14961 && flag_unsafe_math_optimizations)
14962 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14963 && !flag_trapping_math)"
14965 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14966 && !flag_trapping_math)
14969 emit_insn (gen_sse4_1_round<mode>2
14970 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14971 else if (optimize_insn_for_size_p ())
14974 ix86_expand_rint (operands[0], operands[1]);
14978 rtx op0 = gen_reg_rtx (XFmode);
14979 rtx op1 = gen_reg_rtx (XFmode);
14981 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14982 emit_insn (gen_rintxf2 (op0, op1));
14984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14989 (define_expand "round<mode>2"
14990 [(match_operand:X87MODEF 0 "register_operand")
14991 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14992 "(TARGET_USE_FANCY_MATH_387
14993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14994 || TARGET_MIX_SSE_I387)
14995 && flag_unsafe_math_optimizations)
14996 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14997 && !flag_trapping_math && !flag_rounding_math)"
14999 if (optimize_insn_for_size_p ())
15002 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15003 && !flag_trapping_math && !flag_rounding_math)
15007 operands[1] = force_reg (<MODE>mode, operands[1]);
15008 ix86_expand_round_sse4 (operands[0], operands[1]);
15010 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15011 ix86_expand_round (operands[0], operands[1]);
15013 ix86_expand_rounddf_32 (operands[0], operands[1]);
15017 operands[1] = force_reg (<MODE>mode, operands[1]);
15018 ix86_emit_i387_round (operands[0], operands[1]);
15023 (define_insn_and_split "*fistdi2_1"
15024 [(set (match_operand:DI 0 "nonimmediate_operand")
15025 (unspec:DI [(match_operand:XF 1 "register_operand")]
15027 "TARGET_USE_FANCY_MATH_387
15028 && can_create_pseudo_p ()"
15033 if (memory_operand (operands[0], VOIDmode))
15034 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15037 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15038 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15043 [(set_attr "type" "fpspc")
15044 (set_attr "mode" "DI")])
15046 (define_insn "fistdi2"
15047 [(set (match_operand:DI 0 "memory_operand" "=m")
15048 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15050 (clobber (match_scratch:XF 2 "=&1f"))]
15051 "TARGET_USE_FANCY_MATH_387"
15052 "* return output_fix_trunc (insn, operands, false);"
15053 [(set_attr "type" "fpspc")
15054 (set_attr "mode" "DI")])
15056 (define_insn "fistdi2_with_temp"
15057 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15058 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15060 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15061 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15062 "TARGET_USE_FANCY_MATH_387"
15064 [(set_attr "type" "fpspc")
15065 (set_attr "mode" "DI")])
15068 [(set (match_operand:DI 0 "register_operand")
15069 (unspec:DI [(match_operand:XF 1 "register_operand")]
15071 (clobber (match_operand:DI 2 "memory_operand"))
15072 (clobber (match_scratch 3))]
15074 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15075 (clobber (match_dup 3))])
15076 (set (match_dup 0) (match_dup 2))])
15079 [(set (match_operand:DI 0 "memory_operand")
15080 (unspec:DI [(match_operand:XF 1 "register_operand")]
15082 (clobber (match_operand:DI 2 "memory_operand"))
15083 (clobber (match_scratch 3))]
15085 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15086 (clobber (match_dup 3))])])
15088 (define_insn_and_split "*fist<mode>2_1"
15089 [(set (match_operand:SWI24 0 "register_operand")
15090 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15092 "TARGET_USE_FANCY_MATH_387
15093 && can_create_pseudo_p ()"
15098 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15099 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15103 [(set_attr "type" "fpspc")
15104 (set_attr "mode" "<MODE>")])
15106 (define_insn "fist<mode>2"
15107 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15108 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15110 "TARGET_USE_FANCY_MATH_387"
15111 "* return output_fix_trunc (insn, operands, false);"
15112 [(set_attr "type" "fpspc")
15113 (set_attr "mode" "<MODE>")])
15115 (define_insn "fist<mode>2_with_temp"
15116 [(set (match_operand:SWI24 0 "register_operand" "=r")
15117 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15119 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15120 "TARGET_USE_FANCY_MATH_387"
15122 [(set_attr "type" "fpspc")
15123 (set_attr "mode" "<MODE>")])
15126 [(set (match_operand:SWI24 0 "register_operand")
15127 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15129 (clobber (match_operand:SWI24 2 "memory_operand"))]
15131 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15132 (set (match_dup 0) (match_dup 2))])
15135 [(set (match_operand:SWI24 0 "memory_operand")
15136 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15138 (clobber (match_operand:SWI24 2 "memory_operand"))]
15140 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15142 (define_expand "lrintxf<mode>2"
15143 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15144 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15146 "TARGET_USE_FANCY_MATH_387")
15148 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15149 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15150 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15151 UNSPEC_FIX_NOTRUNC))]
15152 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15154 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15155 [(match_operand:SWI248x 0 "nonimmediate_operand")
15156 (match_operand:X87MODEF 1 "register_operand")]
15157 "(TARGET_USE_FANCY_MATH_387
15158 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15159 || TARGET_MIX_SSE_I387)
15160 && flag_unsafe_math_optimizations)
15161 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15162 && <SWI248x:MODE>mode != HImode
15163 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15164 && !flag_trapping_math && !flag_rounding_math)"
15166 if (optimize_insn_for_size_p ())
15169 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15170 && <SWI248x:MODE>mode != HImode
15171 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15172 && !flag_trapping_math && !flag_rounding_math)
15173 ix86_expand_lround (operands[0], operands[1]);
15175 ix86_emit_i387_round (operands[0], operands[1]);
15179 (define_int_iterator FRNDINT_ROUNDING
15180 [UNSPEC_FRNDINT_FLOOR
15181 UNSPEC_FRNDINT_CEIL
15182 UNSPEC_FRNDINT_TRUNC])
15184 (define_int_iterator FIST_ROUNDING
15188 ;; Base name for define_insn
15189 (define_int_attr rounding_insn
15190 [(UNSPEC_FRNDINT_FLOOR "floor")
15191 (UNSPEC_FRNDINT_CEIL "ceil")
15192 (UNSPEC_FRNDINT_TRUNC "btrunc")
15193 (UNSPEC_FIST_FLOOR "floor")
15194 (UNSPEC_FIST_CEIL "ceil")])
15196 (define_int_attr rounding
15197 [(UNSPEC_FRNDINT_FLOOR "floor")
15198 (UNSPEC_FRNDINT_CEIL "ceil")
15199 (UNSPEC_FRNDINT_TRUNC "trunc")
15200 (UNSPEC_FIST_FLOOR "floor")
15201 (UNSPEC_FIST_CEIL "ceil")])
15203 (define_int_attr ROUNDING
15204 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15205 (UNSPEC_FRNDINT_CEIL "CEIL")
15206 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15207 (UNSPEC_FIST_FLOOR "FLOOR")
15208 (UNSPEC_FIST_CEIL "CEIL")])
15210 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15211 (define_insn_and_split "frndintxf2_<rounding>"
15212 [(set (match_operand:XF 0 "register_operand")
15213 (unspec:XF [(match_operand:XF 1 "register_operand")]
15215 (clobber (reg:CC FLAGS_REG))]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations
15218 && can_create_pseudo_p ()"
15223 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15225 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15226 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15228 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15229 operands[2], operands[3]));
15232 [(set_attr "type" "frndint")
15233 (set_attr "i387_cw" "<rounding>")
15234 (set_attr "mode" "XF")])
15236 (define_insn "frndintxf2_<rounding>_i387"
15237 [(set (match_operand:XF 0 "register_operand" "=f")
15238 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15240 (use (match_operand:HI 2 "memory_operand" "m"))
15241 (use (match_operand:HI 3 "memory_operand" "m"))]
15242 "TARGET_USE_FANCY_MATH_387
15243 && flag_unsafe_math_optimizations"
15244 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15245 [(set_attr "type" "frndint")
15246 (set_attr "i387_cw" "<rounding>")
15247 (set_attr "mode" "XF")])
15249 (define_expand "<rounding_insn>xf2"
15250 [(parallel [(set (match_operand:XF 0 "register_operand")
15251 (unspec:XF [(match_operand:XF 1 "register_operand")]
15253 (clobber (reg:CC FLAGS_REG))])]
15254 "TARGET_USE_FANCY_MATH_387
15255 && flag_unsafe_math_optimizations
15256 && !optimize_insn_for_size_p ()")
15258 (define_expand "<rounding_insn><mode>2"
15259 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15260 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15262 (clobber (reg:CC FLAGS_REG))])]
15263 "(TARGET_USE_FANCY_MATH_387
15264 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15265 || TARGET_MIX_SSE_I387)
15266 && flag_unsafe_math_optimizations)
15267 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15268 && !flag_trapping_math)"
15270 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15271 && !flag_trapping_math)
15274 emit_insn (gen_sse4_1_round<mode>2
15275 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15276 else if (optimize_insn_for_size_p ())
15278 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15280 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15281 ix86_expand_floorceil (operands[0], operands[1], true);
15282 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15283 ix86_expand_floorceil (operands[0], operands[1], false);
15284 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15285 ix86_expand_trunc (operands[0], operands[1]);
15287 gcc_unreachable ();
15291 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15292 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15293 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15294 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15295 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15296 ix86_expand_truncdf_32 (operands[0], operands[1]);
15298 gcc_unreachable ();
15305 if (optimize_insn_for_size_p ())
15308 op0 = gen_reg_rtx (XFmode);
15309 op1 = gen_reg_rtx (XFmode);
15310 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15311 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15313 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15318 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15319 (define_insn_and_split "frndintxf2_mask_pm"
15320 [(set (match_operand:XF 0 "register_operand")
15321 (unspec:XF [(match_operand:XF 1 "register_operand")]
15322 UNSPEC_FRNDINT_MASK_PM))
15323 (clobber (reg:CC FLAGS_REG))]
15324 "TARGET_USE_FANCY_MATH_387
15325 && flag_unsafe_math_optimizations
15326 && can_create_pseudo_p ()"
15331 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15333 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15334 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15336 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15337 operands[2], operands[3]));
15340 [(set_attr "type" "frndint")
15341 (set_attr "i387_cw" "mask_pm")
15342 (set_attr "mode" "XF")])
15344 (define_insn "frndintxf2_mask_pm_i387"
15345 [(set (match_operand:XF 0 "register_operand" "=f")
15346 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15347 UNSPEC_FRNDINT_MASK_PM))
15348 (use (match_operand:HI 2 "memory_operand" "m"))
15349 (use (match_operand:HI 3 "memory_operand" "m"))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations"
15352 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15353 [(set_attr "type" "frndint")
15354 (set_attr "i387_cw" "mask_pm")
15355 (set_attr "mode" "XF")])
15357 (define_expand "nearbyintxf2"
15358 [(parallel [(set (match_operand:XF 0 "register_operand")
15359 (unspec:XF [(match_operand:XF 1 "register_operand")]
15360 UNSPEC_FRNDINT_MASK_PM))
15361 (clobber (reg:CC FLAGS_REG))])]
15362 "TARGET_USE_FANCY_MATH_387
15363 && flag_unsafe_math_optimizations")
15365 (define_expand "nearbyint<mode>2"
15366 [(use (match_operand:MODEF 0 "register_operand"))
15367 (use (match_operand:MODEF 1 "register_operand"))]
15368 "TARGET_USE_FANCY_MATH_387
15369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15370 || TARGET_MIX_SSE_I387)
15371 && flag_unsafe_math_optimizations"
15373 rtx op0 = gen_reg_rtx (XFmode);
15374 rtx op1 = gen_reg_rtx (XFmode);
15376 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15377 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15379 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15383 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15384 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15385 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15386 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15388 (clobber (reg:CC FLAGS_REG))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations
15391 && can_create_pseudo_p ()"
15396 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15398 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15399 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15400 if (memory_operand (operands[0], VOIDmode))
15401 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15402 operands[2], operands[3]));
15405 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15406 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15407 (operands[0], operands[1], operands[2],
15408 operands[3], operands[4]));
15412 [(set_attr "type" "fistp")
15413 (set_attr "i387_cw" "<rounding>")
15414 (set_attr "mode" "<MODE>")])
15416 (define_insn "fistdi2_<rounding>"
15417 [(set (match_operand:DI 0 "memory_operand" "=m")
15418 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15420 (use (match_operand:HI 2 "memory_operand" "m"))
15421 (use (match_operand:HI 3 "memory_operand" "m"))
15422 (clobber (match_scratch:XF 4 "=&1f"))]
15423 "TARGET_USE_FANCY_MATH_387
15424 && flag_unsafe_math_optimizations"
15425 "* return output_fix_trunc (insn, operands, false);"
15426 [(set_attr "type" "fistp")
15427 (set_attr "i387_cw" "<rounding>")
15428 (set_attr "mode" "DI")])
15430 (define_insn "fistdi2_<rounding>_with_temp"
15431 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15432 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15434 (use (match_operand:HI 2 "memory_operand" "m,m"))
15435 (use (match_operand:HI 3 "memory_operand" "m,m"))
15436 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15437 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15438 "TARGET_USE_FANCY_MATH_387
15439 && flag_unsafe_math_optimizations"
15441 [(set_attr "type" "fistp")
15442 (set_attr "i387_cw" "<rounding>")
15443 (set_attr "mode" "DI")])
15446 [(set (match_operand:DI 0 "register_operand")
15447 (unspec:DI [(match_operand:XF 1 "register_operand")]
15449 (use (match_operand:HI 2 "memory_operand"))
15450 (use (match_operand:HI 3 "memory_operand"))
15451 (clobber (match_operand:DI 4 "memory_operand"))
15452 (clobber (match_scratch 5))]
15454 [(parallel [(set (match_dup 4)
15455 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15456 (use (match_dup 2))
15457 (use (match_dup 3))
15458 (clobber (match_dup 5))])
15459 (set (match_dup 0) (match_dup 4))])
15462 [(set (match_operand:DI 0 "memory_operand")
15463 (unspec:DI [(match_operand:XF 1 "register_operand")]
15465 (use (match_operand:HI 2 "memory_operand"))
15466 (use (match_operand:HI 3 "memory_operand"))
15467 (clobber (match_operand:DI 4 "memory_operand"))
15468 (clobber (match_scratch 5))]
15470 [(parallel [(set (match_dup 0)
15471 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15472 (use (match_dup 2))
15473 (use (match_dup 3))
15474 (clobber (match_dup 5))])])
15476 (define_insn "fist<mode>2_<rounding>"
15477 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15478 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15480 (use (match_operand:HI 2 "memory_operand" "m"))
15481 (use (match_operand:HI 3 "memory_operand" "m"))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && flag_unsafe_math_optimizations"
15484 "* return output_fix_trunc (insn, operands, false);"
15485 [(set_attr "type" "fistp")
15486 (set_attr "i387_cw" "<rounding>")
15487 (set_attr "mode" "<MODE>")])
15489 (define_insn "fist<mode>2_<rounding>_with_temp"
15490 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15491 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15493 (use (match_operand:HI 2 "memory_operand" "m,m"))
15494 (use (match_operand:HI 3 "memory_operand" "m,m"))
15495 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15496 "TARGET_USE_FANCY_MATH_387
15497 && flag_unsafe_math_optimizations"
15499 [(set_attr "type" "fistp")
15500 (set_attr "i387_cw" "<rounding>")
15501 (set_attr "mode" "<MODE>")])
15504 [(set (match_operand:SWI24 0 "register_operand")
15505 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15507 (use (match_operand:HI 2 "memory_operand"))
15508 (use (match_operand:HI 3 "memory_operand"))
15509 (clobber (match_operand:SWI24 4 "memory_operand"))]
15511 [(parallel [(set (match_dup 4)
15512 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15513 (use (match_dup 2))
15514 (use (match_dup 3))])
15515 (set (match_dup 0) (match_dup 4))])
15518 [(set (match_operand:SWI24 0 "memory_operand")
15519 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15521 (use (match_operand:HI 2 "memory_operand"))
15522 (use (match_operand:HI 3 "memory_operand"))
15523 (clobber (match_operand:SWI24 4 "memory_operand"))]
15525 [(parallel [(set (match_dup 0)
15526 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15527 (use (match_dup 2))
15528 (use (match_dup 3))])])
15530 (define_expand "l<rounding_insn>xf<mode>2"
15531 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15532 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15534 (clobber (reg:CC FLAGS_REG))])]
15535 "TARGET_USE_FANCY_MATH_387
15536 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15537 && flag_unsafe_math_optimizations")
15539 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15540 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15541 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15543 (clobber (reg:CC FLAGS_REG))])]
15544 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15545 && !flag_trapping_math"
15547 if (TARGET_64BIT && optimize_insn_for_size_p ())
15550 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15551 ix86_expand_lfloorceil (operands[0], operands[1], true);
15552 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15553 ix86_expand_lfloorceil (operands[0], operands[1], false);
15555 gcc_unreachable ();
15560 (define_insn "fxam<mode>2_i387"
15561 [(set (match_operand:HI 0 "register_operand" "=a")
15563 [(match_operand:X87MODEF 1 "register_operand" "f")]
15565 "TARGET_USE_FANCY_MATH_387"
15566 "fxam\n\tfnstsw\t%0"
15567 [(set_attr "type" "multi")
15568 (set_attr "length" "4")
15569 (set_attr "unit" "i387")
15570 (set_attr "mode" "<MODE>")])
15572 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15573 [(set (match_operand:HI 0 "register_operand")
15575 [(match_operand:MODEF 1 "memory_operand")]
15577 "TARGET_USE_FANCY_MATH_387
15578 && can_create_pseudo_p ()"
15581 [(set (match_dup 2)(match_dup 1))
15583 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15585 operands[2] = gen_reg_rtx (<MODE>mode);
15587 MEM_VOLATILE_P (operands[1]) = 1;
15589 [(set_attr "type" "multi")
15590 (set_attr "unit" "i387")
15591 (set_attr "mode" "<MODE>")])
15593 (define_expand "isinfxf2"
15594 [(use (match_operand:SI 0 "register_operand"))
15595 (use (match_operand:XF 1 "register_operand"))]
15596 "TARGET_USE_FANCY_MATH_387
15597 && ix86_libc_has_function (function_c99_misc)"
15599 rtx mask = GEN_INT (0x45);
15600 rtx val = GEN_INT (0x05);
15604 rtx scratch = gen_reg_rtx (HImode);
15605 rtx res = gen_reg_rtx (QImode);
15607 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15609 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15610 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15611 cond = gen_rtx_fmt_ee (EQ, QImode,
15612 gen_rtx_REG (CCmode, FLAGS_REG),
15614 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15615 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15619 (define_expand "isinf<mode>2"
15620 [(use (match_operand:SI 0 "register_operand"))
15621 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15622 "TARGET_USE_FANCY_MATH_387
15623 && ix86_libc_has_function (function_c99_misc)
15624 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15626 rtx mask = GEN_INT (0x45);
15627 rtx val = GEN_INT (0x05);
15631 rtx scratch = gen_reg_rtx (HImode);
15632 rtx res = gen_reg_rtx (QImode);
15634 /* Remove excess precision by forcing value through memory. */
15635 if (memory_operand (operands[1], VOIDmode))
15636 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15639 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15641 emit_move_insn (temp, operands[1]);
15642 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15645 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15646 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15647 cond = gen_rtx_fmt_ee (EQ, QImode,
15648 gen_rtx_REG (CCmode, FLAGS_REG),
15650 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15651 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15655 (define_expand "signbitxf2"
15656 [(use (match_operand:SI 0 "register_operand"))
15657 (use (match_operand:XF 1 "register_operand"))]
15658 "TARGET_USE_FANCY_MATH_387"
15660 rtx scratch = gen_reg_rtx (HImode);
15662 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15663 emit_insn (gen_andsi3 (operands[0],
15664 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15668 (define_insn "movmsk_df"
15669 [(set (match_operand:SI 0 "register_operand" "=r")
15671 [(match_operand:DF 1 "register_operand" "x")]
15673 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15674 "%vmovmskpd\t{%1, %0|%0, %1}"
15675 [(set_attr "type" "ssemov")
15676 (set_attr "prefix" "maybe_vex")
15677 (set_attr "mode" "DF")])
15679 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15680 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15681 (define_expand "signbitdf2"
15682 [(use (match_operand:SI 0 "register_operand"))
15683 (use (match_operand:DF 1 "register_operand"))]
15684 "TARGET_USE_FANCY_MATH_387
15685 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15687 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15689 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15690 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15694 rtx scratch = gen_reg_rtx (HImode);
15696 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15697 emit_insn (gen_andsi3 (operands[0],
15698 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15703 (define_expand "signbitsf2"
15704 [(use (match_operand:SI 0 "register_operand"))
15705 (use (match_operand:SF 1 "register_operand"))]
15706 "TARGET_USE_FANCY_MATH_387
15707 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15709 rtx scratch = gen_reg_rtx (HImode);
15711 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15712 emit_insn (gen_andsi3 (operands[0],
15713 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15717 ;; Block operation instructions
15720 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15723 [(set_attr "length" "1")
15724 (set_attr "length_immediate" "0")
15725 (set_attr "modrm" "0")])
15727 (define_expand "movmem<mode>"
15728 [(use (match_operand:BLK 0 "memory_operand"))
15729 (use (match_operand:BLK 1 "memory_operand"))
15730 (use (match_operand:SWI48 2 "nonmemory_operand"))
15731 (use (match_operand:SWI48 3 "const_int_operand"))
15732 (use (match_operand:SI 4 "const_int_operand"))
15733 (use (match_operand:SI 5 "const_int_operand"))
15734 (use (match_operand:SI 6 ""))
15735 (use (match_operand:SI 7 ""))
15736 (use (match_operand:SI 8 ""))]
15739 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15740 operands[2], NULL, operands[3],
15741 operands[4], operands[5],
15742 operands[6], operands[7],
15743 operands[8], false))
15749 ;; Most CPUs don't like single string operations
15750 ;; Handle this case here to simplify previous expander.
15752 (define_expand "strmov"
15753 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15754 (set (match_operand 1 "memory_operand") (match_dup 4))
15755 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15756 (clobber (reg:CC FLAGS_REG))])
15757 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15758 (clobber (reg:CC FLAGS_REG))])]
15761 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15763 /* If .md ever supports :P for Pmode, these can be directly
15764 in the pattern above. */
15765 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15766 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15768 /* Can't use this if the user has appropriated esi or edi. */
15769 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15770 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15772 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15773 operands[2], operands[3],
15774 operands[5], operands[6]));
15778 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15781 (define_expand "strmov_singleop"
15782 [(parallel [(set (match_operand 1 "memory_operand")
15783 (match_operand 3 "memory_operand"))
15784 (set (match_operand 0 "register_operand")
15786 (set (match_operand 2 "register_operand")
15787 (match_operand 5))])]
15789 "ix86_current_function_needs_cld = 1;")
15791 (define_insn "*strmovdi_rex_1"
15792 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15793 (mem:DI (match_operand:P 3 "register_operand" "1")))
15794 (set (match_operand:P 0 "register_operand" "=D")
15795 (plus:P (match_dup 2)
15797 (set (match_operand:P 1 "register_operand" "=S")
15798 (plus:P (match_dup 3)
15801 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15803 [(set_attr "type" "str")
15804 (set_attr "memory" "both")
15805 (set_attr "mode" "DI")])
15807 (define_insn "*strmovsi_1"
15808 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15809 (mem:SI (match_operand:P 3 "register_operand" "1")))
15810 (set (match_operand:P 0 "register_operand" "=D")
15811 (plus:P (match_dup 2)
15813 (set (match_operand:P 1 "register_operand" "=S")
15814 (plus:P (match_dup 3)
15816 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15818 [(set_attr "type" "str")
15819 (set_attr "memory" "both")
15820 (set_attr "mode" "SI")])
15822 (define_insn "*strmovhi_1"
15823 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15824 (mem:HI (match_operand:P 3 "register_operand" "1")))
15825 (set (match_operand:P 0 "register_operand" "=D")
15826 (plus:P (match_dup 2)
15828 (set (match_operand:P 1 "register_operand" "=S")
15829 (plus:P (match_dup 3)
15831 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15833 [(set_attr "type" "str")
15834 (set_attr "memory" "both")
15835 (set_attr "mode" "HI")])
15837 (define_insn "*strmovqi_1"
15838 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15839 (mem:QI (match_operand:P 3 "register_operand" "1")))
15840 (set (match_operand:P 0 "register_operand" "=D")
15841 (plus:P (match_dup 2)
15843 (set (match_operand:P 1 "register_operand" "=S")
15844 (plus:P (match_dup 3)
15846 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15848 [(set_attr "type" "str")
15849 (set_attr "memory" "both")
15850 (set (attr "prefix_rex")
15852 (match_test "<P:MODE>mode == DImode")
15854 (const_string "*")))
15855 (set_attr "mode" "QI")])
15857 (define_expand "rep_mov"
15858 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15859 (set (match_operand 0 "register_operand")
15861 (set (match_operand 2 "register_operand")
15863 (set (match_operand 1 "memory_operand")
15864 (match_operand 3 "memory_operand"))
15865 (use (match_dup 4))])]
15867 "ix86_current_function_needs_cld = 1;")
15869 (define_insn "*rep_movdi_rex64"
15870 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15871 (set (match_operand:P 0 "register_operand" "=D")
15872 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15874 (match_operand:P 3 "register_operand" "0")))
15875 (set (match_operand:P 1 "register_operand" "=S")
15876 (plus:P (ashift:P (match_dup 5) (const_int 3))
15877 (match_operand:P 4 "register_operand" "1")))
15878 (set (mem:BLK (match_dup 3))
15879 (mem:BLK (match_dup 4)))
15880 (use (match_dup 5))]
15882 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15884 [(set_attr "type" "str")
15885 (set_attr "prefix_rep" "1")
15886 (set_attr "memory" "both")
15887 (set_attr "mode" "DI")])
15889 (define_insn "*rep_movsi"
15890 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15894 (match_operand:P 3 "register_operand" "0")))
15895 (set (match_operand:P 1 "register_operand" "=S")
15896 (plus:P (ashift:P (match_dup 5) (const_int 2))
15897 (match_operand:P 4 "register_operand" "1")))
15898 (set (mem:BLK (match_dup 3))
15899 (mem:BLK (match_dup 4)))
15900 (use (match_dup 5))]
15901 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15902 "%^rep{%;} movs{l|d}"
15903 [(set_attr "type" "str")
15904 (set_attr "prefix_rep" "1")
15905 (set_attr "memory" "both")
15906 (set_attr "mode" "SI")])
15908 (define_insn "*rep_movqi"
15909 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15910 (set (match_operand:P 0 "register_operand" "=D")
15911 (plus:P (match_operand:P 3 "register_operand" "0")
15912 (match_operand:P 5 "register_operand" "2")))
15913 (set (match_operand:P 1 "register_operand" "=S")
15914 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15915 (set (mem:BLK (match_dup 3))
15916 (mem:BLK (match_dup 4)))
15917 (use (match_dup 5))]
15918 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15920 [(set_attr "type" "str")
15921 (set_attr "prefix_rep" "1")
15922 (set_attr "memory" "both")
15923 (set_attr "mode" "QI")])
15925 (define_expand "setmem<mode>"
15926 [(use (match_operand:BLK 0 "memory_operand"))
15927 (use (match_operand:SWI48 1 "nonmemory_operand"))
15928 (use (match_operand:QI 2 "nonmemory_operand"))
15929 (use (match_operand 3 "const_int_operand"))
15930 (use (match_operand:SI 4 "const_int_operand"))
15931 (use (match_operand:SI 5 "const_int_operand"))
15932 (use (match_operand:SI 6 ""))
15933 (use (match_operand:SI 7 ""))
15934 (use (match_operand:SI 8 ""))]
15937 if (ix86_expand_set_or_movmem (operands[0], NULL,
15938 operands[1], operands[2],
15939 operands[3], operands[4],
15940 operands[5], operands[6],
15941 operands[7], operands[8], true))
15947 ;; Most CPUs don't like single string operations
15948 ;; Handle this case here to simplify previous expander.
15950 (define_expand "strset"
15951 [(set (match_operand 1 "memory_operand")
15952 (match_operand 2 "register_operand"))
15953 (parallel [(set (match_operand 0 "register_operand")
15955 (clobber (reg:CC FLAGS_REG))])]
15958 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15959 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15961 /* If .md ever supports :P for Pmode, this can be directly
15962 in the pattern above. */
15963 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15964 GEN_INT (GET_MODE_SIZE (GET_MODE
15966 /* Can't use this if the user has appropriated eax or edi. */
15967 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15968 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15970 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15976 (define_expand "strset_singleop"
15977 [(parallel [(set (match_operand 1 "memory_operand")
15978 (match_operand 2 "register_operand"))
15979 (set (match_operand 0 "register_operand")
15981 (unspec [(const_int 0)] UNSPEC_STOS)])]
15983 "ix86_current_function_needs_cld = 1;")
15985 (define_insn "*strsetdi_rex_1"
15986 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15987 (match_operand:DI 2 "register_operand" "a"))
15988 (set (match_operand:P 0 "register_operand" "=D")
15989 (plus:P (match_dup 1)
15991 (unspec [(const_int 0)] UNSPEC_STOS)]
15993 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15995 [(set_attr "type" "str")
15996 (set_attr "memory" "store")
15997 (set_attr "mode" "DI")])
15999 (define_insn "*strsetsi_1"
16000 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16001 (match_operand:SI 2 "register_operand" "a"))
16002 (set (match_operand:P 0 "register_operand" "=D")
16003 (plus:P (match_dup 1)
16005 (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" "SI")])
16012 (define_insn "*strsethi_1"
16013 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16014 (match_operand:HI 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" "HI")])
16025 (define_insn "*strsetqi_1"
16026 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16027 (match_operand:QI 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 "prefix_rex")
16038 (match_test "<P:MODE>mode == DImode")
16040 (const_string "*")))
16041 (set_attr "mode" "QI")])
16043 (define_expand "rep_stos"
16044 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16045 (set (match_operand 0 "register_operand")
16047 (set (match_operand 2 "memory_operand") (const_int 0))
16048 (use (match_operand 3 "register_operand"))
16049 (use (match_dup 1))])]
16051 "ix86_current_function_needs_cld = 1;")
16053 (define_insn "*rep_stosdi_rex64"
16054 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16055 (set (match_operand:P 0 "register_operand" "=D")
16056 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16058 (match_operand:P 3 "register_operand" "0")))
16059 (set (mem:BLK (match_dup 3))
16061 (use (match_operand:DI 2 "register_operand" "a"))
16062 (use (match_dup 4))]
16064 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16066 [(set_attr "type" "str")
16067 (set_attr "prefix_rep" "1")
16068 (set_attr "memory" "store")
16069 (set_attr "mode" "DI")])
16071 (define_insn "*rep_stossi"
16072 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16073 (set (match_operand:P 0 "register_operand" "=D")
16074 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16076 (match_operand:P 3 "register_operand" "0")))
16077 (set (mem:BLK (match_dup 3))
16079 (use (match_operand:SI 2 "register_operand" "a"))
16080 (use (match_dup 4))]
16081 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16082 "%^rep{%;} stos{l|d}"
16083 [(set_attr "type" "str")
16084 (set_attr "prefix_rep" "1")
16085 (set_attr "memory" "store")
16086 (set_attr "mode" "SI")])
16088 (define_insn "*rep_stosqi"
16089 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16090 (set (match_operand:P 0 "register_operand" "=D")
16091 (plus:P (match_operand:P 3 "register_operand" "0")
16092 (match_operand:P 4 "register_operand" "1")))
16093 (set (mem:BLK (match_dup 3))
16095 (use (match_operand:QI 2 "register_operand" "a"))
16096 (use (match_dup 4))]
16097 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16099 [(set_attr "type" "str")
16100 (set_attr "prefix_rep" "1")
16101 (set_attr "memory" "store")
16102 (set (attr "prefix_rex")
16104 (match_test "<P:MODE>mode == DImode")
16106 (const_string "*")))
16107 (set_attr "mode" "QI")])
16109 (define_expand "cmpstrnsi"
16110 [(set (match_operand:SI 0 "register_operand")
16111 (compare:SI (match_operand:BLK 1 "general_operand")
16112 (match_operand:BLK 2 "general_operand")))
16113 (use (match_operand 3 "general_operand"))
16114 (use (match_operand 4 "immediate_operand"))]
16117 rtx addr1, addr2, out, outlow, count, countreg, align;
16119 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16122 /* Can't use this if the user has appropriated ecx, esi or edi. */
16123 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16128 out = gen_reg_rtx (SImode);
16130 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16131 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16132 if (addr1 != XEXP (operands[1], 0))
16133 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16134 if (addr2 != XEXP (operands[2], 0))
16135 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16137 count = operands[3];
16138 countreg = ix86_zero_extend_to_Pmode (count);
16140 /* %%% Iff we are testing strict equality, we can use known alignment
16141 to good advantage. This may be possible with combine, particularly
16142 once cc0 is dead. */
16143 align = operands[4];
16145 if (CONST_INT_P (count))
16147 if (INTVAL (count) == 0)
16149 emit_move_insn (operands[0], const0_rtx);
16152 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16153 operands[1], operands[2]));
16157 rtx (*gen_cmp) (rtx, rtx);
16159 gen_cmp = (TARGET_64BIT
16160 ? gen_cmpdi_1 : gen_cmpsi_1);
16162 emit_insn (gen_cmp (countreg, countreg));
16163 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16164 operands[1], operands[2]));
16167 outlow = gen_lowpart (QImode, out);
16168 emit_insn (gen_cmpintqi (outlow));
16169 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16171 if (operands[0] != out)
16172 emit_move_insn (operands[0], out);
16177 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16179 (define_expand "cmpintqi"
16180 [(set (match_dup 1)
16181 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16183 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16184 (parallel [(set (match_operand:QI 0 "register_operand")
16185 (minus:QI (match_dup 1)
16187 (clobber (reg:CC FLAGS_REG))])]
16190 operands[1] = gen_reg_rtx (QImode);
16191 operands[2] = gen_reg_rtx (QImode);
16194 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16195 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16197 (define_expand "cmpstrnqi_nz_1"
16198 [(parallel [(set (reg:CC FLAGS_REG)
16199 (compare:CC (match_operand 4 "memory_operand")
16200 (match_operand 5 "memory_operand")))
16201 (use (match_operand 2 "register_operand"))
16202 (use (match_operand:SI 3 "immediate_operand"))
16203 (clobber (match_operand 0 "register_operand"))
16204 (clobber (match_operand 1 "register_operand"))
16205 (clobber (match_dup 2))])]
16207 "ix86_current_function_needs_cld = 1;")
16209 (define_insn "*cmpstrnqi_nz_1"
16210 [(set (reg:CC FLAGS_REG)
16211 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16212 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16213 (use (match_operand:P 6 "register_operand" "2"))
16214 (use (match_operand:SI 3 "immediate_operand" "i"))
16215 (clobber (match_operand:P 0 "register_operand" "=S"))
16216 (clobber (match_operand:P 1 "register_operand" "=D"))
16217 (clobber (match_operand:P 2 "register_operand" "=c"))]
16218 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16220 [(set_attr "type" "str")
16221 (set_attr "mode" "QI")
16222 (set (attr "prefix_rex")
16224 (match_test "<P:MODE>mode == DImode")
16226 (const_string "*")))
16227 (set_attr "prefix_rep" "1")])
16229 ;; The same, but the count is not known to not be zero.
16231 (define_expand "cmpstrnqi_1"
16232 [(parallel [(set (reg:CC FLAGS_REG)
16233 (if_then_else:CC (ne (match_operand 2 "register_operand")
16235 (compare:CC (match_operand 4 "memory_operand")
16236 (match_operand 5 "memory_operand"))
16238 (use (match_operand:SI 3 "immediate_operand"))
16239 (use (reg:CC FLAGS_REG))
16240 (clobber (match_operand 0 "register_operand"))
16241 (clobber (match_operand 1 "register_operand"))
16242 (clobber (match_dup 2))])]
16244 "ix86_current_function_needs_cld = 1;")
16246 (define_insn "*cmpstrnqi_1"
16247 [(set (reg:CC FLAGS_REG)
16248 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16250 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16251 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16253 (use (match_operand:SI 3 "immediate_operand" "i"))
16254 (use (reg:CC FLAGS_REG))
16255 (clobber (match_operand:P 0 "register_operand" "=S"))
16256 (clobber (match_operand:P 1 "register_operand" "=D"))
16257 (clobber (match_operand:P 2 "register_operand" "=c"))]
16258 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16260 [(set_attr "type" "str")
16261 (set_attr "mode" "QI")
16262 (set (attr "prefix_rex")
16264 (match_test "<P:MODE>mode == DImode")
16266 (const_string "*")))
16267 (set_attr "prefix_rep" "1")])
16269 (define_expand "strlen<mode>"
16270 [(set (match_operand:P 0 "register_operand")
16271 (unspec:P [(match_operand:BLK 1 "general_operand")
16272 (match_operand:QI 2 "immediate_operand")
16273 (match_operand 3 "immediate_operand")]
16277 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16283 (define_expand "strlenqi_1"
16284 [(parallel [(set (match_operand 0 "register_operand")
16286 (clobber (match_operand 1 "register_operand"))
16287 (clobber (reg:CC FLAGS_REG))])]
16289 "ix86_current_function_needs_cld = 1;")
16291 (define_insn "*strlenqi_1"
16292 [(set (match_operand:P 0 "register_operand" "=&c")
16293 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16294 (match_operand:QI 2 "register_operand" "a")
16295 (match_operand:P 3 "immediate_operand" "i")
16296 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16297 (clobber (match_operand:P 1 "register_operand" "=D"))
16298 (clobber (reg:CC FLAGS_REG))]
16299 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16300 "%^repnz{%;} scasb"
16301 [(set_attr "type" "str")
16302 (set_attr "mode" "QI")
16303 (set (attr "prefix_rex")
16305 (match_test "<P:MODE>mode == DImode")
16307 (const_string "*")))
16308 (set_attr "prefix_rep" "1")])
16310 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16311 ;; handled in combine, but it is not currently up to the task.
16312 ;; When used for their truth value, the cmpstrn* expanders generate
16321 ;; The intermediate three instructions are unnecessary.
16323 ;; This one handles cmpstrn*_nz_1...
16326 (set (reg:CC FLAGS_REG)
16327 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16328 (mem:BLK (match_operand 5 "register_operand"))))
16329 (use (match_operand 6 "register_operand"))
16330 (use (match_operand:SI 3 "immediate_operand"))
16331 (clobber (match_operand 0 "register_operand"))
16332 (clobber (match_operand 1 "register_operand"))
16333 (clobber (match_operand 2 "register_operand"))])
16334 (set (match_operand:QI 7 "register_operand")
16335 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16336 (set (match_operand:QI 8 "register_operand")
16337 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16338 (set (reg FLAGS_REG)
16339 (compare (match_dup 7) (match_dup 8)))
16341 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16343 (set (reg:CC FLAGS_REG)
16344 (compare:CC (mem:BLK (match_dup 4))
16345 (mem:BLK (match_dup 5))))
16346 (use (match_dup 6))
16347 (use (match_dup 3))
16348 (clobber (match_dup 0))
16349 (clobber (match_dup 1))
16350 (clobber (match_dup 2))])])
16352 ;; ...and this one handles cmpstrn*_1.
16355 (set (reg:CC FLAGS_REG)
16356 (if_then_else:CC (ne (match_operand 6 "register_operand")
16358 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16359 (mem:BLK (match_operand 5 "register_operand")))
16361 (use (match_operand:SI 3 "immediate_operand"))
16362 (use (reg:CC FLAGS_REG))
16363 (clobber (match_operand 0 "register_operand"))
16364 (clobber (match_operand 1 "register_operand"))
16365 (clobber (match_operand 2 "register_operand"))])
16366 (set (match_operand:QI 7 "register_operand")
16367 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16368 (set (match_operand:QI 8 "register_operand")
16369 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16370 (set (reg FLAGS_REG)
16371 (compare (match_dup 7) (match_dup 8)))
16373 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16375 (set (reg:CC FLAGS_REG)
16376 (if_then_else:CC (ne (match_dup 6)
16378 (compare:CC (mem:BLK (match_dup 4))
16379 (mem:BLK (match_dup 5)))
16381 (use (match_dup 3))
16382 (use (reg:CC FLAGS_REG))
16383 (clobber (match_dup 0))
16384 (clobber (match_dup 1))
16385 (clobber (match_dup 2))])])
16387 ;; Conditional move instructions.
16389 (define_expand "mov<mode>cc"
16390 [(set (match_operand:SWIM 0 "register_operand")
16391 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16392 (match_operand:SWIM 2 "<general_operand>")
16393 (match_operand:SWIM 3 "<general_operand>")))]
16395 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16397 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16398 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16399 ;; So just document what we're doing explicitly.
16401 (define_expand "x86_mov<mode>cc_0_m1"
16403 [(set (match_operand:SWI48 0 "register_operand")
16404 (if_then_else:SWI48
16405 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16406 [(match_operand 1 "flags_reg_operand")
16410 (clobber (reg:CC FLAGS_REG))])])
16412 (define_insn "*x86_mov<mode>cc_0_m1"
16413 [(set (match_operand:SWI48 0 "register_operand" "=r")
16414 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16415 [(reg FLAGS_REG) (const_int 0)])
16418 (clobber (reg:CC FLAGS_REG))]
16420 "sbb{<imodesuffix>}\t%0, %0"
16421 ; Since we don't have the proper number of operands for an alu insn,
16422 ; fill in all the blanks.
16423 [(set_attr "type" "alu")
16424 (set_attr "use_carry" "1")
16425 (set_attr "pent_pair" "pu")
16426 (set_attr "memory" "none")
16427 (set_attr "imm_disp" "false")
16428 (set_attr "mode" "<MODE>")
16429 (set_attr "length_immediate" "0")])
16431 (define_insn "*x86_mov<mode>cc_0_m1_se"
16432 [(set (match_operand:SWI48 0 "register_operand" "=r")
16433 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16434 [(reg FLAGS_REG) (const_int 0)])
16437 (clobber (reg:CC FLAGS_REG))]
16439 "sbb{<imodesuffix>}\t%0, %0"
16440 [(set_attr "type" "alu")
16441 (set_attr "use_carry" "1")
16442 (set_attr "pent_pair" "pu")
16443 (set_attr "memory" "none")
16444 (set_attr "imm_disp" "false")
16445 (set_attr "mode" "<MODE>")
16446 (set_attr "length_immediate" "0")])
16448 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16449 [(set (match_operand:SWI48 0 "register_operand" "=r")
16450 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16451 [(reg FLAGS_REG) (const_int 0)])))
16452 (clobber (reg:CC FLAGS_REG))]
16454 "sbb{<imodesuffix>}\t%0, %0"
16455 [(set_attr "type" "alu")
16456 (set_attr "use_carry" "1")
16457 (set_attr "pent_pair" "pu")
16458 (set_attr "memory" "none")
16459 (set_attr "imm_disp" "false")
16460 (set_attr "mode" "<MODE>")
16461 (set_attr "length_immediate" "0")])
16463 (define_insn "*mov<mode>cc_noc"
16464 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16465 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16466 [(reg FLAGS_REG) (const_int 0)])
16467 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16468 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16469 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16471 cmov%O2%C1\t{%2, %0|%0, %2}
16472 cmov%O2%c1\t{%3, %0|%0, %3}"
16473 [(set_attr "type" "icmov")
16474 (set_attr "mode" "<MODE>")])
16476 ;; Don't do conditional moves with memory inputs. This splitter helps
16477 ;; register starved x86_32 by forcing inputs into registers before reload.
16479 [(set (match_operand:SWI248 0 "register_operand")
16480 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16481 [(reg FLAGS_REG) (const_int 0)])
16482 (match_operand:SWI248 2 "nonimmediate_operand")
16483 (match_operand:SWI248 3 "nonimmediate_operand")))]
16484 "!TARGET_64BIT && TARGET_CMOVE
16485 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16486 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16487 && can_create_pseudo_p ()
16488 && optimize_insn_for_speed_p ()"
16489 [(set (match_dup 0)
16490 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16492 if (MEM_P (operands[2]))
16493 operands[2] = force_reg (<MODE>mode, operands[2]);
16494 if (MEM_P (operands[3]))
16495 operands[3] = force_reg (<MODE>mode, operands[3]);
16498 (define_insn "*movqicc_noc"
16499 [(set (match_operand:QI 0 "register_operand" "=r,r")
16500 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16501 [(reg FLAGS_REG) (const_int 0)])
16502 (match_operand:QI 2 "register_operand" "r,0")
16503 (match_operand:QI 3 "register_operand" "0,r")))]
16504 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16506 [(set_attr "type" "icmov")
16507 (set_attr "mode" "QI")])
16510 [(set (match_operand:SWI12 0 "register_operand")
16511 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16512 [(reg FLAGS_REG) (const_int 0)])
16513 (match_operand:SWI12 2 "register_operand")
16514 (match_operand:SWI12 3 "register_operand")))]
16515 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16516 && reload_completed"
16517 [(set (match_dup 0)
16518 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16520 operands[0] = gen_lowpart (SImode, operands[0]);
16521 operands[2] = gen_lowpart (SImode, operands[2]);
16522 operands[3] = gen_lowpart (SImode, operands[3]);
16525 ;; Don't do conditional moves with memory inputs
16527 [(match_scratch:SWI248 2 "r")
16528 (set (match_operand:SWI248 0 "register_operand")
16529 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16530 [(reg FLAGS_REG) (const_int 0)])
16532 (match_operand:SWI248 3 "memory_operand")))]
16533 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16534 && optimize_insn_for_speed_p ()"
16535 [(set (match_dup 2) (match_dup 3))
16537 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
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)])
16544 (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 2) (match_dup 0)))])
16552 (define_expand "mov<mode>cc"
16553 [(set (match_operand:X87MODEF 0 "register_operand")
16554 (if_then_else:X87MODEF
16555 (match_operand 1 "comparison_operator")
16556 (match_operand:X87MODEF 2 "register_operand")
16557 (match_operand:X87MODEF 3 "register_operand")))]
16558 "(TARGET_80387 && TARGET_CMOVE)
16559 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16560 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16562 (define_insn "*movxfcc_1"
16563 [(set (match_operand:XF 0 "register_operand" "=f,f")
16564 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16565 [(reg FLAGS_REG) (const_int 0)])
16566 (match_operand:XF 2 "register_operand" "f,0")
16567 (match_operand:XF 3 "register_operand" "0,f")))]
16568 "TARGET_80387 && TARGET_CMOVE"
16570 fcmov%F1\t{%2, %0|%0, %2}
16571 fcmov%f1\t{%3, %0|%0, %3}"
16572 [(set_attr "type" "fcmov")
16573 (set_attr "mode" "XF")])
16575 (define_insn "*movdfcc_1"
16576 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16577 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16578 [(reg FLAGS_REG) (const_int 0)])
16579 (match_operand:DF 2 "nonimmediate_operand"
16581 (match_operand:DF 3 "nonimmediate_operand"
16582 "0 ,f,0 ,rm,0, rm")))]
16583 "TARGET_80387 && TARGET_CMOVE
16584 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16586 fcmov%F1\t{%2, %0|%0, %2}
16587 fcmov%f1\t{%3, %0|%0, %3}
16590 cmov%O2%C1\t{%2, %0|%0, %2}
16591 cmov%O2%c1\t{%3, %0|%0, %3}"
16592 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16593 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16594 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16597 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16598 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16599 [(reg FLAGS_REG) (const_int 0)])
16600 (match_operand:DF 2 "nonimmediate_operand")
16601 (match_operand:DF 3 "nonimmediate_operand")))]
16602 "!TARGET_64BIT && reload_completed"
16603 [(set (match_dup 2)
16604 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16606 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16608 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16609 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16612 (define_insn "*movsfcc_1_387"
16613 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16614 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16615 [(reg FLAGS_REG) (const_int 0)])
16616 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16617 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16618 "TARGET_80387 && TARGET_CMOVE
16619 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16621 fcmov%F1\t{%2, %0|%0, %2}
16622 fcmov%f1\t{%3, %0|%0, %3}
16623 cmov%O2%C1\t{%2, %0|%0, %2}
16624 cmov%O2%c1\t{%3, %0|%0, %3}"
16625 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16626 (set_attr "mode" "SF,SF,SI,SI")])
16628 ;; Don't do conditional moves with memory inputs. This splitter helps
16629 ;; register starved x86_32 by forcing inputs into registers before reload.
16631 [(set (match_operand:MODEF 0 "register_operand")
16632 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16633 [(reg FLAGS_REG) (const_int 0)])
16634 (match_operand:MODEF 2 "nonimmediate_operand")
16635 (match_operand:MODEF 3 "nonimmediate_operand")))]
16636 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16637 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16638 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16639 && can_create_pseudo_p ()
16640 && optimize_insn_for_speed_p ()"
16641 [(set (match_dup 0)
16642 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16644 if (MEM_P (operands[2]))
16645 operands[2] = force_reg (<MODE>mode, operands[2]);
16646 if (MEM_P (operands[3]))
16647 operands[3] = force_reg (<MODE>mode, operands[3]);
16650 ;; Don't do conditional moves with memory inputs
16652 [(match_scratch:MODEF 2 "r")
16653 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16654 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16655 [(reg FLAGS_REG) (const_int 0)])
16657 (match_operand:MODEF 3 "memory_operand")))]
16658 "(<MODE>mode != DFmode || TARGET_64BIT)
16659 && TARGET_80387 && TARGET_CMOVE
16660 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16661 && optimize_insn_for_speed_p ()"
16662 [(set (match_dup 2) (match_dup 3))
16664 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16667 [(match_scratch:MODEF 2 "r")
16668 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16669 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16670 [(reg FLAGS_REG) (const_int 0)])
16671 (match_operand:MODEF 3 "memory_operand")
16673 "(<MODE>mode != DFmode || TARGET_64BIT)
16674 && TARGET_80387 && TARGET_CMOVE
16675 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16676 && optimize_insn_for_speed_p ()"
16677 [(set (match_dup 2) (match_dup 3))
16679 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16681 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16682 ;; the scalar versions to have only XMM registers as operands.
16684 ;; XOP conditional move
16685 (define_insn "*xop_pcmov_<mode>"
16686 [(set (match_operand:MODEF 0 "register_operand" "=x")
16687 (if_then_else:MODEF
16688 (match_operand:MODEF 1 "register_operand" "x")
16689 (match_operand:MODEF 2 "register_operand" "x")
16690 (match_operand:MODEF 3 "register_operand" "x")))]
16692 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16693 [(set_attr "type" "sse4arg")])
16695 ;; These versions of the min/max patterns are intentionally ignorant of
16696 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16697 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16698 ;; are undefined in this condition, we're certain this is correct.
16700 (define_insn "<code><mode>3"
16701 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16703 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16704 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16705 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16707 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16708 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16709 [(set_attr "isa" "noavx,avx")
16710 (set_attr "prefix" "orig,vex")
16711 (set_attr "type" "sseadd")
16712 (set_attr "mode" "<MODE>")])
16714 ;; These versions of the min/max patterns implement exactly the operations
16715 ;; min = (op1 < op2 ? op1 : op2)
16716 ;; max = (!(op1 < op2) ? op1 : op2)
16717 ;; Their operands are not commutative, and thus they may be used in the
16718 ;; presence of -0.0 and NaN.
16720 (define_int_iterator IEEE_MAXMIN
16724 (define_int_attr ieee_maxmin
16725 [(UNSPEC_IEEE_MAX "max")
16726 (UNSPEC_IEEE_MIN "min")])
16728 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16729 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16731 [(match_operand:MODEF 1 "register_operand" "0,x")
16732 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16734 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16736 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16737 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16738 [(set_attr "isa" "noavx,avx")
16739 (set_attr "prefix" "orig,vex")
16740 (set_attr "type" "sseadd")
16741 (set_attr "mode" "<MODE>")])
16743 ;; Make two stack loads independent:
16745 ;; fld %st(0) -> fld bb
16746 ;; fmul bb fmul %st(1), %st
16748 ;; Actually we only match the last two instructions for simplicity.
16750 [(set (match_operand 0 "fp_register_operand")
16751 (match_operand 1 "fp_register_operand"))
16753 (match_operator 2 "binary_fp_operator"
16755 (match_operand 3 "memory_operand")]))]
16756 "REGNO (operands[0]) != REGNO (operands[1])"
16757 [(set (match_dup 0) (match_dup 3))
16758 (set (match_dup 0) (match_dup 4))]
16760 ;; The % modifier is not operational anymore in peephole2's, so we have to
16761 ;; swap the operands manually in the case of addition and multiplication.
16765 if (COMMUTATIVE_ARITH_P (operands[2]))
16766 op0 = operands[0], op1 = operands[1];
16768 op0 = operands[1], op1 = operands[0];
16770 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16771 GET_MODE (operands[2]),
16775 ;; Conditional addition patterns
16776 (define_expand "add<mode>cc"
16777 [(match_operand:SWI 0 "register_operand")
16778 (match_operand 1 "ordered_comparison_operator")
16779 (match_operand:SWI 2 "register_operand")
16780 (match_operand:SWI 3 "const_int_operand")]
16782 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16784 ;; Misc patterns (?)
16786 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16787 ;; Otherwise there will be nothing to keep
16789 ;; [(set (reg ebp) (reg esp))]
16790 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16791 ;; (clobber (eflags)]
16792 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16794 ;; in proper program order.
16796 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16797 [(set (match_operand:P 0 "register_operand" "=r,r")
16798 (plus:P (match_operand:P 1 "register_operand" "0,r")
16799 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16800 (clobber (reg:CC FLAGS_REG))
16801 (clobber (mem:BLK (scratch)))]
16804 switch (get_attr_type (insn))
16807 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16810 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16811 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16812 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16814 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16817 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16818 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16821 [(set (attr "type")
16822 (cond [(and (eq_attr "alternative" "0")
16823 (not (match_test "TARGET_OPT_AGU")))
16824 (const_string "alu")
16825 (match_operand:<MODE> 2 "const0_operand")
16826 (const_string "imov")
16828 (const_string "lea")))
16829 (set (attr "length_immediate")
16830 (cond [(eq_attr "type" "imov")
16832 (and (eq_attr "type" "alu")
16833 (match_operand 2 "const128_operand"))
16836 (const_string "*")))
16837 (set_attr "mode" "<MODE>")])
16839 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16840 [(set (match_operand:P 0 "register_operand" "=r")
16841 (minus:P (match_operand:P 1 "register_operand" "0")
16842 (match_operand:P 2 "register_operand" "r")))
16843 (clobber (reg:CC FLAGS_REG))
16844 (clobber (mem:BLK (scratch)))]
16846 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16847 [(set_attr "type" "alu")
16848 (set_attr "mode" "<MODE>")])
16850 (define_insn "allocate_stack_worker_probe_<mode>"
16851 [(set (match_operand:P 0 "register_operand" "=a")
16852 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16853 UNSPECV_STACK_PROBE))
16854 (clobber (reg:CC FLAGS_REG))]
16855 "ix86_target_stack_probe ()"
16856 "call\t___chkstk_ms"
16857 [(set_attr "type" "multi")
16858 (set_attr "length" "5")])
16860 (define_expand "allocate_stack"
16861 [(match_operand 0 "register_operand")
16862 (match_operand 1 "general_operand")]
16863 "ix86_target_stack_probe ()"
16867 #ifndef CHECK_STACK_LIMIT
16868 #define CHECK_STACK_LIMIT 0
16871 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16872 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16876 rtx (*insn) (rtx, rtx);
16878 x = copy_to_mode_reg (Pmode, operands[1]);
16880 insn = (TARGET_64BIT
16881 ? gen_allocate_stack_worker_probe_di
16882 : gen_allocate_stack_worker_probe_si);
16884 emit_insn (insn (x, x));
16887 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16888 stack_pointer_rtx, 0, OPTAB_DIRECT);
16890 if (x != stack_pointer_rtx)
16891 emit_move_insn (stack_pointer_rtx, x);
16893 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16897 ;; Use IOR for stack probes, this is shorter.
16898 (define_expand "probe_stack"
16899 [(match_operand 0 "memory_operand")]
16902 rtx (*gen_ior3) (rtx, rtx, rtx);
16904 gen_ior3 = (GET_MODE (operands[0]) == DImode
16905 ? gen_iordi3 : gen_iorsi3);
16907 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16911 (define_insn "adjust_stack_and_probe<mode>"
16912 [(set (match_operand:P 0 "register_operand" "=r")
16913 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16914 UNSPECV_PROBE_STACK_RANGE))
16915 (set (reg:P SP_REG)
16916 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16917 (clobber (reg:CC FLAGS_REG))
16918 (clobber (mem:BLK (scratch)))]
16920 "* return output_adjust_stack_and_probe (operands[0]);"
16921 [(set_attr "type" "multi")])
16923 (define_insn "probe_stack_range<mode>"
16924 [(set (match_operand:P 0 "register_operand" "=r")
16925 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16926 (match_operand:P 2 "const_int_operand" "n")]
16927 UNSPECV_PROBE_STACK_RANGE))
16928 (clobber (reg:CC FLAGS_REG))]
16930 "* return output_probe_stack_range (operands[0], operands[2]);"
16931 [(set_attr "type" "multi")])
16933 (define_expand "builtin_setjmp_receiver"
16934 [(label_ref (match_operand 0))]
16935 "!TARGET_64BIT && flag_pic"
16941 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16942 rtx_code_label *label_rtx = gen_label_rtx ();
16943 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16944 xops[0] = xops[1] = picreg;
16945 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16946 ix86_expand_binary_operator (MINUS, SImode, xops);
16950 emit_insn (gen_set_got (pic_offset_table_rtx));
16954 (define_insn_and_split "nonlocal_goto_receiver"
16955 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16956 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16958 "&& reload_completed"
16961 if (crtl->uses_pic_offset_table)
16964 rtx label_rtx = gen_label_rtx ();
16967 /* Get a new pic base. */
16968 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16969 /* Correct this with the offset from the new to the old. */
16970 xops[0] = xops[1] = pic_offset_table_rtx;
16971 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16972 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16973 UNSPEC_MACHOPIC_OFFSET);
16974 xops[2] = gen_rtx_CONST (Pmode, tmp);
16975 ix86_expand_binary_operator (MINUS, SImode, xops);
16978 /* No pic reg restore needed. */
16979 emit_note (NOTE_INSN_DELETED);
16984 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16985 ;; Do not split instructions with mask registers.
16987 [(set (match_operand 0 "general_reg_operand")
16988 (match_operator 3 "promotable_binary_operator"
16989 [(match_operand 1 "general_reg_operand")
16990 (match_operand 2 "aligned_operand")]))
16991 (clobber (reg:CC FLAGS_REG))]
16992 "! TARGET_PARTIAL_REG_STALL && reload_completed
16993 && ((GET_MODE (operands[0]) == HImode
16994 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16995 /* ??? next two lines just !satisfies_constraint_K (...) */
16996 || !CONST_INT_P (operands[2])
16997 || satisfies_constraint_K (operands[2])))
16998 || (GET_MODE (operands[0]) == QImode
16999 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17000 [(parallel [(set (match_dup 0)
17001 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17002 (clobber (reg:CC FLAGS_REG))])]
17004 operands[0] = gen_lowpart (SImode, operands[0]);
17005 operands[1] = gen_lowpart (SImode, operands[1]);
17006 if (GET_CODE (operands[3]) != ASHIFT)
17007 operands[2] = gen_lowpart (SImode, operands[2]);
17008 PUT_MODE (operands[3], SImode);
17011 ; Promote the QImode tests, as i386 has encoding of the AND
17012 ; instruction with 32-bit sign-extended immediate and thus the
17013 ; instruction size is unchanged, except in the %eax case for
17014 ; which it is increased by one byte, hence the ! optimize_size.
17016 [(set (match_operand 0 "flags_reg_operand")
17017 (match_operator 2 "compare_operator"
17018 [(and (match_operand 3 "aligned_operand")
17019 (match_operand 4 "const_int_operand"))
17021 (set (match_operand 1 "register_operand")
17022 (and (match_dup 3) (match_dup 4)))]
17023 "! TARGET_PARTIAL_REG_STALL && reload_completed
17024 && optimize_insn_for_speed_p ()
17025 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17026 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17027 /* Ensure that the operand will remain sign-extended immediate. */
17028 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17029 [(parallel [(set (match_dup 0)
17030 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17033 (and:SI (match_dup 3) (match_dup 4)))])]
17036 = gen_int_mode (INTVAL (operands[4])
17037 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17038 operands[1] = gen_lowpart (SImode, operands[1]);
17039 operands[3] = gen_lowpart (SImode, operands[3]);
17042 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17043 ; the TEST instruction with 32-bit sign-extended immediate and thus
17044 ; the instruction size would at least double, which is not what we
17045 ; want even with ! optimize_size.
17047 [(set (match_operand 0 "flags_reg_operand")
17048 (match_operator 1 "compare_operator"
17049 [(and (match_operand:HI 2 "aligned_operand")
17050 (match_operand:HI 3 "const_int_operand"))
17052 "! TARGET_PARTIAL_REG_STALL && reload_completed
17053 && ! TARGET_FAST_PREFIX
17054 && optimize_insn_for_speed_p ()
17055 /* Ensure that the operand will remain sign-extended immediate. */
17056 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17057 [(set (match_dup 0)
17058 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17062 = gen_int_mode (INTVAL (operands[3])
17063 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17064 operands[2] = gen_lowpart (SImode, operands[2]);
17068 [(set (match_operand 0 "register_operand")
17069 (neg (match_operand 1 "register_operand")))
17070 (clobber (reg:CC FLAGS_REG))]
17071 "! TARGET_PARTIAL_REG_STALL && reload_completed
17072 && (GET_MODE (operands[0]) == HImode
17073 || (GET_MODE (operands[0]) == QImode
17074 && (TARGET_PROMOTE_QImode
17075 || optimize_insn_for_size_p ())))"
17076 [(parallel [(set (match_dup 0)
17077 (neg:SI (match_dup 1)))
17078 (clobber (reg:CC FLAGS_REG))])]
17080 operands[0] = gen_lowpart (SImode, operands[0]);
17081 operands[1] = gen_lowpart (SImode, operands[1]);
17084 ;; Do not split instructions with mask regs.
17086 [(set (match_operand 0 "general_reg_operand")
17087 (not (match_operand 1 "general_reg_operand")))]
17088 "! TARGET_PARTIAL_REG_STALL && reload_completed
17089 && (GET_MODE (operands[0]) == HImode
17090 || (GET_MODE (operands[0]) == QImode
17091 && (TARGET_PROMOTE_QImode
17092 || optimize_insn_for_size_p ())))"
17093 [(set (match_dup 0)
17094 (not:SI (match_dup 1)))]
17096 operands[0] = gen_lowpart (SImode, operands[0]);
17097 operands[1] = gen_lowpart (SImode, operands[1]);
17100 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17101 ;; transform a complex memory operation into two memory to register operations.
17103 ;; Don't push memory operands
17105 [(set (match_operand:SWI 0 "push_operand")
17106 (match_operand:SWI 1 "memory_operand"))
17107 (match_scratch:SWI 2 "<r>")]
17108 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17109 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17110 [(set (match_dup 2) (match_dup 1))
17111 (set (match_dup 0) (match_dup 2))])
17113 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17116 [(set (match_operand:SF 0 "push_operand")
17117 (match_operand:SF 1 "memory_operand"))
17118 (match_scratch:SF 2 "r")]
17119 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17120 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17121 [(set (match_dup 2) (match_dup 1))
17122 (set (match_dup 0) (match_dup 2))])
17124 ;; Don't move an immediate directly to memory when the instruction
17125 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17127 [(match_scratch:SWI124 1 "<r>")
17128 (set (match_operand:SWI124 0 "memory_operand")
17130 "optimize_insn_for_speed_p ()
17131 && ((<MODE>mode == HImode
17132 && TARGET_LCP_STALL)
17133 || (!TARGET_USE_MOV0
17134 && TARGET_SPLIT_LONG_MOVES
17135 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17136 && peep2_regno_dead_p (0, FLAGS_REG)"
17137 [(parallel [(set (match_dup 2) (const_int 0))
17138 (clobber (reg:CC FLAGS_REG))])
17139 (set (match_dup 0) (match_dup 1))]
17140 "operands[2] = gen_lowpart (SImode, operands[1]);")
17143 [(match_scratch:SWI124 2 "<r>")
17144 (set (match_operand:SWI124 0 "memory_operand")
17145 (match_operand:SWI124 1 "immediate_operand"))]
17146 "optimize_insn_for_speed_p ()
17147 && ((<MODE>mode == HImode
17148 && TARGET_LCP_STALL)
17149 || (TARGET_SPLIT_LONG_MOVES
17150 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17151 [(set (match_dup 2) (match_dup 1))
17152 (set (match_dup 0) (match_dup 2))])
17154 ;; Don't compare memory with zero, load and use a test instead.
17156 [(set (match_operand 0 "flags_reg_operand")
17157 (match_operator 1 "compare_operator"
17158 [(match_operand:SI 2 "memory_operand")
17160 (match_scratch:SI 3 "r")]
17161 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17162 [(set (match_dup 3) (match_dup 2))
17163 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17165 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17166 ;; Don't split NOTs with a displacement operand, because resulting XOR
17167 ;; will not be pairable anyway.
17169 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17170 ;; represented using a modRM byte. The XOR replacement is long decoded,
17171 ;; so this split helps here as well.
17173 ;; Note: Can't do this as a regular split because we can't get proper
17174 ;; lifetime information then.
17177 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17178 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17179 "optimize_insn_for_speed_p ()
17180 && ((TARGET_NOT_UNPAIRABLE
17181 && (!MEM_P (operands[0])
17182 || !memory_displacement_operand (operands[0], <MODE>mode)))
17183 || (TARGET_NOT_VECTORMODE
17184 && long_memory_operand (operands[0], <MODE>mode)))
17185 && peep2_regno_dead_p (0, FLAGS_REG)"
17186 [(parallel [(set (match_dup 0)
17187 (xor:SWI124 (match_dup 1) (const_int -1)))
17188 (clobber (reg:CC FLAGS_REG))])])
17190 ;; Non pairable "test imm, reg" instructions can be translated to
17191 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17192 ;; byte opcode instead of two, have a short form for byte operands),
17193 ;; so do it for other CPUs as well. Given that the value was dead,
17194 ;; this should not create any new dependencies. Pass on the sub-word
17195 ;; versions if we're concerned about partial register stalls.
17198 [(set (match_operand 0 "flags_reg_operand")
17199 (match_operator 1 "compare_operator"
17200 [(and:SI (match_operand:SI 2 "register_operand")
17201 (match_operand:SI 3 "immediate_operand"))
17203 "ix86_match_ccmode (insn, CCNOmode)
17204 && (true_regnum (operands[2]) != AX_REG
17205 || satisfies_constraint_K (operands[3]))
17206 && peep2_reg_dead_p (1, operands[2])"
17208 [(set (match_dup 0)
17209 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17212 (and:SI (match_dup 2) (match_dup 3)))])])
17214 ;; We don't need to handle HImode case, because it will be promoted to SImode
17215 ;; on ! TARGET_PARTIAL_REG_STALL
17218 [(set (match_operand 0 "flags_reg_operand")
17219 (match_operator 1 "compare_operator"
17220 [(and:QI (match_operand:QI 2 "register_operand")
17221 (match_operand:QI 3 "immediate_operand"))
17223 "! TARGET_PARTIAL_REG_STALL
17224 && ix86_match_ccmode (insn, CCNOmode)
17225 && true_regnum (operands[2]) != AX_REG
17226 && peep2_reg_dead_p (1, operands[2])"
17228 [(set (match_dup 0)
17229 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17232 (and:QI (match_dup 2) (match_dup 3)))])])
17235 [(set (match_operand 0 "flags_reg_operand")
17236 (match_operator 1 "compare_operator"
17239 (match_operand 2 "ext_register_operand")
17242 (match_operand 3 "const_int_operand"))
17244 "! TARGET_PARTIAL_REG_STALL
17245 && ix86_match_ccmode (insn, CCNOmode)
17246 && true_regnum (operands[2]) != AX_REG
17247 && peep2_reg_dead_p (1, operands[2])"
17248 [(parallel [(set (match_dup 0)
17257 (set (zero_extract:SI (match_dup 2)
17265 (match_dup 3)))])])
17267 ;; Don't do logical operations with memory inputs.
17269 [(match_scratch:SI 2 "r")
17270 (parallel [(set (match_operand:SI 0 "register_operand")
17271 (match_operator:SI 3 "arith_or_logical_operator"
17273 (match_operand:SI 1 "memory_operand")]))
17274 (clobber (reg:CC FLAGS_REG))])]
17275 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17276 [(set (match_dup 2) (match_dup 1))
17277 (parallel [(set (match_dup 0)
17278 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17279 (clobber (reg:CC FLAGS_REG))])])
17282 [(match_scratch:SI 2 "r")
17283 (parallel [(set (match_operand:SI 0 "register_operand")
17284 (match_operator:SI 3 "arith_or_logical_operator"
17285 [(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 2) (match_dup 0)]))
17292 (clobber (reg:CC FLAGS_REG))])])
17294 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17295 ;; refers to the destination of the load!
17298 [(set (match_operand:SI 0 "register_operand")
17299 (match_operand:SI 1 "register_operand"))
17300 (parallel [(set (match_dup 0)
17301 (match_operator:SI 3 "commutative_operator"
17303 (match_operand:SI 2 "memory_operand")]))
17304 (clobber (reg:CC FLAGS_REG))])]
17305 "REGNO (operands[0]) != REGNO (operands[1])
17306 && GENERAL_REGNO_P (REGNO (operands[0]))
17307 && GENERAL_REGNO_P (REGNO (operands[1]))"
17308 [(set (match_dup 0) (match_dup 4))
17309 (parallel [(set (match_dup 0)
17310 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17315 [(set (match_operand 0 "register_operand")
17316 (match_operand 1 "register_operand"))
17318 (match_operator 3 "commutative_operator"
17320 (match_operand 2 "memory_operand")]))]
17321 "REGNO (operands[0]) != REGNO (operands[1])
17322 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17323 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17324 [(set (match_dup 0) (match_dup 2))
17326 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17328 ; Don't do logical operations with memory outputs
17330 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17331 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17332 ; the same decoder scheduling characteristics as the original.
17335 [(match_scratch:SI 2 "r")
17336 (parallel [(set (match_operand:SI 0 "memory_operand")
17337 (match_operator:SI 3 "arith_or_logical_operator"
17339 (match_operand:SI 1 "nonmemory_operand")]))
17340 (clobber (reg:CC FLAGS_REG))])]
17341 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17342 /* Do not split stack checking probes. */
17343 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17344 [(set (match_dup 2) (match_dup 0))
17345 (parallel [(set (match_dup 2)
17346 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17347 (clobber (reg:CC FLAGS_REG))])
17348 (set (match_dup 0) (match_dup 2))])
17351 [(match_scratch:SI 2 "r")
17352 (parallel [(set (match_operand:SI 0 "memory_operand")
17353 (match_operator:SI 3 "arith_or_logical_operator"
17354 [(match_operand:SI 1 "nonmemory_operand")
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17358 /* Do not split stack checking probes. */
17359 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17360 [(set (match_dup 2) (match_dup 0))
17361 (parallel [(set (match_dup 2)
17362 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17363 (clobber (reg:CC FLAGS_REG))])
17364 (set (match_dup 0) (match_dup 2))])
17366 ;; Attempt to use arith or logical operations with memory outputs with
17367 ;; setting of flags.
17369 [(set (match_operand:SWI 0 "register_operand")
17370 (match_operand:SWI 1 "memory_operand"))
17371 (parallel [(set (match_dup 0)
17372 (match_operator:SWI 3 "plusminuslogic_operator"
17374 (match_operand:SWI 2 "<nonmemory_operand>")]))
17375 (clobber (reg:CC FLAGS_REG))])
17376 (set (match_dup 1) (match_dup 0))
17377 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17378 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17379 && peep2_reg_dead_p (4, operands[0])
17380 && !reg_overlap_mentioned_p (operands[0], operands[1])
17381 && !reg_overlap_mentioned_p (operands[0], operands[2])
17382 && (<MODE>mode != QImode
17383 || immediate_operand (operands[2], QImode)
17384 || q_regs_operand (operands[2], QImode))
17385 && ix86_match_ccmode (peep2_next_insn (3),
17386 (GET_CODE (operands[3]) == PLUS
17387 || GET_CODE (operands[3]) == MINUS)
17388 ? CCGOCmode : CCNOmode)"
17389 [(parallel [(set (match_dup 4) (match_dup 5))
17390 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17391 (match_dup 2)]))])]
17393 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17394 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17395 copy_rtx (operands[1]),
17396 copy_rtx (operands[2]));
17397 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17398 operands[5], const0_rtx);
17402 [(parallel [(set (match_operand:SWI 0 "register_operand")
17403 (match_operator:SWI 2 "plusminuslogic_operator"
17405 (match_operand:SWI 1 "memory_operand")]))
17406 (clobber (reg:CC FLAGS_REG))])
17407 (set (match_dup 1) (match_dup 0))
17408 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17409 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17410 && GET_CODE (operands[2]) != MINUS
17411 && peep2_reg_dead_p (3, operands[0])
17412 && !reg_overlap_mentioned_p (operands[0], operands[1])
17413 && ix86_match_ccmode (peep2_next_insn (2),
17414 GET_CODE (operands[2]) == PLUS
17415 ? CCGOCmode : CCNOmode)"
17416 [(parallel [(set (match_dup 3) (match_dup 4))
17417 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17418 (match_dup 0)]))])]
17420 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17421 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17422 copy_rtx (operands[1]),
17423 copy_rtx (operands[0]));
17424 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17425 operands[4], const0_rtx);
17429 [(set (match_operand:SWI12 0 "register_operand")
17430 (match_operand:SWI12 1 "memory_operand"))
17431 (parallel [(set (match_operand:SI 4 "register_operand")
17432 (match_operator:SI 3 "plusminuslogic_operator"
17434 (match_operand:SI 2 "nonmemory_operand")]))
17435 (clobber (reg:CC FLAGS_REG))])
17436 (set (match_dup 1) (match_dup 0))
17437 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17438 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17439 && REG_P (operands[0]) && REG_P (operands[4])
17440 && REGNO (operands[0]) == REGNO (operands[4])
17441 && peep2_reg_dead_p (4, operands[0])
17442 && (<MODE>mode != QImode
17443 || immediate_operand (operands[2], SImode)
17444 || q_regs_operand (operands[2], SImode))
17445 && !reg_overlap_mentioned_p (operands[0], operands[1])
17446 && !reg_overlap_mentioned_p (operands[0], operands[2])
17447 && ix86_match_ccmode (peep2_next_insn (3),
17448 (GET_CODE (operands[3]) == PLUS
17449 || GET_CODE (operands[3]) == MINUS)
17450 ? CCGOCmode : CCNOmode)"
17451 [(parallel [(set (match_dup 4) (match_dup 5))
17452 (set (match_dup 1) (match_dup 6))])]
17454 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17455 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17456 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17457 copy_rtx (operands[1]), operands[2]);
17458 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17459 operands[5], const0_rtx);
17460 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17461 copy_rtx (operands[1]),
17462 copy_rtx (operands[2]));
17465 ;; Attempt to always use XOR for zeroing registers.
17467 [(set (match_operand 0 "register_operand")
17468 (match_operand 1 "const0_operand"))]
17469 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17470 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17471 && GENERAL_REG_P (operands[0])
17472 && peep2_regno_dead_p (0, FLAGS_REG)"
17473 [(parallel [(set (match_dup 0) (const_int 0))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17478 [(set (strict_low_part (match_operand 0 "register_operand"))
17480 "(GET_MODE (operands[0]) == QImode
17481 || GET_MODE (operands[0]) == HImode)
17482 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17483 && peep2_regno_dead_p (0, FLAGS_REG)"
17484 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17485 (clobber (reg:CC FLAGS_REG))])])
17487 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17489 [(set (match_operand:SWI248 0 "register_operand")
17491 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17492 && peep2_regno_dead_p (0, FLAGS_REG)"
17493 [(parallel [(set (match_dup 0) (const_int -1))
17494 (clobber (reg:CC FLAGS_REG))])]
17496 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17497 operands[0] = gen_lowpart (SImode, operands[0]);
17500 ;; Attempt to convert simple lea to add/shift.
17501 ;; These can be created by move expanders.
17502 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17503 ;; relevant lea instructions were already split.
17506 [(set (match_operand:SWI48 0 "register_operand")
17507 (plus:SWI48 (match_dup 0)
17508 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17510 && peep2_regno_dead_p (0, FLAGS_REG)"
17511 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17512 (clobber (reg:CC FLAGS_REG))])])
17515 [(set (match_operand:SWI48 0 "register_operand")
17516 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17519 && peep2_regno_dead_p (0, FLAGS_REG)"
17520 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17521 (clobber (reg:CC FLAGS_REG))])])
17524 [(set (match_operand:DI 0 "register_operand")
17526 (plus:SI (match_operand:SI 1 "register_operand")
17527 (match_operand:SI 2 "nonmemory_operand"))))]
17528 "TARGET_64BIT && !TARGET_OPT_AGU
17529 && REGNO (operands[0]) == REGNO (operands[1])
17530 && peep2_regno_dead_p (0, FLAGS_REG)"
17531 [(parallel [(set (match_dup 0)
17532 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17533 (clobber (reg:CC FLAGS_REG))])])
17536 [(set (match_operand:DI 0 "register_operand")
17538 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17539 (match_operand:SI 2 "register_operand"))))]
17540 "TARGET_64BIT && !TARGET_OPT_AGU
17541 && REGNO (operands[0]) == REGNO (operands[2])
17542 && peep2_regno_dead_p (0, FLAGS_REG)"
17543 [(parallel [(set (match_dup 0)
17544 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17545 (clobber (reg:CC FLAGS_REG))])])
17548 [(set (match_operand:SWI48 0 "register_operand")
17549 (mult:SWI48 (match_dup 0)
17550 (match_operand:SWI48 1 "const_int_operand")))]
17551 "exact_log2 (INTVAL (operands[1])) >= 0
17552 && peep2_regno_dead_p (0, FLAGS_REG)"
17553 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17554 (clobber (reg:CC FLAGS_REG))])]
17555 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17558 [(set (match_operand:DI 0 "register_operand")
17560 (mult:SI (match_operand:SI 1 "register_operand")
17561 (match_operand:SI 2 "const_int_operand"))))]
17563 && exact_log2 (INTVAL (operands[2])) >= 0
17564 && REGNO (operands[0]) == REGNO (operands[1])
17565 && peep2_regno_dead_p (0, FLAGS_REG)"
17566 [(parallel [(set (match_dup 0)
17567 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17568 (clobber (reg:CC FLAGS_REG))])]
17569 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17571 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17572 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17573 ;; On many CPUs it is also faster, since special hardware to avoid esp
17574 ;; dependencies is present.
17576 ;; While some of these conversions may be done using splitters, we use
17577 ;; peepholes in order to allow combine_stack_adjustments pass to see
17578 ;; nonobfuscated RTL.
17580 ;; Convert prologue esp subtractions to push.
17581 ;; We need register to push. In order to keep verify_flow_info happy we have
17583 ;; - use scratch and clobber it in order to avoid dependencies
17584 ;; - use already live register
17585 ;; We can't use the second way right now, since there is no reliable way how to
17586 ;; verify that given register is live. First choice will also most likely in
17587 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17588 ;; call clobbered registers are dead. We may want to use base pointer as an
17589 ;; alternative when no register is available later.
17592 [(match_scratch:W 1 "r")
17593 (parallel [(set (reg:P SP_REG)
17594 (plus:P (reg:P SP_REG)
17595 (match_operand:P 0 "const_int_operand")))
17596 (clobber (reg:CC FLAGS_REG))
17597 (clobber (mem:BLK (scratch)))])]
17598 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17599 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17600 [(clobber (match_dup 1))
17601 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17602 (clobber (mem:BLK (scratch)))])])
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_DOUBLE_PUSH || optimize_insn_for_size_p ())
17612 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17613 [(clobber (match_dup 1))
17614 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17615 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17616 (clobber (mem:BLK (scratch)))])])
17618 ;; Convert esp subtractions to push.
17620 [(match_scratch:W 1 "r")
17621 (parallel [(set (reg:P SP_REG)
17622 (plus:P (reg:P SP_REG)
17623 (match_operand:P 0 "const_int_operand")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17626 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17627 [(clobber (match_dup 1))
17628 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17631 [(match_scratch:W 1 "r")
17632 (parallel [(set (reg:P SP_REG)
17633 (plus:P (reg:P SP_REG)
17634 (match_operand:P 0 "const_int_operand")))
17635 (clobber (reg:CC FLAGS_REG))])]
17636 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17637 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17638 [(clobber (match_dup 1))
17639 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17640 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17642 ;; Convert epilogue deallocator to pop.
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 (clobber (mem:BLK (scratch)))])]
17650 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17651 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17652 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17653 (clobber (mem:BLK (scratch)))])])
17655 ;; Two pops case is tricky, since pop causes dependency
17656 ;; on destination register. We use two registers if available.
17658 [(match_scratch:W 1 "r")
17659 (match_scratch:W 2 "r")
17660 (parallel [(set (reg:P SP_REG)
17661 (plus:P (reg:P SP_REG)
17662 (match_operand:P 0 "const_int_operand")))
17663 (clobber (reg:CC FLAGS_REG))
17664 (clobber (mem:BLK (scratch)))])]
17665 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17666 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17667 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17668 (clobber (mem:BLK (scratch)))])
17669 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17672 [(match_scratch:W 1 "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 "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 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17684 ;; Convert esp additions to pop.
17686 [(match_scratch:W 1 "r")
17687 (parallel [(set (reg:P SP_REG)
17688 (plus:P (reg:P SP_REG)
17689 (match_operand:P 0 "const_int_operand")))
17690 (clobber (reg:CC FLAGS_REG))])]
17691 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17692 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17694 ;; Two pops case is tricky, since pop causes dependency
17695 ;; on destination register. We use two registers if available.
17697 [(match_scratch:W 1 "r")
17698 (match_scratch:W 2 "r")
17699 (parallel [(set (reg:P SP_REG)
17700 (plus:P (reg:P SP_REG)
17701 (match_operand:P 0 "const_int_operand")))
17702 (clobber (reg:CC FLAGS_REG))])]
17703 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17704 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17705 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17708 [(match_scratch:W 1 "r")
17709 (parallel [(set (reg:P SP_REG)
17710 (plus:P (reg:P SP_REG)
17711 (match_operand:P 0 "const_int_operand")))
17712 (clobber (reg:CC FLAGS_REG))])]
17713 "optimize_insn_for_size_p ()
17714 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17715 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17716 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17718 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17719 ;; required and register dies. Similarly for 128 to -128.
17721 [(set (match_operand 0 "flags_reg_operand")
17722 (match_operator 1 "compare_operator"
17723 [(match_operand 2 "register_operand")
17724 (match_operand 3 "const_int_operand")]))]
17725 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17726 && incdec_operand (operands[3], GET_MODE (operands[3])))
17727 || (!TARGET_FUSE_CMP_AND_BRANCH
17728 && INTVAL (operands[3]) == 128))
17729 && ix86_match_ccmode (insn, CCGCmode)
17730 && peep2_reg_dead_p (1, operands[2])"
17731 [(parallel [(set (match_dup 0)
17732 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17733 (clobber (match_dup 2))])])
17735 ;; Convert imul by three, five and nine into lea
17738 [(set (match_operand:SWI48 0 "register_operand")
17739 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17740 (match_operand:SWI48 2 "const359_operand")))
17741 (clobber (reg:CC FLAGS_REG))])]
17742 "!TARGET_PARTIAL_REG_STALL
17743 || <MODE>mode == SImode
17744 || optimize_function_for_size_p (cfun)"
17745 [(set (match_dup 0)
17746 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17748 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17752 [(set (match_operand:SWI48 0 "register_operand")
17753 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17754 (match_operand:SWI48 2 "const359_operand")))
17755 (clobber (reg:CC FLAGS_REG))])]
17756 "optimize_insn_for_speed_p ()
17757 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17758 [(set (match_dup 0) (match_dup 1))
17760 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17762 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17764 ;; imul $32bit_imm, mem, reg is vector decoded, while
17765 ;; imul $32bit_imm, reg, reg is direct decoded.
17767 [(match_scratch:SWI48 3 "r")
17768 (parallel [(set (match_operand:SWI48 0 "register_operand")
17769 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17770 (match_operand:SWI48 2 "immediate_operand")))
17771 (clobber (reg:CC FLAGS_REG))])]
17772 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17773 && !satisfies_constraint_K (operands[2])"
17774 [(set (match_dup 3) (match_dup 1))
17775 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17776 (clobber (reg:CC FLAGS_REG))])])
17779 [(match_scratch:SI 3 "r")
17780 (parallel [(set (match_operand:DI 0 "register_operand")
17782 (mult:SI (match_operand:SI 1 "memory_operand")
17783 (match_operand:SI 2 "immediate_operand"))))
17784 (clobber (reg:CC FLAGS_REG))])]
17786 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17787 && !satisfies_constraint_K (operands[2])"
17788 [(set (match_dup 3) (match_dup 1))
17789 (parallel [(set (match_dup 0)
17790 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17791 (clobber (reg:CC FLAGS_REG))])])
17793 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17794 ;; Convert it into imul reg, reg
17795 ;; It would be better to force assembler to encode instruction using long
17796 ;; immediate, but there is apparently no way to do so.
17798 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17800 (match_operand:SWI248 1 "nonimmediate_operand")
17801 (match_operand:SWI248 2 "const_int_operand")))
17802 (clobber (reg:CC FLAGS_REG))])
17803 (match_scratch:SWI248 3 "r")]
17804 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17805 && satisfies_constraint_K (operands[2])"
17806 [(set (match_dup 3) (match_dup 2))
17807 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17808 (clobber (reg:CC FLAGS_REG))])]
17810 if (!rtx_equal_p (operands[0], operands[1]))
17811 emit_move_insn (operands[0], operands[1]);
17814 ;; After splitting up read-modify operations, array accesses with memory
17815 ;; operands might end up in form:
17817 ;; movl 4(%esp), %edx
17819 ;; instead of pre-splitting:
17821 ;; addl 4(%esp), %eax
17823 ;; movl 4(%esp), %edx
17824 ;; leal (%edx,%eax,4), %eax
17827 [(match_scratch:W 5 "r")
17828 (parallel [(set (match_operand 0 "register_operand")
17829 (ashift (match_operand 1 "register_operand")
17830 (match_operand 2 "const_int_operand")))
17831 (clobber (reg:CC FLAGS_REG))])
17832 (parallel [(set (match_operand 3 "register_operand")
17833 (plus (match_dup 0)
17834 (match_operand 4 "x86_64_general_operand")))
17835 (clobber (reg:CC FLAGS_REG))])]
17836 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17837 /* Validate MODE for lea. */
17838 && ((!TARGET_PARTIAL_REG_STALL
17839 && (GET_MODE (operands[0]) == QImode
17840 || GET_MODE (operands[0]) == HImode))
17841 || GET_MODE (operands[0]) == SImode
17842 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17843 && (rtx_equal_p (operands[0], operands[3])
17844 || peep2_reg_dead_p (2, operands[0]))
17845 /* We reorder load and the shift. */
17846 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17847 [(set (match_dup 5) (match_dup 4))
17848 (set (match_dup 0) (match_dup 1))]
17850 machine_mode op1mode = GET_MODE (operands[1]);
17851 machine_mode mode = op1mode == DImode ? DImode : SImode;
17852 int scale = 1 << INTVAL (operands[2]);
17853 rtx index = gen_lowpart (word_mode, operands[1]);
17854 rtx base = gen_lowpart (word_mode, operands[5]);
17855 rtx dest = gen_lowpart (mode, operands[3]);
17857 operands[1] = gen_rtx_PLUS (word_mode, base,
17858 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17859 operands[5] = base;
17860 if (mode != word_mode)
17861 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17862 if (op1mode != word_mode)
17863 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17864 operands[0] = dest;
17867 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17868 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17869 ;; caught for use by garbage collectors and the like. Using an insn that
17870 ;; maps to SIGILL makes it more likely the program will rightfully die.
17871 ;; Keeping with tradition, "6" is in honor of #UD.
17872 (define_insn "trap"
17873 [(trap_if (const_int 1) (const_int 6))]
17876 #ifdef HAVE_AS_IX86_UD2
17879 return ASM_SHORT "0x0b0f";
17882 [(set_attr "length" "2")])
17884 (define_expand "prefetch"
17885 [(prefetch (match_operand 0 "address_operand")
17886 (match_operand:SI 1 "const_int_operand")
17887 (match_operand:SI 2 "const_int_operand"))]
17888 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17890 bool write = INTVAL (operands[1]) != 0;
17891 int locality = INTVAL (operands[2]);
17893 gcc_assert (IN_RANGE (locality, 0, 3));
17895 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17896 supported by SSE counterpart or the SSE prefetch is not available
17897 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17899 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17900 operands[2] = const2_rtx;
17901 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17902 operands[2] = GEN_INT (3);
17904 operands[1] = const0_rtx;
17907 (define_insn "*prefetch_sse"
17908 [(prefetch (match_operand 0 "address_operand" "p")
17910 (match_operand:SI 1 "const_int_operand"))]
17911 "TARGET_PREFETCH_SSE"
17913 static const char * const patterns[4] = {
17914 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17917 int locality = INTVAL (operands[1]);
17918 gcc_assert (IN_RANGE (locality, 0, 3));
17920 return patterns[locality];
17922 [(set_attr "type" "sse")
17923 (set_attr "atom_sse_attr" "prefetch")
17924 (set (attr "length_address")
17925 (symbol_ref "memory_address_length (operands[0], false)"))
17926 (set_attr "memory" "none")])
17928 (define_insn "*prefetch_3dnow"
17929 [(prefetch (match_operand 0 "address_operand" "p")
17930 (match_operand:SI 1 "const_int_operand" "n")
17934 if (INTVAL (operands[1]) == 0)
17935 return "prefetch\t%a0";
17937 return "prefetchw\t%a0";
17939 [(set_attr "type" "mmx")
17940 (set (attr "length_address")
17941 (symbol_ref "memory_address_length (operands[0], false)"))
17942 (set_attr "memory" "none")])
17944 (define_insn "*prefetch_prefetchwt1_<mode>"
17945 [(prefetch (match_operand:P 0 "address_operand" "p")
17948 "TARGET_PREFETCHWT1"
17949 "prefetchwt1\t%a0";
17950 [(set_attr "type" "sse")
17951 (set (attr "length_address")
17952 (symbol_ref "memory_address_length (operands[0], false)"))
17953 (set_attr "memory" "none")])
17955 (define_expand "stack_protect_set"
17956 [(match_operand 0 "memory_operand")
17957 (match_operand 1 "memory_operand")]
17958 "TARGET_SSP_TLS_GUARD"
17960 rtx (*insn)(rtx, rtx);
17962 #ifdef TARGET_THREAD_SSP_OFFSET
17963 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17964 insn = (TARGET_LP64
17965 ? gen_stack_tls_protect_set_di
17966 : gen_stack_tls_protect_set_si);
17968 insn = (TARGET_LP64
17969 ? gen_stack_protect_set_di
17970 : gen_stack_protect_set_si);
17973 emit_insn (insn (operands[0], operands[1]));
17977 (define_insn "stack_protect_set_<mode>"
17978 [(set (match_operand:PTR 0 "memory_operand" "=m")
17979 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17981 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17982 (clobber (reg:CC FLAGS_REG))]
17983 "TARGET_SSP_TLS_GUARD"
17984 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17985 [(set_attr "type" "multi")])
17987 (define_insn "stack_tls_protect_set_<mode>"
17988 [(set (match_operand:PTR 0 "memory_operand" "=m")
17989 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17990 UNSPEC_SP_TLS_SET))
17991 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17992 (clobber (reg:CC FLAGS_REG))]
17994 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17995 [(set_attr "type" "multi")])
17997 (define_expand "stack_protect_test"
17998 [(match_operand 0 "memory_operand")
17999 (match_operand 1 "memory_operand")
18001 "TARGET_SSP_TLS_GUARD"
18003 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18005 rtx (*insn)(rtx, rtx, rtx);
18007 #ifdef TARGET_THREAD_SSP_OFFSET
18008 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18009 insn = (TARGET_LP64
18010 ? gen_stack_tls_protect_test_di
18011 : gen_stack_tls_protect_test_si);
18013 insn = (TARGET_LP64
18014 ? gen_stack_protect_test_di
18015 : gen_stack_protect_test_si);
18018 emit_insn (insn (flags, operands[0], operands[1]));
18020 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18021 flags, const0_rtx, operands[2]));
18025 (define_insn "stack_protect_test_<mode>"
18026 [(set (match_operand:CCZ 0 "flags_reg_operand")
18027 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18028 (match_operand:PTR 2 "memory_operand" "m")]
18030 (clobber (match_scratch:PTR 3 "=&r"))]
18031 "TARGET_SSP_TLS_GUARD"
18032 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18033 [(set_attr "type" "multi")])
18035 (define_insn "stack_tls_protect_test_<mode>"
18036 [(set (match_operand:CCZ 0 "flags_reg_operand")
18037 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18038 (match_operand:PTR 2 "const_int_operand" "i")]
18039 UNSPEC_SP_TLS_TEST))
18040 (clobber (match_scratch:PTR 3 "=r"))]
18042 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18043 [(set_attr "type" "multi")])
18045 (define_insn "sse4_2_crc32<mode>"
18046 [(set (match_operand:SI 0 "register_operand" "=r")
18048 [(match_operand:SI 1 "register_operand" "0")
18049 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18051 "TARGET_SSE4_2 || TARGET_CRC32"
18052 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18053 [(set_attr "type" "sselog1")
18054 (set_attr "prefix_rep" "1")
18055 (set_attr "prefix_extra" "1")
18056 (set (attr "prefix_data16")
18057 (if_then_else (match_operand:HI 2)
18059 (const_string "*")))
18060 (set (attr "prefix_rex")
18061 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18063 (const_string "*")))
18064 (set_attr "mode" "SI")])
18066 (define_insn "sse4_2_crc32di"
18067 [(set (match_operand:DI 0 "register_operand" "=r")
18069 [(match_operand:DI 1 "register_operand" "0")
18070 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18072 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18073 "crc32{q}\t{%2, %0|%0, %2}"
18074 [(set_attr "type" "sselog1")
18075 (set_attr "prefix_rep" "1")
18076 (set_attr "prefix_extra" "1")
18077 (set_attr "mode" "DI")])
18079 (define_insn "rdpmc"
18080 [(set (match_operand:DI 0 "register_operand" "=A")
18081 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18085 [(set_attr "type" "other")
18086 (set_attr "length" "2")])
18088 (define_insn "rdpmc_rex64"
18089 [(set (match_operand:DI 0 "register_operand" "=a")
18090 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18092 (set (match_operand:DI 1 "register_operand" "=d")
18093 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18096 [(set_attr "type" "other")
18097 (set_attr "length" "2")])
18099 (define_insn "rdtsc"
18100 [(set (match_operand:DI 0 "register_operand" "=A")
18101 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18104 [(set_attr "type" "other")
18105 (set_attr "length" "2")])
18107 (define_insn "rdtsc_rex64"
18108 [(set (match_operand:DI 0 "register_operand" "=a")
18109 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18110 (set (match_operand:DI 1 "register_operand" "=d")
18111 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18114 [(set_attr "type" "other")
18115 (set_attr "length" "2")])
18117 (define_insn "rdtscp"
18118 [(set (match_operand:DI 0 "register_operand" "=A")
18119 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18120 (set (match_operand:SI 1 "register_operand" "=c")
18121 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18124 [(set_attr "type" "other")
18125 (set_attr "length" "3")])
18127 (define_insn "rdtscp_rex64"
18128 [(set (match_operand:DI 0 "register_operand" "=a")
18129 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18130 (set (match_operand:DI 1 "register_operand" "=d")
18131 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18132 (set (match_operand:SI 2 "register_operand" "=c")
18133 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18136 [(set_attr "type" "other")
18137 (set_attr "length" "3")])
18139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18141 ;; FXSR, XSAVE and XSAVEOPT instructions
18143 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18145 (define_insn "fxsave"
18146 [(set (match_operand:BLK 0 "memory_operand" "=m")
18147 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18150 [(set_attr "type" "other")
18151 (set_attr "memory" "store")
18152 (set (attr "length")
18153 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18155 (define_insn "fxsave64"
18156 [(set (match_operand:BLK 0 "memory_operand" "=m")
18157 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18158 "TARGET_64BIT && TARGET_FXSR"
18160 [(set_attr "type" "other")
18161 (set_attr "memory" "store")
18162 (set (attr "length")
18163 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18165 (define_insn "fxrstor"
18166 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18170 [(set_attr "type" "other")
18171 (set_attr "memory" "load")
18172 (set (attr "length")
18173 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18175 (define_insn "fxrstor64"
18176 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18177 UNSPECV_FXRSTOR64)]
18178 "TARGET_64BIT && TARGET_FXSR"
18180 [(set_attr "type" "other")
18181 (set_attr "memory" "load")
18182 (set (attr "length")
18183 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18185 (define_int_iterator ANY_XSAVE
18187 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18188 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18189 (UNSPECV_XSAVES "TARGET_XSAVES")])
18191 (define_int_iterator ANY_XSAVE64
18193 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18194 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18195 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18197 (define_int_attr xsave
18198 [(UNSPECV_XSAVE "xsave")
18199 (UNSPECV_XSAVE64 "xsave64")
18200 (UNSPECV_XSAVEOPT "xsaveopt")
18201 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18202 (UNSPECV_XSAVEC "xsavec")
18203 (UNSPECV_XSAVEC64 "xsavec64")
18204 (UNSPECV_XSAVES "xsaves")
18205 (UNSPECV_XSAVES64 "xsaves64")])
18207 (define_int_iterator ANY_XRSTOR
18209 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18211 (define_int_iterator ANY_XRSTOR64
18213 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18215 (define_int_attr xrstor
18216 [(UNSPECV_XRSTOR "xrstor")
18217 (UNSPECV_XRSTOR64 "xrstor")
18218 (UNSPECV_XRSTORS "xrstors")
18219 (UNSPECV_XRSTORS64 "xrstors")])
18221 (define_insn "<xsave>"
18222 [(set (match_operand:BLK 0 "memory_operand" "=m")
18223 (unspec_volatile:BLK
18224 [(match_operand:DI 1 "register_operand" "A")]
18226 "!TARGET_64BIT && TARGET_XSAVE"
18228 [(set_attr "type" "other")
18229 (set_attr "memory" "store")
18230 (set (attr "length")
18231 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18233 (define_insn "<xsave>_rex64"
18234 [(set (match_operand:BLK 0 "memory_operand" "=m")
18235 (unspec_volatile:BLK
18236 [(match_operand:SI 1 "register_operand" "a")
18237 (match_operand:SI 2 "register_operand" "d")]
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>"
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) + 4"))])
18259 (define_insn "<xrstor>"
18260 [(unspec_volatile:BLK
18261 [(match_operand:BLK 0 "memory_operand" "m")
18262 (match_operand:DI 1 "register_operand" "A")]
18264 "!TARGET_64BIT && TARGET_XSAVE"
18266 [(set_attr "type" "other")
18267 (set_attr "memory" "load")
18268 (set (attr "length")
18269 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18271 (define_insn "<xrstor>_rex64"
18272 [(unspec_volatile:BLK
18273 [(match_operand:BLK 0 "memory_operand" "m")
18274 (match_operand:SI 1 "register_operand" "a")
18275 (match_operand:SI 2 "register_operand" "d")]
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>64"
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) + 4"))])
18297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18299 ;; Floating-point instructions for atomic compound assignments
18301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18303 ; Clobber all floating-point registers on environment save and restore
18304 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18305 (define_insn "fnstenv"
18306 [(set (match_operand:BLK 0 "memory_operand" "=m")
18307 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18308 (clobber (reg:HI FPCR_REG))
18309 (clobber (reg:XF ST0_REG))
18310 (clobber (reg:XF ST1_REG))
18311 (clobber (reg:XF ST2_REG))
18312 (clobber (reg:XF ST3_REG))
18313 (clobber (reg:XF ST4_REG))
18314 (clobber (reg:XF ST5_REG))
18315 (clobber (reg:XF ST6_REG))
18316 (clobber (reg:XF ST7_REG))]
18319 [(set_attr "type" "other")
18320 (set_attr "memory" "store")
18321 (set (attr "length")
18322 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18324 (define_insn "fldenv"
18325 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18327 (clobber (reg:CCFP FPSR_REG))
18328 (clobber (reg:HI FPCR_REG))
18329 (clobber (reg:XF ST0_REG))
18330 (clobber (reg:XF ST1_REG))
18331 (clobber (reg:XF ST2_REG))
18332 (clobber (reg:XF ST3_REG))
18333 (clobber (reg:XF ST4_REG))
18334 (clobber (reg:XF ST5_REG))
18335 (clobber (reg:XF ST6_REG))
18336 (clobber (reg:XF ST7_REG))]
18339 [(set_attr "type" "other")
18340 (set_attr "memory" "load")
18341 (set (attr "length")
18342 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18344 (define_insn "fnstsw"
18345 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18346 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18349 [(set_attr "type" "other,other")
18350 (set_attr "memory" "none,store")
18351 (set (attr "length")
18352 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18354 (define_insn "fnclex"
18355 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18358 [(set_attr "type" "other")
18359 (set_attr "memory" "none")
18360 (set_attr "length" "2")])
18362 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18364 ;; LWP instructions
18366 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18368 (define_expand "lwp_llwpcb"
18369 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18370 UNSPECV_LLWP_INTRINSIC)]
18373 (define_insn "*lwp_llwpcb<mode>1"
18374 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18375 UNSPECV_LLWP_INTRINSIC)]
18378 [(set_attr "type" "lwp")
18379 (set_attr "mode" "<MODE>")
18380 (set_attr "length" "5")])
18382 (define_expand "lwp_slwpcb"
18383 [(set (match_operand 0 "register_operand" "=r")
18384 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18389 insn = (Pmode == DImode
18391 : gen_lwp_slwpcbsi);
18393 emit_insn (insn (operands[0]));
18397 (define_insn "lwp_slwpcb<mode>"
18398 [(set (match_operand:P 0 "register_operand" "=r")
18399 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18402 [(set_attr "type" "lwp")
18403 (set_attr "mode" "<MODE>")
18404 (set_attr "length" "5")])
18406 (define_expand "lwp_lwpval<mode>3"
18407 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18408 (match_operand:SI 2 "nonimmediate_operand" "rm")
18409 (match_operand:SI 3 "const_int_operand" "i")]
18410 UNSPECV_LWPVAL_INTRINSIC)]
18412 ;; Avoid unused variable warning.
18413 "(void) operands[0];")
18415 (define_insn "*lwp_lwpval<mode>3_1"
18416 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18417 (match_operand:SI 1 "nonimmediate_operand" "rm")
18418 (match_operand:SI 2 "const_int_operand" "i")]
18419 UNSPECV_LWPVAL_INTRINSIC)]
18421 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18422 [(set_attr "type" "lwp")
18423 (set_attr "mode" "<MODE>")
18424 (set (attr "length")
18425 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18427 (define_expand "lwp_lwpins<mode>3"
18428 [(set (reg:CCC FLAGS_REG)
18429 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18430 (match_operand:SI 2 "nonimmediate_operand" "rm")
18431 (match_operand:SI 3 "const_int_operand" "i")]
18432 UNSPECV_LWPINS_INTRINSIC))
18433 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18434 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18437 (define_insn "*lwp_lwpins<mode>3_1"
18438 [(set (reg:CCC FLAGS_REG)
18439 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18440 (match_operand:SI 1 "nonimmediate_operand" "rm")
18441 (match_operand:SI 2 "const_int_operand" "i")]
18442 UNSPECV_LWPINS_INTRINSIC))]
18444 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18445 [(set_attr "type" "lwp")
18446 (set_attr "mode" "<MODE>")
18447 (set (attr "length")
18448 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18450 (define_int_iterator RDFSGSBASE
18454 (define_int_iterator WRFSGSBASE
18458 (define_int_attr fsgs
18459 [(UNSPECV_RDFSBASE "fs")
18460 (UNSPECV_RDGSBASE "gs")
18461 (UNSPECV_WRFSBASE "fs")
18462 (UNSPECV_WRGSBASE "gs")])
18464 (define_insn "rd<fsgs>base<mode>"
18465 [(set (match_operand:SWI48 0 "register_operand" "=r")
18466 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18467 "TARGET_64BIT && TARGET_FSGSBASE"
18469 [(set_attr "type" "other")
18470 (set_attr "prefix_extra" "2")])
18472 (define_insn "wr<fsgs>base<mode>"
18473 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18475 "TARGET_64BIT && TARGET_FSGSBASE"
18477 [(set_attr "type" "other")
18478 (set_attr "prefix_extra" "2")])
18480 (define_insn "rdrand<mode>_1"
18481 [(set (match_operand:SWI248 0 "register_operand" "=r")
18482 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18483 (set (reg:CCC FLAGS_REG)
18484 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18487 [(set_attr "type" "other")
18488 (set_attr "prefix_extra" "1")])
18490 (define_insn "rdseed<mode>_1"
18491 [(set (match_operand:SWI248 0 "register_operand" "=r")
18492 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18493 (set (reg:CCC FLAGS_REG)
18494 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18497 [(set_attr "type" "other")
18498 (set_attr "prefix_extra" "1")])
18500 (define_expand "pause"
18501 [(set (match_dup 0)
18502 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18505 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18506 MEM_VOLATILE_P (operands[0]) = 1;
18509 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18510 ;; They have the same encoding.
18511 (define_insn "*pause"
18512 [(set (match_operand:BLK 0)
18513 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18516 [(set_attr "length" "2")
18517 (set_attr "memory" "unknown")])
18519 (define_expand "xbegin"
18520 [(set (match_operand:SI 0 "register_operand")
18521 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18524 rtx_code_label *label = gen_label_rtx ();
18526 /* xbegin is emitted as jump_insn, so reload won't be able
18527 to reload its operand. Force the value into AX hard register. */
18528 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18529 emit_move_insn (ax_reg, constm1_rtx);
18531 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18533 emit_label (label);
18534 LABEL_NUSES (label) = 1;
18536 emit_move_insn (operands[0], ax_reg);
18541 (define_insn "xbegin_1"
18543 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18545 (label_ref (match_operand 1))
18547 (set (match_operand:SI 0 "register_operand" "+a")
18548 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18551 [(set_attr "type" "other")
18552 (set_attr "length" "6")])
18554 (define_insn "xend"
18555 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18558 [(set_attr "type" "other")
18559 (set_attr "length" "3")])
18561 (define_insn "xabort"
18562 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18566 [(set_attr "type" "other")
18567 (set_attr "length" "3")])
18569 (define_expand "xtest"
18570 [(set (match_operand:QI 0 "register_operand")
18571 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18574 emit_insn (gen_xtest_1 ());
18576 ix86_expand_setcc (operands[0], NE,
18577 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18581 (define_insn "xtest_1"
18582 [(set (reg:CCZ FLAGS_REG)
18583 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18586 [(set_attr "type" "other")
18587 (set_attr "length" "3")])
18589 (define_insn "clflushopt"
18590 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18591 UNSPECV_CLFLUSHOPT)]
18592 "TARGET_CLFLUSHOPT"
18594 [(set_attr "type" "sse")
18595 (set_attr "atom_sse_attr" "fence")
18596 (set_attr "memory" "unknown")])
18600 (include "sync.md")