1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
116 ;; For SSE/MMX support:
124 ;; Generic math support
126 UNSPEC_IEEE_MIN ; not commutative
127 UNSPEC_IEEE_MAX ; not commutative
129 ;; x87 Floating point
145 UNSPEC_FRNDINT_MASK_PM
149 ;; x87 Double output FP
183 ;; For AVX512F support
187 (define_c_enum "unspecv" [
190 UNSPECV_PROBE_STACK_RANGE
193 UNSPECV_SPLIT_STACK_RETURN
199 UNSPECV_LLWP_INTRINSIC
200 UNSPECV_SLWP_INTRINSIC
201 UNSPECV_LWPVAL_INTRINSIC
202 UNSPECV_LWPINS_INTRINSIC
224 ;; For atomic compound assignments.
230 ;; For RDRAND support
233 ;; For RDSEED support
244 ;; For CLFLUSHOPT support
248 ;; Constants to represent rounding modes in the ROUND instruction
257 ;; Constants to represent AVX512F embeded rounding
259 [(ROUND_NEAREST_INT 0)
267 ;; Constants to represent pcomtrue/pcomfalse variants
277 ;; Constants used in the XOP pperm instruction
279 [(PPERM_SRC 0x00) /* copy source */
280 (PPERM_INVERT 0x20) /* invert source */
281 (PPERM_REVERSE 0x40) /* bit reverse source */
282 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
283 (PPERM_ZERO 0x80) /* all 0's */
284 (PPERM_ONES 0xa0) /* all 1's */
285 (PPERM_SIGN 0xc0) /* propagate sign bit */
286 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
287 (PPERM_SRC1 0x00) /* use first source byte */
288 (PPERM_SRC2 0x10) /* use second source byte */
291 ;; Registers by name.
370 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
373 ;; In C guard expressions, put expressions which may be compile-time
374 ;; constants first. This allows for better optimization. For
375 ;; example, write "TARGET_64BIT && reload_completed", not
376 ;; "reload_completed && TARGET_64BIT".
380 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
381 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
383 (const (symbol_ref "ix86_schedule")))
385 ;; A basic instruction type. Refinements due to arguments to be
386 ;; provided in other attributes.
389 alu,alu1,negnot,imov,imovx,lea,
390 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
391 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
392 push,pop,call,callv,leave,
394 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
395 fxch,fistp,fisttp,frndint,
396 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
397 ssemul,sseimul,ssediv,sselog,sselog1,
398 sseishft,sseishft1,ssecmp,ssecomi,
399 ssecvt,ssecvt1,sseicvt,sseins,
400 sseshuf,sseshuf1,ssemuladd,sse4arg,
402 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
403 (const_string "other"))
405 ;; Main data type used by the insn
407 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
409 (const_string "unknown"))
411 ;; The CPU unit operations uses.
412 (define_attr "unit" "integer,i387,sse,mmx,unknown"
413 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
414 fxch,fistp,fisttp,frndint")
415 (const_string "i387")
416 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417 ssemul,sseimul,ssediv,sselog,sselog1,
418 sseishft,sseishft1,ssecmp,ssecomi,
419 ssecvt,ssecvt1,sseicvt,sseins,
420 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
422 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
424 (eq_attr "type" "other")
425 (const_string "unknown")]
426 (const_string "integer")))
428 ;; The minimum required alignment of vector mode memory operands of the SSE
429 ;; (non-VEX/EVEX) instruction in bits, if it is different from
430 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
431 ;; multiple alternatives, this should be conservative maximum of those minimum
432 ;; required alignments.
433 (define_attr "ssememalign" "" (const_int 0))
435 ;; The (bounding maximum) length of an instruction immediate.
436 (define_attr "length_immediate" ""
437 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
438 bitmanip,imulx,msklog,mskmov")
440 (eq_attr "unit" "i387,sse,mmx")
442 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
443 rotate,rotatex,rotate1,imul,icmp,push,pop")
444 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
445 (eq_attr "type" "imov,test")
446 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
447 (eq_attr "type" "call")
448 (if_then_else (match_operand 0 "constant_call_address_operand")
451 (eq_attr "type" "callv")
452 (if_then_else (match_operand 1 "constant_call_address_operand")
455 ;; We don't know the size before shorten_branches. Expect
456 ;; the instruction to fit for better scheduling.
457 (eq_attr "type" "ibr")
460 (symbol_ref "/* Update immediate_length and other attributes! */
461 gcc_unreachable (),1")))
463 ;; The (bounding maximum) length of an instruction address.
464 (define_attr "length_address" ""
465 (cond [(eq_attr "type" "str,other,multi,fxch")
467 (and (eq_attr "type" "call")
468 (match_operand 0 "constant_call_address_operand"))
470 (and (eq_attr "type" "callv")
471 (match_operand 1 "constant_call_address_operand"))
474 (symbol_ref "ix86_attr_length_address_default (insn)")))
476 ;; Set when length prefix is used.
477 (define_attr "prefix_data16" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
480 (eq_attr "mode" "HI")
482 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
487 ;; Set when string REP prefix is used.
488 (define_attr "prefix_rep" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
491 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
496 ;; Set when 0f opcode prefix is used.
497 (define_attr "prefix_0f" ""
499 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
500 (eq_attr "unit" "sse,mmx"))
504 ;; Set when REX opcode prefix is used.
505 (define_attr "prefix_rex" ""
506 (cond [(not (match_test "TARGET_64BIT"))
508 (and (eq_attr "mode" "DI")
509 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
510 (eq_attr "unit" "!mmx")))
512 (and (eq_attr "mode" "QI")
513 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
515 (match_test "x86_extended_reg_mentioned_p (insn)")
517 (and (eq_attr "type" "imovx")
518 (match_operand:QI 1 "ext_QIreg_operand"))
523 ;; There are also additional prefixes in 3DNOW, SSSE3.
524 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
525 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
526 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
527 (define_attr "prefix_extra" ""
528 (cond [(eq_attr "type" "ssemuladd,sse4arg")
530 (eq_attr "type" "sseiadd1,ssecvt1")
535 ;; Prefix used: original, VEX or maybe VEX.
536 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
537 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
539 (eq_attr "mode" "XI,V16SF,V8DF")
540 (const_string "evex")
542 (const_string "orig")))
544 ;; VEX W bit is used.
545 (define_attr "prefix_vex_w" "" (const_int 0))
547 ;; The length of VEX prefix
548 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
549 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
550 ;; still prefix_0f 1, with prefix_extra 1.
551 (define_attr "length_vex" ""
552 (if_then_else (and (eq_attr "prefix_0f" "1")
553 (eq_attr "prefix_extra" "0"))
554 (if_then_else (eq_attr "prefix_vex_w" "1")
555 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
556 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
557 (if_then_else (eq_attr "prefix_vex_w" "1")
558 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
559 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
561 ;; 4-bytes evex prefix and 1 byte opcode.
562 (define_attr "length_evex" "" (const_int 5))
564 ;; Set when modrm byte is used.
565 (define_attr "modrm" ""
566 (cond [(eq_attr "type" "str,leave")
568 (eq_attr "unit" "i387")
570 (and (eq_attr "type" "incdec")
571 (and (not (match_test "TARGET_64BIT"))
572 (ior (match_operand:SI 1 "register_operand")
573 (match_operand:HI 1 "register_operand"))))
575 (and (eq_attr "type" "push")
576 (not (match_operand 1 "memory_operand")))
578 (and (eq_attr "type" "pop")
579 (not (match_operand 0 "memory_operand")))
581 (and (eq_attr "type" "imov")
582 (and (not (eq_attr "mode" "DI"))
583 (ior (and (match_operand 0 "register_operand")
584 (match_operand 1 "immediate_operand"))
585 (ior (and (match_operand 0 "ax_reg_operand")
586 (match_operand 1 "memory_displacement_only_operand"))
587 (and (match_operand 0 "memory_displacement_only_operand")
588 (match_operand 1 "ax_reg_operand"))))))
590 (and (eq_attr "type" "call")
591 (match_operand 0 "constant_call_address_operand"))
593 (and (eq_attr "type" "callv")
594 (match_operand 1 "constant_call_address_operand"))
596 (and (eq_attr "type" "alu,alu1,icmp,test")
597 (match_operand 0 "ax_reg_operand"))
598 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
602 ;; The (bounding maximum) length of an instruction in bytes.
603 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
604 ;; Later we may want to split them and compute proper length as for
606 (define_attr "length" ""
607 (cond [(eq_attr "type" "other,multi,fistp,frndint")
609 (eq_attr "type" "fcmp")
611 (eq_attr "unit" "i387")
613 (plus (attr "prefix_data16")
614 (attr "length_address")))
615 (ior (eq_attr "prefix" "evex")
616 (and (ior (eq_attr "prefix" "maybe_evex")
617 (eq_attr "prefix" "maybe_vex"))
618 (match_test "TARGET_AVX512F")))
619 (plus (attr "length_evex")
620 (plus (attr "length_immediate")
622 (attr "length_address"))))
623 (ior (eq_attr "prefix" "vex")
624 (and (ior (eq_attr "prefix" "maybe_vex")
625 (eq_attr "prefix" "maybe_evex"))
626 (match_test "TARGET_AVX")))
627 (plus (attr "length_vex")
628 (plus (attr "length_immediate")
630 (attr "length_address"))))]
631 (plus (plus (attr "modrm")
632 (plus (attr "prefix_0f")
633 (plus (attr "prefix_rex")
634 (plus (attr "prefix_extra")
636 (plus (attr "prefix_rep")
637 (plus (attr "prefix_data16")
638 (plus (attr "length_immediate")
639 (attr "length_address")))))))
641 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
642 ;; `store' if there is a simple memory reference therein, or `unknown'
643 ;; if the instruction is complex.
645 (define_attr "memory" "none,load,store,both,unknown"
646 (cond [(eq_attr "type" "other,multi,str,lwp")
647 (const_string "unknown")
648 (eq_attr "type" "lea,fcmov,fpspc")
649 (const_string "none")
650 (eq_attr "type" "fistp,leave")
651 (const_string "both")
652 (eq_attr "type" "frndint")
653 (const_string "load")
654 (eq_attr "type" "push")
655 (if_then_else (match_operand 1 "memory_operand")
656 (const_string "both")
657 (const_string "store"))
658 (eq_attr "type" "pop")
659 (if_then_else (match_operand 0 "memory_operand")
660 (const_string "both")
661 (const_string "load"))
662 (eq_attr "type" "setcc")
663 (if_then_else (match_operand 0 "memory_operand")
664 (const_string "store")
665 (const_string "none"))
666 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
667 (if_then_else (ior (match_operand 0 "memory_operand")
668 (match_operand 1 "memory_operand"))
669 (const_string "load")
670 (const_string "none"))
671 (eq_attr "type" "ibr")
672 (if_then_else (match_operand 0 "memory_operand")
673 (const_string "load")
674 (const_string "none"))
675 (eq_attr "type" "call")
676 (if_then_else (match_operand 0 "constant_call_address_operand")
677 (const_string "none")
678 (const_string "load"))
679 (eq_attr "type" "callv")
680 (if_then_else (match_operand 1 "constant_call_address_operand")
681 (const_string "none")
682 (const_string "load"))
683 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
684 (match_operand 1 "memory_operand"))
685 (const_string "both")
686 (and (match_operand 0 "memory_operand")
687 (match_operand 1 "memory_operand"))
688 (const_string "both")
689 (match_operand 0 "memory_operand")
690 (const_string "store")
691 (match_operand 1 "memory_operand")
692 (const_string "load")
694 "!alu1,negnot,ishift1,
695 imov,imovx,icmp,test,bitmanip,
697 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
698 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
699 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
700 (match_operand 2 "memory_operand"))
701 (const_string "load")
702 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
703 (match_operand 3 "memory_operand"))
704 (const_string "load")
706 (const_string "none")))
708 ;; Indicates if an instruction has both an immediate and a displacement.
710 (define_attr "imm_disp" "false,true,unknown"
711 (cond [(eq_attr "type" "other,multi")
712 (const_string "unknown")
713 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
714 (and (match_operand 0 "memory_displacement_operand")
715 (match_operand 1 "immediate_operand")))
716 (const_string "true")
717 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
718 (and (match_operand 0 "memory_displacement_operand")
719 (match_operand 2 "immediate_operand")))
720 (const_string "true")
722 (const_string "false")))
724 ;; Indicates if an FP operation has an integer source.
726 (define_attr "fp_int_src" "false,true"
727 (const_string "false"))
729 ;; Defines rounding mode of an FP operation.
731 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
732 (const_string "any"))
734 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
735 (define_attr "use_carry" "0,1" (const_string "0"))
737 ;; Define attribute to indicate unaligned ssemov insns
738 (define_attr "movu" "0,1" (const_string "0"))
740 ;; Used to control the "enabled" attribute on a per-instruction basis.
741 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
742 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
743 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
744 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
745 (const_string "base"))
747 (define_attr "enabled" ""
748 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
749 (eq_attr "isa" "x64_sse4")
750 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
751 (eq_attr "isa" "x64_sse4_noavx")
752 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
753 (eq_attr "isa" "x64_avx")
754 (symbol_ref "TARGET_64BIT && TARGET_AVX")
755 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
756 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
757 (eq_attr "isa" "sse2_noavx")
758 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
759 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
760 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
761 (eq_attr "isa" "sse4_noavx")
762 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
763 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
764 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
765 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
766 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
767 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
768 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
769 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
770 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
771 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
772 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
773 (eq_attr "isa" "fma_avx512f")
774 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
775 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
776 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
777 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
778 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
782 (define_attr "preferred_for_speed" "" (const_int 1))
784 ;; Describe a user's asm statement.
785 (define_asm_attributes
786 [(set_attr "length" "128")
787 (set_attr "type" "multi")])
789 (define_code_iterator plusminus [plus minus])
791 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
793 (define_code_iterator multdiv [mult div])
795 ;; Base name for define_insn
796 (define_code_attr plusminus_insn
797 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
798 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
800 ;; Base name for insn mnemonic.
801 (define_code_attr plusminus_mnemonic
802 [(plus "add") (ss_plus "adds") (us_plus "addus")
803 (minus "sub") (ss_minus "subs") (us_minus "subus")])
804 (define_code_attr plusminus_carry_mnemonic
805 [(plus "adc") (minus "sbb")])
806 (define_code_attr multdiv_mnemonic
807 [(mult "mul") (div "div")])
809 ;; Mark commutative operators as such in constraints.
810 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
811 (minus "") (ss_minus "") (us_minus "")])
813 ;; Mapping of max and min
814 (define_code_iterator maxmin [smax smin umax umin])
816 ;; Mapping of signed max and min
817 (define_code_iterator smaxmin [smax smin])
819 ;; Mapping of unsigned max and min
820 (define_code_iterator umaxmin [umax umin])
822 ;; Base name for integer and FP insn mnemonic
823 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
824 (umax "maxu") (umin "minu")])
825 (define_code_attr maxmin_float [(smax "max") (smin "min")])
827 ;; Mapping of logic operators
828 (define_code_iterator any_logic [and ior xor])
829 (define_code_iterator any_or [ior xor])
830 (define_code_iterator fpint_logic [and xor])
832 ;; Base name for insn mnemonic.
833 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
835 ;; Mapping of logic-shift operators
836 (define_code_iterator any_lshift [ashift lshiftrt])
838 ;; Mapping of shift-right operators
839 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
841 ;; Mapping of all shift operators
842 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
844 ;; Base name for define_insn
845 (define_code_attr shift_insn
846 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
848 ;; Base name for insn mnemonic.
849 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
850 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
852 ;; Mapping of rotate operators
853 (define_code_iterator any_rotate [rotate rotatert])
855 ;; Base name for define_insn
856 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
858 ;; Base name for insn mnemonic.
859 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
861 ;; Mapping of abs neg operators
862 (define_code_iterator absneg [abs neg])
864 ;; Base name for x87 insn mnemonic.
865 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
867 ;; Used in signed and unsigned widening multiplications.
868 (define_code_iterator any_extend [sign_extend zero_extend])
870 ;; Prefix for insn menmonic.
871 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
873 ;; Prefix for define_insn
874 (define_code_attr u [(sign_extend "") (zero_extend "u")])
875 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
876 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
878 ;; Used in signed and unsigned truncations.
879 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
880 ;; Instruction suffix for truncations.
881 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
883 ;; Used in signed and unsigned fix.
884 (define_code_iterator any_fix [fix unsigned_fix])
885 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
887 ;; Used in signed and unsigned float.
888 (define_code_iterator any_float [float unsigned_float])
889 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
891 ;; All integer modes.
892 (define_mode_iterator SWI1248x [QI HI SI DI])
894 ;; All integer modes with AVX512BW.
895 (define_mode_iterator SWI1248_AVX512BW
896 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
898 ;; All integer modes without QImode.
899 (define_mode_iterator SWI248x [HI SI DI])
901 ;; All integer modes without QImode and HImode.
902 (define_mode_iterator SWI48x [SI DI])
904 ;; All integer modes without SImode and DImode.
905 (define_mode_iterator SWI12 [QI HI])
907 ;; All integer modes without DImode.
908 (define_mode_iterator SWI124 [QI HI SI])
910 ;; All integer modes without QImode and DImode.
911 (define_mode_iterator SWI24 [HI SI])
913 ;; Single word integer modes.
914 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
916 ;; Single word integer modes without QImode.
917 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
919 ;; Single word integer modes without QImode and HImode.
920 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
922 ;; All math-dependant single and double word integer modes.
923 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
924 (HI "TARGET_HIMODE_MATH")
925 SI DI (TI "TARGET_64BIT")])
927 ;; Math-dependant single word integer modes.
928 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
929 (HI "TARGET_HIMODE_MATH")
930 SI (DI "TARGET_64BIT")])
932 ;; Math-dependant integer modes without DImode.
933 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
934 (HI "TARGET_HIMODE_MATH")
937 ;; Math-dependant single word integer modes without QImode.
938 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
939 SI (DI "TARGET_64BIT")])
941 ;; Double word integer modes.
942 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
943 (TI "TARGET_64BIT")])
945 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
946 ;; compile time constant, it is faster to use <MODE_SIZE> than
947 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
948 ;; command line options just use GET_MODE_SIZE macro.
949 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
950 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
951 (V16QI "16") (V32QI "32") (V64QI "64")
952 (V8HI "16") (V16HI "32") (V32HI "64")
953 (V4SI "16") (V8SI "32") (V16SI "64")
954 (V2DI "16") (V4DI "32") (V8DI "64")
955 (V1TI "16") (V2TI "32") (V4TI "64")
956 (V2DF "16") (V4DF "32") (V8DF "64")
957 (V4SF "16") (V8SF "32") (V16SF "64")])
959 ;; Double word integer modes as mode attribute.
960 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
961 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
963 ;; Half mode for double word integer modes.
964 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
965 (DI "TARGET_64BIT")])
967 ;; Instruction suffix for integer modes.
968 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
970 ;; Instruction suffix for masks.
971 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
973 ;; Pointer size prefix for integer modes (Intel asm dialect)
974 (define_mode_attr iptrsize [(QI "BYTE")
979 ;; Register class for integer modes.
980 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
982 ;; Immediate operand constraint for integer modes.
983 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
985 ;; General operand constraint for word modes.
986 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
988 ;; Immediate operand constraint for double integer modes.
989 (define_mode_attr di [(SI "nF") (DI "e")])
991 ;; Immediate operand constraint for shifts.
992 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
994 ;; General operand predicate for integer modes.
995 (define_mode_attr general_operand
996 [(QI "general_operand")
997 (HI "general_operand")
998 (SI "x86_64_general_operand")
999 (DI "x86_64_general_operand")
1000 (TI "x86_64_general_operand")])
1002 ;; General sign extend operand predicate for integer modes,
1003 ;; which disallows VOIDmode operands and thus it is suitable
1004 ;; for use inside sign_extend.
1005 (define_mode_attr general_sext_operand
1006 [(QI "sext_operand")
1008 (SI "x86_64_sext_operand")
1009 (DI "x86_64_sext_operand")])
1011 ;; General sign/zero extend operand predicate for integer modes.
1012 (define_mode_attr general_szext_operand
1013 [(QI "general_operand")
1014 (HI "general_operand")
1015 (SI "x86_64_szext_general_operand")
1016 (DI "x86_64_szext_general_operand")])
1018 ;; Immediate operand predicate for integer modes.
1019 (define_mode_attr immediate_operand
1020 [(QI "immediate_operand")
1021 (HI "immediate_operand")
1022 (SI "x86_64_immediate_operand")
1023 (DI "x86_64_immediate_operand")])
1025 ;; Nonmemory operand predicate for integer modes.
1026 (define_mode_attr nonmemory_operand
1027 [(QI "nonmemory_operand")
1028 (HI "nonmemory_operand")
1029 (SI "x86_64_nonmemory_operand")
1030 (DI "x86_64_nonmemory_operand")])
1032 ;; Operand predicate for shifts.
1033 (define_mode_attr shift_operand
1034 [(QI "nonimmediate_operand")
1035 (HI "nonimmediate_operand")
1036 (SI "nonimmediate_operand")
1037 (DI "shiftdi_operand")
1038 (TI "register_operand")])
1040 ;; Operand predicate for shift argument.
1041 (define_mode_attr shift_immediate_operand
1042 [(QI "const_1_to_31_operand")
1043 (HI "const_1_to_31_operand")
1044 (SI "const_1_to_31_operand")
1045 (DI "const_1_to_63_operand")])
1047 ;; Input operand predicate for arithmetic left shifts.
1048 (define_mode_attr ashl_input_operand
1049 [(QI "nonimmediate_operand")
1050 (HI "nonimmediate_operand")
1051 (SI "nonimmediate_operand")
1052 (DI "ashldi_input_operand")
1053 (TI "reg_or_pm1_operand")])
1055 ;; SSE and x87 SFmode and DFmode floating point modes
1056 (define_mode_iterator MODEF [SF DF])
1058 ;; All x87 floating point modes
1059 (define_mode_iterator X87MODEF [SF DF XF])
1061 ;; SSE instruction suffix for various modes
1062 (define_mode_attr ssemodesuffix
1063 [(SF "ss") (DF "sd")
1064 (V16SF "ps") (V8DF "pd")
1065 (V8SF "ps") (V4DF "pd")
1066 (V4SF "ps") (V2DF "pd")
1067 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1068 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1069 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1071 ;; SSE vector suffix for floating point modes
1072 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1074 ;; SSE vector mode corresponding to a scalar mode
1075 (define_mode_attr ssevecmode
1076 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1077 (define_mode_attr ssevecmodelower
1078 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1080 ;; Instruction suffix for REX 64bit operators.
1081 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1083 ;; This mode iterator allows :P to be used for patterns that operate on
1084 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1085 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1087 ;; This mode iterator allows :W to be used for patterns that operate on
1088 ;; word_mode sized quantities.
1089 (define_mode_iterator W
1090 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1092 ;; This mode iterator allows :PTR to be used for patterns that operate on
1093 ;; ptr_mode sized quantities.
1094 (define_mode_iterator PTR
1095 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1097 ;; Scheduling descriptions
1099 (include "pentium.md")
1102 (include "athlon.md")
1103 (include "bdver1.md")
1104 (include "bdver3.md")
1105 (include "btver2.md")
1106 (include "geode.md")
1109 (include "core2.md")
1112 ;; Operand and operator predicates and constraints
1114 (include "predicates.md")
1115 (include "constraints.md")
1118 ;; Compare and branch/compare and store instructions.
1120 (define_expand "cbranch<mode>4"
1121 [(set (reg:CC FLAGS_REG)
1122 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1123 (match_operand:SDWIM 2 "<general_operand>")))
1124 (set (pc) (if_then_else
1125 (match_operator 0 "ordered_comparison_operator"
1126 [(reg:CC FLAGS_REG) (const_int 0)])
1127 (label_ref (match_operand 3))
1131 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1132 operands[1] = force_reg (<MODE>mode, operands[1]);
1133 ix86_expand_branch (GET_CODE (operands[0]),
1134 operands[1], operands[2], operands[3]);
1138 (define_expand "cstore<mode>4"
1139 [(set (reg:CC FLAGS_REG)
1140 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1141 (match_operand:SWIM 3 "<general_operand>")))
1142 (set (match_operand:QI 0 "register_operand")
1143 (match_operator 1 "ordered_comparison_operator"
1144 [(reg:CC FLAGS_REG) (const_int 0)]))]
1147 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1148 operands[2] = force_reg (<MODE>mode, operands[2]);
1149 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1150 operands[2], operands[3]);
1154 (define_expand "cmp<mode>_1"
1155 [(set (reg:CC FLAGS_REG)
1156 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1157 (match_operand:SWI48 1 "<general_operand>")))])
1159 (define_insn "*cmp<mode>_ccno_1"
1160 [(set (reg FLAGS_REG)
1161 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1162 (match_operand:SWI 1 "const0_operand")))]
1163 "ix86_match_ccmode (insn, CCNOmode)"
1165 test{<imodesuffix>}\t%0, %0
1166 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1167 [(set_attr "type" "test,icmp")
1168 (set_attr "length_immediate" "0,1")
1169 (set_attr "mode" "<MODE>")])
1171 (define_insn "*cmp<mode>_1"
1172 [(set (reg FLAGS_REG)
1173 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1174 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1175 "ix86_match_ccmode (insn, CCmode)"
1176 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1177 [(set_attr "type" "icmp")
1178 (set_attr "mode" "<MODE>")])
1180 (define_insn "*cmp<mode>_minus_1"
1181 [(set (reg FLAGS_REG)
1183 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1184 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1186 "ix86_match_ccmode (insn, CCGOCmode)"
1187 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1188 [(set_attr "type" "icmp")
1189 (set_attr "mode" "<MODE>")])
1191 (define_insn "*cmpqi_ext_1"
1192 [(set (reg FLAGS_REG)
1194 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1197 (match_operand 1 "ext_register_operand" "Q,Q")
1199 (const_int 8)) 0)))]
1200 "ix86_match_ccmode (insn, CCmode)"
1201 "cmp{b}\t{%h1, %0|%0, %h1}"
1202 [(set_attr "isa" "*,nox64")
1203 (set_attr "type" "icmp")
1204 (set_attr "mode" "QI")])
1206 (define_insn "*cmpqi_ext_2"
1207 [(set (reg FLAGS_REG)
1211 (match_operand 0 "ext_register_operand" "Q")
1214 (match_operand:QI 1 "const0_operand")))]
1215 "ix86_match_ccmode (insn, CCNOmode)"
1217 [(set_attr "type" "test")
1218 (set_attr "length_immediate" "0")
1219 (set_attr "mode" "QI")])
1221 (define_expand "cmpqi_ext_3"
1222 [(set (reg:CC FLAGS_REG)
1226 (match_operand 0 "ext_register_operand")
1229 (match_operand:QI 1 "const_int_operand")))])
1231 (define_insn "*cmpqi_ext_3"
1232 [(set (reg FLAGS_REG)
1236 (match_operand 0 "ext_register_operand" "Q,Q")
1239 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1240 "ix86_match_ccmode (insn, CCmode)"
1241 "cmp{b}\t{%1, %h0|%h0, %1}"
1242 [(set_attr "isa" "*,nox64")
1243 (set_attr "type" "icmp")
1244 (set_attr "modrm" "1")
1245 (set_attr "mode" "QI")])
1247 (define_insn "*cmpqi_ext_4"
1248 [(set (reg FLAGS_REG)
1252 (match_operand 0 "ext_register_operand" "Q")
1257 (match_operand 1 "ext_register_operand" "Q")
1259 (const_int 8)) 0)))]
1260 "ix86_match_ccmode (insn, CCmode)"
1261 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1262 [(set_attr "type" "icmp")
1263 (set_attr "mode" "QI")])
1265 ;; These implement float point compares.
1266 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1267 ;; which would allow mix and match FP modes on the compares. Which is what
1268 ;; the old patterns did, but with many more of them.
1270 (define_expand "cbranchxf4"
1271 [(set (reg:CC FLAGS_REG)
1272 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1273 (match_operand:XF 2 "nonmemory_operand")))
1274 (set (pc) (if_then_else
1275 (match_operator 0 "ix86_fp_comparison_operator"
1278 (label_ref (match_operand 3))
1282 ix86_expand_branch (GET_CODE (operands[0]),
1283 operands[1], operands[2], operands[3]);
1287 (define_expand "cstorexf4"
1288 [(set (reg:CC FLAGS_REG)
1289 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1290 (match_operand:XF 3 "nonmemory_operand")))
1291 (set (match_operand:QI 0 "register_operand")
1292 (match_operator 1 "ix86_fp_comparison_operator"
1297 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1298 operands[2], operands[3]);
1302 (define_expand "cbranch<mode>4"
1303 [(set (reg:CC FLAGS_REG)
1304 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1305 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1306 (set (pc) (if_then_else
1307 (match_operator 0 "ix86_fp_comparison_operator"
1310 (label_ref (match_operand 3))
1312 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1314 ix86_expand_branch (GET_CODE (operands[0]),
1315 operands[1], operands[2], operands[3]);
1319 (define_expand "cstore<mode>4"
1320 [(set (reg:CC FLAGS_REG)
1321 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1322 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1323 (set (match_operand:QI 0 "register_operand")
1324 (match_operator 1 "ix86_fp_comparison_operator"
1327 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1329 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1330 operands[2], operands[3]);
1334 (define_expand "cbranchcc4"
1335 [(set (pc) (if_then_else
1336 (match_operator 0 "comparison_operator"
1337 [(match_operand 1 "flags_reg_operand")
1338 (match_operand 2 "const0_operand")])
1339 (label_ref (match_operand 3))
1343 ix86_expand_branch (GET_CODE (operands[0]),
1344 operands[1], operands[2], operands[3]);
1348 (define_expand "cstorecc4"
1349 [(set (match_operand:QI 0 "register_operand")
1350 (match_operator 1 "comparison_operator"
1351 [(match_operand 2 "flags_reg_operand")
1352 (match_operand 3 "const0_operand")]))]
1355 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356 operands[2], operands[3]);
1361 ;; FP compares, step 1:
1362 ;; Set the FP condition codes.
1364 ;; CCFPmode compare with exceptions
1365 ;; CCFPUmode compare with no exceptions
1367 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1368 ;; used to manage the reg stack popping would not be preserved.
1370 (define_insn "*cmp<mode>_0_i387"
1371 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (match_operand:X87MODEF 1 "register_operand" "f")
1375 (match_operand:X87MODEF 2 "const0_operand"))]
1378 "* return output_fp_compare (insn, operands, false, false);"
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set_attr "mode" "<MODE>")])
1383 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1384 [(set (reg:CCFP FLAGS_REG)
1386 (match_operand:X87MODEF 1 "register_operand" "f")
1387 (match_operand:X87MODEF 2 "const0_operand")))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1391 "&& reload_completed"
1394 [(compare:CCFP (match_dup 1)(match_dup 2))]
1396 (set (reg:CC FLAGS_REG)
1397 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "mode" "<MODE>")])
1403 (define_insn "*cmpxf_i387"
1404 [(set (match_operand:HI 0 "register_operand" "=a")
1407 (match_operand:XF 1 "register_operand" "f")
1408 (match_operand:XF 2 "register_operand" "f"))]
1411 "* return output_fp_compare (insn, operands, false, false);"
1412 [(set_attr "type" "multi")
1413 (set_attr "unit" "i387")
1414 (set_attr "mode" "XF")])
1416 (define_insn_and_split "*cmpxf_cc_i387"
1417 [(set (reg:CCFP FLAGS_REG)
1419 (match_operand:XF 1 "register_operand" "f")
1420 (match_operand:XF 2 "register_operand" "f")))
1421 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1422 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1424 "&& reload_completed"
1427 [(compare:CCFP (match_dup 1)(match_dup 2))]
1429 (set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "mode" "XF")])
1436 (define_insn "*cmp<mode>_i387"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1440 (match_operand:MODEF 1 "register_operand" "f")
1441 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1444 "* return output_fp_compare (insn, operands, false, false);"
1445 [(set_attr "type" "multi")
1446 (set_attr "unit" "i387")
1447 (set_attr "mode" "<MODE>")])
1449 (define_insn_and_split "*cmp<mode>_cc_i387"
1450 [(set (reg:CCFP FLAGS_REG)
1452 (match_operand:MODEF 1 "register_operand" "f")
1453 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1454 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1455 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1457 "&& reload_completed"
1460 [(compare:CCFP (match_dup 1)(match_dup 2))]
1462 (set (reg:CC FLAGS_REG)
1463 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1465 [(set_attr "type" "multi")
1466 (set_attr "unit" "i387")
1467 (set_attr "mode" "<MODE>")])
1469 (define_insn "*cmpu<mode>_i387"
1470 [(set (match_operand:HI 0 "register_operand" "=a")
1473 (match_operand:X87MODEF 1 "register_operand" "f")
1474 (match_operand:X87MODEF 2 "register_operand" "f"))]
1477 "* return output_fp_compare (insn, operands, false, true);"
1478 [(set_attr "type" "multi")
1479 (set_attr "unit" "i387")
1480 (set_attr "mode" "<MODE>")])
1482 (define_insn_and_split "*cmpu<mode>_cc_i387"
1483 [(set (reg:CCFPU FLAGS_REG)
1485 (match_operand:X87MODEF 1 "register_operand" "f")
1486 (match_operand:X87MODEF 2 "register_operand" "f")))
1487 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1488 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1490 "&& reload_completed"
1493 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1495 (set (reg:CC FLAGS_REG)
1496 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1498 [(set_attr "type" "multi")
1499 (set_attr "unit" "i387")
1500 (set_attr "mode" "<MODE>")])
1502 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1503 [(set (match_operand:HI 0 "register_operand" "=a")
1506 (match_operand:X87MODEF 1 "register_operand" "f")
1507 (match_operator:X87MODEF 3 "float_operator"
1508 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1511 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1512 || optimize_function_for_size_p (cfun))"
1513 "* return output_fp_compare (insn, operands, false, false);"
1514 [(set_attr "type" "multi")
1515 (set_attr "unit" "i387")
1516 (set_attr "fp_int_src" "true")
1517 (set_attr "mode" "<SWI24:MODE>")])
1519 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1522 (match_operand:X87MODEF 1 "register_operand" "f")
1523 (match_operator:X87MODEF 3 "float_operator"
1524 [(match_operand:SWI24 2 "memory_operand" "m")])))
1525 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1526 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1527 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1528 || optimize_function_for_size_p (cfun))"
1530 "&& reload_completed"
1535 (match_op_dup 3 [(match_dup 2)]))]
1537 (set (reg:CC FLAGS_REG)
1538 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1540 [(set_attr "type" "multi")
1541 (set_attr "unit" "i387")
1542 (set_attr "fp_int_src" "true")
1543 (set_attr "mode" "<SWI24:MODE>")])
1545 ;; FP compares, step 2
1546 ;; Move the fpsw to ax.
1548 (define_insn "x86_fnstsw_1"
1549 [(set (match_operand:HI 0 "register_operand" "=a")
1550 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1553 [(set_attr "length" "2")
1554 (set_attr "mode" "SI")
1555 (set_attr "unit" "i387")])
1557 ;; FP compares, step 3
1558 ;; Get ax into flags, general case.
1560 (define_insn "x86_sahf_1"
1561 [(set (reg:CC FLAGS_REG)
1562 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1566 #ifndef HAVE_AS_IX86_SAHF
1568 return ASM_BYTE "0x9e";
1573 [(set_attr "length" "1")
1574 (set_attr "athlon_decode" "vector")
1575 (set_attr "amdfam10_decode" "direct")
1576 (set_attr "bdver1_decode" "direct")
1577 (set_attr "mode" "SI")])
1579 ;; Pentium Pro can do steps 1 through 3 in one go.
1580 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1581 ;; (these i387 instructions set flags directly)
1583 (define_mode_iterator FPCMP [CCFP CCFPU])
1584 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1586 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1587 [(set (reg:FPCMP FLAGS_REG)
1589 (match_operand:MODEF 0 "register_operand" "f,x")
1590 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1591 "TARGET_MIX_SSE_I387
1592 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1593 "* return output_fp_compare (insn, operands, true,
1594 <FPCMP:MODE>mode == CCFPUmode);"
1595 [(set_attr "type" "fcmp,ssecomi")
1596 (set_attr "prefix" "orig,maybe_vex")
1597 (set_attr "mode" "<MODEF:MODE>")
1598 (set (attr "prefix_rep")
1599 (if_then_else (eq_attr "type" "ssecomi")
1601 (const_string "*")))
1602 (set (attr "prefix_data16")
1603 (cond [(eq_attr "type" "fcmp")
1605 (eq_attr "mode" "DF")
1608 (const_string "0")))
1609 (set_attr "athlon_decode" "vector")
1610 (set_attr "amdfam10_decode" "direct")
1611 (set_attr "bdver1_decode" "double")])
1613 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1614 [(set (reg:FPCMP FLAGS_REG)
1616 (match_operand:MODEF 0 "register_operand" "x")
1617 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1619 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1620 "* return output_fp_compare (insn, operands, true,
1621 <FPCMP:MODE>mode == CCFPUmode);"
1622 [(set_attr "type" "ssecomi")
1623 (set_attr "prefix" "maybe_vex")
1624 (set_attr "mode" "<MODEF:MODE>")
1625 (set_attr "prefix_rep" "0")
1626 (set (attr "prefix_data16")
1627 (if_then_else (eq_attr "mode" "DF")
1629 (const_string "0")))
1630 (set_attr "athlon_decode" "vector")
1631 (set_attr "amdfam10_decode" "direct")
1632 (set_attr "bdver1_decode" "double")])
1634 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1635 [(set (reg:FPCMP FLAGS_REG)
1637 (match_operand:X87MODEF 0 "register_operand" "f")
1638 (match_operand:X87MODEF 1 "register_operand" "f")))]
1639 "TARGET_80387 && TARGET_CMOVE
1640 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1641 "* return output_fp_compare (insn, operands, true,
1642 <FPCMP:MODE>mode == CCFPUmode);"
1643 [(set_attr "type" "fcmp")
1644 (set_attr "mode" "<X87MODEF:MODE>")
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "direct")
1647 (set_attr "bdver1_decode" "double")])
1649 ;; Push/pop instructions.
1651 (define_insn "*push<mode>2"
1652 [(set (match_operand:DWI 0 "push_operand" "=<")
1653 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1656 [(set_attr "type" "multi")
1657 (set_attr "mode" "<MODE>")])
1660 [(set (match_operand:TI 0 "push_operand")
1661 (match_operand:TI 1 "general_operand"))]
1662 "TARGET_64BIT && reload_completed
1663 && !SSE_REG_P (operands[1])"
1665 "ix86_split_long_move (operands); DONE;")
1667 (define_insn "*pushdi2_rex64"
1668 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1669 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1674 [(set_attr "type" "push,multi")
1675 (set_attr "mode" "DI")])
1677 ;; Convert impossible pushes of immediate to existing instructions.
1678 ;; First try to get scratch register and go through it. In case this
1679 ;; fails, push sign extended lower part first and then overwrite
1680 ;; upper part by 32bit move.
1682 [(match_scratch:DI 2 "r")
1683 (set (match_operand:DI 0 "push_operand")
1684 (match_operand:DI 1 "immediate_operand"))]
1685 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1686 && !x86_64_immediate_operand (operands[1], DImode)"
1687 [(set (match_dup 2) (match_dup 1))
1688 (set (match_dup 0) (match_dup 2))])
1690 ;; We need to define this as both peepholer and splitter for case
1691 ;; peephole2 pass is not run.
1692 ;; "&& 1" is needed to keep it from matching the previous pattern.
1694 [(set (match_operand:DI 0 "push_operand")
1695 (match_operand:DI 1 "immediate_operand"))]
1696 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1697 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1698 [(set (match_dup 0) (match_dup 1))
1699 (set (match_dup 2) (match_dup 3))]
1701 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1703 operands[1] = gen_lowpart (DImode, operands[2]);
1704 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1709 [(set (match_operand:DI 0 "push_operand")
1710 (match_operand:DI 1 "immediate_operand"))]
1711 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1712 ? epilogue_completed : reload_completed)
1713 && !symbolic_operand (operands[1], DImode)
1714 && !x86_64_immediate_operand (operands[1], DImode)"
1715 [(set (match_dup 0) (match_dup 1))
1716 (set (match_dup 2) (match_dup 3))]
1718 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1720 operands[1] = gen_lowpart (DImode, operands[2]);
1721 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1726 [(set (match_operand:DI 0 "push_operand")
1727 (match_operand:DI 1 "general_operand"))]
1728 "!TARGET_64BIT && reload_completed
1729 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1731 "ix86_split_long_move (operands); DONE;")
1733 (define_insn "*pushsi2"
1734 [(set (match_operand:SI 0 "push_operand" "=<")
1735 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "SI")])
1741 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1742 ;; "push a byte/word". But actually we use pushl, which has the effect
1743 ;; of rounding the amount pushed up to a word.
1745 ;; For TARGET_64BIT we always round up to 8 bytes.
1746 (define_insn "*push<mode>2_rex64"
1747 [(set (match_operand:SWI124 0 "push_operand" "=X")
1748 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1751 [(set_attr "type" "push")
1752 (set_attr "mode" "DI")])
1754 (define_insn "*push<mode>2"
1755 [(set (match_operand:SWI12 0 "push_operand" "=X")
1756 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "SI")])
1762 (define_insn "*push<mode>2_prologue"
1763 [(set (match_operand:W 0 "push_operand" "=<")
1764 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1765 (clobber (mem:BLK (scratch)))]
1767 "push{<imodesuffix>}\t%1"
1768 [(set_attr "type" "push")
1769 (set_attr "mode" "<MODE>")])
1771 (define_insn "*pop<mode>1"
1772 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1773 (match_operand:W 1 "pop_operand" ">"))]
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1779 (define_insn "*pop<mode>1_epilogue"
1780 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1781 (match_operand:W 1 "pop_operand" ">"))
1782 (clobber (mem:BLK (scratch)))]
1784 "pop{<imodesuffix>}\t%0"
1785 [(set_attr "type" "pop")
1786 (set_attr "mode" "<MODE>")])
1788 (define_insn "*pushfl<mode>2"
1789 [(set (match_operand:W 0 "push_operand" "=<")
1790 (match_operand:W 1 "flags_reg_operand"))]
1792 "pushf{<imodesuffix>}"
1793 [(set_attr "type" "push")
1794 (set_attr "mode" "<MODE>")])
1796 (define_insn "*popfl<mode>1"
1797 [(set (match_operand:W 0 "flags_reg_operand")
1798 (match_operand:W 1 "pop_operand" ">"))]
1800 "popf{<imodesuffix>}"
1801 [(set_attr "type" "pop")
1802 (set_attr "mode" "<MODE>")])
1805 ;; Move instructions.
1807 (define_expand "movxi"
1808 [(set (match_operand:XI 0 "nonimmediate_operand")
1809 (match_operand:XI 1 "general_operand"))]
1811 "ix86_expand_move (XImode, operands); DONE;")
1813 ;; Reload patterns to support multi-word load/store
1814 ;; with non-offsetable address.
1815 (define_expand "reload_noff_store"
1816 [(parallel [(match_operand 0 "memory_operand" "=m")
1817 (match_operand 1 "register_operand" "r")
1818 (match_operand:DI 2 "register_operand" "=&r")])]
1821 rtx mem = operands[0];
1822 rtx addr = XEXP (mem, 0);
1824 emit_move_insn (operands[2], addr);
1825 mem = replace_equiv_address_nv (mem, operands[2]);
1827 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1831 (define_expand "reload_noff_load"
1832 [(parallel [(match_operand 0 "register_operand" "=r")
1833 (match_operand 1 "memory_operand" "m")
1834 (match_operand:DI 2 "register_operand" "=r")])]
1837 rtx mem = operands[1];
1838 rtx addr = XEXP (mem, 0);
1840 emit_move_insn (operands[2], addr);
1841 mem = replace_equiv_address_nv (mem, operands[2]);
1843 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1847 (define_expand "movoi"
1848 [(set (match_operand:OI 0 "nonimmediate_operand")
1849 (match_operand:OI 1 "general_operand"))]
1851 "ix86_expand_move (OImode, operands); DONE;")
1853 (define_expand "movti"
1854 [(set (match_operand:TI 0 "nonimmediate_operand")
1855 (match_operand:TI 1 "nonimmediate_operand"))]
1856 "TARGET_64BIT || TARGET_SSE"
1859 ix86_expand_move (TImode, operands);
1861 ix86_expand_vector_move (TImode, operands);
1865 ;; This expands to what emit_move_complex would generate if we didn't
1866 ;; have a movti pattern. Having this avoids problems with reload on
1867 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1868 ;; to have around all the time.
1869 (define_expand "movcdi"
1870 [(set (match_operand:CDI 0 "nonimmediate_operand")
1871 (match_operand:CDI 1 "general_operand"))]
1874 if (push_operand (operands[0], CDImode))
1875 emit_move_complex_push (CDImode, operands[0], operands[1]);
1877 emit_move_complex_parts (operands[0], operands[1]);
1881 (define_expand "mov<mode>"
1882 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1883 (match_operand:SWI1248x 1 "general_operand"))]
1885 "ix86_expand_move (<MODE>mode, operands); DONE;")
1887 (define_insn "*mov<mode>_xor"
1888 [(set (match_operand:SWI48 0 "register_operand" "=r")
1889 (match_operand:SWI48 1 "const0_operand"))
1890 (clobber (reg:CC FLAGS_REG))]
1893 [(set_attr "type" "alu1")
1894 (set_attr "mode" "SI")
1895 (set_attr "length_immediate" "0")])
1897 (define_insn "*mov<mode>_or"
1898 [(set (match_operand:SWI48 0 "register_operand" "=r")
1899 (match_operand:SWI48 1 "const_int_operand"))
1900 (clobber (reg:CC FLAGS_REG))]
1902 && operands[1] == constm1_rtx"
1903 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1904 [(set_attr "type" "alu1")
1905 (set_attr "mode" "<MODE>")
1906 (set_attr "length_immediate" "1")])
1908 (define_insn "*movxi_internal_avx512f"
1909 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1910 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1911 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1913 switch (which_alternative)
1916 return standard_sse_constant_opcode (insn, operands[1]);
1919 if (misaligned_operand (operands[0], XImode)
1920 || misaligned_operand (operands[1], XImode))
1921 return "vmovdqu32\t{%1, %0|%0, %1}";
1923 return "vmovdqa32\t{%1, %0|%0, %1}";
1928 [(set_attr "type" "sselog1,ssemov,ssemov")
1929 (set_attr "prefix" "evex")
1930 (set_attr "mode" "XI")])
1932 (define_insn "*movoi_internal_avx"
1933 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1934 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1935 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937 switch (get_attr_type (insn))
1940 return standard_sse_constant_opcode (insn, operands[1]);
1943 if (misaligned_operand (operands[0], OImode)
1944 || misaligned_operand (operands[1], OImode))
1946 if (get_attr_mode (insn) == MODE_V8SF)
1947 return "vmovups\t{%1, %0|%0, %1}";
1948 else if (get_attr_mode (insn) == MODE_XI)
1949 return "vmovdqu32\t{%1, %0|%0, %1}";
1951 return "vmovdqu\t{%1, %0|%0, %1}";
1955 if (get_attr_mode (insn) == MODE_V8SF)
1956 return "vmovaps\t{%1, %0|%0, %1}";
1957 else if (get_attr_mode (insn) == MODE_XI)
1958 return "vmovdqa32\t{%1, %0|%0, %1}";
1960 return "vmovdqa\t{%1, %0|%0, %1}";
1967 [(set_attr "type" "sselog1,ssemov,ssemov")
1968 (set_attr "prefix" "vex")
1970 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1971 (match_operand 1 "ext_sse_reg_operand"))
1973 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1974 (const_string "V8SF")
1975 (and (eq_attr "alternative" "2")
1976 (match_test "TARGET_SSE_TYPELESS_STORES"))
1977 (const_string "V8SF")
1979 (const_string "OI")))])
1981 (define_insn "*movti_internal"
1982 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
1983 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
1984 "(TARGET_64BIT || TARGET_SSE)
1985 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1987 switch (get_attr_type (insn))
1993 return standard_sse_constant_opcode (insn, operands[1]);
1996 /* TDmode values are passed as TImode on the stack. Moving them
1997 to stack may result in unaligned memory access. */
1998 if (misaligned_operand (operands[0], TImode)
1999 || misaligned_operand (operands[1], TImode))
2001 if (get_attr_mode (insn) == MODE_V4SF)
2002 return "%vmovups\t{%1, %0|%0, %1}";
2003 else if (get_attr_mode (insn) == MODE_XI)
2004 return "vmovdqu32\t{%1, %0|%0, %1}";
2006 return "%vmovdqu\t{%1, %0|%0, %1}";
2010 if (get_attr_mode (insn) == MODE_V4SF)
2011 return "%vmovaps\t{%1, %0|%0, %1}";
2012 else if (get_attr_mode (insn) == MODE_XI)
2013 return "vmovdqa32\t{%1, %0|%0, %1}";
2015 return "%vmovdqa\t{%1, %0|%0, %1}";
2022 [(set_attr "isa" "x64,x64,*,*,*")
2023 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2024 (set (attr "prefix")
2025 (if_then_else (eq_attr "type" "sselog1,ssemov")
2026 (const_string "maybe_vex")
2027 (const_string "orig")))
2029 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2030 (match_operand 1 "ext_sse_reg_operand"))
2032 (eq_attr "alternative" "0,1")
2034 (ior (not (match_test "TARGET_SSE2"))
2035 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2036 (const_string "V4SF")
2037 (and (eq_attr "alternative" "4")
2038 (match_test "TARGET_SSE_TYPELESS_STORES"))
2039 (const_string "V4SF")
2040 (match_test "TARGET_AVX")
2042 (match_test "optimize_function_for_size_p (cfun)")
2043 (const_string "V4SF")
2045 (const_string "TI")))])
2048 [(set (match_operand:TI 0 "nonimmediate_operand")
2049 (match_operand:TI 1 "general_operand"))]
2051 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2053 "ix86_split_long_move (operands); DONE;")
2055 (define_insn "*movdi_internal"
2056 [(set (match_operand:DI 0 "nonimmediate_operand"
2057 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2058 (match_operand:DI 1 "general_operand"
2059 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2060 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2062 switch (get_attr_type (insn))
2065 return "kmovq\t{%1, %0|%0, %1}";
2071 return "pxor\t%0, %0";
2074 /* Handle broken assemblers that require movd instead of movq. */
2075 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2076 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2077 return "movd\t{%1, %0|%0, %1}";
2078 return "movq\t{%1, %0|%0, %1}";
2081 if (GENERAL_REG_P (operands[0]))
2082 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2084 return standard_sse_constant_opcode (insn, operands[1]);
2087 switch (get_attr_mode (insn))
2090 /* Handle broken assemblers that require movd instead of movq. */
2091 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2092 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2093 return "%vmovd\t{%1, %0|%0, %1}";
2094 return "%vmovq\t{%1, %0|%0, %1}";
2096 return "%vmovdqa\t{%1, %0|%0, %1}";
2098 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2101 gcc_assert (!TARGET_AVX);
2102 return "movlps\t{%1, %0|%0, %1}";
2104 return "%vmovaps\t{%1, %0|%0, %1}";
2111 if (SSE_REG_P (operands[0]))
2112 return "movq2dq\t{%1, %0|%0, %1}";
2114 return "movdq2q\t{%1, %0|%0, %1}";
2117 return "lea{q}\t{%E1, %0|%0, %E1}";
2120 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2121 if (get_attr_mode (insn) == MODE_SI)
2122 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2123 else if (which_alternative == 4)
2124 return "movabs{q}\t{%1, %0|%0, %1}";
2125 else if (ix86_use_lea_for_mov (insn, operands))
2126 return "lea{q}\t{%E1, %0|%0, %E1}";
2128 return "mov{q}\t{%1, %0|%0, %1}";
2135 (cond [(eq_attr "alternative" "0,1")
2136 (const_string "nox64")
2137 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2138 (const_string "x64")
2139 (eq_attr "alternative" "17")
2140 (const_string "x64_sse4")
2142 (const_string "*")))
2144 (cond [(eq_attr "alternative" "0,1")
2145 (const_string "multi")
2146 (eq_attr "alternative" "6")
2147 (const_string "mmx")
2148 (eq_attr "alternative" "7,8,9,10,11")
2149 (const_string "mmxmov")
2150 (eq_attr "alternative" "12,17")
2151 (const_string "sselog1")
2152 (eq_attr "alternative" "13,14,15,16,18")
2153 (const_string "ssemov")
2154 (eq_attr "alternative" "19,20")
2155 (const_string "ssecvt")
2156 (eq_attr "alternative" "21,22,23,24")
2157 (const_string "mskmov")
2158 (match_operand 1 "pic_32bit_operand")
2159 (const_string "lea")
2161 (const_string "imov")))
2164 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2166 (const_string "*")))
2167 (set (attr "length_immediate")
2168 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2170 (eq_attr "alternative" "17")
2173 (const_string "*")))
2174 (set (attr "prefix_rex")
2175 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2177 (const_string "*")))
2178 (set (attr "prefix_extra")
2179 (if_then_else (eq_attr "alternative" "17")
2181 (const_string "*")))
2182 (set (attr "prefix")
2183 (if_then_else (eq_attr "type" "sselog1,ssemov")
2184 (const_string "maybe_vex")
2185 (const_string "orig")))
2186 (set (attr "prefix_data16")
2187 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2189 (const_string "*")))
2191 (cond [(eq_attr "alternative" "2")
2193 (eq_attr "alternative" "12,13")
2194 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2195 (match_operand 1 "ext_sse_reg_operand"))
2197 (ior (not (match_test "TARGET_SSE2"))
2198 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2199 (const_string "V4SF")
2200 (match_test "TARGET_AVX")
2202 (match_test "optimize_function_for_size_p (cfun)")
2203 (const_string "V4SF")
2205 (const_string "TI"))
2207 (and (eq_attr "alternative" "14,15")
2208 (not (match_test "TARGET_SSE2")))
2209 (const_string "V2SF")
2210 (eq_attr "alternative" "17")
2213 (const_string "DI")))])
2216 [(set (match_operand:DI 0 "nonimmediate_operand")
2217 (match_operand:DI 1 "general_operand"))]
2218 "!TARGET_64BIT && reload_completed
2219 && !(MMX_REG_P (operands[0])
2220 || SSE_REG_P (operands[0])
2221 || MASK_REG_P (operands[0]))
2222 && !(MMX_REG_P (operands[1])
2223 || SSE_REG_P (operands[1])
2224 || MASK_REG_P (operands[1]))"
2226 "ix86_split_long_move (operands); DONE;")
2228 (define_insn "*movsi_internal"
2229 [(set (match_operand:SI 0 "nonimmediate_operand"
2230 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2231 (match_operand:SI 1 "general_operand"
2232 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2233 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2235 switch (get_attr_type (insn))
2238 if (GENERAL_REG_P (operands[0]))
2239 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2241 return standard_sse_constant_opcode (insn, operands[1]);
2244 return "kmovd\t{%1, %0|%0, %1}";
2247 switch (get_attr_mode (insn))
2250 return "%vmovd\t{%1, %0|%0, %1}";
2252 return "%vmovdqa\t{%1, %0|%0, %1}";
2254 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2257 return "%vmovaps\t{%1, %0|%0, %1}";
2260 gcc_assert (!TARGET_AVX);
2261 return "movss\t{%1, %0|%0, %1}";
2268 return "pxor\t%0, %0";
2271 switch (get_attr_mode (insn))
2274 return "movq\t{%1, %0|%0, %1}";
2276 return "movd\t{%1, %0|%0, %1}";
2283 return "lea{l}\t{%E1, %0|%0, %E1}";
2286 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287 if (ix86_use_lea_for_mov (insn, operands))
2288 return "lea{l}\t{%E1, %0|%0, %E1}";
2290 return "mov{l}\t{%1, %0|%0, %1}";
2297 (if_then_else (eq_attr "alternative" "11")
2298 (const_string "sse4")
2299 (const_string "*")))
2301 (cond [(eq_attr "alternative" "2")
2302 (const_string "mmx")
2303 (eq_attr "alternative" "3,4,5")
2304 (const_string "mmxmov")
2305 (eq_attr "alternative" "6,11")
2306 (const_string "sselog1")
2307 (eq_attr "alternative" "7,8,9,10,12")
2308 (const_string "ssemov")
2309 (eq_attr "alternative" "13,14")
2310 (const_string "mskmov")
2311 (match_operand 1 "pic_32bit_operand")
2312 (const_string "lea")
2314 (const_string "imov")))
2315 (set (attr "length_immediate")
2316 (if_then_else (eq_attr "alternative" "11")
2318 (const_string "*")))
2319 (set (attr "prefix_extra")
2320 (if_then_else (eq_attr "alternative" "11")
2322 (const_string "*")))
2323 (set (attr "prefix")
2324 (if_then_else (eq_attr "type" "sselog1,ssemov")
2325 (const_string "maybe_vex")
2326 (const_string "orig")))
2327 (set (attr "prefix_data16")
2328 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2330 (const_string "*")))
2332 (cond [(eq_attr "alternative" "2,3")
2334 (eq_attr "alternative" "6,7")
2335 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2336 (match_operand 1 "ext_sse_reg_operand"))
2338 (ior (not (match_test "TARGET_SSE2"))
2339 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2340 (const_string "V4SF")
2341 (match_test "TARGET_AVX")
2343 (match_test "optimize_function_for_size_p (cfun)")
2344 (const_string "V4SF")
2346 (const_string "TI"))
2348 (and (eq_attr "alternative" "8,9")
2349 (not (match_test "TARGET_SSE2")))
2351 (eq_attr "alternative" "11")
2354 (const_string "SI")))])
2356 (define_insn "kmovw"
2357 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2359 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2361 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2363 kmovw\t{%k1, %0|%0, %k1}
2364 kmovw\t{%1, %0|%0, %1}";
2365 [(set_attr "mode" "HI")
2366 (set_attr "type" "mskmov")
2367 (set_attr "prefix" "vex")])
2370 (define_insn "*movhi_internal"
2371 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2372 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2373 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2375 switch (get_attr_type (insn))
2378 /* movzwl is faster than movw on p2 due to partial word stalls,
2379 though not as fast as an aligned movl. */
2380 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2383 switch (which_alternative)
2385 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2386 case 5: return "kmovw\t{%1, %0|%0, %1}";
2387 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2388 default: gcc_unreachable ();
2392 if (get_attr_mode (insn) == MODE_SI)
2393 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2395 return "mov{w}\t{%1, %0|%0, %1}";
2399 (cond [(eq_attr "alternative" "4,5,6")
2400 (const_string "mskmov")
2401 (match_test "optimize_function_for_size_p (cfun)")
2402 (const_string "imov")
2403 (and (eq_attr "alternative" "0")
2404 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2405 (not (match_test "TARGET_HIMODE_MATH"))))
2406 (const_string "imov")
2407 (and (eq_attr "alternative" "1,2")
2408 (match_operand:HI 1 "aligned_operand"))
2409 (const_string "imov")
2410 (and (match_test "TARGET_MOVX")
2411 (eq_attr "alternative" "0,2"))
2412 (const_string "imovx")
2414 (const_string "imov")))
2415 (set (attr "prefix")
2416 (if_then_else (eq_attr "alternative" "4,5,6")
2417 (const_string "vex")
2418 (const_string "orig")))
2420 (cond [(eq_attr "type" "imovx")
2422 (and (eq_attr "alternative" "1,2")
2423 (match_operand:HI 1 "aligned_operand"))
2425 (and (eq_attr "alternative" "0")
2426 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2427 (not (match_test "TARGET_HIMODE_MATH"))))
2430 (const_string "HI")))])
2432 ;; Situation is quite tricky about when to choose full sized (SImode) move
2433 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2434 ;; partial register dependency machines (such as AMD Athlon), where QImode
2435 ;; moves issue extra dependency and for partial register stalls machines
2436 ;; that don't use QImode patterns (and QImode move cause stall on the next
2439 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2440 ;; register stall machines with, where we use QImode instructions, since
2441 ;; partial register stall can be caused there. Then we use movzx.
2443 (define_insn "*movqi_internal"
2444 [(set (match_operand:QI 0 "nonimmediate_operand"
2445 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2446 (match_operand:QI 1 "general_operand"
2447 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2448 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 switch (get_attr_type (insn))
2453 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2454 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2457 switch (which_alternative)
2459 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2460 : "kmovw\t{%k1, %0|%0, %k1}";
2461 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2462 : "kmovw\t{%1, %0|%0, %1}";
2463 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2464 : "kmovw\t{%1, %k0|%k0, %1}";
2467 gcc_assert (TARGET_AVX512DQ);
2468 return "kmovb\t{%1, %0|%0, %1}";
2469 default: gcc_unreachable ();
2473 if (get_attr_mode (insn) == MODE_SI)
2474 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2476 return "mov{b}\t{%1, %0|%0, %1}";
2479 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2481 (cond [(eq_attr "alternative" "3,5")
2482 (const_string "imovx")
2483 (eq_attr "alternative" "7,8,9,10,11")
2484 (const_string "mskmov")
2485 (and (eq_attr "alternative" "5")
2486 (not (match_operand:QI 1 "aligned_operand")))
2487 (const_string "imovx")
2488 (match_test "optimize_function_for_size_p (cfun)")
2489 (const_string "imov")
2490 (and (eq_attr "alternative" "3")
2491 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2492 (not (match_test "TARGET_QIMODE_MATH"))))
2493 (const_string "imov")
2494 (and (match_test "TARGET_MOVX")
2495 (eq_attr "alternative" "2"))
2496 (const_string "imovx")
2498 (const_string "imov")))
2499 (set (attr "prefix")
2500 (if_then_else (eq_attr "alternative" "7,8,9")
2501 (const_string "vex")
2502 (const_string "orig")))
2504 (cond [(eq_attr "alternative" "3,4,5")
2506 (eq_attr "alternative" "6")
2508 (eq_attr "type" "imovx")
2510 (and (eq_attr "type" "imov")
2511 (and (eq_attr "alternative" "0,1")
2512 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2513 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2514 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2516 ;; Avoid partial register stalls when not using QImode arithmetic
2517 (and (eq_attr "type" "imov")
2518 (and (eq_attr "alternative" "0,1")
2519 (and (match_test "TARGET_PARTIAL_REG_STALL")
2520 (not (match_test "TARGET_QIMODE_MATH")))))
2523 (const_string "QI")))])
2525 ;; Stores and loads of ax to arbitrary constant address.
2526 ;; We fake an second form of instruction to force reload to load address
2527 ;; into register when rax is not available
2528 (define_insn "*movabs<mode>_1"
2529 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2530 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2531 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2533 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2534 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2535 [(set_attr "type" "imov")
2536 (set_attr "modrm" "0,*")
2537 (set_attr "length_address" "8,0")
2538 (set_attr "length_immediate" "0,*")
2539 (set_attr "memory" "store")
2540 (set_attr "mode" "<MODE>")])
2542 (define_insn "*movabs<mode>_2"
2543 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2544 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2545 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2547 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2548 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2549 [(set_attr "type" "imov")
2550 (set_attr "modrm" "0,*")
2551 (set_attr "length_address" "8,0")
2552 (set_attr "length_immediate" "0")
2553 (set_attr "memory" "load")
2554 (set_attr "mode" "<MODE>")])
2556 (define_insn "*swap<mode>"
2557 [(set (match_operand:SWI48 0 "register_operand" "+r")
2558 (match_operand:SWI48 1 "register_operand" "+r"))
2562 "xchg{<imodesuffix>}\t%1, %0"
2563 [(set_attr "type" "imov")
2564 (set_attr "mode" "<MODE>")
2565 (set_attr "pent_pair" "np")
2566 (set_attr "athlon_decode" "vector")
2567 (set_attr "amdfam10_decode" "double")
2568 (set_attr "bdver1_decode" "double")])
2570 (define_insn "*swap<mode>_1"
2571 [(set (match_operand:SWI12 0 "register_operand" "+r")
2572 (match_operand:SWI12 1 "register_operand" "+r"))
2575 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2577 [(set_attr "type" "imov")
2578 (set_attr "mode" "SI")
2579 (set_attr "pent_pair" "np")
2580 (set_attr "athlon_decode" "vector")
2581 (set_attr "amdfam10_decode" "double")
2582 (set_attr "bdver1_decode" "double")])
2584 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2585 ;; is disabled for AMDFAM10
2586 (define_insn "*swap<mode>_2"
2587 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2588 (match_operand:SWI12 1 "register_operand" "+<r>"))
2591 "TARGET_PARTIAL_REG_STALL"
2592 "xchg{<imodesuffix>}\t%1, %0"
2593 [(set_attr "type" "imov")
2594 (set_attr "mode" "<MODE>")
2595 (set_attr "pent_pair" "np")
2596 (set_attr "athlon_decode" "vector")])
2598 (define_expand "movstrict<mode>"
2599 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2600 (match_operand:SWI12 1 "general_operand"))]
2603 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2605 if (GET_CODE (operands[0]) == SUBREG
2606 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2608 /* Don't generate memory->memory moves, go through a register */
2609 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2610 operands[1] = force_reg (<MODE>mode, operands[1]);
2613 (define_insn "*movstrict<mode>_1"
2614 [(set (strict_low_part
2615 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2616 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2617 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2618 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2619 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2620 [(set_attr "type" "imov")
2621 (set_attr "mode" "<MODE>")])
2623 (define_insn "*movstrict<mode>_xor"
2624 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2625 (match_operand:SWI12 1 "const0_operand"))
2626 (clobber (reg:CC FLAGS_REG))]
2628 "xor{<imodesuffix>}\t%0, %0"
2629 [(set_attr "type" "alu1")
2630 (set_attr "mode" "<MODE>")
2631 (set_attr "length_immediate" "0")])
2633 (define_insn "*mov<mode>_extv_1"
2634 [(set (match_operand:SWI24 0 "register_operand" "=R")
2635 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2639 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2640 [(set_attr "type" "imovx")
2641 (set_attr "mode" "SI")])
2643 (define_insn "*movqi_extv_1"
2644 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2645 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2650 switch (get_attr_type (insn))
2653 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2655 return "mov{b}\t{%h1, %0|%0, %h1}";
2658 [(set_attr "isa" "*,*,nox64")
2660 (if_then_else (and (match_operand:QI 0 "register_operand")
2661 (ior (not (match_operand:QI 0 "QIreg_operand"))
2662 (match_test "TARGET_MOVX")))
2663 (const_string "imovx")
2664 (const_string "imov")))
2666 (if_then_else (eq_attr "type" "imovx")
2668 (const_string "QI")))])
2670 (define_insn "*mov<mode>_extzv_1"
2671 [(set (match_operand:SWI48 0 "register_operand" "=R")
2672 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2676 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2677 [(set_attr "type" "imovx")
2678 (set_attr "mode" "SI")])
2680 (define_insn "*movqi_extzv_2"
2681 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2683 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2688 switch (get_attr_type (insn))
2691 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2693 return "mov{b}\t{%h1, %0|%0, %h1}";
2696 [(set_attr "isa" "*,*,nox64")
2698 (if_then_else (and (match_operand:QI 0 "register_operand")
2699 (ior (not (match_operand:QI 0 "QIreg_operand"))
2700 (match_test "TARGET_MOVX")))
2701 (const_string "imovx")
2702 (const_string "imov")))
2704 (if_then_else (eq_attr "type" "imovx")
2706 (const_string "QI")))])
2708 (define_insn "mov<mode>_insv_1"
2709 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2712 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2715 if (CONST_INT_P (operands[1]))
2716 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2717 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2719 [(set_attr "isa" "*,nox64")
2720 (set_attr "type" "imov")
2721 (set_attr "mode" "QI")])
2723 (define_insn "*movqi_insv_2"
2724 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2727 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2730 "mov{b}\t{%h1, %h0|%h0, %h1}"
2731 [(set_attr "type" "imov")
2732 (set_attr "mode" "QI")])
2734 ;; Floating point push instructions.
2736 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2737 (define_insn "*pushtf"
2738 [(set (match_operand:TF 0 "push_operand" "=<,<")
2739 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2740 "(TARGET_64BIT || TARGET_SSE)
2741 && (!ix86_use_pseudo_pic_reg ()
2742 || !can_create_pseudo_p ()
2743 || GET_CODE (operands[1]) != CONST_DOUBLE
2744 || standard_sse_constant_p (operands[1]))"
2746 /* This insn should be already split before reg-stack. */
2749 [(set_attr "isa" "*,x64")
2750 (set_attr "type" "multi")
2751 (set_attr "unit" "sse,*")
2752 (set_attr "mode" "TF,DI")])
2754 ;; %%% Kill this when call knows how to work this out.
2756 [(set (match_operand:TF 0 "push_operand")
2757 (match_operand:TF 1 "sse_reg_operand"))]
2758 "TARGET_SSE && reload_completed"
2759 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2760 (set (match_dup 0) (match_dup 1))]
2762 /* Preserve memory attributes. */
2763 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2766 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2767 (define_insn "*pushxf"
2768 [(set (match_operand:XF 0 "push_operand" "=<,<")
2769 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2770 "!ix86_use_pseudo_pic_reg ()
2771 || !can_create_pseudo_p ()
2772 || GET_CODE (operands[1]) != CONST_DOUBLE
2773 || standard_80387_constant_p (operands[1]) > 0"
2775 /* This insn should be already split before reg-stack. */
2778 [(set_attr "type" "multi")
2779 (set_attr "unit" "i387,*")
2781 (cond [(eq_attr "alternative" "1")
2782 (if_then_else (match_test "TARGET_64BIT")
2784 (const_string "SI"))
2786 (const_string "XF")))])
2788 ;; %%% Kill this when call knows how to work this out.
2790 [(set (match_operand:XF 0 "push_operand")
2791 (match_operand:XF 1 "fp_register_operand"))]
2793 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2794 (set (match_dup 0) (match_dup 1))]
2796 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2797 /* Preserve memory attributes. */
2798 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2801 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2802 (define_insn "*pushdf"
2803 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2804 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2805 "!ix86_use_pseudo_pic_reg ()
2806 || !can_create_pseudo_p ()
2807 || GET_CODE (operands[1]) != CONST_DOUBLE
2808 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2809 && standard_80387_constant_p (operands[1]) > 0)
2810 || (TARGET_SSE2 && TARGET_SSE_MATH
2811 && standard_sse_constant_p (operands[1]))"
2813 /* This insn should be already split before reg-stack. */
2816 [(set_attr "isa" "*,nox64,x64,sse2")
2817 (set_attr "type" "multi")
2818 (set_attr "unit" "i387,*,*,sse")
2819 (set_attr "mode" "DF,SI,DI,DF")])
2821 ;; %%% Kill this when call knows how to work this out.
2823 [(set (match_operand:DF 0 "push_operand")
2824 (match_operand:DF 1 "any_fp_register_operand"))]
2826 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2827 (set (match_dup 0) (match_dup 1))]
2829 /* Preserve memory attributes. */
2830 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2833 (define_insn "*pushsf_rex64"
2834 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2835 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2838 /* Anything else should be already split before reg-stack. */
2839 gcc_assert (which_alternative == 1);
2840 return "push{q}\t%q1";
2842 [(set_attr "type" "multi,push,multi")
2843 (set_attr "unit" "i387,*,*")
2844 (set_attr "mode" "SF,DI,SF")])
2846 (define_insn "*pushsf"
2847 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2848 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2851 /* Anything else should be already split before reg-stack. */
2852 gcc_assert (which_alternative == 1);
2853 return "push{l}\t%1";
2855 [(set_attr "type" "multi,push,multi")
2856 (set_attr "unit" "i387,*,*")
2857 (set_attr "mode" "SF,SI,SF")])
2859 ;; %%% Kill this when call knows how to work this out.
2861 [(set (match_operand:SF 0 "push_operand")
2862 (match_operand:SF 1 "any_fp_register_operand"))]
2864 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2865 (set (match_dup 0) (match_dup 1))]
2867 rtx op = XEXP (operands[0], 0);
2868 if (GET_CODE (op) == PRE_DEC)
2870 gcc_assert (!TARGET_64BIT);
2875 op = XEXP (XEXP (op, 1), 1);
2876 gcc_assert (CONST_INT_P (op));
2879 /* Preserve memory attributes. */
2880 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2884 [(set (match_operand:SF 0 "push_operand")
2885 (match_operand:SF 1 "memory_operand"))]
2887 && (operands[2] = find_constant_src (insn))"
2888 [(set (match_dup 0) (match_dup 2))])
2891 [(set (match_operand 0 "push_operand")
2892 (match_operand 1 "general_operand"))]
2894 && (GET_MODE (operands[0]) == TFmode
2895 || GET_MODE (operands[0]) == XFmode
2896 || GET_MODE (operands[0]) == DFmode)
2897 && !ANY_FP_REG_P (operands[1])"
2899 "ix86_split_long_move (operands); DONE;")
2901 ;; Floating point move instructions.
2903 (define_expand "movtf"
2904 [(set (match_operand:TF 0 "nonimmediate_operand")
2905 (match_operand:TF 1 "nonimmediate_operand"))]
2906 "TARGET_64BIT || TARGET_SSE"
2907 "ix86_expand_move (TFmode, operands); DONE;")
2909 (define_expand "mov<mode>"
2910 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2911 (match_operand:X87MODEF 1 "general_operand"))]
2913 "ix86_expand_move (<MODE>mode, operands); DONE;")
2915 (define_insn "*movtf_internal"
2916 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2917 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2918 "(TARGET_64BIT || TARGET_SSE)
2919 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2920 && (!can_create_pseudo_p ()
2921 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2922 || GET_CODE (operands[1]) != CONST_DOUBLE
2923 || (optimize_function_for_size_p (cfun)
2924 && standard_sse_constant_p (operands[1])
2925 && !memory_operand (operands[0], TFmode))
2926 || (!TARGET_MEMORY_MISMATCH_STALL
2927 && memory_operand (operands[0], TFmode)))"
2929 switch (get_attr_type (insn))
2932 return standard_sse_constant_opcode (insn, operands[1]);
2935 /* Handle misaligned load/store since we
2936 don't have movmisaligntf pattern. */
2937 if (misaligned_operand (operands[0], TFmode)
2938 || misaligned_operand (operands[1], TFmode))
2940 if (get_attr_mode (insn) == MODE_V4SF)
2941 return "%vmovups\t{%1, %0|%0, %1}";
2943 return "%vmovdqu\t{%1, %0|%0, %1}";
2947 if (get_attr_mode (insn) == MODE_V4SF)
2948 return "%vmovaps\t{%1, %0|%0, %1}";
2950 return "%vmovdqa\t{%1, %0|%0, %1}";
2960 [(set_attr "isa" "*,*,*,x64,x64")
2961 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2962 (set (attr "prefix")
2963 (if_then_else (eq_attr "type" "sselog1,ssemov")
2964 (const_string "maybe_vex")
2965 (const_string "orig")))
2967 (cond [(eq_attr "alternative" "3,4")
2969 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2970 (const_string "V4SF")
2971 (and (eq_attr "alternative" "2")
2972 (match_test "TARGET_SSE_TYPELESS_STORES"))
2973 (const_string "V4SF")
2974 (match_test "TARGET_AVX")
2976 (ior (not (match_test "TARGET_SSE2"))
2977 (match_test "optimize_function_for_size_p (cfun)"))
2978 (const_string "V4SF")
2980 (const_string "TI")))])
2982 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2983 (define_insn "*movxf_internal"
2984 [(set (match_operand:XF 0 "nonimmediate_operand"
2985 "=f,m,f,?Yx*r ,!o ,!o")
2986 (match_operand:XF 1 "general_operand"
2987 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2988 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2989 && (!can_create_pseudo_p ()
2990 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2991 || GET_CODE (operands[1]) != CONST_DOUBLE
2992 || (optimize_function_for_size_p (cfun)
2993 && standard_80387_constant_p (operands[1]) > 0
2994 && !memory_operand (operands[0], XFmode))
2995 || (!TARGET_MEMORY_MISMATCH_STALL
2996 && memory_operand (operands[0], XFmode)))"
2998 switch (get_attr_type (insn))
3001 if (which_alternative == 2)
3002 return standard_80387_constant_opcode (operands[1]);
3003 return output_387_reg_move (insn, operands);
3012 [(set_attr "isa" "*,*,*,*,nox64,x64")
3013 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3015 (cond [(eq_attr "alternative" "3,4,5")
3016 (if_then_else (match_test "TARGET_64BIT")
3018 (const_string "SI"))
3020 (const_string "XF")))])
3022 ;; Possible store forwarding (partial memory) stall in alternative 4.
3023 (define_insn "*movdf_internal"
3024 [(set (match_operand:DF 0 "nonimmediate_operand"
3025 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3026 (match_operand:DF 1 "general_operand"
3027 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3028 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3029 && (!can_create_pseudo_p ()
3030 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3031 || GET_CODE (operands[1]) != CONST_DOUBLE
3032 || (optimize_function_for_size_p (cfun)
3033 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3034 && standard_80387_constant_p (operands[1]) > 0)
3035 || (TARGET_SSE2 && TARGET_SSE_MATH
3036 && standard_sse_constant_p (operands[1])))
3037 && !memory_operand (operands[0], DFmode))
3038 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3039 && memory_operand (operands[0], DFmode)))"
3041 switch (get_attr_type (insn))
3044 if (which_alternative == 2)
3045 return standard_80387_constant_opcode (operands[1]);
3046 return output_387_reg_move (insn, operands);
3052 if (get_attr_mode (insn) == MODE_SI)
3053 return "mov{l}\t{%1, %k0|%k0, %1}";
3054 else if (which_alternative == 8)
3055 return "movabs{q}\t{%1, %0|%0, %1}";
3057 return "mov{q}\t{%1, %0|%0, %1}";
3060 return standard_sse_constant_opcode (insn, operands[1]);
3063 switch (get_attr_mode (insn))
3066 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3067 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3068 return "%vmovsd\t{%1, %0|%0, %1}";
3071 return "%vmovaps\t{%1, %0|%0, %1}";
3073 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3075 return "%vmovapd\t{%1, %0|%0, %1}";
3078 gcc_assert (!TARGET_AVX);
3079 return "movlps\t{%1, %0|%0, %1}";
3081 gcc_assert (!TARGET_AVX);
3082 return "movlpd\t{%1, %0|%0, %1}";
3085 /* Handle broken assemblers that require movd instead of movq. */
3086 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3087 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3088 return "%vmovd\t{%1, %0|%0, %1}";
3089 return "%vmovq\t{%1, %0|%0, %1}";
3100 (cond [(eq_attr "alternative" "3,4")
3101 (const_string "nox64")
3102 (eq_attr "alternative" "5,6,7,8,17,18")
3103 (const_string "x64")
3104 (eq_attr "alternative" "9,10,11,12")
3105 (const_string "sse2")
3107 (const_string "*")))
3109 (cond [(eq_attr "alternative" "0,1,2")
3110 (const_string "fmov")
3111 (eq_attr "alternative" "3,4")
3112 (const_string "multi")
3113 (eq_attr "alternative" "5,6,7,8")
3114 (const_string "imov")
3115 (eq_attr "alternative" "9,13")
3116 (const_string "sselog1")
3118 (const_string "ssemov")))
3120 (if_then_else (eq_attr "alternative" "8")
3122 (const_string "*")))
3123 (set (attr "length_immediate")
3124 (if_then_else (eq_attr "alternative" "8")
3126 (const_string "*")))
3127 (set (attr "prefix")
3128 (if_then_else (eq_attr "type" "sselog1,ssemov")
3129 (const_string "maybe_vex")
3130 (const_string "orig")))
3131 (set (attr "prefix_data16")
3133 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3134 (eq_attr "mode" "V1DF"))
3136 (const_string "*")))
3138 (cond [(eq_attr "alternative" "3,4,7")
3140 (eq_attr "alternative" "5,6,8,17,18")
3143 /* xorps is one byte shorter for non-AVX targets. */
3144 (eq_attr "alternative" "9,13")
3145 (cond [(not (match_test "TARGET_SSE2"))
3146 (const_string "V4SF")
3147 (match_test "TARGET_AVX512F")
3149 (match_test "TARGET_AVX")
3150 (const_string "V2DF")
3151 (match_test "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3156 (const_string "V2DF"))
3158 /* For architectures resolving dependencies on
3159 whole SSE registers use movapd to break dependency
3160 chains, otherwise use short move to avoid extra work. */
3162 /* movaps is one byte shorter for non-AVX targets. */
3163 (eq_attr "alternative" "10,14")
3164 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3165 (match_operand 1 "ext_sse_reg_operand"))
3166 (const_string "V8DF")
3167 (ior (not (match_test "TARGET_SSE2"))
3168 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3169 (const_string "V4SF")
3170 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3171 (const_string "V2DF")
3172 (match_test "TARGET_AVX")
3174 (match_test "optimize_function_for_size_p (cfun)")
3175 (const_string "V4SF")
3177 (const_string "DF"))
3179 /* For architectures resolving dependencies on register
3180 parts we may avoid extra work to zero out upper part
3182 (eq_attr "alternative" "11,15")
3183 (cond [(not (match_test "TARGET_SSE2"))
3184 (const_string "V2SF")
3185 (match_test "TARGET_AVX")
3187 (match_test "TARGET_SSE_SPLIT_REGS")
3188 (const_string "V1DF")
3190 (const_string "DF"))
3192 (and (eq_attr "alternative" "12,16")
3193 (not (match_test "TARGET_SSE2")))
3194 (const_string "V2SF")
3196 (const_string "DF")))])
3198 (define_insn "*movsf_internal"
3199 [(set (match_operand:SF 0 "nonimmediate_operand"
3200 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3201 (match_operand:SF 1 "general_operand"
3202 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3203 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3204 && (!can_create_pseudo_p ()
3205 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3206 || GET_CODE (operands[1]) != CONST_DOUBLE
3207 || (optimize_function_for_size_p (cfun)
3208 && ((!TARGET_SSE_MATH
3209 && standard_80387_constant_p (operands[1]) > 0)
3211 && standard_sse_constant_p (operands[1]))))
3212 || memory_operand (operands[0], SFmode))"
3214 switch (get_attr_type (insn))
3217 if (which_alternative == 2)
3218 return standard_80387_constant_opcode (operands[1]);
3219 return output_387_reg_move (insn, operands);
3222 return "mov{l}\t{%1, %0|%0, %1}";
3225 return standard_sse_constant_opcode (insn, operands[1]);
3228 switch (get_attr_mode (insn))
3231 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3232 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3233 return "%vmovss\t{%1, %0|%0, %1}";
3236 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3238 return "%vmovaps\t{%1, %0|%0, %1}";
3241 return "%vmovd\t{%1, %0|%0, %1}";
3248 switch (get_attr_mode (insn))
3251 return "movq\t{%1, %0|%0, %1}";
3253 return "movd\t{%1, %0|%0, %1}";
3264 (cond [(eq_attr "alternative" "0,1,2")
3265 (const_string "fmov")
3266 (eq_attr "alternative" "3,4")
3267 (const_string "imov")
3268 (eq_attr "alternative" "5")
3269 (const_string "sselog1")
3270 (eq_attr "alternative" "11,12,13,14,15")
3271 (const_string "mmxmov")
3273 (const_string "ssemov")))
3274 (set (attr "prefix")
3275 (if_then_else (eq_attr "type" "sselog1,ssemov")
3276 (const_string "maybe_vex")
3277 (const_string "orig")))
3278 (set (attr "prefix_data16")
3279 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3281 (const_string "*")))
3283 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3285 (eq_attr "alternative" "11")
3287 (eq_attr "alternative" "5")
3288 (cond [(not (match_test "TARGET_SSE2"))
3289 (const_string "V4SF")
3290 (match_test "TARGET_AVX512F")
3291 (const_string "V16SF")
3292 (match_test "TARGET_AVX")
3293 (const_string "V4SF")
3294 (match_test "optimize_function_for_size_p (cfun)")
3295 (const_string "V4SF")
3296 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3299 (const_string "V4SF"))
3301 /* For architectures resolving dependencies on
3302 whole SSE registers use APS move to break dependency
3303 chains, otherwise use short move to avoid extra work.
3305 Do the same for architectures resolving dependencies on
3306 the parts. While in DF mode it is better to always handle
3307 just register parts, the SF mode is different due to lack
3308 of instructions to load just part of the register. It is
3309 better to maintain the whole registers in single format
3310 to avoid problems on using packed logical operations. */
3311 (eq_attr "alternative" "6")
3312 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3313 (match_operand 1 "ext_sse_reg_operand"))
3314 (const_string "V16SF")
3315 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3316 (match_test "TARGET_SSE_SPLIT_REGS"))
3317 (const_string "V4SF")
3319 (const_string "SF"))
3321 (const_string "SF")))])
3324 [(set (match_operand 0 "any_fp_register_operand")
3325 (match_operand 1 "memory_operand"))]
3327 && (GET_MODE (operands[0]) == TFmode
3328 || GET_MODE (operands[0]) == XFmode
3329 || GET_MODE (operands[0]) == DFmode
3330 || GET_MODE (operands[0]) == SFmode)
3331 && (operands[2] = find_constant_src (insn))"
3332 [(set (match_dup 0) (match_dup 2))]
3334 rtx c = operands[2];
3335 int r = REGNO (operands[0]);
3337 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3338 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3343 [(set (match_operand 0 "any_fp_register_operand")
3344 (float_extend (match_operand 1 "memory_operand")))]
3346 && (GET_MODE (operands[0]) == TFmode
3347 || GET_MODE (operands[0]) == XFmode
3348 || GET_MODE (operands[0]) == DFmode)
3349 && (operands[2] = find_constant_src (insn))"
3350 [(set (match_dup 0) (match_dup 2))]
3352 rtx c = operands[2];
3353 int r = REGNO (operands[0]);
3355 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3356 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3360 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3362 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3363 (match_operand:X87MODEF 1 "immediate_operand"))]
3365 && (standard_80387_constant_p (operands[1]) == 8
3366 || standard_80387_constant_p (operands[1]) == 9)"
3367 [(set (match_dup 0)(match_dup 1))
3369 (neg:X87MODEF (match_dup 0)))]
3373 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3374 if (real_isnegzero (&r))
3375 operands[1] = CONST0_RTX (<MODE>mode);
3377 operands[1] = CONST1_RTX (<MODE>mode);
3381 [(set (match_operand 0 "nonimmediate_operand")
3382 (match_operand 1 "general_operand"))]
3384 && (GET_MODE (operands[0]) == TFmode
3385 || GET_MODE (operands[0]) == XFmode
3386 || GET_MODE (operands[0]) == DFmode)
3387 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3389 "ix86_split_long_move (operands); DONE;")
3391 (define_insn "swapxf"
3392 [(set (match_operand:XF 0 "register_operand" "+f")
3393 (match_operand:XF 1 "register_operand" "+f"))
3398 if (STACK_TOP_P (operands[0]))
3403 [(set_attr "type" "fxch")
3404 (set_attr "mode" "XF")])
3406 (define_insn "*swap<mode>"
3407 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3408 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3411 "TARGET_80387 || reload_completed"
3413 if (STACK_TOP_P (operands[0]))
3418 [(set_attr "type" "fxch")
3419 (set_attr "mode" "<MODE>")])
3421 ;; Zero extension instructions
3423 (define_expand "zero_extendsidi2"
3424 [(set (match_operand:DI 0 "nonimmediate_operand")
3425 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3427 (define_insn "*zero_extendsidi2"
3428 [(set (match_operand:DI 0 "nonimmediate_operand"
3429 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3431 (match_operand:SI 1 "x86_64_zext_operand"
3432 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3435 switch (get_attr_type (insn))
3438 if (ix86_use_lea_for_mov (insn, operands))
3439 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3441 return "mov{l}\t{%1, %k0|%k0, %1}";
3447 return "movd\t{%1, %0|%0, %1}";
3450 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3453 if (GENERAL_REG_P (operands[0]))
3454 return "%vmovd\t{%1, %k0|%k0, %1}";
3456 return "%vmovd\t{%1, %0|%0, %1}";
3463 (cond [(eq_attr "alternative" "0,1,2")
3464 (const_string "nox64")
3465 (eq_attr "alternative" "3,7")
3466 (const_string "x64")
3467 (eq_attr "alternative" "8")
3468 (const_string "x64_sse4")
3469 (eq_attr "alternative" "10")
3470 (const_string "sse2")
3472 (const_string "*")))
3474 (cond [(eq_attr "alternative" "0,1,2,4")
3475 (const_string "multi")
3476 (eq_attr "alternative" "5,6")
3477 (const_string "mmxmov")
3478 (eq_attr "alternative" "7,9,10")
3479 (const_string "ssemov")
3480 (eq_attr "alternative" "8")
3481 (const_string "sselog1")
3483 (const_string "imovx")))
3484 (set (attr "prefix_extra")
3485 (if_then_else (eq_attr "alternative" "8")
3487 (const_string "*")))
3488 (set (attr "length_immediate")
3489 (if_then_else (eq_attr "alternative" "8")
3491 (const_string "*")))
3492 (set (attr "prefix")
3493 (if_then_else (eq_attr "type" "ssemov,sselog1")
3494 (const_string "maybe_vex")
3495 (const_string "orig")))
3496 (set (attr "prefix_0f")
3497 (if_then_else (eq_attr "type" "imovx")
3499 (const_string "*")))
3501 (cond [(eq_attr "alternative" "5,6")
3503 (eq_attr "alternative" "7,8,9")
3506 (const_string "SI")))])
3509 [(set (match_operand:DI 0 "memory_operand")
3510 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3512 [(set (match_dup 4) (const_int 0))]
3513 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3516 [(set (match_operand:DI 0 "register_operand")
3517 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3518 "!TARGET_64BIT && reload_completed
3519 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3520 && true_regnum (operands[0]) == true_regnum (operands[1])"
3521 [(set (match_dup 4) (const_int 0))]
3522 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3525 [(set (match_operand:DI 0 "nonimmediate_operand")
3526 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3527 "!TARGET_64BIT && reload_completed
3528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3530 [(set (match_dup 3) (match_dup 1))
3531 (set (match_dup 4) (const_int 0))]
3532 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3534 (define_insn "zero_extend<mode>di2"
3535 [(set (match_operand:DI 0 "register_operand" "=r")
3537 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3539 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3540 [(set_attr "type" "imovx")
3541 (set_attr "mode" "SI")])
3543 (define_expand "zero_extend<mode>si2"
3544 [(set (match_operand:SI 0 "register_operand")
3545 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3548 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 operands[1] = force_reg (<MODE>mode, operands[1]);
3551 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3556 (define_insn_and_split "zero_extend<mode>si2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3559 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3560 (clobber (reg:CC FLAGS_REG))]
3561 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3563 "&& reload_completed"
3564 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3565 (clobber (reg:CC FLAGS_REG))])]
3567 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3569 ix86_expand_clear (operands[0]);
3571 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3572 emit_insn (gen_movstrict<mode>
3573 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3577 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "SI")])
3582 (define_insn "*zero_extend<mode>si2"
3583 [(set (match_operand:SI 0 "register_operand" "=r")
3585 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3586 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3587 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3588 [(set_attr "type" "imovx")
3589 (set_attr "mode" "SI")])
3591 (define_expand "zero_extendqihi2"
3592 [(set (match_operand:HI 0 "register_operand")
3593 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3596 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3598 operands[1] = force_reg (QImode, operands[1]);
3599 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3604 (define_insn_and_split "zero_extendqihi2_and"
3605 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3606 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3607 (clobber (reg:CC FLAGS_REG))]
3608 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3610 "&& reload_completed"
3611 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3612 (clobber (reg:CC FLAGS_REG))])]
3614 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3616 ix86_expand_clear (operands[0]);
3618 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3619 emit_insn (gen_movstrictqi
3620 (gen_lowpart (QImode, operands[0]), operands[1]));
3624 operands[0] = gen_lowpart (SImode, operands[0]);
3626 [(set_attr "type" "alu1")
3627 (set_attr "mode" "SI")])
3629 ; zero extend to SImode to avoid partial register stalls
3630 (define_insn "*zero_extendqihi2"
3631 [(set (match_operand:HI 0 "register_operand" "=r")
3632 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3633 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3634 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3635 [(set_attr "type" "imovx")
3636 (set_attr "mode" "SI")])
3638 ;; Sign extension instructions
3640 (define_expand "extendsidi2"
3641 [(set (match_operand:DI 0 "register_operand")
3642 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3647 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3652 (define_insn "*extendsidi2_rex64"
3653 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3654 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3658 movs{lq|x}\t{%1, %0|%0, %1}"
3659 [(set_attr "type" "imovx")
3660 (set_attr "mode" "DI")
3661 (set_attr "prefix_0f" "0")
3662 (set_attr "modrm" "0,1")])
3664 (define_insn "extendsidi2_1"
3665 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3666 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3667 (clobber (reg:CC FLAGS_REG))
3668 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3672 ;; Split the memory case. If the source register doesn't die, it will stay
3673 ;; this way, if it does die, following peephole2s take care of it.
3675 [(set (match_operand:DI 0 "memory_operand")
3676 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3677 (clobber (reg:CC FLAGS_REG))
3678 (clobber (match_operand:SI 2 "register_operand"))]
3682 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3684 emit_move_insn (operands[3], operands[1]);
3686 /* Generate a cltd if possible and doing so it profitable. */
3687 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3688 && true_regnum (operands[1]) == AX_REG
3689 && true_regnum (operands[2]) == DX_REG)
3691 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3695 emit_move_insn (operands[2], operands[1]);
3696 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3698 emit_move_insn (operands[4], operands[2]);
3702 ;; Peepholes for the case where the source register does die, after
3703 ;; being split with the above splitter.
3705 [(set (match_operand:SI 0 "memory_operand")
3706 (match_operand:SI 1 "register_operand"))
3707 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3708 (parallel [(set (match_dup 2)
3709 (ashiftrt:SI (match_dup 2) (const_int 31)))
3710 (clobber (reg:CC FLAGS_REG))])
3711 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3712 "REGNO (operands[1]) != REGNO (operands[2])
3713 && peep2_reg_dead_p (2, operands[1])
3714 && peep2_reg_dead_p (4, operands[2])
3715 && !reg_mentioned_p (operands[2], operands[3])"
3716 [(set (match_dup 0) (match_dup 1))
3717 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3718 (clobber (reg:CC FLAGS_REG))])
3719 (set (match_dup 3) (match_dup 1))])
3722 [(set (match_operand:SI 0 "memory_operand")
3723 (match_operand:SI 1 "register_operand"))
3724 (parallel [(set (match_operand:SI 2 "register_operand")
3725 (ashiftrt:SI (match_dup 1) (const_int 31)))
3726 (clobber (reg:CC FLAGS_REG))])
3727 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3728 "/* cltd is shorter than sarl $31, %eax */
3729 !optimize_function_for_size_p (cfun)
3730 && true_regnum (operands[1]) == AX_REG
3731 && true_regnum (operands[2]) == DX_REG
3732 && peep2_reg_dead_p (2, operands[1])
3733 && peep2_reg_dead_p (3, operands[2])
3734 && !reg_mentioned_p (operands[2], operands[3])"
3735 [(set (match_dup 0) (match_dup 1))
3736 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3737 (clobber (reg:CC FLAGS_REG))])
3738 (set (match_dup 3) (match_dup 1))])
3740 ;; Extend to register case. Optimize case where source and destination
3741 ;; registers match and cases where we can use cltd.
3743 [(set (match_operand:DI 0 "register_operand")
3744 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3745 (clobber (reg:CC FLAGS_REG))
3746 (clobber (match_scratch:SI 2))]
3750 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3752 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3753 emit_move_insn (operands[3], operands[1]);
3755 /* Generate a cltd if possible and doing so it profitable. */
3756 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3757 && true_regnum (operands[3]) == AX_REG
3758 && true_regnum (operands[4]) == DX_REG)
3760 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3764 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3765 emit_move_insn (operands[4], operands[1]);
3767 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3771 (define_insn "extend<mode>di2"
3772 [(set (match_operand:DI 0 "register_operand" "=r")
3774 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3776 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3777 [(set_attr "type" "imovx")
3778 (set_attr "mode" "DI")])
3780 (define_insn "extendhisi2"
3781 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3782 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3785 switch (get_attr_prefix_0f (insn))
3788 return "{cwtl|cwde}";
3790 return "movs{wl|x}\t{%1, %0|%0, %1}";
3793 [(set_attr "type" "imovx")
3794 (set_attr "mode" "SI")
3795 (set (attr "prefix_0f")
3796 ;; movsx is short decodable while cwtl is vector decoded.
3797 (if_then_else (and (eq_attr "cpu" "!k6")
3798 (eq_attr "alternative" "0"))
3800 (const_string "1")))
3802 (if_then_else (eq_attr "prefix_0f" "0")
3804 (const_string "1")))])
3806 (define_insn "*extendhisi2_zext"
3807 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3810 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3813 switch (get_attr_prefix_0f (insn))
3816 return "{cwtl|cwde}";
3818 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3821 [(set_attr "type" "imovx")
3822 (set_attr "mode" "SI")
3823 (set (attr "prefix_0f")
3824 ;; movsx is short decodable while cwtl is vector decoded.
3825 (if_then_else (and (eq_attr "cpu" "!k6")
3826 (eq_attr "alternative" "0"))
3828 (const_string "1")))
3830 (if_then_else (eq_attr "prefix_0f" "0")
3832 (const_string "1")))])
3834 (define_insn "extendqisi2"
3835 [(set (match_operand:SI 0 "register_operand" "=r")
3836 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3838 "movs{bl|x}\t{%1, %0|%0, %1}"
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "SI")])
3842 (define_insn "*extendqisi2_zext"
3843 [(set (match_operand:DI 0 "register_operand" "=r")
3845 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3847 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3848 [(set_attr "type" "imovx")
3849 (set_attr "mode" "SI")])
3851 (define_insn "extendqihi2"
3852 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3853 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3856 switch (get_attr_prefix_0f (insn))
3859 return "{cbtw|cbw}";
3861 return "movs{bw|x}\t{%1, %0|%0, %1}";
3864 [(set_attr "type" "imovx")
3865 (set_attr "mode" "HI")
3866 (set (attr "prefix_0f")
3867 ;; movsx is short decodable while cwtl is vector decoded.
3868 (if_then_else (and (eq_attr "cpu" "!k6")
3869 (eq_attr "alternative" "0"))
3871 (const_string "1")))
3873 (if_then_else (eq_attr "prefix_0f" "0")
3875 (const_string "1")))])
3877 ;; Conversions between float and double.
3879 ;; These are all no-ops in the model used for the 80387.
3880 ;; So just emit moves.
3882 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3884 [(set (match_operand:DF 0 "push_operand")
3885 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3887 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3888 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3891 [(set (match_operand:XF 0 "push_operand")
3892 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3894 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3895 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3896 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3898 (define_expand "extendsfdf2"
3899 [(set (match_operand:DF 0 "nonimmediate_operand")
3900 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3901 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3903 /* ??? Needed for compress_float_constant since all fp constants
3904 are TARGET_LEGITIMATE_CONSTANT_P. */
3905 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3907 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3908 && standard_80387_constant_p (operands[1]) > 0)
3910 operands[1] = simplify_const_unary_operation
3911 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3912 emit_move_insn_1 (operands[0], operands[1]);
3915 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3919 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3921 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3923 We do the conversion post reload to avoid producing of 128bit spills
3924 that might lead to ICE on 32bit target. The sequence unlikely combine
3927 [(set (match_operand:DF 0 "register_operand")
3929 (match_operand:SF 1 "nonimmediate_operand")))]
3930 "TARGET_USE_VECTOR_FP_CONVERTS
3931 && optimize_insn_for_speed_p ()
3932 && reload_completed && SSE_REG_P (operands[0])"
3937 (parallel [(const_int 0) (const_int 1)]))))]
3939 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3940 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3941 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3942 Try to avoid move when unpacking can be done in source. */
3943 if (REG_P (operands[1]))
3945 /* If it is unsafe to overwrite upper half of source, we need
3946 to move to destination and unpack there. */
3947 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3948 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3949 && true_regnum (operands[0]) != true_regnum (operands[1]))
3951 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3952 emit_move_insn (tmp, operands[1]);
3955 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3956 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3960 emit_insn (gen_vec_setv4sf_0 (operands[3],
3961 CONST0_RTX (V4SFmode), operands[1]));
3964 ;; It's more profitable to split and then extend in the same register.
3966 [(set (match_operand:DF 0 "register_operand")
3968 (match_operand:SF 1 "memory_operand")))]
3969 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3970 && optimize_insn_for_speed_p ()
3971 && SSE_REG_P (operands[0])"
3972 [(set (match_dup 2) (match_dup 1))
3973 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3974 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3976 (define_insn "*extendsfdf2_mixed"
3977 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3979 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3980 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3982 switch (which_alternative)
3986 return output_387_reg_move (insn, operands);
3989 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3995 [(set_attr "type" "fmov,fmov,ssecvt")
3996 (set_attr "prefix" "orig,orig,maybe_vex")
3997 (set_attr "mode" "SF,XF,DF")])
3999 (define_insn "*extendsfdf2_sse"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4001 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4002 "TARGET_SSE2 && TARGET_SSE_MATH"
4003 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4004 [(set_attr "type" "ssecvt")
4005 (set_attr "prefix" "maybe_vex")
4006 (set_attr "mode" "DF")])
4008 (define_insn "*extendsfdf2_i387"
4009 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4010 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4012 "* return output_387_reg_move (insn, operands);"
4013 [(set_attr "type" "fmov")
4014 (set_attr "mode" "SF,XF")])
4016 (define_expand "extend<mode>xf2"
4017 [(set (match_operand:XF 0 "nonimmediate_operand")
4018 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4021 /* ??? Needed for compress_float_constant since all fp constants
4022 are TARGET_LEGITIMATE_CONSTANT_P. */
4023 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4025 if (standard_80387_constant_p (operands[1]) > 0)
4027 operands[1] = simplify_const_unary_operation
4028 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4029 emit_move_insn_1 (operands[0], operands[1]);
4032 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4036 (define_insn "*extend<mode>xf2_i387"
4037 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4039 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4041 "* return output_387_reg_move (insn, operands);"
4042 [(set_attr "type" "fmov")
4043 (set_attr "mode" "<MODE>,XF")])
4045 ;; %%% This seems bad bad news.
4046 ;; This cannot output into an f-reg because there is no way to be sure
4047 ;; of truncating in that case. Otherwise this is just like a simple move
4048 ;; insn. So we pretend we can output to a reg in order to get better
4049 ;; register preferencing, but we really use a stack slot.
4051 ;; Conversion from DFmode to SFmode.
4053 (define_expand "truncdfsf2"
4054 [(set (match_operand:SF 0 "nonimmediate_operand")
4056 (match_operand:DF 1 "nonimmediate_operand")))]
4057 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4059 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4061 else if (flag_unsafe_math_optimizations)
4065 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4066 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4071 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4073 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4075 We do the conversion post reload to avoid producing of 128bit spills
4076 that might lead to ICE on 32bit target. The sequence unlikely combine
4079 [(set (match_operand:SF 0 "register_operand")
4081 (match_operand:DF 1 "nonimmediate_operand")))]
4082 "TARGET_USE_VECTOR_FP_CONVERTS
4083 && optimize_insn_for_speed_p ()
4084 && reload_completed && SSE_REG_P (operands[0])"
4087 (float_truncate:V2SF
4091 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4092 operands[3] = CONST0_RTX (V2SFmode);
4093 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4094 /* Use movsd for loading from memory, unpcklpd for registers.
4095 Try to avoid move when unpacking can be done in source, or SSE3
4096 movddup is available. */
4097 if (REG_P (operands[1]))
4100 && true_regnum (operands[0]) != true_regnum (operands[1])
4101 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4102 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4104 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4105 emit_move_insn (tmp, operands[1]);
4108 else if (!TARGET_SSE3)
4109 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4110 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4113 emit_insn (gen_sse2_loadlpd (operands[4],
4114 CONST0_RTX (V2DFmode), operands[1]));
4117 ;; It's more profitable to split and then extend in the same register.
4119 [(set (match_operand:SF 0 "register_operand")
4121 (match_operand:DF 1 "memory_operand")))]
4122 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4123 && optimize_insn_for_speed_p ()
4124 && SSE_REG_P (operands[0])"
4125 [(set (match_dup 2) (match_dup 1))
4126 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4127 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4129 (define_expand "truncdfsf2_with_temp"
4130 [(parallel [(set (match_operand:SF 0)
4131 (float_truncate:SF (match_operand:DF 1)))
4132 (clobber (match_operand:SF 2))])])
4134 (define_insn "*truncdfsf_fast_mixed"
4135 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4137 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4138 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4140 switch (which_alternative)
4143 return output_387_reg_move (insn, operands);
4145 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4150 [(set_attr "type" "fmov,ssecvt")
4151 (set_attr "prefix" "orig,maybe_vex")
4152 (set_attr "mode" "SF")])
4154 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4155 ;; because nothing we do here is unsafe.
4156 (define_insn "*truncdfsf_fast_sse"
4157 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4159 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4160 "TARGET_SSE2 && TARGET_SSE_MATH"
4161 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4162 [(set_attr "type" "ssecvt")
4163 (set_attr "prefix" "maybe_vex")
4164 (set_attr "mode" "SF")])
4166 (define_insn "*truncdfsf_fast_i387"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4169 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4170 "TARGET_80387 && flag_unsafe_math_optimizations"
4171 "* return output_387_reg_move (insn, operands);"
4172 [(set_attr "type" "fmov")
4173 (set_attr "mode" "SF")])
4175 (define_insn "*truncdfsf_mixed"
4176 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4178 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4179 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4180 "TARGET_MIX_SSE_I387"
4182 switch (which_alternative)
4185 return output_387_reg_move (insn, operands);
4187 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4193 [(set_attr "isa" "*,sse2,*,*,*")
4194 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4195 (set_attr "unit" "*,*,i387,i387,i387")
4196 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4197 (set_attr "mode" "SF")])
4199 (define_insn "*truncdfsf_i387"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4202 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4203 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4206 switch (which_alternative)
4209 return output_387_reg_move (insn, operands);
4215 [(set_attr "type" "fmov,multi,multi,multi")
4216 (set_attr "unit" "*,i387,i387,i387")
4217 (set_attr "mode" "SF")])
4219 (define_insn "*truncdfsf2_i387_1"
4220 [(set (match_operand:SF 0 "memory_operand" "=m")
4222 (match_operand:DF 1 "register_operand" "f")))]
4224 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4225 && !TARGET_MIX_SSE_I387"
4226 "* return output_387_reg_move (insn, operands);"
4227 [(set_attr "type" "fmov")
4228 (set_attr "mode" "SF")])
4231 [(set (match_operand:SF 0 "register_operand")
4233 (match_operand:DF 1 "fp_register_operand")))
4234 (clobber (match_operand 2))]
4236 [(set (match_dup 2) (match_dup 1))
4237 (set (match_dup 0) (match_dup 2))]
4238 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4240 ;; Conversion from XFmode to {SF,DF}mode
4242 (define_expand "truncxf<mode>2"
4243 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4244 (float_truncate:MODEF
4245 (match_operand:XF 1 "register_operand")))
4246 (clobber (match_dup 2))])]
4249 if (flag_unsafe_math_optimizations)
4251 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4252 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4253 if (reg != operands[0])
4254 emit_move_insn (operands[0], reg);
4258 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4261 (define_insn "*truncxfsf2_mixed"
4262 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4264 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4265 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4268 gcc_assert (!which_alternative);
4269 return output_387_reg_move (insn, operands);
4271 [(set_attr "type" "fmov,multi,multi,multi")
4272 (set_attr "unit" "*,i387,i387,i387")
4273 (set_attr "mode" "SF")])
4275 (define_insn "*truncxfdf2_mixed"
4276 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4278 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4279 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4282 gcc_assert (!which_alternative);
4283 return output_387_reg_move (insn, operands);
4285 [(set_attr "isa" "*,*,sse2,*")
4286 (set_attr "type" "fmov,multi,multi,multi")
4287 (set_attr "unit" "*,i387,i387,i387")
4288 (set_attr "mode" "DF")])
4290 (define_insn "truncxf<mode>2_i387_noop"
4291 [(set (match_operand:MODEF 0 "register_operand" "=f")
4292 (float_truncate:MODEF
4293 (match_operand:XF 1 "register_operand" "f")))]
4294 "TARGET_80387 && flag_unsafe_math_optimizations"
4295 "* return output_387_reg_move (insn, operands);"
4296 [(set_attr "type" "fmov")
4297 (set_attr "mode" "<MODE>")])
4299 (define_insn "*truncxf<mode>2_i387"
4300 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4301 (float_truncate:MODEF
4302 (match_operand:XF 1 "register_operand" "f")))]
4304 "* return output_387_reg_move (insn, operands);"
4305 [(set_attr "type" "fmov")
4306 (set_attr "mode" "<MODE>")])
4309 [(set (match_operand:MODEF 0 "register_operand")
4310 (float_truncate:MODEF
4311 (match_operand:XF 1 "register_operand")))
4312 (clobber (match_operand:MODEF 2 "memory_operand"))]
4313 "TARGET_80387 && reload_completed"
4314 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4315 (set (match_dup 0) (match_dup 2))])
4318 [(set (match_operand:MODEF 0 "memory_operand")
4319 (float_truncate:MODEF
4320 (match_operand:XF 1 "register_operand")))
4321 (clobber (match_operand:MODEF 2 "memory_operand"))]
4323 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4325 ;; Signed conversion to DImode.
4327 (define_expand "fix_truncxfdi2"
4328 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4329 (fix:DI (match_operand:XF 1 "register_operand")))
4330 (clobber (reg:CC FLAGS_REG))])]
4335 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4340 (define_expand "fix_trunc<mode>di2"
4341 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4342 (fix:DI (match_operand:MODEF 1 "register_operand")))
4343 (clobber (reg:CC FLAGS_REG))])]
4344 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4347 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4349 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4352 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4354 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4355 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4356 if (out != operands[0])
4357 emit_move_insn (operands[0], out);
4362 ;; Signed conversion to SImode.
4364 (define_expand "fix_truncxfsi2"
4365 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4366 (fix:SI (match_operand:XF 1 "register_operand")))
4367 (clobber (reg:CC FLAGS_REG))])]
4372 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4377 (define_expand "fix_trunc<mode>si2"
4378 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4379 (fix:SI (match_operand:MODEF 1 "register_operand")))
4380 (clobber (reg:CC FLAGS_REG))])]
4381 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4384 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4386 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4389 if (SSE_FLOAT_MODE_P (<MODE>mode))
4391 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4392 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4393 if (out != operands[0])
4394 emit_move_insn (operands[0], out);
4399 ;; Signed conversion to HImode.
4401 (define_expand "fix_trunc<mode>hi2"
4402 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4403 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4404 (clobber (reg:CC FLAGS_REG))])]
4406 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4410 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4415 ;; Unsigned conversion to SImode.
4417 (define_expand "fixuns_trunc<mode>si2"
4419 [(set (match_operand:SI 0 "register_operand")
4421 (match_operand:MODEF 1 "nonimmediate_operand")))
4423 (clobber (match_scratch:<ssevecmode> 3))
4424 (clobber (match_scratch:<ssevecmode> 4))])]
4425 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4427 machine_mode mode = <MODE>mode;
4428 machine_mode vecmode = <ssevecmode>mode;
4429 REAL_VALUE_TYPE TWO31r;
4432 if (optimize_insn_for_size_p ())
4435 real_ldexp (&TWO31r, &dconst1, 31);
4436 two31 = const_double_from_real_value (TWO31r, mode);
4437 two31 = ix86_build_const_vector (vecmode, true, two31);
4438 operands[2] = force_reg (vecmode, two31);
4441 (define_insn_and_split "*fixuns_trunc<mode>_1"
4442 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4444 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4445 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4446 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4447 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4448 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4449 && optimize_function_for_speed_p (cfun)"
4451 "&& reload_completed"
4454 ix86_split_convert_uns_si_sse (operands);
4458 ;; Unsigned conversion to HImode.
4459 ;; Without these patterns, we'll try the unsigned SI conversion which
4460 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4462 (define_expand "fixuns_trunc<mode>hi2"
4464 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4465 (set (match_operand:HI 0 "nonimmediate_operand")
4466 (subreg:HI (match_dup 2) 0))]
4467 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4468 "operands[2] = gen_reg_rtx (SImode);")
4470 ;; When SSE is available, it is always faster to use it!
4471 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4472 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4473 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4474 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4475 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4476 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4477 [(set_attr "type" "sseicvt")
4478 (set_attr "prefix" "maybe_vex")
4479 (set (attr "prefix_rex")
4481 (match_test "<SWI48:MODE>mode == DImode")
4483 (const_string "*")))
4484 (set_attr "mode" "<MODEF:MODE>")
4485 (set_attr "athlon_decode" "double,vector")
4486 (set_attr "amdfam10_decode" "double,double")
4487 (set_attr "bdver1_decode" "double,double")])
4489 ;; Avoid vector decoded forms of the instruction.
4491 [(match_scratch:MODEF 2 "x")
4492 (set (match_operand:SWI48 0 "register_operand")
4493 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4494 "TARGET_AVOID_VECTOR_DECODE
4495 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4496 && optimize_insn_for_speed_p ()"
4497 [(set (match_dup 2) (match_dup 1))
4498 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4500 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4501 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4502 (fix:SWI248x (match_operand 1 "register_operand")))]
4503 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4505 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4506 && (TARGET_64BIT || <MODE>mode != DImode))
4508 && can_create_pseudo_p ()"
4513 if (memory_operand (operands[0], VOIDmode))
4514 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4517 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4518 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4524 [(set_attr "type" "fisttp")
4525 (set_attr "mode" "<MODE>")])
4527 (define_insn "fix_trunc<mode>_i387_fisttp"
4528 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4529 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4530 (clobber (match_scratch:XF 2 "=&1f"))]
4531 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && TARGET_SSE_MATH)"
4536 "* return output_fix_trunc (insn, operands, true);"
4537 [(set_attr "type" "fisttp")
4538 (set_attr "mode" "<MODE>")])
4540 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4541 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4542 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4543 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4544 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4545 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4547 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4548 && (TARGET_64BIT || <MODE>mode != DImode))
4549 && TARGET_SSE_MATH)"
4551 [(set_attr "type" "fisttp")
4552 (set_attr "mode" "<MODE>")])
4555 [(set (match_operand:SWI248x 0 "register_operand")
4556 (fix:SWI248x (match_operand 1 "register_operand")))
4557 (clobber (match_operand:SWI248x 2 "memory_operand"))
4558 (clobber (match_scratch 3))]
4560 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4561 (clobber (match_dup 3))])
4562 (set (match_dup 0) (match_dup 2))])
4565 [(set (match_operand:SWI248x 0 "memory_operand")
4566 (fix:SWI248x (match_operand 1 "register_operand")))
4567 (clobber (match_operand:SWI248x 2 "memory_operand"))
4568 (clobber (match_scratch 3))]
4570 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4571 (clobber (match_dup 3))])])
4573 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4574 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4575 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4576 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4577 ;; function in i386.c.
4578 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4579 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4580 (fix:SWI248x (match_operand 1 "register_operand")))
4581 (clobber (reg:CC FLAGS_REG))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && (TARGET_64BIT || <MODE>mode != DImode))
4586 && can_create_pseudo_p ()"
4591 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4593 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4594 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4595 if (memory_operand (operands[0], VOIDmode))
4596 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4597 operands[2], operands[3]));
4600 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4601 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4602 operands[2], operands[3],
4607 [(set_attr "type" "fistp")
4608 (set_attr "i387_cw" "trunc")
4609 (set_attr "mode" "<MODE>")])
4611 (define_insn "fix_truncdi_i387"
4612 [(set (match_operand:DI 0 "memory_operand" "=m")
4613 (fix:DI (match_operand 1 "register_operand" "f")))
4614 (use (match_operand:HI 2 "memory_operand" "m"))
4615 (use (match_operand:HI 3 "memory_operand" "m"))
4616 (clobber (match_scratch:XF 4 "=&1f"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4620 "* return output_fix_trunc (insn, operands, false);"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "DI")])
4625 (define_insn "fix_truncdi_i387_with_temp"
4626 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4627 (fix:DI (match_operand 1 "register_operand" "f,f")))
4628 (use (match_operand:HI 2 "memory_operand" "m,m"))
4629 (use (match_operand:HI 3 "memory_operand" "m,m"))
4630 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4631 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4632 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4636 [(set_attr "type" "fistp")
4637 (set_attr "i387_cw" "trunc")
4638 (set_attr "mode" "DI")])
4641 [(set (match_operand:DI 0 "register_operand")
4642 (fix:DI (match_operand 1 "register_operand")))
4643 (use (match_operand:HI 2 "memory_operand"))
4644 (use (match_operand:HI 3 "memory_operand"))
4645 (clobber (match_operand:DI 4 "memory_operand"))
4646 (clobber (match_scratch 5))]
4648 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4651 (clobber (match_dup 5))])
4652 (set (match_dup 0) (match_dup 4))])
4655 [(set (match_operand:DI 0 "memory_operand")
4656 (fix:DI (match_operand 1 "register_operand")))
4657 (use (match_operand:HI 2 "memory_operand"))
4658 (use (match_operand:HI 3 "memory_operand"))
4659 (clobber (match_operand:DI 4 "memory_operand"))
4660 (clobber (match_scratch 5))]
4662 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4665 (clobber (match_dup 5))])])
4667 (define_insn "fix_trunc<mode>_i387"
4668 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4669 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4670 (use (match_operand:HI 2 "memory_operand" "m"))
4671 (use (match_operand:HI 3 "memory_operand" "m"))]
4672 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4675 "* return output_fix_trunc (insn, operands, false);"
4676 [(set_attr "type" "fistp")
4677 (set_attr "i387_cw" "trunc")
4678 (set_attr "mode" "<MODE>")])
4680 (define_insn "fix_trunc<mode>_i387_with_temp"
4681 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4682 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4683 (use (match_operand:HI 2 "memory_operand" "m,m"))
4684 (use (match_operand:HI 3 "memory_operand" "m,m"))
4685 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4686 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4688 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4690 [(set_attr "type" "fistp")
4691 (set_attr "i387_cw" "trunc")
4692 (set_attr "mode" "<MODE>")])
4695 [(set (match_operand:SWI24 0 "register_operand")
4696 (fix:SWI24 (match_operand 1 "register_operand")))
4697 (use (match_operand:HI 2 "memory_operand"))
4698 (use (match_operand:HI 3 "memory_operand"))
4699 (clobber (match_operand:SWI24 4 "memory_operand"))]
4701 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4703 (use (match_dup 3))])
4704 (set (match_dup 0) (match_dup 4))])
4707 [(set (match_operand:SWI24 0 "memory_operand")
4708 (fix:SWI24 (match_operand 1 "register_operand")))
4709 (use (match_operand:HI 2 "memory_operand"))
4710 (use (match_operand:HI 3 "memory_operand"))
4711 (clobber (match_operand:SWI24 4 "memory_operand"))]
4713 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4715 (use (match_dup 3))])])
4717 (define_insn "x86_fnstcw_1"
4718 [(set (match_operand:HI 0 "memory_operand" "=m")
4719 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4722 [(set (attr "length")
4723 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4724 (set_attr "mode" "HI")
4725 (set_attr "unit" "i387")
4726 (set_attr "bdver1_decode" "vector")])
4728 (define_insn "x86_fldcw_1"
4729 [(set (reg:HI FPCR_REG)
4730 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4733 [(set (attr "length")
4734 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4735 (set_attr "mode" "HI")
4736 (set_attr "unit" "i387")
4737 (set_attr "athlon_decode" "vector")
4738 (set_attr "amdfam10_decode" "vector")
4739 (set_attr "bdver1_decode" "vector")])
4741 ;; Conversion between fixed point and floating point.
4743 ;; Even though we only accept memory inputs, the backend _really_
4744 ;; wants to be able to do this between registers. Thankfully, LRA
4745 ;; will fix this up for us during register allocation.
4747 (define_insn "floathi<mode>2"
4748 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4749 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4752 || TARGET_MIX_SSE_I387)"
4754 [(set_attr "type" "fmov")
4755 (set_attr "mode" "<MODE>")
4756 (set_attr "fp_int_src" "true")])
4758 (define_insn "float<SWI48x:mode>xf2"
4759 [(set (match_operand:XF 0 "register_operand" "=f")
4760 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4763 [(set_attr "type" "fmov")
4764 (set_attr "mode" "XF")
4765 (set_attr "fp_int_src" "true")])
4767 (define_expand "float<SWI48:mode><MODEF:mode>2"
4768 [(set (match_operand:MODEF 0 "register_operand")
4769 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4770 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4772 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4773 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4775 rtx reg = gen_reg_rtx (XFmode);
4776 rtx (*insn)(rtx, rtx);
4778 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4780 if (<MODEF:MODE>mode == SFmode)
4781 insn = gen_truncxfsf2;
4782 else if (<MODEF:MODE>mode == DFmode)
4783 insn = gen_truncxfdf2;
4787 emit_insn (insn (operands[0], reg));
4792 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4793 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4795 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4796 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4799 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4800 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4801 [(set_attr "type" "fmov,sseicvt,sseicvt")
4802 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4803 (set_attr "mode" "<MODEF:MODE>")
4804 (set (attr "prefix_rex")
4806 (and (eq_attr "prefix" "maybe_vex")
4807 (match_test "<SWI48:MODE>mode == DImode"))
4809 (const_string "*")))
4810 (set_attr "unit" "i387,*,*")
4811 (set_attr "athlon_decode" "*,double,direct")
4812 (set_attr "amdfam10_decode" "*,vector,double")
4813 (set_attr "bdver1_decode" "*,double,direct")
4814 (set_attr "fp_int_src" "true")
4815 (set (attr "enabled")
4816 (cond [(eq_attr "alternative" "0")
4817 (symbol_ref "TARGET_MIX_SSE_I387
4818 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4821 (symbol_ref "true")))
4822 (set (attr "preferred_for_speed")
4823 (cond [(eq_attr "alternative" "1")
4824 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4825 (symbol_ref "true")))
4828 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4829 [(set (match_operand:MODEF 0 "register_operand" "=f")
4830 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4831 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4833 [(set_attr "type" "fmov")
4834 (set_attr "mode" "<MODEF:MODE>")
4835 (set_attr "fp_int_src" "true")])
4837 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4838 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4839 ;; alternative in sse2_loadld.
4841 [(set (match_operand:MODEF 0 "register_operand")
4842 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4843 "TARGET_SSE2 && TARGET_SSE_MATH
4844 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4845 && reload_completed && SSE_REG_P (operands[0])
4846 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4849 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4851 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4853 emit_insn (gen_sse2_loadld (operands[4],
4854 CONST0_RTX (V4SImode), operands[1]));
4856 if (<ssevecmode>mode == V4SFmode)
4857 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4859 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4863 ;; Avoid partial SSE register dependency stalls
4865 [(set (match_operand:MODEF 0 "register_operand")
4866 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4867 "TARGET_SSE2 && TARGET_SSE_MATH
4868 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4869 && optimize_function_for_speed_p (cfun)
4870 && reload_completed && SSE_REG_P (operands[0])"
4873 const machine_mode vmode = <MODEF:ssevecmode>mode;
4874 const machine_mode mode = <MODEF:MODE>mode;
4875 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4877 emit_move_insn (op0, CONST0_RTX (vmode));
4879 t = gen_rtx_FLOAT (mode, operands[1]);
4880 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4881 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4882 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4886 ;; Break partial reg stall for cvtsd2ss.
4889 [(set (match_operand:SF 0 "register_operand")
4891 (match_operand:DF 1 "nonimmediate_operand")))]
4892 "TARGET_SSE2 && TARGET_SSE_MATH
4893 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4894 && optimize_function_for_speed_p (cfun)
4895 && SSE_REG_P (operands[0])
4896 && (!SSE_REG_P (operands[1])
4897 || REGNO (operands[0]) != REGNO (operands[1]))"
4901 (float_truncate:V2SF
4906 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4908 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4910 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4913 ;; Break partial reg stall for cvtss2sd.
4916 [(set (match_operand:DF 0 "register_operand")
4918 (match_operand:SF 1 "nonimmediate_operand")))]
4919 "TARGET_SSE2 && TARGET_SSE_MATH
4920 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4921 && optimize_function_for_speed_p (cfun)
4922 && SSE_REG_P (operands[0])
4923 && (!SSE_REG_P (operands[1])
4924 || REGNO (operands[0]) != REGNO (operands[1]))"
4930 (parallel [(const_int 0) (const_int 1)])))
4934 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4936 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4938 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4941 ;; Avoid store forwarding (partial memory) stall penalty
4942 ;; by passing DImode value through XMM registers. */
4944 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4945 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4947 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4948 (clobber (match_scratch:V4SI 3 "=X,x"))
4949 (clobber (match_scratch:V4SI 4 "=X,x"))
4950 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4951 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4952 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4953 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4955 [(set_attr "type" "multi")
4956 (set_attr "mode" "<X87MODEF:MODE>")
4957 (set_attr "unit" "i387")
4958 (set_attr "fp_int_src" "true")])
4961 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4962 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4963 (clobber (match_scratch:V4SI 3))
4964 (clobber (match_scratch:V4SI 4))
4965 (clobber (match_operand:DI 2 "memory_operand"))]
4966 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4967 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4968 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4969 && reload_completed"
4970 [(set (match_dup 2) (match_dup 3))
4971 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4973 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4974 Assemble the 64-bit DImode value in an xmm register. */
4975 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4976 gen_rtx_SUBREG (SImode, operands[1], 0)));
4977 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4978 gen_rtx_SUBREG (SImode, operands[1], 4)));
4979 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4982 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4986 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4987 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4988 (clobber (match_scratch:V4SI 3))
4989 (clobber (match_scratch:V4SI 4))
4990 (clobber (match_operand:DI 2 "memory_operand"))]
4991 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4992 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4993 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4994 && reload_completed"
4995 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4997 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4998 [(set (match_operand:MODEF 0 "register_operand")
4999 (unsigned_float:MODEF
5000 (match_operand:SWI12 1 "nonimmediate_operand")))]
5002 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5004 operands[1] = convert_to_mode (SImode, operands[1], 1);
5005 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5009 ;; Avoid store forwarding (partial memory) stall penalty by extending
5010 ;; SImode value to DImode through XMM register instead of pushing two
5011 ;; SImode values to stack. Also note that fild loads from memory only.
5013 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5014 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5015 (unsigned_float:X87MODEF
5016 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5017 (clobber (match_scratch:DI 3 "=x"))
5018 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5020 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5021 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5023 "&& reload_completed"
5024 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5025 (set (match_dup 2) (match_dup 3))
5027 (float:X87MODEF (match_dup 2)))]
5029 [(set_attr "type" "multi")
5030 (set_attr "mode" "<MODE>")])
5032 (define_expand "floatunssi<mode>2"
5034 [(set (match_operand:X87MODEF 0 "register_operand")
5035 (unsigned_float:X87MODEF
5036 (match_operand:SI 1 "nonimmediate_operand")))
5037 (clobber (match_scratch:DI 3))
5038 (clobber (match_dup 2))])]
5040 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5041 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5042 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5044 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5046 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5050 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5053 (define_expand "floatunsdisf2"
5054 [(use (match_operand:SF 0 "register_operand"))
5055 (use (match_operand:DI 1 "nonimmediate_operand"))]
5056 "TARGET_64BIT && TARGET_SSE_MATH"
5057 "x86_emit_floatuns (operands); DONE;")
5059 (define_expand "floatunsdidf2"
5060 [(use (match_operand:DF 0 "register_operand"))
5061 (use (match_operand:DI 1 "nonimmediate_operand"))]
5062 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5063 && TARGET_SSE2 && TARGET_SSE_MATH"
5066 x86_emit_floatuns (operands);
5068 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5072 ;; Load effective address instructions
5074 (define_insn_and_split "*lea<mode>"
5075 [(set (match_operand:SWI48 0 "register_operand" "=r")
5076 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5079 if (SImode_address_operand (operands[1], VOIDmode))
5081 gcc_assert (TARGET_64BIT);
5082 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5085 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5087 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5090 machine_mode mode = <MODE>mode;
5093 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5094 change operands[] array behind our back. */
5095 pat = PATTERN (curr_insn);
5097 operands[0] = SET_DEST (pat);
5098 operands[1] = SET_SRC (pat);
5100 /* Emit all operations in SImode for zero-extended addresses. */
5101 if (SImode_address_operand (operands[1], VOIDmode))
5104 ix86_split_lea_for_addr (curr_insn, operands, mode);
5106 /* Zero-extend return register to DImode for zero-extended addresses. */
5107 if (mode != <MODE>mode)
5108 emit_insn (gen_zero_extendsidi2
5109 (operands[0], gen_lowpart (mode, operands[0])));
5113 [(set_attr "type" "lea")
5116 (match_operand 1 "SImode_address_operand")
5118 (const_string "<MODE>")))])
5122 (define_expand "add<mode>3"
5123 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5124 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5125 (match_operand:SDWIM 2 "<general_operand>")))]
5127 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5129 (define_insn_and_split "*add<dwi>3_doubleword"
5130 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5132 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5133 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5134 (clobber (reg:CC FLAGS_REG))]
5135 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5138 [(parallel [(set (reg:CC FLAGS_REG)
5139 (unspec:CC [(match_dup 1) (match_dup 2)]
5142 (plus:DWIH (match_dup 1) (match_dup 2)))])
5143 (parallel [(set (match_dup 3)
5147 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5149 (clobber (reg:CC FLAGS_REG))])]
5150 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5152 (define_insn "*add<mode>3_cc"
5153 [(set (reg:CC FLAGS_REG)
5155 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5156 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5158 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5159 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5160 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5161 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5162 [(set_attr "type" "alu")
5163 (set_attr "mode" "<MODE>")])
5165 (define_insn "addqi3_cc"
5166 [(set (reg:CC FLAGS_REG)
5168 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5169 (match_operand:QI 2 "general_operand" "qn,qm")]
5171 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5172 (plus:QI (match_dup 1) (match_dup 2)))]
5173 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5174 "add{b}\t{%2, %0|%0, %2}"
5175 [(set_attr "type" "alu")
5176 (set_attr "mode" "QI")])
5178 (define_insn "*add<mode>_1"
5179 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5181 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5182 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5183 (clobber (reg:CC FLAGS_REG))]
5184 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5186 switch (get_attr_type (insn))
5192 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5193 if (operands[2] == const1_rtx)
5194 return "inc{<imodesuffix>}\t%0";
5197 gcc_assert (operands[2] == constm1_rtx);
5198 return "dec{<imodesuffix>}\t%0";
5202 /* For most processors, ADD is faster than LEA. This alternative
5203 was added to use ADD as much as possible. */
5204 if (which_alternative == 2)
5207 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5210 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5211 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5212 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5214 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5218 (cond [(eq_attr "alternative" "3")
5219 (const_string "lea")
5220 (match_operand:SWI48 2 "incdec_operand")
5221 (const_string "incdec")
5223 (const_string "alu")))
5224 (set (attr "length_immediate")
5226 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5228 (const_string "*")))
5229 (set_attr "mode" "<MODE>")])
5231 ;; It may seem that nonimmediate operand is proper one for operand 1.
5232 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5233 ;; we take care in ix86_binary_operator_ok to not allow two memory
5234 ;; operands so proper swapping will be done in reload. This allow
5235 ;; patterns constructed from addsi_1 to match.
5237 (define_insn "addsi_1_zext"
5238 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5240 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5241 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5242 (clobber (reg:CC FLAGS_REG))]
5243 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5245 switch (get_attr_type (insn))
5251 if (operands[2] == const1_rtx)
5252 return "inc{l}\t%k0";
5255 gcc_assert (operands[2] == constm1_rtx);
5256 return "dec{l}\t%k0";
5260 /* For most processors, ADD is faster than LEA. This alternative
5261 was added to use ADD as much as possible. */
5262 if (which_alternative == 1)
5265 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5268 if (x86_maybe_negate_const_int (&operands[2], SImode))
5269 return "sub{l}\t{%2, %k0|%k0, %2}";
5271 return "add{l}\t{%2, %k0|%k0, %2}";
5275 (cond [(eq_attr "alternative" "2")
5276 (const_string "lea")
5277 (match_operand:SI 2 "incdec_operand")
5278 (const_string "incdec")
5280 (const_string "alu")))
5281 (set (attr "length_immediate")
5283 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5285 (const_string "*")))
5286 (set_attr "mode" "SI")])
5288 (define_insn "*addhi_1"
5289 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5290 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5291 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5292 (clobber (reg:CC FLAGS_REG))]
5293 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5295 switch (get_attr_type (insn))
5301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302 if (operands[2] == const1_rtx)
5303 return "inc{w}\t%0";
5306 gcc_assert (operands[2] == constm1_rtx);
5307 return "dec{w}\t%0";
5311 /* For most processors, ADD is faster than LEA. This alternative
5312 was added to use ADD as much as possible. */
5313 if (which_alternative == 2)
5316 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5320 if (x86_maybe_negate_const_int (&operands[2], HImode))
5321 return "sub{w}\t{%2, %0|%0, %2}";
5323 return "add{w}\t{%2, %0|%0, %2}";
5327 (cond [(eq_attr "alternative" "3")
5328 (const_string "lea")
5329 (match_operand:HI 2 "incdec_operand")
5330 (const_string "incdec")
5332 (const_string "alu")))
5333 (set (attr "length_immediate")
5335 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5337 (const_string "*")))
5338 (set_attr "mode" "HI,HI,HI,SI")])
5340 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5341 (define_insn "*addqi_1"
5342 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5343 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5344 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5345 (clobber (reg:CC FLAGS_REG))]
5346 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5348 bool widen = (which_alternative == 3 || which_alternative == 4);
5350 switch (get_attr_type (insn))
5356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357 if (operands[2] == const1_rtx)
5358 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5361 gcc_assert (operands[2] == constm1_rtx);
5362 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5366 /* For most processors, ADD is faster than LEA. These alternatives
5367 were added to use ADD as much as possible. */
5368 if (which_alternative == 2 || which_alternative == 4)
5371 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5375 if (x86_maybe_negate_const_int (&operands[2], QImode))
5378 return "sub{l}\t{%2, %k0|%k0, %2}";
5380 return "sub{b}\t{%2, %0|%0, %2}";
5383 return "add{l}\t{%k2, %k0|%k0, %k2}";
5385 return "add{b}\t{%2, %0|%0, %2}";
5389 (cond [(eq_attr "alternative" "5")
5390 (const_string "lea")
5391 (match_operand:QI 2 "incdec_operand")
5392 (const_string "incdec")
5394 (const_string "alu")))
5395 (set (attr "length_immediate")
5397 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5399 (const_string "*")))
5400 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5402 (define_insn "*addqi_1_slp"
5403 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5404 (plus:QI (match_dup 0)
5405 (match_operand:QI 1 "general_operand" "qn,qm")))
5406 (clobber (reg:CC FLAGS_REG))]
5407 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5408 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5410 switch (get_attr_type (insn))
5413 if (operands[1] == const1_rtx)
5414 return "inc{b}\t%0";
5417 gcc_assert (operands[1] == constm1_rtx);
5418 return "dec{b}\t%0";
5422 if (x86_maybe_negate_const_int (&operands[1], QImode))
5423 return "sub{b}\t{%1, %0|%0, %1}";
5425 return "add{b}\t{%1, %0|%0, %1}";
5429 (if_then_else (match_operand:QI 1 "incdec_operand")
5430 (const_string "incdec")
5431 (const_string "alu1")))
5432 (set (attr "memory")
5433 (if_then_else (match_operand 1 "memory_operand")
5434 (const_string "load")
5435 (const_string "none")))
5436 (set_attr "mode" "QI")])
5438 ;; Split non destructive adds if we cannot use lea.
5440 [(set (match_operand:SWI48 0 "register_operand")
5441 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5442 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5443 (clobber (reg:CC FLAGS_REG))]
5444 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5445 [(set (match_dup 0) (match_dup 1))
5446 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5447 (clobber (reg:CC FLAGS_REG))])])
5449 ;; Convert add to the lea pattern to avoid flags dependency.
5451 [(set (match_operand:SWI 0 "register_operand")
5452 (plus:SWI (match_operand:SWI 1 "register_operand")
5453 (match_operand:SWI 2 "<nonmemory_operand>")))
5454 (clobber (reg:CC FLAGS_REG))]
5455 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5458 machine_mode mode = <MODE>mode;
5461 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5464 operands[0] = gen_lowpart (mode, operands[0]);
5465 operands[1] = gen_lowpart (mode, operands[1]);
5466 operands[2] = gen_lowpart (mode, operands[2]);
5469 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5471 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5475 ;; Split non destructive adds if we cannot use lea.
5477 [(set (match_operand:DI 0 "register_operand")
5479 (plus:SI (match_operand:SI 1 "register_operand")
5480 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5481 (clobber (reg:CC FLAGS_REG))]
5483 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5484 [(set (match_dup 3) (match_dup 1))
5485 (parallel [(set (match_dup 0)
5486 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5487 (clobber (reg:CC FLAGS_REG))])]
5488 "operands[3] = gen_lowpart (SImode, operands[0]);")
5490 ;; Convert add to the lea pattern to avoid flags dependency.
5492 [(set (match_operand:DI 0 "register_operand")
5494 (plus:SI (match_operand:SI 1 "register_operand")
5495 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5496 (clobber (reg:CC FLAGS_REG))]
5497 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5499 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5501 (define_insn "*add<mode>_2"
5502 [(set (reg FLAGS_REG)
5505 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5506 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5508 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5509 (plus:SWI (match_dup 1) (match_dup 2)))]
5510 "ix86_match_ccmode (insn, CCGOCmode)
5511 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5513 switch (get_attr_type (insn))
5516 if (operands[2] == const1_rtx)
5517 return "inc{<imodesuffix>}\t%0";
5520 gcc_assert (operands[2] == constm1_rtx);
5521 return "dec{<imodesuffix>}\t%0";
5525 if (which_alternative == 2)
5528 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5531 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5532 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5533 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5535 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5539 (if_then_else (match_operand:SWI 2 "incdec_operand")
5540 (const_string "incdec")
5541 (const_string "alu")))
5542 (set (attr "length_immediate")
5544 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5546 (const_string "*")))
5547 (set_attr "mode" "<MODE>")])
5549 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5550 (define_insn "*addsi_2_zext"
5551 [(set (reg FLAGS_REG)
5553 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5554 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5556 (set (match_operand:DI 0 "register_operand" "=r,r")
5557 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5558 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5559 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5561 switch (get_attr_type (insn))
5564 if (operands[2] == const1_rtx)
5565 return "inc{l}\t%k0";
5568 gcc_assert (operands[2] == constm1_rtx);
5569 return "dec{l}\t%k0";
5573 if (which_alternative == 1)
5576 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5579 if (x86_maybe_negate_const_int (&operands[2], SImode))
5580 return "sub{l}\t{%2, %k0|%k0, %2}";
5582 return "add{l}\t{%2, %k0|%k0, %2}";
5586 (if_then_else (match_operand:SI 2 "incdec_operand")
5587 (const_string "incdec")
5588 (const_string "alu")))
5589 (set (attr "length_immediate")
5591 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5593 (const_string "*")))
5594 (set_attr "mode" "SI")])
5596 (define_insn "*add<mode>_3"
5597 [(set (reg FLAGS_REG)
5599 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5600 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5601 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5602 "ix86_match_ccmode (insn, CCZmode)
5603 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5605 switch (get_attr_type (insn))
5608 if (operands[2] == const1_rtx)
5609 return "inc{<imodesuffix>}\t%0";
5612 gcc_assert (operands[2] == constm1_rtx);
5613 return "dec{<imodesuffix>}\t%0";
5617 if (which_alternative == 1)
5620 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5624 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5625 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5627 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5631 (if_then_else (match_operand:SWI 2 "incdec_operand")
5632 (const_string "incdec")
5633 (const_string "alu")))
5634 (set (attr "length_immediate")
5636 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5638 (const_string "*")))
5639 (set_attr "mode" "<MODE>")])
5641 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5642 (define_insn "*addsi_3_zext"
5643 [(set (reg FLAGS_REG)
5645 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5646 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5647 (set (match_operand:DI 0 "register_operand" "=r,r")
5648 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5649 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5650 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5652 switch (get_attr_type (insn))
5655 if (operands[2] == const1_rtx)
5656 return "inc{l}\t%k0";
5659 gcc_assert (operands[2] == constm1_rtx);
5660 return "dec{l}\t%k0";
5664 if (which_alternative == 1)
5667 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5670 if (x86_maybe_negate_const_int (&operands[2], SImode))
5671 return "sub{l}\t{%2, %k0|%k0, %2}";
5673 return "add{l}\t{%2, %k0|%k0, %2}";
5677 (if_then_else (match_operand:SI 2 "incdec_operand")
5678 (const_string "incdec")
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5684 (const_string "*")))
5685 (set_attr "mode" "SI")])
5687 ; For comparisons against 1, -1 and 128, we may generate better code
5688 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5689 ; is matched then. We can't accept general immediate, because for
5690 ; case of overflows, the result is messed up.
5691 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5692 ; only for comparisons not depending on it.
5694 (define_insn "*adddi_4"
5695 [(set (reg FLAGS_REG)
5697 (match_operand:DI 1 "nonimmediate_operand" "0")
5698 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5699 (clobber (match_scratch:DI 0 "=rm"))]
5701 && ix86_match_ccmode (insn, CCGCmode)"
5703 switch (get_attr_type (insn))
5706 if (operands[2] == constm1_rtx)
5707 return "inc{q}\t%0";
5710 gcc_assert (operands[2] == const1_rtx);
5711 return "dec{q}\t%0";
5715 if (x86_maybe_negate_const_int (&operands[2], DImode))
5716 return "add{q}\t{%2, %0|%0, %2}";
5718 return "sub{q}\t{%2, %0|%0, %2}";
5722 (if_then_else (match_operand:DI 2 "incdec_operand")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set (attr "length_immediate")
5727 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5729 (const_string "*")))
5730 (set_attr "mode" "DI")])
5732 ; For comparisons against 1, -1 and 128, we may generate better code
5733 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5734 ; is matched then. We can't accept general immediate, because for
5735 ; case of overflows, the result is messed up.
5736 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5737 ; only for comparisons not depending on it.
5739 (define_insn "*add<mode>_4"
5740 [(set (reg FLAGS_REG)
5742 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5743 (match_operand:SWI124 2 "const_int_operand" "n")))
5744 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5745 "ix86_match_ccmode (insn, CCGCmode)"
5747 switch (get_attr_type (insn))
5750 if (operands[2] == constm1_rtx)
5751 return "inc{<imodesuffix>}\t%0";
5754 gcc_assert (operands[2] == const1_rtx);
5755 return "dec{<imodesuffix>}\t%0";
5759 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5760 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5762 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5766 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5767 (const_string "incdec")
5768 (const_string "alu")))
5769 (set (attr "length_immediate")
5771 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5773 (const_string "*")))
5774 (set_attr "mode" "<MODE>")])
5776 (define_insn "*add<mode>_5"
5777 [(set (reg FLAGS_REG)
5780 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5781 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5783 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5784 "ix86_match_ccmode (insn, CCGOCmode)
5785 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5787 switch (get_attr_type (insn))
5790 if (operands[2] == const1_rtx)
5791 return "inc{<imodesuffix>}\t%0";
5794 gcc_assert (operands[2] == constm1_rtx);
5795 return "dec{<imodesuffix>}\t%0";
5799 if (which_alternative == 1)
5802 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5807 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5809 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5813 (if_then_else (match_operand:SWI 2 "incdec_operand")
5814 (const_string "incdec")
5815 (const_string "alu")))
5816 (set (attr "length_immediate")
5818 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5820 (const_string "*")))
5821 (set_attr "mode" "<MODE>")])
5823 (define_insn "addqi_ext_1"
5824 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5829 (match_operand 1 "ext_register_operand" "0,0")
5832 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5833 (clobber (reg:CC FLAGS_REG))]
5836 switch (get_attr_type (insn))
5839 if (operands[2] == const1_rtx)
5840 return "inc{b}\t%h0";
5843 gcc_assert (operands[2] == constm1_rtx);
5844 return "dec{b}\t%h0";
5848 return "add{b}\t{%2, %h0|%h0, %2}";
5851 [(set_attr "isa" "*,nox64")
5853 (if_then_else (match_operand:QI 2 "incdec_operand")
5854 (const_string "incdec")
5855 (const_string "alu")))
5856 (set_attr "modrm" "1")
5857 (set_attr "mode" "QI")])
5859 (define_insn "*addqi_ext_2"
5860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5865 (match_operand 1 "ext_register_operand" "%0")
5869 (match_operand 2 "ext_register_operand" "Q")
5872 (clobber (reg:CC FLAGS_REG))]
5874 "add{b}\t{%h2, %h0|%h0, %h2}"
5875 [(set_attr "type" "alu")
5876 (set_attr "mode" "QI")])
5878 ;; Add with jump on overflow.
5879 (define_expand "addv<mode>4"
5880 [(parallel [(set (reg:CCO FLAGS_REG)
5883 (match_operand:SWI 1 "nonimmediate_operand"))
5886 (plus:SWI (match_dup 1)
5887 (match_operand:SWI 2
5888 "<general_operand>")))))
5889 (set (match_operand:SWI 0 "register_operand")
5890 (plus:SWI (match_dup 1) (match_dup 2)))])
5891 (set (pc) (if_then_else
5892 (eq (reg:CCO FLAGS_REG) (const_int 0))
5893 (label_ref (match_operand 3))
5897 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5898 if (CONST_INT_P (operands[2]))
5899 operands[4] = operands[2];
5901 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5904 (define_insn "*addv<mode>4"
5905 [(set (reg:CCO FLAGS_REG)
5908 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5910 (match_operand:SWI 2 "<general_sext_operand>"
5913 (plus:SWI (match_dup 1) (match_dup 2)))))
5914 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5915 (plus:SWI (match_dup 1) (match_dup 2)))]
5916 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5917 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5918 [(set_attr "type" "alu")
5919 (set_attr "mode" "<MODE>")])
5921 (define_insn "*addv<mode>4_1"
5922 [(set (reg:CCO FLAGS_REG)
5925 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5926 (match_operand:<DWI> 3 "const_int_operand" "i"))
5928 (plus:SWI (match_dup 1)
5929 (match_operand:SWI 2 "x86_64_immediate_operand"
5931 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5932 (plus:SWI (match_dup 1) (match_dup 2)))]
5933 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5934 && CONST_INT_P (operands[2])
5935 && INTVAL (operands[2]) == INTVAL (operands[3])"
5936 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5937 [(set_attr "type" "alu")
5938 (set_attr "mode" "<MODE>")
5939 (set (attr "length_immediate")
5940 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5942 (match_test "<MODE_SIZE> == 8")
5944 (const_string "<MODE_SIZE>")))])
5946 ;; The lea patterns for modes less than 32 bits need to be matched by
5947 ;; several insns converted to real lea by splitters.
5949 (define_insn_and_split "*lea_general_1"
5950 [(set (match_operand 0 "register_operand" "=r")
5951 (plus (plus (match_operand 1 "index_register_operand" "l")
5952 (match_operand 2 "register_operand" "r"))
5953 (match_operand 3 "immediate_operand" "i")))]
5954 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5955 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5956 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5957 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5958 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5959 || GET_MODE (operands[3]) == VOIDmode)"
5961 "&& reload_completed"
5964 machine_mode mode = SImode;
5967 operands[0] = gen_lowpart (mode, operands[0]);
5968 operands[1] = gen_lowpart (mode, operands[1]);
5969 operands[2] = gen_lowpart (mode, operands[2]);
5970 operands[3] = gen_lowpart (mode, operands[3]);
5972 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5975 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5978 [(set_attr "type" "lea")
5979 (set_attr "mode" "SI")])
5981 (define_insn_and_split "*lea_general_2"
5982 [(set (match_operand 0 "register_operand" "=r")
5983 (plus (mult (match_operand 1 "index_register_operand" "l")
5984 (match_operand 2 "const248_operand" "n"))
5985 (match_operand 3 "nonmemory_operand" "ri")))]
5986 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5987 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5988 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5989 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5990 || GET_MODE (operands[3]) == VOIDmode)"
5992 "&& reload_completed"
5995 machine_mode mode = SImode;
5998 operands[0] = gen_lowpart (mode, operands[0]);
5999 operands[1] = gen_lowpart (mode, operands[1]);
6000 operands[3] = gen_lowpart (mode, operands[3]);
6002 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6008 [(set_attr "type" "lea")
6009 (set_attr "mode" "SI")])
6011 (define_insn_and_split "*lea_general_3"
6012 [(set (match_operand 0 "register_operand" "=r")
6013 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6014 (match_operand 2 "const248_operand" "n"))
6015 (match_operand 3 "register_operand" "r"))
6016 (match_operand 4 "immediate_operand" "i")))]
6017 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6018 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6022 "&& reload_completed"
6025 machine_mode mode = SImode;
6028 operands[0] = gen_lowpart (mode, operands[0]);
6029 operands[1] = gen_lowpart (mode, operands[1]);
6030 operands[3] = gen_lowpart (mode, operands[3]);
6031 operands[4] = gen_lowpart (mode, operands[4]);
6033 pat = gen_rtx_PLUS (mode,
6035 gen_rtx_MULT (mode, operands[1],
6040 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6043 [(set_attr "type" "lea")
6044 (set_attr "mode" "SI")])
6046 (define_insn_and_split "*lea_general_4"
6047 [(set (match_operand 0 "register_operand" "=r")
6049 (match_operand 1 "index_register_operand" "l")
6050 (match_operand 2 "const_int_operand" "n"))
6051 (match_operand 3 "const_int_operand" "n")))]
6052 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6053 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6054 || GET_MODE (operands[0]) == SImode
6055 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6056 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6057 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6058 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6059 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6061 "&& reload_completed"
6064 machine_mode mode = GET_MODE (operands[0]);
6067 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6070 operands[0] = gen_lowpart (mode, operands[0]);
6071 operands[1] = gen_lowpart (mode, operands[1]);
6074 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6076 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6077 INTVAL (operands[3]));
6079 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6082 [(set_attr "type" "lea")
6084 (if_then_else (match_operand:DI 0)
6086 (const_string "SI")))])
6088 ;; Subtract instructions
6090 (define_expand "sub<mode>3"
6091 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6092 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6093 (match_operand:SDWIM 2 "<general_operand>")))]
6095 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6097 (define_insn_and_split "*sub<dwi>3_doubleword"
6098 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6100 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6101 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6102 (clobber (reg:CC FLAGS_REG))]
6103 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6106 [(parallel [(set (reg:CC FLAGS_REG)
6107 (compare:CC (match_dup 1) (match_dup 2)))
6109 (minus:DWIH (match_dup 1) (match_dup 2)))])
6110 (parallel [(set (match_dup 3)
6114 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6116 (clobber (reg:CC FLAGS_REG))])]
6117 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6119 (define_insn "*sub<mode>_1"
6120 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6122 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6123 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6124 (clobber (reg:CC FLAGS_REG))]
6125 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6126 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6127 [(set_attr "type" "alu")
6128 (set_attr "mode" "<MODE>")])
6130 (define_insn "*subsi_1_zext"
6131 [(set (match_operand:DI 0 "register_operand" "=r")
6133 (minus:SI (match_operand:SI 1 "register_operand" "0")
6134 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6135 (clobber (reg:CC FLAGS_REG))]
6136 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6137 "sub{l}\t{%2, %k0|%k0, %2}"
6138 [(set_attr "type" "alu")
6139 (set_attr "mode" "SI")])
6141 (define_insn "*subqi_1_slp"
6142 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6143 (minus:QI (match_dup 0)
6144 (match_operand:QI 1 "general_operand" "qn,qm")))
6145 (clobber (reg:CC FLAGS_REG))]
6146 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6147 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6148 "sub{b}\t{%1, %0|%0, %1}"
6149 [(set_attr "type" "alu1")
6150 (set_attr "mode" "QI")])
6152 (define_insn "*sub<mode>_2"
6153 [(set (reg FLAGS_REG)
6156 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6157 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6160 (minus:SWI (match_dup 1) (match_dup 2)))]
6161 "ix86_match_ccmode (insn, CCGOCmode)
6162 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6163 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6164 [(set_attr "type" "alu")
6165 (set_attr "mode" "<MODE>")])
6167 (define_insn "*subsi_2_zext"
6168 [(set (reg FLAGS_REG)
6170 (minus:SI (match_operand:SI 1 "register_operand" "0")
6171 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6173 (set (match_operand:DI 0 "register_operand" "=r")
6175 (minus:SI (match_dup 1)
6177 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6178 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6179 "sub{l}\t{%2, %k0|%k0, %2}"
6180 [(set_attr "type" "alu")
6181 (set_attr "mode" "SI")])
6183 ;; Subtract with jump on overflow.
6184 (define_expand "subv<mode>4"
6185 [(parallel [(set (reg:CCO FLAGS_REG)
6186 (eq:CCO (minus:<DWI>
6188 (match_operand:SWI 1 "nonimmediate_operand"))
6191 (minus:SWI (match_dup 1)
6192 (match_operand:SWI 2
6193 "<general_operand>")))))
6194 (set (match_operand:SWI 0 "register_operand")
6195 (minus:SWI (match_dup 1) (match_dup 2)))])
6196 (set (pc) (if_then_else
6197 (eq (reg:CCO FLAGS_REG) (const_int 0))
6198 (label_ref (match_operand 3))
6202 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6203 if (CONST_INT_P (operands[2]))
6204 operands[4] = operands[2];
6206 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6209 (define_insn "*subv<mode>4"
6210 [(set (reg:CCO FLAGS_REG)
6211 (eq:CCO (minus:<DWI>
6213 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6215 (match_operand:SWI 2 "<general_sext_operand>"
6218 (minus:SWI (match_dup 1) (match_dup 2)))))
6219 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6220 (minus:SWI (match_dup 1) (match_dup 2)))]
6221 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6222 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6223 [(set_attr "type" "alu")
6224 (set_attr "mode" "<MODE>")])
6226 (define_insn "*subv<mode>4_1"
6227 [(set (reg:CCO FLAGS_REG)
6228 (eq:CCO (minus:<DWI>
6230 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6231 (match_operand:<DWI> 3 "const_int_operand" "i"))
6233 (minus:SWI (match_dup 1)
6234 (match_operand:SWI 2 "x86_64_immediate_operand"
6236 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6237 (minus:SWI (match_dup 1) (match_dup 2)))]
6238 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6239 && CONST_INT_P (operands[2])
6240 && INTVAL (operands[2]) == INTVAL (operands[3])"
6241 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6242 [(set_attr "type" "alu")
6243 (set_attr "mode" "<MODE>")
6244 (set (attr "length_immediate")
6245 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6247 (match_test "<MODE_SIZE> == 8")
6249 (const_string "<MODE_SIZE>")))])
6251 (define_insn "*sub<mode>_3"
6252 [(set (reg FLAGS_REG)
6253 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6254 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6255 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6256 (minus:SWI (match_dup 1) (match_dup 2)))]
6257 "ix86_match_ccmode (insn, CCmode)
6258 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6259 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6260 [(set_attr "type" "alu")
6261 (set_attr "mode" "<MODE>")])
6263 (define_insn "*subsi_3_zext"
6264 [(set (reg FLAGS_REG)
6265 (compare (match_operand:SI 1 "register_operand" "0")
6266 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6267 (set (match_operand:DI 0 "register_operand" "=r")
6269 (minus:SI (match_dup 1)
6271 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6272 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6273 "sub{l}\t{%2, %1|%1, %2}"
6274 [(set_attr "type" "alu")
6275 (set_attr "mode" "SI")])
6277 ;; Add with carry and subtract with borrow
6279 (define_expand "<plusminus_insn><mode>3_carry"
6281 [(set (match_operand:SWI 0 "nonimmediate_operand")
6283 (match_operand:SWI 1 "nonimmediate_operand")
6284 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6285 [(match_operand 3 "flags_reg_operand")
6287 (match_operand:SWI 2 "<general_operand>"))))
6288 (clobber (reg:CC FLAGS_REG))])]
6289 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6291 (define_insn "*<plusminus_insn><mode>3_carry"
6292 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6294 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6296 (match_operator 3 "ix86_carry_flag_operator"
6297 [(reg FLAGS_REG) (const_int 0)])
6298 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6299 (clobber (reg:CC FLAGS_REG))]
6300 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6301 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6302 [(set_attr "type" "alu")
6303 (set_attr "use_carry" "1")
6304 (set_attr "pent_pair" "pu")
6305 (set_attr "mode" "<MODE>")])
6307 (define_insn "*addsi3_carry_zext"
6308 [(set (match_operand:DI 0 "register_operand" "=r")
6310 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6311 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6312 [(reg FLAGS_REG) (const_int 0)])
6313 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6314 (clobber (reg:CC FLAGS_REG))]
6315 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6316 "adc{l}\t{%2, %k0|%k0, %2}"
6317 [(set_attr "type" "alu")
6318 (set_attr "use_carry" "1")
6319 (set_attr "pent_pair" "pu")
6320 (set_attr "mode" "SI")])
6322 (define_insn "*subsi3_carry_zext"
6323 [(set (match_operand:DI 0 "register_operand" "=r")
6325 (minus:SI (match_operand:SI 1 "register_operand" "0")
6326 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6327 [(reg FLAGS_REG) (const_int 0)])
6328 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6329 (clobber (reg:CC FLAGS_REG))]
6330 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6331 "sbb{l}\t{%2, %k0|%k0, %2}"
6332 [(set_attr "type" "alu")
6333 (set_attr "pent_pair" "pu")
6334 (set_attr "mode" "SI")])
6338 (define_insn "adcx<mode>3"
6339 [(set (reg:CCC FLAGS_REG)
6342 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6344 (match_operator 4 "ix86_carry_flag_operator"
6345 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6346 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6348 (set (match_operand:SWI48 0 "register_operand" "=r")
6349 (plus:SWI48 (match_dup 1)
6350 (plus:SWI48 (match_op_dup 4
6351 [(match_dup 3) (const_int 0)])
6353 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6354 "adcx\t{%2, %0|%0, %2}"
6355 [(set_attr "type" "alu")
6356 (set_attr "use_carry" "1")
6357 (set_attr "mode" "<MODE>")])
6359 ;; Overflow setting add instructions
6361 (define_insn "*add<mode>3_cconly_overflow"
6362 [(set (reg:CCC FLAGS_REG)
6365 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6366 (match_operand:SWI 2 "<general_operand>" "<g>"))
6368 (clobber (match_scratch:SWI 0 "=<r>"))]
6369 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6370 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6371 [(set_attr "type" "alu")
6372 (set_attr "mode" "<MODE>")])
6374 (define_insn "*add<mode>3_cc_overflow"
6375 [(set (reg:CCC FLAGS_REG)
6378 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6379 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6381 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6382 (plus:SWI (match_dup 1) (match_dup 2)))]
6383 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6384 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6385 [(set_attr "type" "alu")
6386 (set_attr "mode" "<MODE>")])
6388 (define_insn "*addsi3_zext_cc_overflow"
6389 [(set (reg:CCC FLAGS_REG)
6392 (match_operand:SI 1 "nonimmediate_operand" "%0")
6393 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6395 (set (match_operand:DI 0 "register_operand" "=r")
6396 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6397 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6398 "add{l}\t{%2, %k0|%k0, %2}"
6399 [(set_attr "type" "alu")
6400 (set_attr "mode" "SI")])
6402 ;; The patterns that match these are at the end of this file.
6404 (define_expand "<plusminus_insn>xf3"
6405 [(set (match_operand:XF 0 "register_operand")
6407 (match_operand:XF 1 "register_operand")
6408 (match_operand:XF 2 "register_operand")))]
6411 (define_expand "<plusminus_insn><mode>3"
6412 [(set (match_operand:MODEF 0 "register_operand")
6414 (match_operand:MODEF 1 "register_operand")
6415 (match_operand:MODEF 2 "nonimmediate_operand")))]
6416 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6417 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6419 ;; Multiply instructions
6421 (define_expand "mul<mode>3"
6422 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6424 (match_operand:SWIM248 1 "register_operand")
6425 (match_operand:SWIM248 2 "<general_operand>")))
6426 (clobber (reg:CC FLAGS_REG))])])
6428 (define_expand "mulqi3"
6429 [(parallel [(set (match_operand:QI 0 "register_operand")
6431 (match_operand:QI 1 "register_operand")
6432 (match_operand:QI 2 "nonimmediate_operand")))
6433 (clobber (reg:CC FLAGS_REG))])]
6434 "TARGET_QIMODE_MATH")
6437 ;; IMUL reg32/64, reg32/64, imm8 Direct
6438 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6439 ;; IMUL reg32/64, reg32/64, imm32 Direct
6440 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6441 ;; IMUL reg32/64, reg32/64 Direct
6442 ;; IMUL reg32/64, mem32/64 Direct
6444 ;; On BDVER1, all above IMULs use DirectPath
6446 (define_insn "*mul<mode>3_1"
6447 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6449 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6450 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6454 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6455 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6456 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6457 [(set_attr "type" "imul")
6458 (set_attr "prefix_0f" "0,0,1")
6459 (set (attr "athlon_decode")
6460 (cond [(eq_attr "cpu" "athlon")
6461 (const_string "vector")
6462 (eq_attr "alternative" "1")
6463 (const_string "vector")
6464 (and (eq_attr "alternative" "2")
6465 (match_operand 1 "memory_operand"))
6466 (const_string "vector")]
6467 (const_string "direct")))
6468 (set (attr "amdfam10_decode")
6469 (cond [(and (eq_attr "alternative" "0,1")
6470 (match_operand 1 "memory_operand"))
6471 (const_string "vector")]
6472 (const_string "direct")))
6473 (set_attr "bdver1_decode" "direct")
6474 (set_attr "mode" "<MODE>")])
6476 (define_insn "*mulsi3_1_zext"
6477 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6479 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6480 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6481 (clobber (reg:CC FLAGS_REG))]
6483 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6485 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6486 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6487 imul{l}\t{%2, %k0|%k0, %2}"
6488 [(set_attr "type" "imul")
6489 (set_attr "prefix_0f" "0,0,1")
6490 (set (attr "athlon_decode")
6491 (cond [(eq_attr "cpu" "athlon")
6492 (const_string "vector")
6493 (eq_attr "alternative" "1")
6494 (const_string "vector")
6495 (and (eq_attr "alternative" "2")
6496 (match_operand 1 "memory_operand"))
6497 (const_string "vector")]
6498 (const_string "direct")))
6499 (set (attr "amdfam10_decode")
6500 (cond [(and (eq_attr "alternative" "0,1")
6501 (match_operand 1 "memory_operand"))
6502 (const_string "vector")]
6503 (const_string "direct")))
6504 (set_attr "bdver1_decode" "direct")
6505 (set_attr "mode" "SI")])
6508 ;; IMUL reg16, reg16, imm8 VectorPath
6509 ;; IMUL reg16, mem16, imm8 VectorPath
6510 ;; IMUL reg16, reg16, imm16 VectorPath
6511 ;; IMUL reg16, mem16, imm16 VectorPath
6512 ;; IMUL reg16, reg16 Direct
6513 ;; IMUL reg16, mem16 Direct
6515 ;; On BDVER1, all HI MULs use DoublePath
6517 (define_insn "*mulhi3_1"
6518 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6519 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6520 (match_operand:HI 2 "general_operand" "K,n,mr")))
6521 (clobber (reg:CC FLAGS_REG))]
6523 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6525 imul{w}\t{%2, %1, %0|%0, %1, %2}
6526 imul{w}\t{%2, %1, %0|%0, %1, %2}
6527 imul{w}\t{%2, %0|%0, %2}"
6528 [(set_attr "type" "imul")
6529 (set_attr "prefix_0f" "0,0,1")
6530 (set (attr "athlon_decode")
6531 (cond [(eq_attr "cpu" "athlon")
6532 (const_string "vector")
6533 (eq_attr "alternative" "1,2")
6534 (const_string "vector")]
6535 (const_string "direct")))
6536 (set (attr "amdfam10_decode")
6537 (cond [(eq_attr "alternative" "0,1")
6538 (const_string "vector")]
6539 (const_string "direct")))
6540 (set_attr "bdver1_decode" "double")
6541 (set_attr "mode" "HI")])
6543 ;;On AMDFAM10 and BDVER1
6547 (define_insn "*mulqi3_1"
6548 [(set (match_operand:QI 0 "register_operand" "=a")
6549 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6550 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6551 (clobber (reg:CC FLAGS_REG))]
6553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6555 [(set_attr "type" "imul")
6556 (set_attr "length_immediate" "0")
6557 (set (attr "athlon_decode")
6558 (if_then_else (eq_attr "cpu" "athlon")
6559 (const_string "vector")
6560 (const_string "direct")))
6561 (set_attr "amdfam10_decode" "direct")
6562 (set_attr "bdver1_decode" "direct")
6563 (set_attr "mode" "QI")])
6565 ;; Multiply with jump on overflow.
6566 (define_expand "mulv<mode>4"
6567 [(parallel [(set (reg:CCO FLAGS_REG)
6570 (match_operand:SWI48 1 "register_operand"))
6573 (mult:SWI48 (match_dup 1)
6574 (match_operand:SWI48 2
6575 "<general_operand>")))))
6576 (set (match_operand:SWI48 0 "register_operand")
6577 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6578 (set (pc) (if_then_else
6579 (eq (reg:CCO FLAGS_REG) (const_int 0))
6580 (label_ref (match_operand 3))
6584 if (CONST_INT_P (operands[2]))
6585 operands[4] = operands[2];
6587 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6590 (define_insn "*mulv<mode>4"
6591 [(set (reg:CCO FLAGS_REG)
6594 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6596 (match_operand:SWI48 2 "<general_sext_operand>"
6599 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6600 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6601 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6602 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6604 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6605 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6606 [(set_attr "type" "imul")
6607 (set_attr "prefix_0f" "0,1")
6608 (set (attr "athlon_decode")
6609 (cond [(eq_attr "cpu" "athlon")
6610 (const_string "vector")
6611 (eq_attr "alternative" "0")
6612 (const_string "vector")
6613 (and (eq_attr "alternative" "1")
6614 (match_operand 1 "memory_operand"))
6615 (const_string "vector")]
6616 (const_string "direct")))
6617 (set (attr "amdfam10_decode")
6618 (cond [(and (eq_attr "alternative" "1")
6619 (match_operand 1 "memory_operand"))
6620 (const_string "vector")]
6621 (const_string "direct")))
6622 (set_attr "bdver1_decode" "direct")
6623 (set_attr "mode" "<MODE>")])
6625 (define_insn "*mulv<mode>4_1"
6626 [(set (reg:CCO FLAGS_REG)
6629 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6630 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6632 (mult:SWI48 (match_dup 1)
6633 (match_operand:SWI 2 "x86_64_immediate_operand"
6635 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6636 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6637 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6638 && CONST_INT_P (operands[2])
6639 && INTVAL (operands[2]) == INTVAL (operands[3])"
6641 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6642 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6643 [(set_attr "type" "imul")
6644 (set (attr "athlon_decode")
6645 (cond [(eq_attr "cpu" "athlon")
6646 (const_string "vector")
6647 (eq_attr "alternative" "1")
6648 (const_string "vector")]
6649 (const_string "direct")))
6650 (set (attr "amdfam10_decode")
6651 (cond [(match_operand 1 "memory_operand")
6652 (const_string "vector")]
6653 (const_string "direct")))
6654 (set_attr "bdver1_decode" "direct")
6655 (set_attr "mode" "<MODE>")
6656 (set (attr "length_immediate")
6657 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6659 (match_test "<MODE_SIZE> == 8")
6661 (const_string "<MODE_SIZE>")))])
6663 (define_expand "<u>mul<mode><dwi>3"
6664 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6667 (match_operand:DWIH 1 "nonimmediate_operand"))
6669 (match_operand:DWIH 2 "register_operand"))))
6670 (clobber (reg:CC FLAGS_REG))])])
6672 (define_expand "<u>mulqihi3"
6673 [(parallel [(set (match_operand:HI 0 "register_operand")
6676 (match_operand:QI 1 "nonimmediate_operand"))
6678 (match_operand:QI 2 "register_operand"))))
6679 (clobber (reg:CC FLAGS_REG))])]
6680 "TARGET_QIMODE_MATH")
6682 (define_insn "*bmi2_umulditi3_1"
6683 [(set (match_operand:DI 0 "register_operand" "=r")
6685 (match_operand:DI 2 "nonimmediate_operand" "%d")
6686 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6687 (set (match_operand:DI 1 "register_operand" "=r")
6690 (mult:TI (zero_extend:TI (match_dup 2))
6691 (zero_extend:TI (match_dup 3)))
6693 "TARGET_64BIT && TARGET_BMI2
6694 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6695 "mulx\t{%3, %0, %1|%1, %0, %3}"
6696 [(set_attr "type" "imulx")
6697 (set_attr "prefix" "vex")
6698 (set_attr "mode" "DI")])
6700 (define_insn "*bmi2_umulsidi3_1"
6701 [(set (match_operand:SI 0 "register_operand" "=r")
6703 (match_operand:SI 2 "nonimmediate_operand" "%d")
6704 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6705 (set (match_operand:SI 1 "register_operand" "=r")
6708 (mult:DI (zero_extend:DI (match_dup 2))
6709 (zero_extend:DI (match_dup 3)))
6711 "!TARGET_64BIT && TARGET_BMI2
6712 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713 "mulx\t{%3, %0, %1|%1, %0, %3}"
6714 [(set_attr "type" "imulx")
6715 (set_attr "prefix" "vex")
6716 (set_attr "mode" "SI")])
6718 (define_insn "*umul<mode><dwi>3_1"
6719 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6722 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6724 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6725 (clobber (reg:CC FLAGS_REG))]
6726 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6729 mul{<imodesuffix>}\t%2"
6730 [(set_attr "isa" "bmi2,*")
6731 (set_attr "type" "imulx,imul")
6732 (set_attr "length_immediate" "*,0")
6733 (set (attr "athlon_decode")
6734 (cond [(eq_attr "alternative" "1")
6735 (if_then_else (eq_attr "cpu" "athlon")
6736 (const_string "vector")
6737 (const_string "double"))]
6738 (const_string "*")))
6739 (set_attr "amdfam10_decode" "*,double")
6740 (set_attr "bdver1_decode" "*,direct")
6741 (set_attr "prefix" "vex,orig")
6742 (set_attr "mode" "<MODE>")])
6744 ;; Convert mul to the mulx pattern to avoid flags dependency.
6746 [(set (match_operand:<DWI> 0 "register_operand")
6749 (match_operand:DWIH 1 "register_operand"))
6751 (match_operand:DWIH 2 "nonimmediate_operand"))))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "TARGET_BMI2 && reload_completed
6754 && true_regnum (operands[1]) == DX_REG"
6755 [(parallel [(set (match_dup 3)
6756 (mult:DWIH (match_dup 1) (match_dup 2)))
6760 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6761 (zero_extend:<DWI> (match_dup 2)))
6764 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6766 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6769 (define_insn "*mul<mode><dwi>3_1"
6770 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6773 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6775 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6776 (clobber (reg:CC FLAGS_REG))]
6777 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6778 "imul{<imodesuffix>}\t%2"
6779 [(set_attr "type" "imul")
6780 (set_attr "length_immediate" "0")
6781 (set (attr "athlon_decode")
6782 (if_then_else (eq_attr "cpu" "athlon")
6783 (const_string "vector")
6784 (const_string "double")))
6785 (set_attr "amdfam10_decode" "double")
6786 (set_attr "bdver1_decode" "direct")
6787 (set_attr "mode" "<MODE>")])
6789 (define_insn "*<u>mulqihi3_1"
6790 [(set (match_operand:HI 0 "register_operand" "=a")
6793 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6795 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6796 (clobber (reg:CC FLAGS_REG))]
6798 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6799 "<sgnprefix>mul{b}\t%2"
6800 [(set_attr "type" "imul")
6801 (set_attr "length_immediate" "0")
6802 (set (attr "athlon_decode")
6803 (if_then_else (eq_attr "cpu" "athlon")
6804 (const_string "vector")
6805 (const_string "direct")))
6806 (set_attr "amdfam10_decode" "direct")
6807 (set_attr "bdver1_decode" "direct")
6808 (set_attr "mode" "QI")])
6810 (define_expand "<s>mul<mode>3_highpart"
6811 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6816 (match_operand:SWI48 1 "nonimmediate_operand"))
6818 (match_operand:SWI48 2 "register_operand")))
6820 (clobber (match_scratch:SWI48 3))
6821 (clobber (reg:CC FLAGS_REG))])]
6823 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6825 (define_insn "*<s>muldi3_highpart_1"
6826 [(set (match_operand:DI 0 "register_operand" "=d")
6831 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6833 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6835 (clobber (match_scratch:DI 3 "=1"))
6836 (clobber (reg:CC FLAGS_REG))]
6838 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839 "<sgnprefix>mul{q}\t%2"
6840 [(set_attr "type" "imul")
6841 (set_attr "length_immediate" "0")
6842 (set (attr "athlon_decode")
6843 (if_then_else (eq_attr "cpu" "athlon")
6844 (const_string "vector")
6845 (const_string "double")))
6846 (set_attr "amdfam10_decode" "double")
6847 (set_attr "bdver1_decode" "direct")
6848 (set_attr "mode" "DI")])
6850 (define_insn "*<s>mulsi3_highpart_1"
6851 [(set (match_operand:SI 0 "register_operand" "=d")
6856 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6858 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6860 (clobber (match_scratch:SI 3 "=1"))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6863 "<sgnprefix>mul{l}\t%2"
6864 [(set_attr "type" "imul")
6865 (set_attr "length_immediate" "0")
6866 (set (attr "athlon_decode")
6867 (if_then_else (eq_attr "cpu" "athlon")
6868 (const_string "vector")
6869 (const_string "double")))
6870 (set_attr "amdfam10_decode" "double")
6871 (set_attr "bdver1_decode" "direct")
6872 (set_attr "mode" "SI")])
6874 (define_insn "*<s>mulsi3_highpart_zext"
6875 [(set (match_operand:DI 0 "register_operand" "=d")
6876 (zero_extend:DI (truncate:SI
6878 (mult:DI (any_extend:DI
6879 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6881 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6883 (clobber (match_scratch:SI 3 "=1"))
6884 (clobber (reg:CC FLAGS_REG))]
6886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887 "<sgnprefix>mul{l}\t%2"
6888 [(set_attr "type" "imul")
6889 (set_attr "length_immediate" "0")
6890 (set (attr "athlon_decode")
6891 (if_then_else (eq_attr "cpu" "athlon")
6892 (const_string "vector")
6893 (const_string "double")))
6894 (set_attr "amdfam10_decode" "double")
6895 (set_attr "bdver1_decode" "direct")
6896 (set_attr "mode" "SI")])
6898 ;; The patterns that match these are at the end of this file.
6900 (define_expand "mulxf3"
6901 [(set (match_operand:XF 0 "register_operand")
6902 (mult:XF (match_operand:XF 1 "register_operand")
6903 (match_operand:XF 2 "register_operand")))]
6906 (define_expand "mul<mode>3"
6907 [(set (match_operand:MODEF 0 "register_operand")
6908 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6909 (match_operand:MODEF 2 "nonimmediate_operand")))]
6910 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6911 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6913 ;; Divide instructions
6915 ;; The patterns that match these are at the end of this file.
6917 (define_expand "divxf3"
6918 [(set (match_operand:XF 0 "register_operand")
6919 (div:XF (match_operand:XF 1 "register_operand")
6920 (match_operand:XF 2 "register_operand")))]
6923 (define_expand "divdf3"
6924 [(set (match_operand:DF 0 "register_operand")
6925 (div:DF (match_operand:DF 1 "register_operand")
6926 (match_operand:DF 2 "nonimmediate_operand")))]
6927 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6928 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6930 (define_expand "divsf3"
6931 [(set (match_operand:SF 0 "register_operand")
6932 (div:SF (match_operand:SF 1 "register_operand")
6933 (match_operand:SF 2 "nonimmediate_operand")))]
6934 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6939 && optimize_insn_for_speed_p ()
6940 && flag_finite_math_only && !flag_trapping_math
6941 && flag_unsafe_math_optimizations)
6943 ix86_emit_swdivsf (operands[0], operands[1],
6944 operands[2], SFmode);
6949 ;; Divmod instructions.
6951 (define_expand "divmod<mode>4"
6952 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6954 (match_operand:SWIM248 1 "register_operand")
6955 (match_operand:SWIM248 2 "nonimmediate_operand")))
6956 (set (match_operand:SWIM248 3 "register_operand")
6957 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6958 (clobber (reg:CC FLAGS_REG))])])
6960 ;; Split with 8bit unsigned divide:
6961 ;; if (dividend an divisor are in [0-255])
6962 ;; use 8bit unsigned integer divide
6964 ;; use original integer divide
6966 [(set (match_operand:SWI48 0 "register_operand")
6967 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6968 (match_operand:SWI48 3 "nonimmediate_operand")))
6969 (set (match_operand:SWI48 1 "register_operand")
6970 (mod:SWI48 (match_dup 2) (match_dup 3)))
6971 (clobber (reg:CC FLAGS_REG))]
6972 "TARGET_USE_8BIT_IDIV
6973 && TARGET_QIMODE_MATH
6974 && can_create_pseudo_p ()
6975 && !optimize_insn_for_size_p ()"
6977 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6979 (define_insn_and_split "divmod<mode>4_1"
6980 [(set (match_operand:SWI48 0 "register_operand" "=a")
6981 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6982 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6983 (set (match_operand:SWI48 1 "register_operand" "=&d")
6984 (mod:SWI48 (match_dup 2) (match_dup 3)))
6985 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6986 (clobber (reg:CC FLAGS_REG))]
6990 [(parallel [(set (match_dup 1)
6991 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6992 (clobber (reg:CC FLAGS_REG))])
6993 (parallel [(set (match_dup 0)
6994 (div:SWI48 (match_dup 2) (match_dup 3)))
6996 (mod:SWI48 (match_dup 2) (match_dup 3)))
6998 (clobber (reg:CC FLAGS_REG))])]
7000 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7002 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7003 operands[4] = operands[2];
7006 /* Avoid use of cltd in favor of a mov+shift. */
7007 emit_move_insn (operands[1], operands[2]);
7008 operands[4] = operands[1];
7011 [(set_attr "type" "multi")
7012 (set_attr "mode" "<MODE>")])
7014 (define_insn_and_split "*divmod<mode>4"
7015 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7016 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7017 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7018 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7019 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7020 (clobber (reg:CC FLAGS_REG))]
7024 [(parallel [(set (match_dup 1)
7025 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7026 (clobber (reg:CC FLAGS_REG))])
7027 (parallel [(set (match_dup 0)
7028 (div:SWIM248 (match_dup 2) (match_dup 3)))
7030 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7032 (clobber (reg:CC FLAGS_REG))])]
7034 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7036 if (<MODE>mode != HImode
7037 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7038 operands[4] = operands[2];
7041 /* Avoid use of cltd in favor of a mov+shift. */
7042 emit_move_insn (operands[1], operands[2]);
7043 operands[4] = operands[1];
7046 [(set_attr "type" "multi")
7047 (set_attr "mode" "<MODE>")])
7049 (define_insn "*divmod<mode>4_noext"
7050 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7051 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7052 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7053 (set (match_operand:SWIM248 1 "register_operand" "=d")
7054 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7055 (use (match_operand:SWIM248 4 "register_operand" "1"))
7056 (clobber (reg:CC FLAGS_REG))]
7058 "idiv{<imodesuffix>}\t%3"
7059 [(set_attr "type" "idiv")
7060 (set_attr "mode" "<MODE>")])
7062 (define_expand "divmodqi4"
7063 [(parallel [(set (match_operand:QI 0 "register_operand")
7065 (match_operand:QI 1 "register_operand")
7066 (match_operand:QI 2 "nonimmediate_operand")))
7067 (set (match_operand:QI 3 "register_operand")
7068 (mod:QI (match_dup 1) (match_dup 2)))
7069 (clobber (reg:CC FLAGS_REG))])]
7070 "TARGET_QIMODE_MATH"
7075 tmp0 = gen_reg_rtx (HImode);
7076 tmp1 = gen_reg_rtx (HImode);
7078 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7080 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7081 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7083 /* Extract remainder from AH. */
7084 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7085 insn = emit_move_insn (operands[3], tmp1);
7087 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7088 set_unique_reg_note (insn, REG_EQUAL, mod);
7090 /* Extract quotient from AL. */
7091 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7093 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7094 set_unique_reg_note (insn, REG_EQUAL, div);
7099 ;; Divide AX by r/m8, with result stored in
7102 ;; Change div/mod to HImode and extend the second argument to HImode
7103 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7104 ;; combine may fail.
7105 (define_insn "divmodhiqi3"
7106 [(set (match_operand:HI 0 "register_operand" "=a")
7111 (mod:HI (match_operand:HI 1 "register_operand" "0")
7113 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7117 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7118 (clobber (reg:CC FLAGS_REG))]
7119 "TARGET_QIMODE_MATH"
7121 [(set_attr "type" "idiv")
7122 (set_attr "mode" "QI")])
7124 (define_expand "udivmod<mode>4"
7125 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7127 (match_operand:SWIM248 1 "register_operand")
7128 (match_operand:SWIM248 2 "nonimmediate_operand")))
7129 (set (match_operand:SWIM248 3 "register_operand")
7130 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7131 (clobber (reg:CC FLAGS_REG))])])
7133 ;; Split with 8bit unsigned divide:
7134 ;; if (dividend an divisor are in [0-255])
7135 ;; use 8bit unsigned integer divide
7137 ;; use original integer divide
7139 [(set (match_operand:SWI48 0 "register_operand")
7140 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7141 (match_operand:SWI48 3 "nonimmediate_operand")))
7142 (set (match_operand:SWI48 1 "register_operand")
7143 (umod:SWI48 (match_dup 2) (match_dup 3)))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_USE_8BIT_IDIV
7146 && TARGET_QIMODE_MATH
7147 && can_create_pseudo_p ()
7148 && !optimize_insn_for_size_p ()"
7150 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7152 (define_insn_and_split "udivmod<mode>4_1"
7153 [(set (match_operand:SWI48 0 "register_operand" "=a")
7154 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7155 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWI48 1 "register_operand" "=&d")
7157 (umod:SWI48 (match_dup 2) (match_dup 3)))
7158 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7159 (clobber (reg:CC FLAGS_REG))]
7163 [(set (match_dup 1) (const_int 0))
7164 (parallel [(set (match_dup 0)
7165 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7167 (umod:SWI48 (match_dup 2) (match_dup 3)))
7169 (clobber (reg:CC FLAGS_REG))])]
7171 [(set_attr "type" "multi")
7172 (set_attr "mode" "<MODE>")])
7174 (define_insn_and_split "*udivmod<mode>4"
7175 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7176 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7177 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7178 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7179 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7180 (clobber (reg:CC FLAGS_REG))]
7184 [(set (match_dup 1) (const_int 0))
7185 (parallel [(set (match_dup 0)
7186 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7188 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7190 (clobber (reg:CC FLAGS_REG))])]
7192 [(set_attr "type" "multi")
7193 (set_attr "mode" "<MODE>")])
7195 (define_insn "*udivmod<mode>4_noext"
7196 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7197 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7198 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7199 (set (match_operand:SWIM248 1 "register_operand" "=d")
7200 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7201 (use (match_operand:SWIM248 4 "register_operand" "1"))
7202 (clobber (reg:CC FLAGS_REG))]
7204 "div{<imodesuffix>}\t%3"
7205 [(set_attr "type" "idiv")
7206 (set_attr "mode" "<MODE>")])
7208 (define_expand "udivmodqi4"
7209 [(parallel [(set (match_operand:QI 0 "register_operand")
7211 (match_operand:QI 1 "register_operand")
7212 (match_operand:QI 2 "nonimmediate_operand")))
7213 (set (match_operand:QI 3 "register_operand")
7214 (umod:QI (match_dup 1) (match_dup 2)))
7215 (clobber (reg:CC FLAGS_REG))])]
7216 "TARGET_QIMODE_MATH"
7221 tmp0 = gen_reg_rtx (HImode);
7222 tmp1 = gen_reg_rtx (HImode);
7224 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7226 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7227 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7229 /* Extract remainder from AH. */
7230 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7231 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7232 insn = emit_move_insn (operands[3], tmp1);
7234 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7235 set_unique_reg_note (insn, REG_EQUAL, mod);
7237 /* Extract quotient from AL. */
7238 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7240 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7241 set_unique_reg_note (insn, REG_EQUAL, div);
7246 (define_insn "udivmodhiqi3"
7247 [(set (match_operand:HI 0 "register_operand" "=a")
7252 (mod:HI (match_operand:HI 1 "register_operand" "0")
7254 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7258 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7259 (clobber (reg:CC FLAGS_REG))]
7260 "TARGET_QIMODE_MATH"
7262 [(set_attr "type" "idiv")
7263 (set_attr "mode" "QI")])
7265 ;; We cannot use div/idiv for double division, because it causes
7266 ;; "division by zero" on the overflow and that's not what we expect
7267 ;; from truncate. Because true (non truncating) double division is
7268 ;; never generated, we can't create this insn anyway.
7271 ; [(set (match_operand:SI 0 "register_operand" "=a")
7273 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7275 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7276 ; (set (match_operand:SI 3 "register_operand" "=d")
7278 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7279 ; (clobber (reg:CC FLAGS_REG))]
7281 ; "div{l}\t{%2, %0|%0, %2}"
7282 ; [(set_attr "type" "idiv")])
7284 ;;- Logical AND instructions
7286 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7287 ;; Note that this excludes ah.
7289 (define_expand "testsi_ccno_1"
7290 [(set (reg:CCNO FLAGS_REG)
7292 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7293 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7296 (define_expand "testqi_ccz_1"
7297 [(set (reg:CCZ FLAGS_REG)
7298 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7299 (match_operand:QI 1 "nonmemory_operand"))
7302 (define_expand "testdi_ccno_1"
7303 [(set (reg:CCNO FLAGS_REG)
7305 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7306 (match_operand:DI 1 "x86_64_szext_general_operand"))
7308 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7310 (define_insn "*testdi_1"
7311 [(set (reg FLAGS_REG)
7314 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7315 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7317 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7318 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7320 test{l}\t{%k1, %k0|%k0, %k1}
7321 test{l}\t{%k1, %k0|%k0, %k1}
7322 test{q}\t{%1, %0|%0, %1}
7323 test{q}\t{%1, %0|%0, %1}
7324 test{q}\t{%1, %0|%0, %1}"
7325 [(set_attr "type" "test")
7326 (set_attr "modrm" "0,1,0,1,1")
7327 (set_attr "mode" "SI,SI,DI,DI,DI")])
7329 (define_insn "*testqi_1_maybe_si"
7330 [(set (reg FLAGS_REG)
7333 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7334 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7336 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7337 && ix86_match_ccmode (insn,
7338 CONST_INT_P (operands[1])
7339 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7341 if (which_alternative == 3)
7343 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7344 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7345 return "test{l}\t{%1, %k0|%k0, %1}";
7347 return "test{b}\t{%1, %0|%0, %1}";
7349 [(set_attr "type" "test")
7350 (set_attr "modrm" "0,1,1,1")
7351 (set_attr "mode" "QI,QI,QI,SI")
7352 (set_attr "pent_pair" "uv,np,uv,np")])
7354 (define_insn "*test<mode>_1"
7355 [(set (reg FLAGS_REG)
7358 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7359 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7361 "ix86_match_ccmode (insn, CCNOmode)
7362 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7363 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7364 [(set_attr "type" "test")
7365 (set_attr "modrm" "0,1,1")
7366 (set_attr "mode" "<MODE>")
7367 (set_attr "pent_pair" "uv,np,uv")])
7369 (define_expand "testqi_ext_ccno_0"
7370 [(set (reg:CCNO FLAGS_REG)
7374 (match_operand 0 "ext_register_operand")
7377 (match_operand 1 "const_int_operand"))
7380 (define_insn "*testqi_ext_0"
7381 [(set (reg FLAGS_REG)
7385 (match_operand 0 "ext_register_operand" "Q")
7388 (match_operand 1 "const_int_operand" "n"))
7390 "ix86_match_ccmode (insn, CCNOmode)"
7391 "test{b}\t{%1, %h0|%h0, %1}"
7392 [(set_attr "type" "test")
7393 (set_attr "mode" "QI")
7394 (set_attr "length_immediate" "1")
7395 (set_attr "modrm" "1")
7396 (set_attr "pent_pair" "np")])
7398 (define_insn "*testqi_ext_1"
7399 [(set (reg FLAGS_REG)
7403 (match_operand 0 "ext_register_operand" "Q,Q")
7407 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7409 "ix86_match_ccmode (insn, CCNOmode)"
7410 "test{b}\t{%1, %h0|%h0, %1}"
7411 [(set_attr "isa" "*,nox64")
7412 (set_attr "type" "test")
7413 (set_attr "mode" "QI")])
7415 (define_insn "*testqi_ext_2"
7416 [(set (reg FLAGS_REG)
7420 (match_operand 0 "ext_register_operand" "Q")
7424 (match_operand 1 "ext_register_operand" "Q")
7428 "ix86_match_ccmode (insn, CCNOmode)"
7429 "test{b}\t{%h1, %h0|%h0, %h1}"
7430 [(set_attr "type" "test")
7431 (set_attr "mode" "QI")])
7433 ;; Combine likes to form bit extractions for some tests. Humor it.
7434 (define_insn "*testqi_ext_3"
7435 [(set (reg FLAGS_REG)
7436 (compare (zero_extract:SWI48
7437 (match_operand 0 "nonimmediate_operand" "rm")
7438 (match_operand:SWI48 1 "const_int_operand")
7439 (match_operand:SWI48 2 "const_int_operand"))
7441 "ix86_match_ccmode (insn, CCNOmode)
7442 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7443 || GET_MODE (operands[0]) == SImode
7444 || GET_MODE (operands[0]) == HImode
7445 || GET_MODE (operands[0]) == QImode)
7446 /* Ensure that resulting mask is zero or sign extended operand. */
7447 && INTVAL (operands[2]) >= 0
7448 && ((INTVAL (operands[1]) > 0
7449 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7450 || (<MODE>mode == DImode
7451 && INTVAL (operands[1]) > 32
7452 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7456 [(set (match_operand 0 "flags_reg_operand")
7457 (match_operator 1 "compare_operator"
7459 (match_operand 2 "nonimmediate_operand")
7460 (match_operand 3 "const_int_operand")
7461 (match_operand 4 "const_int_operand"))
7463 "ix86_match_ccmode (insn, CCNOmode)"
7464 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7466 rtx val = operands[2];
7467 HOST_WIDE_INT len = INTVAL (operands[3]);
7468 HOST_WIDE_INT pos = INTVAL (operands[4]);
7470 machine_mode mode, submode;
7472 mode = GET_MODE (val);
7475 /* ??? Combine likes to put non-volatile mem extractions in QImode
7476 no matter the size of the test. So find a mode that works. */
7477 if (! MEM_VOLATILE_P (val))
7479 mode = smallest_mode_for_size (pos + len, MODE_INT);
7480 val = adjust_address (val, mode, 0);
7483 else if (GET_CODE (val) == SUBREG
7484 && (submode = GET_MODE (SUBREG_REG (val)),
7485 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7486 && pos + len <= GET_MODE_BITSIZE (submode)
7487 && GET_MODE_CLASS (submode) == MODE_INT)
7489 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7491 val = SUBREG_REG (val);
7493 else if (mode == HImode && pos + len <= 8)
7495 /* Small HImode tests can be converted to QImode. */
7497 val = gen_lowpart (QImode, val);
7500 if (len == HOST_BITS_PER_WIDE_INT)
7503 mask = ((HOST_WIDE_INT)1 << len) - 1;
7506 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7509 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7510 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7511 ;; this is relatively important trick.
7512 ;; Do the conversion only post-reload to avoid limiting of the register class
7515 [(set (match_operand 0 "flags_reg_operand")
7516 (match_operator 1 "compare_operator"
7517 [(and (match_operand 2 "register_operand")
7518 (match_operand 3 "const_int_operand"))
7521 && QI_REG_P (operands[2])
7522 && GET_MODE (operands[2]) != QImode
7523 && ((ix86_match_ccmode (insn, CCZmode)
7524 && !(INTVAL (operands[3]) & ~(255 << 8)))
7525 || (ix86_match_ccmode (insn, CCNOmode)
7526 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7529 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7533 operands[2] = gen_lowpart (SImode, operands[2]);
7534 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7538 [(set (match_operand 0 "flags_reg_operand")
7539 (match_operator 1 "compare_operator"
7540 [(and (match_operand 2 "nonimmediate_operand")
7541 (match_operand 3 "const_int_operand"))
7544 && GET_MODE (operands[2]) != QImode
7545 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7546 && ((ix86_match_ccmode (insn, CCZmode)
7547 && !(INTVAL (operands[3]) & ~255))
7548 || (ix86_match_ccmode (insn, CCNOmode)
7549 && !(INTVAL (operands[3]) & ~127)))"
7551 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7554 operands[2] = gen_lowpart (QImode, operands[2]);
7555 operands[3] = gen_lowpart (QImode, operands[3]);
7559 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7560 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7561 (match_operand:SWI1248x 2 "mask_reg_operand")))
7562 (clobber (reg:CC FLAGS_REG))]
7563 "TARGET_AVX512F && reload_completed"
7565 (any_logic:SWI1248x (match_dup 1)
7568 (define_insn "*k<logic><mode>"
7569 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7570 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7571 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7574 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7575 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7577 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7579 [(set_attr "mode" "<MODE>")
7580 (set_attr "type" "msklog")
7581 (set_attr "prefix" "vex")])
7583 ;; %%% This used to optimize known byte-wide and operations to memory,
7584 ;; and sometimes to QImode registers. If this is considered useful,
7585 ;; it should be done with splitters.
7587 (define_expand "and<mode>3"
7588 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7589 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7590 (match_operand:SWIM 2 "<general_szext_operand>")))]
7593 machine_mode mode = <MODE>mode;
7594 rtx (*insn) (rtx, rtx);
7596 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7598 HOST_WIDE_INT ival = INTVAL (operands[2]);
7600 if (ival == (HOST_WIDE_INT) 0xffffffff)
7602 else if (ival == 0xffff)
7604 else if (ival == 0xff)
7608 if (mode == <MODE>mode)
7610 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7614 if (<MODE>mode == DImode)
7615 insn = (mode == SImode)
7616 ? gen_zero_extendsidi2
7618 ? gen_zero_extendhidi2
7619 : gen_zero_extendqidi2;
7620 else if (<MODE>mode == SImode)
7621 insn = (mode == HImode)
7622 ? gen_zero_extendhisi2
7623 : gen_zero_extendqisi2;
7624 else if (<MODE>mode == HImode)
7625 insn = gen_zero_extendqihi2;
7629 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7633 (define_insn "*anddi_1"
7634 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7636 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7637 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7638 (clobber (reg:CC FLAGS_REG))]
7639 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7641 switch (get_attr_type (insn))
7647 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7650 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7651 if (get_attr_mode (insn) == MODE_SI)
7652 return "and{l}\t{%k2, %k0|%k0, %k2}";
7654 return "and{q}\t{%2, %0|%0, %2}";
7657 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7658 (set_attr "length_immediate" "*,*,*,0,0")
7659 (set (attr "prefix_rex")
7661 (and (eq_attr "type" "imovx")
7662 (and (match_test "INTVAL (operands[2]) == 0xff")
7663 (match_operand 1 "ext_QIreg_operand")))
7665 (const_string "*")))
7666 (set_attr "mode" "SI,DI,DI,SI,DI")])
7668 (define_insn "*andsi_1"
7669 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7670 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7671 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7672 (clobber (reg:CC FLAGS_REG))]
7673 "ix86_binary_operator_ok (AND, SImode, operands)"
7675 switch (get_attr_type (insn))
7681 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7684 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7685 return "and{l}\t{%2, %0|%0, %2}";
7688 [(set_attr "type" "alu,alu,imovx,msklog")
7689 (set (attr "prefix_rex")
7691 (and (eq_attr "type" "imovx")
7692 (and (match_test "INTVAL (operands[2]) == 0xff")
7693 (match_operand 1 "ext_QIreg_operand")))
7695 (const_string "*")))
7696 (set_attr "length_immediate" "*,*,0,0")
7697 (set_attr "mode" "SI")])
7699 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7700 (define_insn "*andsi_1_zext"
7701 [(set (match_operand:DI 0 "register_operand" "=r")
7703 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7704 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7705 (clobber (reg:CC FLAGS_REG))]
7706 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7707 "and{l}\t{%2, %k0|%k0, %2}"
7708 [(set_attr "type" "alu")
7709 (set_attr "mode" "SI")])
7711 (define_insn "*andhi_1"
7712 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7713 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7714 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "ix86_binary_operator_ok (AND, HImode, operands)"
7718 switch (get_attr_type (insn))
7724 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7727 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7728 return "and{w}\t{%2, %0|%0, %2}";
7731 [(set_attr "type" "alu,alu,imovx,msklog")
7732 (set_attr "length_immediate" "*,*,0,*")
7733 (set (attr "prefix_rex")
7735 (and (eq_attr "type" "imovx")
7736 (match_operand 1 "ext_QIreg_operand"))
7738 (const_string "*")))
7739 (set_attr "mode" "HI,HI,SI,HI")])
7741 ;; %%% Potential partial reg stall on alternative 2. What to do?
7742 (define_insn "*andqi_1"
7743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7744 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7745 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7746 (clobber (reg:CC FLAGS_REG))]
7747 "ix86_binary_operator_ok (AND, QImode, operands)"
7749 switch (which_alternative)
7753 return "and{b}\t{%2, %0|%0, %2}";
7755 return "and{l}\t{%k2, %k0|%k0, %k2}";
7757 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7758 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7763 [(set_attr "type" "alu,alu,alu,msklog")
7764 (set_attr "mode" "QI,QI,SI,HI")])
7766 (define_insn "*andqi_1_slp"
7767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7768 (and:QI (match_dup 0)
7769 (match_operand:QI 1 "general_operand" "qn,qmn")))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7772 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7773 "and{b}\t{%1, %0|%0, %1}"
7774 [(set_attr "type" "alu1")
7775 (set_attr "mode" "QI")])
7777 (define_insn "kandn<mode>"
7778 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7781 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7782 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7783 (clobber (reg:CC FLAGS_REG))]
7786 switch (which_alternative)
7789 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7793 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7794 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7796 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7801 [(set_attr "isa" "bmi,*,avx512f")
7802 (set_attr "type" "bitmanip,*,msklog")
7803 (set_attr "prefix" "*,*,vex")
7804 (set_attr "btver2_decode" "direct,*,*")
7805 (set_attr "mode" "<MODE>")])
7808 [(set (match_operand:SWI12 0 "general_reg_operand")
7812 (match_operand:SWI12 1 "general_reg_operand")))
7813 (clobber (reg:CC FLAGS_REG))]
7814 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7816 (not:HI (match_dup 0)))
7817 (parallel [(set (match_dup 0)
7818 (and:HI (match_dup 0)
7820 (clobber (reg:CC FLAGS_REG))])])
7822 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7824 [(set (match_operand:DI 0 "register_operand")
7825 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7826 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7827 (clobber (reg:CC FLAGS_REG))]
7829 [(parallel [(set (match_dup 0)
7830 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7831 (clobber (reg:CC FLAGS_REG))])]
7832 "operands[2] = gen_lowpart (SImode, operands[2]);")
7835 [(set (match_operand:SWI248 0 "register_operand")
7836 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7837 (match_operand:SWI248 2 "const_int_operand")))
7838 (clobber (reg:CC FLAGS_REG))]
7840 && true_regnum (operands[0]) != true_regnum (operands[1])"
7843 HOST_WIDE_INT ival = INTVAL (operands[2]);
7845 rtx (*insn) (rtx, rtx);
7847 if (ival == (HOST_WIDE_INT) 0xffffffff)
7849 else if (ival == 0xffff)
7853 gcc_assert (ival == 0xff);
7857 if (<MODE>mode == DImode)
7858 insn = (mode == SImode)
7859 ? gen_zero_extendsidi2
7861 ? gen_zero_extendhidi2
7862 : gen_zero_extendqidi2;
7865 if (<MODE>mode != SImode)
7866 /* Zero extend to SImode to avoid partial register stalls. */
7867 operands[0] = gen_lowpart (SImode, operands[0]);
7869 insn = (mode == HImode)
7870 ? gen_zero_extendhisi2
7871 : gen_zero_extendqisi2;
7873 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7878 [(set (match_operand 0 "register_operand")
7880 (const_int -65536)))
7881 (clobber (reg:CC FLAGS_REG))]
7882 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7883 || optimize_function_for_size_p (cfun)"
7884 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7885 "operands[1] = gen_lowpart (HImode, operands[0]);")
7888 [(set (match_operand 0 "ext_register_operand")
7891 (clobber (reg:CC FLAGS_REG))]
7892 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7893 && reload_completed"
7894 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895 "operands[1] = gen_lowpart (QImode, operands[0]);")
7898 [(set (match_operand 0 "ext_register_operand")
7900 (const_int -65281)))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903 && reload_completed"
7904 [(parallel [(set (zero_extract:SI (match_dup 0)
7908 (zero_extract:SI (match_dup 0)
7911 (zero_extract:SI (match_dup 0)
7914 (clobber (reg:CC FLAGS_REG))])]
7915 "operands[0] = gen_lowpart (SImode, operands[0]);")
7917 (define_insn "*anddi_2"
7918 [(set (reg FLAGS_REG)
7921 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7922 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7924 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7925 (and:DI (match_dup 1) (match_dup 2)))]
7927 && ix86_match_ccmode
7929 /* If we are going to emit andl instead of andq, and the operands[2]
7930 constant might have the SImode sign bit set, make sure the sign
7931 flag isn't tested, because the instruction will set the sign flag
7932 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7933 conservatively assume it might have bit 31 set. */
7934 (satisfies_constraint_Z (operands[2])
7935 && (!CONST_INT_P (operands[2])
7936 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7937 ? CCZmode : CCNOmode)
7938 && ix86_binary_operator_ok (AND, DImode, operands)"
7940 and{l}\t{%k2, %k0|%k0, %k2}
7941 and{q}\t{%2, %0|%0, %2}
7942 and{q}\t{%2, %0|%0, %2}"
7943 [(set_attr "type" "alu")
7944 (set_attr "mode" "SI,DI,DI")])
7946 (define_insn "*andqi_2_maybe_si"
7947 [(set (reg FLAGS_REG)
7949 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7950 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7952 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7953 (and:QI (match_dup 1) (match_dup 2)))]
7954 "ix86_binary_operator_ok (AND, QImode, operands)
7955 && ix86_match_ccmode (insn,
7956 CONST_INT_P (operands[2])
7957 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7959 if (which_alternative == 2)
7961 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7962 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7963 return "and{l}\t{%2, %k0|%k0, %2}";
7965 return "and{b}\t{%2, %0|%0, %2}";
7967 [(set_attr "type" "alu")
7968 (set_attr "mode" "QI,QI,SI")])
7970 (define_insn "*and<mode>_2"
7971 [(set (reg FLAGS_REG)
7972 (compare (and:SWI124
7973 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7974 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7976 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7977 (and:SWI124 (match_dup 1) (match_dup 2)))]
7978 "ix86_match_ccmode (insn, CCNOmode)
7979 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7980 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7981 [(set_attr "type" "alu")
7982 (set_attr "mode" "<MODE>")])
7984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7985 (define_insn "*andsi_2_zext"
7986 [(set (reg FLAGS_REG)
7988 (match_operand:SI 1 "nonimmediate_operand" "%0")
7989 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7991 (set (match_operand:DI 0 "register_operand" "=r")
7992 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7994 && ix86_binary_operator_ok (AND, SImode, operands)"
7995 "and{l}\t{%2, %k0|%k0, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "mode" "SI")])
7999 (define_insn "*andqi_2_slp"
8000 [(set (reg FLAGS_REG)
8002 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8003 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8005 (set (strict_low_part (match_dup 0))
8006 (and:QI (match_dup 0) (match_dup 1)))]
8007 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008 && ix86_match_ccmode (insn, CCNOmode)
8009 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8010 "and{b}\t{%1, %0|%0, %1}"
8011 [(set_attr "type" "alu1")
8012 (set_attr "mode" "QI")])
8014 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8015 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8016 ;; for a QImode operand, which of course failed.
8017 (define_insn "andqi_ext_0"
8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8023 (match_operand 1 "ext_register_operand" "0")
8026 (match_operand 2 "const_int_operand" "n")))
8027 (clobber (reg:CC FLAGS_REG))]
8029 "and{b}\t{%2, %h0|%h0, %2}"
8030 [(set_attr "type" "alu")
8031 (set_attr "length_immediate" "1")
8032 (set_attr "modrm" "1")
8033 (set_attr "mode" "QI")])
8035 ;; Generated by peephole translating test to and. This shows up
8036 ;; often in fp comparisons.
8037 (define_insn "*andqi_ext_0_cc"
8038 [(set (reg FLAGS_REG)
8042 (match_operand 1 "ext_register_operand" "0")
8045 (match_operand 2 "const_int_operand" "n"))
8047 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8056 "ix86_match_ccmode (insn, CCNOmode)"
8057 "and{b}\t{%2, %h0|%h0, %2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "length_immediate" "1")
8060 (set_attr "modrm" "1")
8061 (set_attr "mode" "QI")])
8063 (define_insn "*andqi_ext_1"
8064 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8069 (match_operand 1 "ext_register_operand" "0,0")
8073 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8074 (clobber (reg:CC FLAGS_REG))]
8076 "and{b}\t{%2, %h0|%h0, %2}"
8077 [(set_attr "isa" "*,nox64")
8078 (set_attr "type" "alu")
8079 (set_attr "length_immediate" "0")
8080 (set_attr "mode" "QI")])
8082 (define_insn "*andqi_ext_2"
8083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8088 (match_operand 1 "ext_register_operand" "%0")
8092 (match_operand 2 "ext_register_operand" "Q")
8095 (clobber (reg:CC FLAGS_REG))]
8097 "and{b}\t{%h2, %h0|%h0, %h2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "length_immediate" "0")
8100 (set_attr "mode" "QI")])
8102 ;; Convert wide AND instructions with immediate operand to shorter QImode
8103 ;; equivalents when possible.
8104 ;; Don't do the splitting with memory operands, since it introduces risk
8105 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8106 ;; for size, but that can (should?) be handled by generic code instead.
8108 [(set (match_operand 0 "register_operand")
8109 (and (match_operand 1 "register_operand")
8110 (match_operand 2 "const_int_operand")))
8111 (clobber (reg:CC FLAGS_REG))]
8113 && QI_REG_P (operands[0])
8114 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8115 && !(~INTVAL (operands[2]) & ~(255 << 8))
8116 && GET_MODE (operands[0]) != QImode"
8117 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8118 (and:SI (zero_extract:SI (match_dup 1)
8119 (const_int 8) (const_int 8))
8121 (clobber (reg:CC FLAGS_REG))])]
8123 operands[0] = gen_lowpart (SImode, operands[0]);
8124 operands[1] = gen_lowpart (SImode, operands[1]);
8125 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8128 ;; Since AND can be encoded with sign extended immediate, this is only
8129 ;; profitable when 7th bit is not set.
8131 [(set (match_operand 0 "register_operand")
8132 (and (match_operand 1 "general_operand")
8133 (match_operand 2 "const_int_operand")))
8134 (clobber (reg:CC FLAGS_REG))]
8136 && ANY_QI_REG_P (operands[0])
8137 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8138 && !(~INTVAL (operands[2]) & ~255)
8139 && !(INTVAL (operands[2]) & 128)
8140 && GET_MODE (operands[0]) != QImode"
8141 [(parallel [(set (strict_low_part (match_dup 0))
8142 (and:QI (match_dup 1)
8144 (clobber (reg:CC FLAGS_REG))])]
8146 operands[0] = gen_lowpart (QImode, operands[0]);
8147 operands[1] = gen_lowpart (QImode, operands[1]);
8148 operands[2] = gen_lowpart (QImode, operands[2]);
8151 ;; Logical inclusive and exclusive OR instructions
8153 ;; %%% This used to optimize known byte-wide and operations to memory.
8154 ;; If this is considered useful, it should be done with splitters.
8156 (define_expand "<code><mode>3"
8157 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8158 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8159 (match_operand:SWIM 2 "<general_operand>")))]
8161 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8163 (define_insn "*<code><mode>_1"
8164 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8166 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8167 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8168 (clobber (reg:CC FLAGS_REG))]
8169 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8171 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8172 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8173 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8174 [(set_attr "type" "alu,alu,msklog")
8175 (set_attr "mode" "<MODE>")])
8177 (define_insn "*<code>hi_1"
8178 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8180 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8181 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8182 (clobber (reg:CC FLAGS_REG))]
8183 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8185 <logic>{w}\t{%2, %0|%0, %2}
8186 <logic>{w}\t{%2, %0|%0, %2}
8187 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8188 [(set_attr "type" "alu,alu,msklog")
8189 (set_attr "mode" "HI")])
8191 ;; %%% Potential partial reg stall on alternative 2. What to do?
8192 (define_insn "*<code>qi_1"
8193 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8194 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8195 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8199 <logic>{b}\t{%2, %0|%0, %2}
8200 <logic>{b}\t{%2, %0|%0, %2}
8201 <logic>{l}\t{%k2, %k0|%k0, %k2}
8202 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8203 [(set_attr "type" "alu,alu,alu,msklog")
8204 (set_attr "mode" "QI,QI,SI,HI")])
8206 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8207 (define_insn "*<code>si_1_zext"
8208 [(set (match_operand:DI 0 "register_operand" "=r")
8210 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8211 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8212 (clobber (reg:CC FLAGS_REG))]
8213 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8214 "<logic>{l}\t{%2, %k0|%k0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "mode" "SI")])
8218 (define_insn "*<code>si_1_zext_imm"
8219 [(set (match_operand:DI 0 "register_operand" "=r")
8221 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8222 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8223 (clobber (reg:CC FLAGS_REG))]
8224 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8225 "<logic>{l}\t{%2, %k0|%k0, %2}"
8226 [(set_attr "type" "alu")
8227 (set_attr "mode" "SI")])
8229 (define_insn "*<code>qi_1_slp"
8230 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8231 (any_or:QI (match_dup 0)
8232 (match_operand:QI 1 "general_operand" "qmn,qn")))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8236 "<logic>{b}\t{%1, %0|%0, %1}"
8237 [(set_attr "type" "alu1")
8238 (set_attr "mode" "QI")])
8240 (define_insn "*<code><mode>_2"
8241 [(set (reg FLAGS_REG)
8242 (compare (any_or:SWI
8243 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8244 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8246 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8247 (any_or:SWI (match_dup 1) (match_dup 2)))]
8248 "ix86_match_ccmode (insn, CCNOmode)
8249 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8250 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "mode" "<MODE>")])
8254 (define_insn "kxnor<mode>"
8255 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8258 (match_operand:SWI12 1 "register_operand" "0,k")
8259 (match_operand:SWI12 2 "register_operand" "r,k"))))
8260 (clobber (reg:CC FLAGS_REG))]
8263 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8264 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8265 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8267 [(set_attr "type" "*,msklog")
8268 (set_attr "prefix" "*,vex")
8269 (set_attr "mode" "<MODE>")])
8271 (define_insn "kxnor<mode>"
8272 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8275 (match_operand:SWI48x 1 "register_operand" "0,k")
8276 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8277 (clobber (reg:CC FLAGS_REG))]
8281 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8282 [(set_attr "type" "*,msklog")
8283 (set_attr "prefix" "*,vex")
8284 (set_attr "mode" "<MODE>")])
8287 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8291 (match_operand:SWI1248x 1 "general_reg_operand"))))
8292 (clobber (reg:CC FLAGS_REG))]
8293 "TARGET_AVX512F && reload_completed"
8294 [(parallel [(set (match_dup 0)
8295 (xor:HI (match_dup 0)
8297 (clobber (reg:CC FLAGS_REG))])
8299 (not:HI (match_dup 0)))])
8301 ;;There are kortrest[bdq] but no intrinsics for them.
8302 ;;We probably don't need to implement them.
8303 (define_insn "kortestzhi"
8304 [(set (reg:CCZ FLAGS_REG)
8307 (match_operand:HI 0 "register_operand" "k")
8308 (match_operand:HI 1 "register_operand" "k"))
8310 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8311 "kortestw\t{%1, %0|%0, %1}"
8312 [(set_attr "mode" "HI")
8313 (set_attr "type" "msklog")
8314 (set_attr "prefix" "vex")])
8316 (define_insn "kortestchi"
8317 [(set (reg:CCC FLAGS_REG)
8320 (match_operand:HI 0 "register_operand" "k")
8321 (match_operand:HI 1 "register_operand" "k"))
8323 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8324 "kortestw\t{%1, %0|%0, %1}"
8325 [(set_attr "mode" "HI")
8326 (set_attr "type" "msklog")
8327 (set_attr "prefix" "vex")])
8329 (define_insn "kunpckhi"
8330 [(set (match_operand:HI 0 "register_operand" "=k")
8333 (match_operand:HI 1 "register_operand" "k")
8335 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8337 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8338 [(set_attr "mode" "HI")
8339 (set_attr "type" "msklog")
8340 (set_attr "prefix" "vex")])
8342 (define_insn "kunpcksi"
8343 [(set (match_operand:SI 0 "register_operand" "=k")
8346 (match_operand:SI 1 "register_operand" "k")
8348 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8350 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8351 [(set_attr "mode" "SI")])
8353 (define_insn "kunpckdi"
8354 [(set (match_operand:DI 0 "register_operand" "=k")
8357 (match_operand:DI 1 "register_operand" "k")
8359 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8361 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8362 [(set_attr "mode" "DI")])
8364 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8365 ;; ??? Special case for immediate operand is missing - it is tricky.
8366 (define_insn "*<code>si_2_zext"
8367 [(set (reg FLAGS_REG)
8368 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8369 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8371 (set (match_operand:DI 0 "register_operand" "=r")
8372 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8373 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8374 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8375 "<logic>{l}\t{%2, %k0|%k0, %2}"
8376 [(set_attr "type" "alu")
8377 (set_attr "mode" "SI")])
8379 (define_insn "*<code>si_2_zext_imm"
8380 [(set (reg FLAGS_REG)
8382 (match_operand:SI 1 "nonimmediate_operand" "%0")
8383 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8385 (set (match_operand:DI 0 "register_operand" "=r")
8386 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8387 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8388 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8389 "<logic>{l}\t{%2, %k0|%k0, %2}"
8390 [(set_attr "type" "alu")
8391 (set_attr "mode" "SI")])
8393 (define_insn "*<code>qi_2_slp"
8394 [(set (reg FLAGS_REG)
8395 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8396 (match_operand:QI 1 "general_operand" "qmn,qn"))
8398 (set (strict_low_part (match_dup 0))
8399 (any_or:QI (match_dup 0) (match_dup 1)))]
8400 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8401 && ix86_match_ccmode (insn, CCNOmode)
8402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8403 "<logic>{b}\t{%1, %0|%0, %1}"
8404 [(set_attr "type" "alu1")
8405 (set_attr "mode" "QI")])
8407 (define_insn "*<code><mode>_3"
8408 [(set (reg FLAGS_REG)
8409 (compare (any_or:SWI
8410 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8411 (match_operand:SWI 2 "<general_operand>" "<g>"))
8413 (clobber (match_scratch:SWI 0 "=<r>"))]
8414 "ix86_match_ccmode (insn, CCNOmode)
8415 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8416 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "mode" "<MODE>")])
8420 (define_insn "*<code>qi_ext_0"
8421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8426 (match_operand 1 "ext_register_operand" "0")
8429 (match_operand 2 "const_int_operand" "n")))
8430 (clobber (reg:CC FLAGS_REG))]
8431 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8432 "<logic>{b}\t{%2, %h0|%h0, %2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "length_immediate" "1")
8435 (set_attr "modrm" "1")
8436 (set_attr "mode" "QI")])
8438 (define_insn "*<code>qi_ext_1"
8439 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8444 (match_operand 1 "ext_register_operand" "0,0")
8448 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8449 (clobber (reg:CC FLAGS_REG))]
8450 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8451 "<logic>{b}\t{%2, %h0|%h0, %2}"
8452 [(set_attr "isa" "*,nox64")
8453 (set_attr "type" "alu")
8454 (set_attr "length_immediate" "0")
8455 (set_attr "mode" "QI")])
8457 (define_insn "*<code>qi_ext_2"
8458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8465 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8468 (clobber (reg:CC FLAGS_REG))]
8469 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8470 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "length_immediate" "0")
8473 (set_attr "mode" "QI")])
8476 [(set (match_operand 0 "register_operand")
8477 (any_or (match_operand 1 "register_operand")
8478 (match_operand 2 "const_int_operand")))
8479 (clobber (reg:CC FLAGS_REG))]
8481 && QI_REG_P (operands[0])
8482 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8483 && !(INTVAL (operands[2]) & ~(255 << 8))
8484 && GET_MODE (operands[0]) != QImode"
8485 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8486 (any_or:SI (zero_extract:SI (match_dup 1)
8487 (const_int 8) (const_int 8))
8489 (clobber (reg:CC FLAGS_REG))])]
8491 operands[0] = gen_lowpart (SImode, operands[0]);
8492 operands[1] = gen_lowpart (SImode, operands[1]);
8493 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8496 ;; Since OR can be encoded with sign extended immediate, this is only
8497 ;; profitable when 7th bit is set.
8499 [(set (match_operand 0 "register_operand")
8500 (any_or (match_operand 1 "general_operand")
8501 (match_operand 2 "const_int_operand")))
8502 (clobber (reg:CC FLAGS_REG))]
8504 && ANY_QI_REG_P (operands[0])
8505 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8506 && !(INTVAL (operands[2]) & ~255)
8507 && (INTVAL (operands[2]) & 128)
8508 && GET_MODE (operands[0]) != QImode"
8509 [(parallel [(set (strict_low_part (match_dup 0))
8510 (any_or:QI (match_dup 1)
8512 (clobber (reg:CC FLAGS_REG))])]
8514 operands[0] = gen_lowpart (QImode, operands[0]);
8515 operands[1] = gen_lowpart (QImode, operands[1]);
8516 operands[2] = gen_lowpart (QImode, operands[2]);
8519 (define_expand "xorqi_cc_ext_1"
8521 (set (reg:CCNO FLAGS_REG)
8525 (match_operand 1 "ext_register_operand")
8528 (match_operand:QI 2 "const_int_operand"))
8530 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8540 (define_insn "*xorqi_cc_ext_1"
8541 [(set (reg FLAGS_REG)
8545 (match_operand 1 "ext_register_operand" "0,0")
8548 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8550 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8559 "ix86_match_ccmode (insn, CCNOmode)"
8560 "xor{b}\t{%2, %h0|%h0, %2}"
8561 [(set_attr "isa" "*,nox64")
8562 (set_attr "type" "alu")
8563 (set_attr "modrm" "1")
8564 (set_attr "mode" "QI")])
8566 ;; Negation instructions
8568 (define_expand "neg<mode>2"
8569 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8570 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8572 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8574 (define_insn_and_split "*neg<dwi>2_doubleword"
8575 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8576 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8582 [(set (reg:CCZ FLAGS_REG)
8583 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8584 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8587 (plus:DWIH (match_dup 3)
8588 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8590 (clobber (reg:CC FLAGS_REG))])
8593 (neg:DWIH (match_dup 2)))
8594 (clobber (reg:CC FLAGS_REG))])]
8595 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8597 (define_insn "*neg<mode>2_1"
8598 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8599 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8600 (clobber (reg:CC FLAGS_REG))]
8601 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8602 "neg{<imodesuffix>}\t%0"
8603 [(set_attr "type" "negnot")
8604 (set_attr "mode" "<MODE>")])
8606 ;; Combine is quite creative about this pattern.
8607 (define_insn "*negsi2_1_zext"
8608 [(set (match_operand:DI 0 "register_operand" "=r")
8610 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8613 (clobber (reg:CC FLAGS_REG))]
8614 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8616 [(set_attr "type" "negnot")
8617 (set_attr "mode" "SI")])
8619 ;; The problem with neg is that it does not perform (compare x 0),
8620 ;; it really performs (compare 0 x), which leaves us with the zero
8621 ;; flag being the only useful item.
8623 (define_insn "*neg<mode>2_cmpz"
8624 [(set (reg:CCZ FLAGS_REG)
8626 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8628 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8629 (neg:SWI (match_dup 1)))]
8630 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8631 "neg{<imodesuffix>}\t%0"
8632 [(set_attr "type" "negnot")
8633 (set_attr "mode" "<MODE>")])
8635 (define_insn "*negsi2_cmpz_zext"
8636 [(set (reg:CCZ FLAGS_REG)
8640 (match_operand:DI 1 "register_operand" "0")
8644 (set (match_operand:DI 0 "register_operand" "=r")
8645 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8648 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8650 [(set_attr "type" "negnot")
8651 (set_attr "mode" "SI")])
8653 ;; Negate with jump on overflow.
8654 (define_expand "negv<mode>3"
8655 [(parallel [(set (reg:CCO FLAGS_REG)
8656 (ne:CCO (match_operand:SWI 1 "register_operand")
8658 (set (match_operand:SWI 0 "register_operand")
8659 (neg:SWI (match_dup 1)))])
8660 (set (pc) (if_then_else
8661 (eq (reg:CCO FLAGS_REG) (const_int 0))
8662 (label_ref (match_operand 2))
8667 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8671 (define_insn "*negv<mode>3"
8672 [(set (reg:CCO FLAGS_REG)
8673 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8674 (match_operand:SWI 2 "const_int_operand")))
8675 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8676 (neg:SWI (match_dup 1)))]
8677 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8678 && mode_signbit_p (<MODE>mode, operands[2])"
8679 "neg{<imodesuffix>}\t%0"
8680 [(set_attr "type" "negnot")
8681 (set_attr "mode" "<MODE>")])
8683 ;; Changing of sign for FP values is doable using integer unit too.
8685 (define_expand "<code><mode>2"
8686 [(set (match_operand:X87MODEF 0 "register_operand")
8687 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8688 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8689 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8691 (define_insn "*absneg<mode>2_mixed"
8692 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8693 (match_operator:MODEF 3 "absneg_operator"
8694 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8695 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8700 (define_insn "*absneg<mode>2_sse"
8701 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8702 (match_operator:MODEF 3 "absneg_operator"
8703 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8704 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8705 (clobber (reg:CC FLAGS_REG))]
8706 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8709 (define_insn "*absneg<mode>2_i387"
8710 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8711 (match_operator:X87MODEF 3 "absneg_operator"
8712 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8713 (use (match_operand 2))
8714 (clobber (reg:CC FLAGS_REG))]
8715 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8718 (define_expand "<code>tf2"
8719 [(set (match_operand:TF 0 "register_operand")
8720 (absneg:TF (match_operand:TF 1 "register_operand")))]
8722 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8724 (define_insn "*absnegtf2_sse"
8725 [(set (match_operand:TF 0 "register_operand" "=x,x")
8726 (match_operator:TF 3 "absneg_operator"
8727 [(match_operand:TF 1 "register_operand" "0,x")]))
8728 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8729 (clobber (reg:CC FLAGS_REG))]
8733 ;; Splitters for fp abs and neg.
8736 [(set (match_operand 0 "fp_register_operand")
8737 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8738 (use (match_operand 2))
8739 (clobber (reg:CC FLAGS_REG))]
8741 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8744 [(set (match_operand 0 "register_operand")
8745 (match_operator 3 "absneg_operator"
8746 [(match_operand 1 "register_operand")]))
8747 (use (match_operand 2 "nonimmediate_operand"))
8748 (clobber (reg:CC FLAGS_REG))]
8749 "reload_completed && SSE_REG_P (operands[0])"
8750 [(set (match_dup 0) (match_dup 3))]
8752 machine_mode mode = GET_MODE (operands[0]);
8753 machine_mode vmode = GET_MODE (operands[2]);
8756 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8757 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8758 if (operands_match_p (operands[0], operands[2]))
8761 operands[1] = operands[2];
8764 if (GET_CODE (operands[3]) == ABS)
8765 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8767 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8772 [(set (match_operand:SF 0 "register_operand")
8773 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8774 (use (match_operand:V4SF 2))
8775 (clobber (reg:CC FLAGS_REG))]
8777 [(parallel [(set (match_dup 0) (match_dup 1))
8778 (clobber (reg:CC FLAGS_REG))])]
8781 operands[0] = gen_lowpart (SImode, operands[0]);
8782 if (GET_CODE (operands[1]) == ABS)
8784 tmp = gen_int_mode (0x7fffffff, SImode);
8785 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8789 tmp = gen_int_mode (0x80000000, SImode);
8790 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8796 [(set (match_operand:DF 0 "register_operand")
8797 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8798 (use (match_operand 2))
8799 (clobber (reg:CC FLAGS_REG))]
8801 [(parallel [(set (match_dup 0) (match_dup 1))
8802 (clobber (reg:CC FLAGS_REG))])]
8807 tmp = gen_lowpart (DImode, operands[0]);
8808 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8811 if (GET_CODE (operands[1]) == ABS)
8814 tmp = gen_rtx_NOT (DImode, tmp);
8818 operands[0] = gen_highpart (SImode, operands[0]);
8819 if (GET_CODE (operands[1]) == ABS)
8821 tmp = gen_int_mode (0x7fffffff, SImode);
8822 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8826 tmp = gen_int_mode (0x80000000, SImode);
8827 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8834 [(set (match_operand:XF 0 "register_operand")
8835 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8836 (use (match_operand 2))
8837 (clobber (reg:CC FLAGS_REG))]
8839 [(parallel [(set (match_dup 0) (match_dup 1))
8840 (clobber (reg:CC FLAGS_REG))])]
8843 operands[0] = gen_rtx_REG (SImode,
8844 true_regnum (operands[0])
8845 + (TARGET_64BIT ? 1 : 2));
8846 if (GET_CODE (operands[1]) == ABS)
8848 tmp = GEN_INT (0x7fff);
8849 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8853 tmp = GEN_INT (0x8000);
8854 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8859 ;; Conditionalize these after reload. If they match before reload, we
8860 ;; lose the clobber and ability to use integer instructions.
8862 (define_insn "*<code><mode>2_1"
8863 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8864 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8866 && (reload_completed
8867 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8868 "f<absneg_mnemonic>"
8869 [(set_attr "type" "fsgn")
8870 (set_attr "mode" "<MODE>")])
8872 (define_insn "*<code>extendsfdf2"
8873 [(set (match_operand:DF 0 "register_operand" "=f")
8874 (absneg:DF (float_extend:DF
8875 (match_operand:SF 1 "register_operand" "0"))))]
8876 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8877 "f<absneg_mnemonic>"
8878 [(set_attr "type" "fsgn")
8879 (set_attr "mode" "DF")])
8881 (define_insn "*<code>extendsfxf2"
8882 [(set (match_operand:XF 0 "register_operand" "=f")
8883 (absneg:XF (float_extend:XF
8884 (match_operand:SF 1 "register_operand" "0"))))]
8886 "f<absneg_mnemonic>"
8887 [(set_attr "type" "fsgn")
8888 (set_attr "mode" "XF")])
8890 (define_insn "*<code>extenddfxf2"
8891 [(set (match_operand:XF 0 "register_operand" "=f")
8892 (absneg:XF (float_extend:XF
8893 (match_operand:DF 1 "register_operand" "0"))))]
8895 "f<absneg_mnemonic>"
8896 [(set_attr "type" "fsgn")
8897 (set_attr "mode" "XF")])
8899 ;; Copysign instructions
8901 (define_mode_iterator CSGNMODE [SF DF TF])
8902 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8904 (define_expand "copysign<mode>3"
8905 [(match_operand:CSGNMODE 0 "register_operand")
8906 (match_operand:CSGNMODE 1 "nonmemory_operand")
8907 (match_operand:CSGNMODE 2 "register_operand")]
8908 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8909 || (TARGET_SSE && (<MODE>mode == TFmode))"
8910 "ix86_expand_copysign (operands); DONE;")
8912 (define_insn_and_split "copysign<mode>3_const"
8913 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8915 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8916 (match_operand:CSGNMODE 2 "register_operand" "0")
8917 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8919 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8920 || (TARGET_SSE && (<MODE>mode == TFmode))"
8922 "&& reload_completed"
8924 "ix86_split_copysign_const (operands); DONE;")
8926 (define_insn "copysign<mode>3_var"
8927 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8929 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8930 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8931 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8932 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8934 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8935 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8936 || (TARGET_SSE && (<MODE>mode == TFmode))"
8940 [(set (match_operand:CSGNMODE 0 "register_operand")
8942 [(match_operand:CSGNMODE 2 "register_operand")
8943 (match_operand:CSGNMODE 3 "register_operand")
8944 (match_operand:<CSGNVMODE> 4)
8945 (match_operand:<CSGNVMODE> 5)]
8947 (clobber (match_scratch:<CSGNVMODE> 1))]
8948 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8949 || (TARGET_SSE && (<MODE>mode == TFmode)))
8950 && reload_completed"
8952 "ix86_split_copysign_var (operands); DONE;")
8954 ;; One complement instructions
8956 (define_expand "one_cmpl<mode>2"
8957 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8958 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8960 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8962 (define_insn "*one_cmpl<mode>2_1"
8963 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8964 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8965 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8967 not{<imodesuffix>}\t%0
8968 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8969 [(set_attr "isa" "*,avx512bw")
8970 (set_attr "type" "negnot,msklog")
8971 (set_attr "prefix" "*,vex")
8972 (set_attr "mode" "<MODE>")])
8974 (define_insn "*one_cmplhi2_1"
8975 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8976 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8977 "ix86_unary_operator_ok (NOT, HImode, operands)"
8980 knotw\t{%1, %0|%0, %1}"
8981 [(set_attr "isa" "*,avx512f")
8982 (set_attr "type" "negnot,msklog")
8983 (set_attr "prefix" "*,vex")
8984 (set_attr "mode" "HI")])
8986 ;; %%% Potential partial reg stall on alternative 1. What to do?
8987 (define_insn "*one_cmplqi2_1"
8988 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8989 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8990 "ix86_unary_operator_ok (NOT, QImode, operands)"
8992 switch (which_alternative)
8995 return "not{b}\t%0";
8997 return "not{l}\t%k0";
8999 if (TARGET_AVX512DQ)
9000 return "knotb\t{%1, %0|%0, %1}";
9001 return "knotw\t{%1, %0|%0, %1}";
9006 [(set_attr "isa" "*,*,avx512f")
9007 (set_attr "type" "negnot,negnot,msklog")
9008 (set_attr "prefix" "*,*,vex")
9009 (set_attr "mode" "QI,SI,QI")])
9011 ;; ??? Currently never generated - xor is used instead.
9012 (define_insn "*one_cmplsi2_1_zext"
9013 [(set (match_operand:DI 0 "register_operand" "=r")
9015 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9016 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9018 [(set_attr "type" "negnot")
9019 (set_attr "mode" "SI")])
9021 (define_insn "*one_cmpl<mode>2_2"
9022 [(set (reg FLAGS_REG)
9023 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9025 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9026 (not:SWI (match_dup 1)))]
9027 "ix86_match_ccmode (insn, CCNOmode)
9028 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9030 [(set_attr "type" "alu1")
9031 (set_attr "mode" "<MODE>")])
9034 [(set (match_operand 0 "flags_reg_operand")
9035 (match_operator 2 "compare_operator"
9036 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9038 (set (match_operand:SWI 1 "nonimmediate_operand")
9039 (not:SWI (match_dup 3)))]
9040 "ix86_match_ccmode (insn, CCNOmode)"
9041 [(parallel [(set (match_dup 0)
9042 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9045 (xor:SWI (match_dup 3) (const_int -1)))])])
9047 ;; ??? Currently never generated - xor is used instead.
9048 (define_insn "*one_cmplsi2_2_zext"
9049 [(set (reg FLAGS_REG)
9050 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9052 (set (match_operand:DI 0 "register_operand" "=r")
9053 (zero_extend:DI (not:SI (match_dup 1))))]
9054 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9055 && ix86_unary_operator_ok (NOT, SImode, operands)"
9057 [(set_attr "type" "alu1")
9058 (set_attr "mode" "SI")])
9061 [(set (match_operand 0 "flags_reg_operand")
9062 (match_operator 2 "compare_operator"
9063 [(not:SI (match_operand:SI 3 "register_operand"))
9065 (set (match_operand:DI 1 "register_operand")
9066 (zero_extend:DI (not:SI (match_dup 3))))]
9067 "ix86_match_ccmode (insn, CCNOmode)"
9068 [(parallel [(set (match_dup 0)
9069 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9072 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9074 ;; Shift instructions
9076 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9077 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9078 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9079 ;; from the assembler input.
9081 ;; This instruction shifts the target reg/mem as usual, but instead of
9082 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9083 ;; is a left shift double, bits are taken from the high order bits of
9084 ;; reg, else if the insn is a shift right double, bits are taken from the
9085 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9086 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9088 ;; Since sh[lr]d does not change the `reg' operand, that is done
9089 ;; separately, making all shifts emit pairs of shift double and normal
9090 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9091 ;; support a 63 bit shift, each shift where the count is in a reg expands
9092 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9094 ;; If the shift count is a constant, we need never emit more than one
9095 ;; shift pair, instead using moves and sign extension for counts greater
9098 (define_expand "ashl<mode>3"
9099 [(set (match_operand:SDWIM 0 "<shift_operand>")
9100 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9101 (match_operand:QI 2 "nonmemory_operand")))]
9103 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9105 (define_insn "*ashl<mode>3_doubleword"
9106 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9107 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9108 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9109 (clobber (reg:CC FLAGS_REG))]
9112 [(set_attr "type" "multi")])
9115 [(set (match_operand:DWI 0 "register_operand")
9116 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9117 (match_operand:QI 2 "nonmemory_operand")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9121 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9123 ;; By default we don't ask for a scratch register, because when DWImode
9124 ;; values are manipulated, registers are already at a premium. But if
9125 ;; we have one handy, we won't turn it away.
9128 [(match_scratch:DWIH 3 "r")
9129 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9131 (match_operand:<DWI> 1 "nonmemory_operand")
9132 (match_operand:QI 2 "nonmemory_operand")))
9133 (clobber (reg:CC FLAGS_REG))])
9137 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9139 (define_insn "x86_64_shld"
9140 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9141 (ior:DI (ashift:DI (match_dup 0)
9142 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9143 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9144 (minus:QI (const_int 64) (match_dup 2)))))
9145 (clobber (reg:CC FLAGS_REG))]
9147 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9148 [(set_attr "type" "ishift")
9149 (set_attr "prefix_0f" "1")
9150 (set_attr "mode" "DI")
9151 (set_attr "athlon_decode" "vector")
9152 (set_attr "amdfam10_decode" "vector")
9153 (set_attr "bdver1_decode" "vector")])
9155 (define_insn "x86_shld"
9156 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9157 (ior:SI (ashift:SI (match_dup 0)
9158 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9159 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9160 (minus:QI (const_int 32) (match_dup 2)))))
9161 (clobber (reg:CC FLAGS_REG))]
9163 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9164 [(set_attr "type" "ishift")
9165 (set_attr "prefix_0f" "1")
9166 (set_attr "mode" "SI")
9167 (set_attr "pent_pair" "np")
9168 (set_attr "athlon_decode" "vector")
9169 (set_attr "amdfam10_decode" "vector")
9170 (set_attr "bdver1_decode" "vector")])
9172 (define_expand "x86_shift<mode>_adj_1"
9173 [(set (reg:CCZ FLAGS_REG)
9174 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9177 (set (match_operand:SWI48 0 "register_operand")
9178 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9179 (match_operand:SWI48 1 "register_operand")
9182 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9183 (match_operand:SWI48 3 "register_operand")
9186 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9188 (define_expand "x86_shift<mode>_adj_2"
9189 [(use (match_operand:SWI48 0 "register_operand"))
9190 (use (match_operand:SWI48 1 "register_operand"))
9191 (use (match_operand:QI 2 "register_operand"))]
9194 rtx_code_label *label = gen_label_rtx ();
9197 emit_insn (gen_testqi_ccz_1 (operands[2],
9198 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9200 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9201 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9202 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9203 gen_rtx_LABEL_REF (VOIDmode, label),
9205 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9206 JUMP_LABEL (tmp) = label;
9208 emit_move_insn (operands[0], operands[1]);
9209 ix86_expand_clear (operands[1]);
9212 LABEL_NUSES (label) = 1;
9217 ;; Avoid useless masking of count operand.
9218 (define_insn "*ashl<mode>3_mask"
9219 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9221 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9224 (match_operand:SI 2 "register_operand" "c")
9225 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9228 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9229 == GET_MODE_BITSIZE (<MODE>mode)-1"
9231 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9233 [(set_attr "type" "ishift")
9234 (set_attr "mode" "<MODE>")])
9236 (define_insn "*bmi2_ashl<mode>3_1"
9237 [(set (match_operand:SWI48 0 "register_operand" "=r")
9238 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9239 (match_operand:SWI48 2 "register_operand" "r")))]
9241 "shlx\t{%2, %1, %0|%0, %1, %2}"
9242 [(set_attr "type" "ishiftx")
9243 (set_attr "mode" "<MODE>")])
9245 (define_insn "*ashl<mode>3_1"
9246 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9247 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9248 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9252 switch (get_attr_type (insn))
9259 gcc_assert (operands[2] == const1_rtx);
9260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9261 return "add{<imodesuffix>}\t%0, %0";
9264 if (operands[2] == const1_rtx
9265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9266 return "sal{<imodesuffix>}\t%0";
9268 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9271 [(set_attr "isa" "*,*,bmi2")
9273 (cond [(eq_attr "alternative" "1")
9274 (const_string "lea")
9275 (eq_attr "alternative" "2")
9276 (const_string "ishiftx")
9277 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9278 (match_operand 0 "register_operand"))
9279 (match_operand 2 "const1_operand"))
9280 (const_string "alu")
9282 (const_string "ishift")))
9283 (set (attr "length_immediate")
9285 (ior (eq_attr "type" "alu")
9286 (and (eq_attr "type" "ishift")
9287 (and (match_operand 2 "const1_operand")
9288 (ior (match_test "TARGET_SHIFT1")
9289 (match_test "optimize_function_for_size_p (cfun)")))))
9291 (const_string "*")))
9292 (set_attr "mode" "<MODE>")])
9294 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9296 [(set (match_operand:SWI48 0 "register_operand")
9297 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9298 (match_operand:QI 2 "register_operand")))
9299 (clobber (reg:CC FLAGS_REG))]
9300 "TARGET_BMI2 && reload_completed"
9302 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9303 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9305 (define_insn "*bmi2_ashlsi3_1_zext"
9306 [(set (match_operand:DI 0 "register_operand" "=r")
9308 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9309 (match_operand:SI 2 "register_operand" "r"))))]
9310 "TARGET_64BIT && TARGET_BMI2"
9311 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9312 [(set_attr "type" "ishiftx")
9313 (set_attr "mode" "SI")])
9315 (define_insn "*ashlsi3_1_zext"
9316 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9318 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9319 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9320 (clobber (reg:CC FLAGS_REG))]
9321 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9323 switch (get_attr_type (insn))
9330 gcc_assert (operands[2] == const1_rtx);
9331 return "add{l}\t%k0, %k0";
9334 if (operands[2] == const1_rtx
9335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9336 return "sal{l}\t%k0";
9338 return "sal{l}\t{%2, %k0|%k0, %2}";
9341 [(set_attr "isa" "*,*,bmi2")
9343 (cond [(eq_attr "alternative" "1")
9344 (const_string "lea")
9345 (eq_attr "alternative" "2")
9346 (const_string "ishiftx")
9347 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9348 (match_operand 2 "const1_operand"))
9349 (const_string "alu")
9351 (const_string "ishift")))
9352 (set (attr "length_immediate")
9354 (ior (eq_attr "type" "alu")
9355 (and (eq_attr "type" "ishift")
9356 (and (match_operand 2 "const1_operand")
9357 (ior (match_test "TARGET_SHIFT1")
9358 (match_test "optimize_function_for_size_p (cfun)")))))
9360 (const_string "*")))
9361 (set_attr "mode" "SI")])
9363 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9365 [(set (match_operand:DI 0 "register_operand")
9367 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9368 (match_operand:QI 2 "register_operand"))))
9369 (clobber (reg:CC FLAGS_REG))]
9370 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9372 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9373 "operands[2] = gen_lowpart (SImode, operands[2]);")
9375 (define_insn "*ashlhi3_1"
9376 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9377 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9378 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9379 (clobber (reg:CC FLAGS_REG))]
9380 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9382 switch (get_attr_type (insn))
9388 gcc_assert (operands[2] == const1_rtx);
9389 return "add{w}\t%0, %0";
9392 if (operands[2] == const1_rtx
9393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9394 return "sal{w}\t%0";
9396 return "sal{w}\t{%2, %0|%0, %2}";
9400 (cond [(eq_attr "alternative" "1")
9401 (const_string "lea")
9402 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9403 (match_operand 0 "register_operand"))
9404 (match_operand 2 "const1_operand"))
9405 (const_string "alu")
9407 (const_string "ishift")))
9408 (set (attr "length_immediate")
9410 (ior (eq_attr "type" "alu")
9411 (and (eq_attr "type" "ishift")
9412 (and (match_operand 2 "const1_operand")
9413 (ior (match_test "TARGET_SHIFT1")
9414 (match_test "optimize_function_for_size_p (cfun)")))))
9416 (const_string "*")))
9417 (set_attr "mode" "HI,SI")])
9419 ;; %%% Potential partial reg stall on alternative 1. What to do?
9420 (define_insn "*ashlqi3_1"
9421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9422 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9423 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9427 switch (get_attr_type (insn))
9433 gcc_assert (operands[2] == const1_rtx);
9434 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9435 return "add{l}\t%k0, %k0";
9437 return "add{b}\t%0, %0";
9440 if (operands[2] == const1_rtx
9441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9443 if (get_attr_mode (insn) == MODE_SI)
9444 return "sal{l}\t%k0";
9446 return "sal{b}\t%0";
9450 if (get_attr_mode (insn) == MODE_SI)
9451 return "sal{l}\t{%2, %k0|%k0, %2}";
9453 return "sal{b}\t{%2, %0|%0, %2}";
9458 (cond [(eq_attr "alternative" "2")
9459 (const_string "lea")
9460 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9461 (match_operand 0 "register_operand"))
9462 (match_operand 2 "const1_operand"))
9463 (const_string "alu")
9465 (const_string "ishift")))
9466 (set (attr "length_immediate")
9468 (ior (eq_attr "type" "alu")
9469 (and (eq_attr "type" "ishift")
9470 (and (match_operand 2 "const1_operand")
9471 (ior (match_test "TARGET_SHIFT1")
9472 (match_test "optimize_function_for_size_p (cfun)")))))
9474 (const_string "*")))
9475 (set_attr "mode" "QI,SI,SI")])
9477 (define_insn "*ashlqi3_1_slp"
9478 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9479 (ashift:QI (match_dup 0)
9480 (match_operand:QI 1 "nonmemory_operand" "cI")))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "(optimize_function_for_size_p (cfun)
9483 || !TARGET_PARTIAL_FLAG_REG_STALL
9484 || (operands[1] == const1_rtx
9486 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9488 switch (get_attr_type (insn))
9491 gcc_assert (operands[1] == const1_rtx);
9492 return "add{b}\t%0, %0";
9495 if (operands[1] == const1_rtx
9496 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9497 return "sal{b}\t%0";
9499 return "sal{b}\t{%1, %0|%0, %1}";
9503 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9504 (match_operand 0 "register_operand"))
9505 (match_operand 1 "const1_operand"))
9506 (const_string "alu")
9508 (const_string "ishift1")))
9509 (set (attr "length_immediate")
9511 (ior (eq_attr "type" "alu")
9512 (and (eq_attr "type" "ishift1")
9513 (and (match_operand 1 "const1_operand")
9514 (ior (match_test "TARGET_SHIFT1")
9515 (match_test "optimize_function_for_size_p (cfun)")))))
9517 (const_string "*")))
9518 (set_attr "mode" "QI")])
9520 ;; Convert ashift to the lea pattern to avoid flags dependency.
9522 [(set (match_operand 0 "register_operand")
9523 (ashift (match_operand 1 "index_register_operand")
9524 (match_operand:QI 2 "const_int_operand")))
9525 (clobber (reg:CC FLAGS_REG))]
9526 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9528 && true_regnum (operands[0]) != true_regnum (operands[1])"
9531 machine_mode mode = GET_MODE (operands[0]);
9534 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9537 operands[0] = gen_lowpart (mode, operands[0]);
9538 operands[1] = gen_lowpart (mode, operands[1]);
9541 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9543 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9545 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9549 ;; Convert ashift to the lea pattern to avoid flags dependency.
9551 [(set (match_operand:DI 0 "register_operand")
9553 (ashift:SI (match_operand:SI 1 "index_register_operand")
9554 (match_operand:QI 2 "const_int_operand"))))
9555 (clobber (reg:CC FLAGS_REG))]
9556 "TARGET_64BIT && reload_completed
9557 && true_regnum (operands[0]) != true_regnum (operands[1])"
9559 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9561 operands[1] = gen_lowpart (SImode, operands[1]);
9562 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9565 ;; This pattern can't accept a variable shift count, since shifts by
9566 ;; zero don't affect the flags. We assume that shifts by constant
9567 ;; zero are optimized away.
9568 (define_insn "*ashl<mode>3_cmp"
9569 [(set (reg FLAGS_REG)
9571 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9572 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9575 (ashift:SWI (match_dup 1) (match_dup 2)))]
9576 "(optimize_function_for_size_p (cfun)
9577 || !TARGET_PARTIAL_FLAG_REG_STALL
9578 || (operands[2] == const1_rtx
9580 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9581 && ix86_match_ccmode (insn, CCGOCmode)
9582 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9584 switch (get_attr_type (insn))
9587 gcc_assert (operands[2] == const1_rtx);
9588 return "add{<imodesuffix>}\t%0, %0";
9591 if (operands[2] == const1_rtx
9592 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9593 return "sal{<imodesuffix>}\t%0";
9595 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9599 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9600 (match_operand 0 "register_operand"))
9601 (match_operand 2 "const1_operand"))
9602 (const_string "alu")
9604 (const_string "ishift")))
9605 (set (attr "length_immediate")
9607 (ior (eq_attr "type" "alu")
9608 (and (eq_attr "type" "ishift")
9609 (and (match_operand 2 "const1_operand")
9610 (ior (match_test "TARGET_SHIFT1")
9611 (match_test "optimize_function_for_size_p (cfun)")))))
9613 (const_string "*")))
9614 (set_attr "mode" "<MODE>")])
9616 (define_insn "*ashlsi3_cmp_zext"
9617 [(set (reg FLAGS_REG)
9619 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9620 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9622 (set (match_operand:DI 0 "register_operand" "=r")
9623 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9625 && (optimize_function_for_size_p (cfun)
9626 || !TARGET_PARTIAL_FLAG_REG_STALL
9627 || (operands[2] == const1_rtx
9629 || TARGET_DOUBLE_WITH_ADD)))
9630 && ix86_match_ccmode (insn, CCGOCmode)
9631 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9633 switch (get_attr_type (insn))
9636 gcc_assert (operands[2] == const1_rtx);
9637 return "add{l}\t%k0, %k0";
9640 if (operands[2] == const1_rtx
9641 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9642 return "sal{l}\t%k0";
9644 return "sal{l}\t{%2, %k0|%k0, %2}";
9648 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9649 (match_operand 2 "const1_operand"))
9650 (const_string "alu")
9652 (const_string "ishift")))
9653 (set (attr "length_immediate")
9655 (ior (eq_attr "type" "alu")
9656 (and (eq_attr "type" "ishift")
9657 (and (match_operand 2 "const1_operand")
9658 (ior (match_test "TARGET_SHIFT1")
9659 (match_test "optimize_function_for_size_p (cfun)")))))
9661 (const_string "*")))
9662 (set_attr "mode" "SI")])
9664 (define_insn "*ashl<mode>3_cconly"
9665 [(set (reg FLAGS_REG)
9667 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9668 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9670 (clobber (match_scratch:SWI 0 "=<r>"))]
9671 "(optimize_function_for_size_p (cfun)
9672 || !TARGET_PARTIAL_FLAG_REG_STALL
9673 || (operands[2] == const1_rtx
9675 || TARGET_DOUBLE_WITH_ADD)))
9676 && ix86_match_ccmode (insn, CCGOCmode)"
9678 switch (get_attr_type (insn))
9681 gcc_assert (operands[2] == const1_rtx);
9682 return "add{<imodesuffix>}\t%0, %0";
9685 if (operands[2] == const1_rtx
9686 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9687 return "sal{<imodesuffix>}\t%0";
9689 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9693 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9694 (match_operand 0 "register_operand"))
9695 (match_operand 2 "const1_operand"))
9696 (const_string "alu")
9698 (const_string "ishift")))
9699 (set (attr "length_immediate")
9701 (ior (eq_attr "type" "alu")
9702 (and (eq_attr "type" "ishift")
9703 (and (match_operand 2 "const1_operand")
9704 (ior (match_test "TARGET_SHIFT1")
9705 (match_test "optimize_function_for_size_p (cfun)")))))
9707 (const_string "*")))
9708 (set_attr "mode" "<MODE>")])
9710 ;; See comment above `ashl<mode>3' about how this works.
9712 (define_expand "<shift_insn><mode>3"
9713 [(set (match_operand:SDWIM 0 "<shift_operand>")
9714 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9715 (match_operand:QI 2 "nonmemory_operand")))]
9717 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9719 ;; Avoid useless masking of count operand.
9720 (define_insn "*<shift_insn><mode>3_mask"
9721 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9723 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9726 (match_operand:SI 2 "register_operand" "c")
9727 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9728 (clobber (reg:CC FLAGS_REG))]
9729 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9730 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9731 == GET_MODE_BITSIZE (<MODE>mode)-1"
9733 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9735 [(set_attr "type" "ishift")
9736 (set_attr "mode" "<MODE>")])
9738 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9739 [(set (match_operand:DWI 0 "register_operand" "=r")
9740 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9741 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9742 (clobber (reg:CC FLAGS_REG))]
9745 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9747 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9748 [(set_attr "type" "multi")])
9750 ;; By default we don't ask for a scratch register, because when DWImode
9751 ;; values are manipulated, registers are already at a premium. But if
9752 ;; we have one handy, we won't turn it away.
9755 [(match_scratch:DWIH 3 "r")
9756 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9758 (match_operand:<DWI> 1 "register_operand")
9759 (match_operand:QI 2 "nonmemory_operand")))
9760 (clobber (reg:CC FLAGS_REG))])
9764 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9766 (define_insn "x86_64_shrd"
9767 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9768 (ior:DI (lshiftrt:DI (match_dup 0)
9769 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9770 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9771 (minus:QI (const_int 64) (match_dup 2)))))
9772 (clobber (reg:CC FLAGS_REG))]
9774 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9775 [(set_attr "type" "ishift")
9776 (set_attr "prefix_0f" "1")
9777 (set_attr "mode" "DI")
9778 (set_attr "athlon_decode" "vector")
9779 (set_attr "amdfam10_decode" "vector")
9780 (set_attr "bdver1_decode" "vector")])
9782 (define_insn "x86_shrd"
9783 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9784 (ior:SI (lshiftrt:SI (match_dup 0)
9785 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9786 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9787 (minus:QI (const_int 32) (match_dup 2)))))
9788 (clobber (reg:CC FLAGS_REG))]
9790 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9791 [(set_attr "type" "ishift")
9792 (set_attr "prefix_0f" "1")
9793 (set_attr "mode" "SI")
9794 (set_attr "pent_pair" "np")
9795 (set_attr "athlon_decode" "vector")
9796 (set_attr "amdfam10_decode" "vector")
9797 (set_attr "bdver1_decode" "vector")])
9799 (define_insn "ashrdi3_cvt"
9800 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9801 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9802 (match_operand:QI 2 "const_int_operand")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "TARGET_64BIT && INTVAL (operands[2]) == 63
9805 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9806 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9809 sar{q}\t{%2, %0|%0, %2}"
9810 [(set_attr "type" "imovx,ishift")
9811 (set_attr "prefix_0f" "0,*")
9812 (set_attr "length_immediate" "0,*")
9813 (set_attr "modrm" "0,1")
9814 (set_attr "mode" "DI")])
9816 (define_insn "ashrsi3_cvt"
9817 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9818 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9819 (match_operand:QI 2 "const_int_operand")))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "INTVAL (operands[2]) == 31
9822 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9823 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9826 sar{l}\t{%2, %0|%0, %2}"
9827 [(set_attr "type" "imovx,ishift")
9828 (set_attr "prefix_0f" "0,*")
9829 (set_attr "length_immediate" "0,*")
9830 (set_attr "modrm" "0,1")
9831 (set_attr "mode" "SI")])
9833 (define_insn "*ashrsi3_cvt_zext"
9834 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9836 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9837 (match_operand:QI 2 "const_int_operand"))))
9838 (clobber (reg:CC FLAGS_REG))]
9839 "TARGET_64BIT && INTVAL (operands[2]) == 31
9840 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9841 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9844 sar{l}\t{%2, %k0|%k0, %2}"
9845 [(set_attr "type" "imovx,ishift")
9846 (set_attr "prefix_0f" "0,*")
9847 (set_attr "length_immediate" "0,*")
9848 (set_attr "modrm" "0,1")
9849 (set_attr "mode" "SI")])
9851 (define_expand "x86_shift<mode>_adj_3"
9852 [(use (match_operand:SWI48 0 "register_operand"))
9853 (use (match_operand:SWI48 1 "register_operand"))
9854 (use (match_operand:QI 2 "register_operand"))]
9857 rtx_code_label *label = gen_label_rtx ();
9860 emit_insn (gen_testqi_ccz_1 (operands[2],
9861 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9863 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9864 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9865 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9866 gen_rtx_LABEL_REF (VOIDmode, label),
9868 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9869 JUMP_LABEL (tmp) = label;
9871 emit_move_insn (operands[0], operands[1]);
9872 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9873 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9875 LABEL_NUSES (label) = 1;
9880 (define_insn "*bmi2_<shift_insn><mode>3_1"
9881 [(set (match_operand:SWI48 0 "register_operand" "=r")
9882 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9883 (match_operand:SWI48 2 "register_operand" "r")))]
9885 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9886 [(set_attr "type" "ishiftx")
9887 (set_attr "mode" "<MODE>")])
9889 (define_insn "*<shift_insn><mode>3_1"
9890 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9892 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9893 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9897 switch (get_attr_type (insn))
9903 if (operands[2] == const1_rtx
9904 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9905 return "<shift>{<imodesuffix>}\t%0";
9907 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9910 [(set_attr "isa" "*,bmi2")
9911 (set_attr "type" "ishift,ishiftx")
9912 (set (attr "length_immediate")
9914 (and (match_operand 2 "const1_operand")
9915 (ior (match_test "TARGET_SHIFT1")
9916 (match_test "optimize_function_for_size_p (cfun)")))
9918 (const_string "*")))
9919 (set_attr "mode" "<MODE>")])
9921 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9923 [(set (match_operand:SWI48 0 "register_operand")
9924 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9925 (match_operand:QI 2 "register_operand")))
9926 (clobber (reg:CC FLAGS_REG))]
9927 "TARGET_BMI2 && reload_completed"
9929 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9930 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9932 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9933 [(set (match_operand:DI 0 "register_operand" "=r")
9935 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9936 (match_operand:SI 2 "register_operand" "r"))))]
9937 "TARGET_64BIT && TARGET_BMI2"
9938 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9939 [(set_attr "type" "ishiftx")
9940 (set_attr "mode" "SI")])
9942 (define_insn "*<shift_insn>si3_1_zext"
9943 [(set (match_operand:DI 0 "register_operand" "=r,r")
9945 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9946 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9947 (clobber (reg:CC FLAGS_REG))]
9948 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9950 switch (get_attr_type (insn))
9956 if (operands[2] == const1_rtx
9957 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9958 return "<shift>{l}\t%k0";
9960 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9963 [(set_attr "isa" "*,bmi2")
9964 (set_attr "type" "ishift,ishiftx")
9965 (set (attr "length_immediate")
9967 (and (match_operand 2 "const1_operand")
9968 (ior (match_test "TARGET_SHIFT1")
9969 (match_test "optimize_function_for_size_p (cfun)")))
9971 (const_string "*")))
9972 (set_attr "mode" "SI")])
9974 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9976 [(set (match_operand:DI 0 "register_operand")
9978 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9979 (match_operand:QI 2 "register_operand"))))
9980 (clobber (reg:CC FLAGS_REG))]
9981 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9983 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9984 "operands[2] = gen_lowpart (SImode, operands[2]);")
9986 (define_insn "*<shift_insn><mode>3_1"
9987 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9989 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9990 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9991 (clobber (reg:CC FLAGS_REG))]
9992 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9994 if (operands[2] == const1_rtx
9995 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9996 return "<shift>{<imodesuffix>}\t%0";
9998 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10000 [(set_attr "type" "ishift")
10001 (set (attr "length_immediate")
10003 (and (match_operand 2 "const1_operand")
10004 (ior (match_test "TARGET_SHIFT1")
10005 (match_test "optimize_function_for_size_p (cfun)")))
10007 (const_string "*")))
10008 (set_attr "mode" "<MODE>")])
10010 (define_insn "*<shift_insn>qi3_1_slp"
10011 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10012 (any_shiftrt:QI (match_dup 0)
10013 (match_operand:QI 1 "nonmemory_operand" "cI")))
10014 (clobber (reg:CC FLAGS_REG))]
10015 "(optimize_function_for_size_p (cfun)
10016 || !TARGET_PARTIAL_REG_STALL
10017 || (operands[1] == const1_rtx
10018 && TARGET_SHIFT1))"
10020 if (operands[1] == const1_rtx
10021 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10022 return "<shift>{b}\t%0";
10024 return "<shift>{b}\t{%1, %0|%0, %1}";
10026 [(set_attr "type" "ishift1")
10027 (set (attr "length_immediate")
10029 (and (match_operand 1 "const1_operand")
10030 (ior (match_test "TARGET_SHIFT1")
10031 (match_test "optimize_function_for_size_p (cfun)")))
10033 (const_string "*")))
10034 (set_attr "mode" "QI")])
10036 ;; This pattern can't accept a variable shift count, since shifts by
10037 ;; zero don't affect the flags. We assume that shifts by constant
10038 ;; zero are optimized away.
10039 (define_insn "*<shift_insn><mode>3_cmp"
10040 [(set (reg FLAGS_REG)
10043 (match_operand:SWI 1 "nonimmediate_operand" "0")
10044 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10046 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10047 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10048 "(optimize_function_for_size_p (cfun)
10049 || !TARGET_PARTIAL_FLAG_REG_STALL
10050 || (operands[2] == const1_rtx
10052 && ix86_match_ccmode (insn, CCGOCmode)
10053 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10055 if (operands[2] == const1_rtx
10056 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10057 return "<shift>{<imodesuffix>}\t%0";
10059 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10061 [(set_attr "type" "ishift")
10062 (set (attr "length_immediate")
10064 (and (match_operand 2 "const1_operand")
10065 (ior (match_test "TARGET_SHIFT1")
10066 (match_test "optimize_function_for_size_p (cfun)")))
10068 (const_string "*")))
10069 (set_attr "mode" "<MODE>")])
10071 (define_insn "*<shift_insn>si3_cmp_zext"
10072 [(set (reg FLAGS_REG)
10074 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10075 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10077 (set (match_operand:DI 0 "register_operand" "=r")
10078 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10080 && (optimize_function_for_size_p (cfun)
10081 || !TARGET_PARTIAL_FLAG_REG_STALL
10082 || (operands[2] == const1_rtx
10084 && ix86_match_ccmode (insn, CCGOCmode)
10085 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10087 if (operands[2] == const1_rtx
10088 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10089 return "<shift>{l}\t%k0";
10091 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10093 [(set_attr "type" "ishift")
10094 (set (attr "length_immediate")
10096 (and (match_operand 2 "const1_operand")
10097 (ior (match_test "TARGET_SHIFT1")
10098 (match_test "optimize_function_for_size_p (cfun)")))
10100 (const_string "*")))
10101 (set_attr "mode" "SI")])
10103 (define_insn "*<shift_insn><mode>3_cconly"
10104 [(set (reg FLAGS_REG)
10107 (match_operand:SWI 1 "register_operand" "0")
10108 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10110 (clobber (match_scratch:SWI 0 "=<r>"))]
10111 "(optimize_function_for_size_p (cfun)
10112 || !TARGET_PARTIAL_FLAG_REG_STALL
10113 || (operands[2] == const1_rtx
10115 && ix86_match_ccmode (insn, CCGOCmode)"
10117 if (operands[2] == const1_rtx
10118 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10119 return "<shift>{<imodesuffix>}\t%0";
10121 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10123 [(set_attr "type" "ishift")
10124 (set (attr "length_immediate")
10126 (and (match_operand 2 "const1_operand")
10127 (ior (match_test "TARGET_SHIFT1")
10128 (match_test "optimize_function_for_size_p (cfun)")))
10130 (const_string "*")))
10131 (set_attr "mode" "<MODE>")])
10133 ;; Rotate instructions
10135 (define_expand "<rotate_insn>ti3"
10136 [(set (match_operand:TI 0 "register_operand")
10137 (any_rotate:TI (match_operand:TI 1 "register_operand")
10138 (match_operand:QI 2 "nonmemory_operand")))]
10141 if (const_1_to_63_operand (operands[2], VOIDmode))
10142 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10143 (operands[0], operands[1], operands[2]));
10150 (define_expand "<rotate_insn>di3"
10151 [(set (match_operand:DI 0 "shiftdi_operand")
10152 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10153 (match_operand:QI 2 "nonmemory_operand")))]
10157 ix86_expand_binary_operator (<CODE>, DImode, operands);
10158 else if (const_1_to_31_operand (operands[2], VOIDmode))
10159 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10160 (operands[0], operands[1], operands[2]));
10167 (define_expand "<rotate_insn><mode>3"
10168 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10169 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10170 (match_operand:QI 2 "nonmemory_operand")))]
10172 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10174 ;; Avoid useless masking of count operand.
10175 (define_insn "*<rotate_insn><mode>3_mask"
10176 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10178 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10181 (match_operand:SI 2 "register_operand" "c")
10182 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10185 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10186 == GET_MODE_BITSIZE (<MODE>mode)-1"
10188 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10190 [(set_attr "type" "rotate")
10191 (set_attr "mode" "<MODE>")])
10193 ;; Implement rotation using two double-precision
10194 ;; shift instructions and a scratch register.
10196 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10197 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10198 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10199 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10200 (clobber (reg:CC FLAGS_REG))
10201 (clobber (match_scratch:DWIH 3 "=&r"))]
10205 [(set (match_dup 3) (match_dup 4))
10207 [(set (match_dup 4)
10208 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10209 (lshiftrt:DWIH (match_dup 5)
10210 (minus:QI (match_dup 6) (match_dup 2)))))
10211 (clobber (reg:CC FLAGS_REG))])
10213 [(set (match_dup 5)
10214 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10215 (lshiftrt:DWIH (match_dup 3)
10216 (minus:QI (match_dup 6) (match_dup 2)))))
10217 (clobber (reg:CC FLAGS_REG))])]
10219 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10221 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10224 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10225 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10226 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10227 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10228 (clobber (reg:CC FLAGS_REG))
10229 (clobber (match_scratch:DWIH 3 "=&r"))]
10233 [(set (match_dup 3) (match_dup 4))
10235 [(set (match_dup 4)
10236 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10237 (ashift:DWIH (match_dup 5)
10238 (minus:QI (match_dup 6) (match_dup 2)))))
10239 (clobber (reg:CC FLAGS_REG))])
10241 [(set (match_dup 5)
10242 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10243 (ashift:DWIH (match_dup 3)
10244 (minus:QI (match_dup 6) (match_dup 2)))))
10245 (clobber (reg:CC FLAGS_REG))])]
10247 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10249 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10252 (define_insn "*bmi2_rorx<mode>3_1"
10253 [(set (match_operand:SWI48 0 "register_operand" "=r")
10254 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10255 (match_operand:QI 2 "immediate_operand" "<S>")))]
10257 "rorx\t{%2, %1, %0|%0, %1, %2}"
10258 [(set_attr "type" "rotatex")
10259 (set_attr "mode" "<MODE>")])
10261 (define_insn "*<rotate_insn><mode>3_1"
10262 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10264 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10265 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10269 switch (get_attr_type (insn))
10275 if (operands[2] == const1_rtx
10276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10277 return "<rotate>{<imodesuffix>}\t%0";
10279 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10282 [(set_attr "isa" "*,bmi2")
10283 (set_attr "type" "rotate,rotatex")
10284 (set (attr "length_immediate")
10286 (and (eq_attr "type" "rotate")
10287 (and (match_operand 2 "const1_operand")
10288 (ior (match_test "TARGET_SHIFT1")
10289 (match_test "optimize_function_for_size_p (cfun)"))))
10291 (const_string "*")))
10292 (set_attr "mode" "<MODE>")])
10294 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10296 [(set (match_operand:SWI48 0 "register_operand")
10297 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10298 (match_operand:QI 2 "immediate_operand")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "TARGET_BMI2 && reload_completed"
10301 [(set (match_dup 0)
10302 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10305 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10309 [(set (match_operand:SWI48 0 "register_operand")
10310 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10311 (match_operand:QI 2 "immediate_operand")))
10312 (clobber (reg:CC FLAGS_REG))]
10313 "TARGET_BMI2 && reload_completed"
10314 [(set (match_dup 0)
10315 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10317 (define_insn "*bmi2_rorxsi3_1_zext"
10318 [(set (match_operand:DI 0 "register_operand" "=r")
10320 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10321 (match_operand:QI 2 "immediate_operand" "I"))))]
10322 "TARGET_64BIT && TARGET_BMI2"
10323 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10324 [(set_attr "type" "rotatex")
10325 (set_attr "mode" "SI")])
10327 (define_insn "*<rotate_insn>si3_1_zext"
10328 [(set (match_operand:DI 0 "register_operand" "=r,r")
10330 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10331 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10335 switch (get_attr_type (insn))
10341 if (operands[2] == const1_rtx
10342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10343 return "<rotate>{l}\t%k0";
10345 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10348 [(set_attr "isa" "*,bmi2")
10349 (set_attr "type" "rotate,rotatex")
10350 (set (attr "length_immediate")
10352 (and (eq_attr "type" "rotate")
10353 (and (match_operand 2 "const1_operand")
10354 (ior (match_test "TARGET_SHIFT1")
10355 (match_test "optimize_function_for_size_p (cfun)"))))
10357 (const_string "*")))
10358 (set_attr "mode" "SI")])
10360 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10362 [(set (match_operand:DI 0 "register_operand")
10364 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10365 (match_operand:QI 2 "immediate_operand"))))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10368 [(set (match_dup 0)
10369 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10372 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10376 [(set (match_operand:DI 0 "register_operand")
10378 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10379 (match_operand:QI 2 "immediate_operand"))))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10382 [(set (match_dup 0)
10383 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10385 (define_insn "*<rotate_insn><mode>3_1"
10386 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10387 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10388 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10392 if (operands[2] == const1_rtx
10393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10394 return "<rotate>{<imodesuffix>}\t%0";
10396 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10398 [(set_attr "type" "rotate")
10399 (set (attr "length_immediate")
10401 (and (match_operand 2 "const1_operand")
10402 (ior (match_test "TARGET_SHIFT1")
10403 (match_test "optimize_function_for_size_p (cfun)")))
10405 (const_string "*")))
10406 (set_attr "mode" "<MODE>")])
10408 (define_insn "*<rotate_insn>qi3_1_slp"
10409 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10410 (any_rotate:QI (match_dup 0)
10411 (match_operand:QI 1 "nonmemory_operand" "cI")))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "(optimize_function_for_size_p (cfun)
10414 || !TARGET_PARTIAL_REG_STALL
10415 || (operands[1] == const1_rtx
10416 && TARGET_SHIFT1))"
10418 if (operands[1] == const1_rtx
10419 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10420 return "<rotate>{b}\t%0";
10422 return "<rotate>{b}\t{%1, %0|%0, %1}";
10424 [(set_attr "type" "rotate1")
10425 (set (attr "length_immediate")
10427 (and (match_operand 1 "const1_operand")
10428 (ior (match_test "TARGET_SHIFT1")
10429 (match_test "optimize_function_for_size_p (cfun)")))
10431 (const_string "*")))
10432 (set_attr "mode" "QI")])
10435 [(set (match_operand:HI 0 "register_operand")
10436 (any_rotate:HI (match_dup 0) (const_int 8)))
10437 (clobber (reg:CC FLAGS_REG))]
10439 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10440 [(parallel [(set (strict_low_part (match_dup 0))
10441 (bswap:HI (match_dup 0)))
10442 (clobber (reg:CC FLAGS_REG))])])
10444 ;; Bit set / bit test instructions
10446 (define_expand "extv"
10447 [(set (match_operand:SI 0 "register_operand")
10448 (sign_extract:SI (match_operand:SI 1 "register_operand")
10449 (match_operand:SI 2 "const8_operand")
10450 (match_operand:SI 3 "const8_operand")))]
10453 /* Handle extractions from %ah et al. */
10454 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10457 /* From mips.md: extract_bit_field doesn't verify that our source
10458 matches the predicate, so check it again here. */
10459 if (! ext_register_operand (operands[1], VOIDmode))
10463 (define_expand "extzv"
10464 [(set (match_operand:SI 0 "register_operand")
10465 (zero_extract:SI (match_operand 1 "ext_register_operand")
10466 (match_operand:SI 2 "const8_operand")
10467 (match_operand:SI 3 "const8_operand")))]
10470 /* Handle extractions from %ah et al. */
10471 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10474 /* From mips.md: extract_bit_field doesn't verify that our source
10475 matches the predicate, so check it again here. */
10476 if (! ext_register_operand (operands[1], VOIDmode))
10480 (define_expand "insv"
10481 [(set (zero_extract (match_operand 0 "register_operand")
10482 (match_operand 1 "const_int_operand")
10483 (match_operand 2 "const_int_operand"))
10484 (match_operand 3 "register_operand"))]
10487 rtx (*gen_mov_insv_1) (rtx, rtx);
10489 if (ix86_expand_pinsr (operands))
10492 /* Handle insertions to %ah et al. */
10493 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10496 /* From mips.md: insert_bit_field doesn't verify that our source
10497 matches the predicate, so check it again here. */
10498 if (! ext_register_operand (operands[0], VOIDmode))
10501 gen_mov_insv_1 = (TARGET_64BIT
10502 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10504 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10508 ;; %%% bts, btr, btc, bt.
10509 ;; In general these instructions are *slow* when applied to memory,
10510 ;; since they enforce atomic operation. When applied to registers,
10511 ;; it depends on the cpu implementation. They're never faster than
10512 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10513 ;; no point. But in 64-bit, we can't hold the relevant immediates
10514 ;; within the instruction itself, so operating on bits in the high
10515 ;; 32-bits of a register becomes easier.
10517 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10518 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10519 ;; negdf respectively, so they can never be disabled entirely.
10521 (define_insn "*btsq"
10522 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10524 (match_operand:DI 1 "const_0_to_63_operand"))
10526 (clobber (reg:CC FLAGS_REG))]
10527 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10528 "bts{q}\t{%1, %0|%0, %1}"
10529 [(set_attr "type" "alu1")
10530 (set_attr "prefix_0f" "1")
10531 (set_attr "mode" "DI")])
10533 (define_insn "*btrq"
10534 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10536 (match_operand:DI 1 "const_0_to_63_operand"))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10540 "btr{q}\t{%1, %0|%0, %1}"
10541 [(set_attr "type" "alu1")
10542 (set_attr "prefix_0f" "1")
10543 (set_attr "mode" "DI")])
10545 (define_insn "*btcq"
10546 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10548 (match_operand:DI 1 "const_0_to_63_operand"))
10549 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10552 "btc{q}\t{%1, %0|%0, %1}"
10553 [(set_attr "type" "alu1")
10554 (set_attr "prefix_0f" "1")
10555 (set_attr "mode" "DI")])
10557 ;; Allow Nocona to avoid these instructions if a register is available.
10560 [(match_scratch:DI 2 "r")
10561 (parallel [(set (zero_extract:DI
10562 (match_operand:DI 0 "register_operand")
10564 (match_operand:DI 1 "const_0_to_63_operand"))
10566 (clobber (reg:CC FLAGS_REG))])]
10567 "TARGET_64BIT && !TARGET_USE_BT"
10570 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10573 if (HOST_BITS_PER_WIDE_INT >= 64)
10574 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10575 else if (i < HOST_BITS_PER_WIDE_INT)
10576 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10578 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10580 op1 = immed_double_const (lo, hi, DImode);
10583 emit_move_insn (operands[2], op1);
10587 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10592 [(match_scratch:DI 2 "r")
10593 (parallel [(set (zero_extract:DI
10594 (match_operand:DI 0 "register_operand")
10596 (match_operand:DI 1 "const_0_to_63_operand"))
10598 (clobber (reg:CC FLAGS_REG))])]
10599 "TARGET_64BIT && !TARGET_USE_BT"
10602 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10605 if (HOST_BITS_PER_WIDE_INT >= 64)
10606 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10607 else if (i < HOST_BITS_PER_WIDE_INT)
10608 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10610 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10612 op1 = immed_double_const (~lo, ~hi, DImode);
10615 emit_move_insn (operands[2], op1);
10619 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10624 [(match_scratch:DI 2 "r")
10625 (parallel [(set (zero_extract:DI
10626 (match_operand:DI 0 "register_operand")
10628 (match_operand:DI 1 "const_0_to_63_operand"))
10629 (not:DI (zero_extract:DI
10630 (match_dup 0) (const_int 1) (match_dup 1))))
10631 (clobber (reg:CC FLAGS_REG))])]
10632 "TARGET_64BIT && !TARGET_USE_BT"
10635 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10638 if (HOST_BITS_PER_WIDE_INT >= 64)
10639 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10640 else if (i < HOST_BITS_PER_WIDE_INT)
10641 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10643 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10645 op1 = immed_double_const (lo, hi, DImode);
10648 emit_move_insn (operands[2], op1);
10652 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10656 (define_insn "*bt<mode>"
10657 [(set (reg:CCC FLAGS_REG)
10659 (zero_extract:SWI48
10660 (match_operand:SWI48 0 "register_operand" "r")
10662 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10664 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10665 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10666 [(set_attr "type" "alu1")
10667 (set_attr "prefix_0f" "1")
10668 (set_attr "mode" "<MODE>")])
10670 ;; Store-flag instructions.
10672 ;; For all sCOND expanders, also expand the compare or test insn that
10673 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10675 (define_insn_and_split "*setcc_di_1"
10676 [(set (match_operand:DI 0 "register_operand" "=q")
10677 (match_operator:DI 1 "ix86_comparison_operator"
10678 [(reg FLAGS_REG) (const_int 0)]))]
10679 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10681 "&& reload_completed"
10682 [(set (match_dup 2) (match_dup 1))
10683 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10685 PUT_MODE (operands[1], QImode);
10686 operands[2] = gen_lowpart (QImode, operands[0]);
10689 (define_insn_and_split "*setcc_si_1_and"
10690 [(set (match_operand:SI 0 "register_operand" "=q")
10691 (match_operator:SI 1 "ix86_comparison_operator"
10692 [(reg FLAGS_REG) (const_int 0)]))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "!TARGET_PARTIAL_REG_STALL
10695 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10697 "&& reload_completed"
10698 [(set (match_dup 2) (match_dup 1))
10699 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10700 (clobber (reg:CC FLAGS_REG))])]
10702 PUT_MODE (operands[1], QImode);
10703 operands[2] = gen_lowpart (QImode, operands[0]);
10706 (define_insn_and_split "*setcc_si_1_movzbl"
10707 [(set (match_operand:SI 0 "register_operand" "=q")
10708 (match_operator:SI 1 "ix86_comparison_operator"
10709 [(reg FLAGS_REG) (const_int 0)]))]
10710 "!TARGET_PARTIAL_REG_STALL
10711 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10713 "&& reload_completed"
10714 [(set (match_dup 2) (match_dup 1))
10715 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10717 PUT_MODE (operands[1], QImode);
10718 operands[2] = gen_lowpart (QImode, operands[0]);
10721 (define_insn "*setcc_qi"
10722 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10723 (match_operator:QI 1 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)]))]
10727 [(set_attr "type" "setcc")
10728 (set_attr "mode" "QI")])
10730 (define_insn "*setcc_qi_slp"
10731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10732 (match_operator:QI 1 "ix86_comparison_operator"
10733 [(reg FLAGS_REG) (const_int 0)]))]
10736 [(set_attr "type" "setcc")
10737 (set_attr "mode" "QI")])
10739 ;; In general it is not safe to assume too much about CCmode registers,
10740 ;; so simplify-rtx stops when it sees a second one. Under certain
10741 ;; conditions this is safe on x86, so help combine not create
10748 [(set (match_operand:QI 0 "nonimmediate_operand")
10749 (ne:QI (match_operator 1 "ix86_comparison_operator"
10750 [(reg FLAGS_REG) (const_int 0)])
10753 [(set (match_dup 0) (match_dup 1))]
10754 "PUT_MODE (operands[1], QImode);")
10757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10758 (ne:QI (match_operator 1 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)])
10762 [(set (match_dup 0) (match_dup 1))]
10763 "PUT_MODE (operands[1], QImode);")
10766 [(set (match_operand:QI 0 "nonimmediate_operand")
10767 (eq:QI (match_operator 1 "ix86_comparison_operator"
10768 [(reg FLAGS_REG) (const_int 0)])
10771 [(set (match_dup 0) (match_dup 1))]
10773 rtx new_op1 = copy_rtx (operands[1]);
10774 operands[1] = new_op1;
10775 PUT_MODE (new_op1, QImode);
10776 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10777 GET_MODE (XEXP (new_op1, 0))));
10779 /* Make sure that (a) the CCmode we have for the flags is strong
10780 enough for the reversed compare or (b) we have a valid FP compare. */
10781 if (! ix86_comparison_operator (new_op1, VOIDmode))
10786 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10787 (eq:QI (match_operator 1 "ix86_comparison_operator"
10788 [(reg FLAGS_REG) (const_int 0)])
10791 [(set (match_dup 0) (match_dup 1))]
10793 rtx new_op1 = copy_rtx (operands[1]);
10794 operands[1] = new_op1;
10795 PUT_MODE (new_op1, QImode);
10796 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10797 GET_MODE (XEXP (new_op1, 0))));
10799 /* Make sure that (a) the CCmode we have for the flags is strong
10800 enough for the reversed compare or (b) we have a valid FP compare. */
10801 if (! ix86_comparison_operator (new_op1, VOIDmode))
10805 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10806 ;; subsequent logical operations are used to imitate conditional moves.
10807 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10810 (define_insn "setcc_<mode>_sse"
10811 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10812 (match_operator:MODEF 3 "sse_comparison_operator"
10813 [(match_operand:MODEF 1 "register_operand" "0,x")
10814 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10815 "SSE_FLOAT_MODE_P (<MODE>mode)"
10817 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10818 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10819 [(set_attr "isa" "noavx,avx")
10820 (set_attr "type" "ssecmp")
10821 (set_attr "length_immediate" "1")
10822 (set_attr "prefix" "orig,vex")
10823 (set_attr "mode" "<MODE>")])
10825 ;; Basic conditional jump instructions.
10826 ;; We ignore the overflow flag for signed branch instructions.
10828 (define_insn "*jcc_1"
10830 (if_then_else (match_operator 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)])
10832 (label_ref (match_operand 0))
10836 [(set_attr "type" "ibr")
10837 (set_attr "modrm" "0")
10838 (set (attr "length")
10839 (if_then_else (and (ge (minus (match_dup 0) (pc))
10841 (lt (minus (match_dup 0) (pc))
10846 (define_insn "*jcc_2"
10848 (if_then_else (match_operator 1 "ix86_comparison_operator"
10849 [(reg FLAGS_REG) (const_int 0)])
10851 (label_ref (match_operand 0))))]
10854 [(set_attr "type" "ibr")
10855 (set_attr "modrm" "0")
10856 (set (attr "length")
10857 (if_then_else (and (ge (minus (match_dup 0) (pc))
10859 (lt (minus (match_dup 0) (pc))
10864 ;; In general it is not safe to assume too much about CCmode registers,
10865 ;; so simplify-rtx stops when it sees a second one. Under certain
10866 ;; conditions this is safe on x86, so help combine not create
10874 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10875 [(reg FLAGS_REG) (const_int 0)])
10877 (label_ref (match_operand 1))
10881 (if_then_else (match_dup 0)
10882 (label_ref (match_dup 1))
10884 "PUT_MODE (operands[0], VOIDmode);")
10888 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10889 [(reg FLAGS_REG) (const_int 0)])
10891 (label_ref (match_operand 1))
10895 (if_then_else (match_dup 0)
10896 (label_ref (match_dup 1))
10899 rtx new_op0 = copy_rtx (operands[0]);
10900 operands[0] = new_op0;
10901 PUT_MODE (new_op0, VOIDmode);
10902 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10903 GET_MODE (XEXP (new_op0, 0))));
10905 /* Make sure that (a) the CCmode we have for the flags is strong
10906 enough for the reversed compare or (b) we have a valid FP compare. */
10907 if (! ix86_comparison_operator (new_op0, VOIDmode))
10911 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10912 ;; pass generates from shift insn with QImode operand. Actually, the mode
10913 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10914 ;; appropriate modulo of the bit offset value.
10916 (define_insn_and_split "*jcc_bt<mode>"
10918 (if_then_else (match_operator 0 "bt_comparison_operator"
10919 [(zero_extract:SWI48
10920 (match_operand:SWI48 1 "register_operand" "r")
10923 (match_operand:QI 2 "register_operand" "r")))
10925 (label_ref (match_operand 3))
10927 (clobber (reg:CC FLAGS_REG))]
10928 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10931 [(set (reg:CCC FLAGS_REG)
10933 (zero_extract:SWI48
10939 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10940 (label_ref (match_dup 3))
10943 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10945 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10948 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10949 ;; zero extended to SImode.
10950 (define_insn_and_split "*jcc_bt<mode>_1"
10952 (if_then_else (match_operator 0 "bt_comparison_operator"
10953 [(zero_extract:SWI48
10954 (match_operand:SWI48 1 "register_operand" "r")
10956 (match_operand:SI 2 "register_operand" "r"))
10958 (label_ref (match_operand 3))
10960 (clobber (reg:CC FLAGS_REG))]
10961 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10964 [(set (reg:CCC FLAGS_REG)
10966 (zero_extract:SWI48
10972 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10973 (label_ref (match_dup 3))
10976 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10978 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10981 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10982 ;; also for DImode, this is what combine produces.
10983 (define_insn_and_split "*jcc_bt<mode>_mask"
10985 (if_then_else (match_operator 0 "bt_comparison_operator"
10986 [(zero_extract:SWI48
10987 (match_operand:SWI48 1 "register_operand" "r")
10990 (match_operand:SI 2 "register_operand" "r")
10991 (match_operand:SI 3 "const_int_operand" "n")))])
10992 (label_ref (match_operand 4))
10994 (clobber (reg:CC FLAGS_REG))]
10995 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10996 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10997 == GET_MODE_BITSIZE (<MODE>mode)-1"
11000 [(set (reg:CCC FLAGS_REG)
11002 (zero_extract:SWI48
11008 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11009 (label_ref (match_dup 4))
11012 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11014 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11017 (define_insn_and_split "*jcc_btsi_1"
11019 (if_then_else (match_operator 0 "bt_comparison_operator"
11022 (match_operand:SI 1 "register_operand" "r")
11023 (match_operand:QI 2 "register_operand" "r"))
11026 (label_ref (match_operand 3))
11028 (clobber (reg:CC FLAGS_REG))]
11029 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11032 [(set (reg:CCC FLAGS_REG)
11040 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11041 (label_ref (match_dup 3))
11044 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11046 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11049 ;; avoid useless masking of bit offset operand
11050 (define_insn_and_split "*jcc_btsi_mask_1"
11053 (match_operator 0 "bt_comparison_operator"
11056 (match_operand:SI 1 "register_operand" "r")
11059 (match_operand:SI 2 "register_operand" "r")
11060 (match_operand:SI 3 "const_int_operand" "n")) 0))
11063 (label_ref (match_operand 4))
11065 (clobber (reg:CC FLAGS_REG))]
11066 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11067 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11070 [(set (reg:CCC FLAGS_REG)
11078 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11079 (label_ref (match_dup 4))
11081 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11083 ;; Define combination compare-and-branch fp compare instructions to help
11086 (define_insn "*jcc<mode>_0_i387"
11088 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11089 [(match_operand:X87MODEF 1 "register_operand" "f")
11090 (match_operand:X87MODEF 2 "const0_operand")])
11091 (label_ref (match_operand 3))
11093 (clobber (reg:CCFP FPSR_REG))
11094 (clobber (reg:CCFP FLAGS_REG))
11095 (clobber (match_scratch:HI 4 "=a"))]
11096 "TARGET_80387 && !TARGET_CMOVE"
11099 (define_insn "*jcc<mode>_0_r_i387"
11101 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11102 [(match_operand:X87MODEF 1 "register_operand" "f")
11103 (match_operand:X87MODEF 2 "const0_operand")])
11105 (label_ref (match_operand 3))))
11106 (clobber (reg:CCFP FPSR_REG))
11107 (clobber (reg:CCFP FLAGS_REG))
11108 (clobber (match_scratch:HI 4 "=a"))]
11109 "TARGET_80387 && !TARGET_CMOVE"
11112 (define_insn "*jccxf_i387"
11114 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11115 [(match_operand:XF 1 "register_operand" "f")
11116 (match_operand:XF 2 "register_operand" "f")])
11117 (label_ref (match_operand 3))
11119 (clobber (reg:CCFP FPSR_REG))
11120 (clobber (reg:CCFP FLAGS_REG))
11121 (clobber (match_scratch:HI 4 "=a"))]
11122 "TARGET_80387 && !TARGET_CMOVE"
11125 (define_insn "*jccxf_r_i387"
11127 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11128 [(match_operand:XF 1 "register_operand" "f")
11129 (match_operand:XF 2 "register_operand" "f")])
11131 (label_ref (match_operand 3))))
11132 (clobber (reg:CCFP FPSR_REG))
11133 (clobber (reg:CCFP FLAGS_REG))
11134 (clobber (match_scratch:HI 4 "=a"))]
11135 "TARGET_80387 && !TARGET_CMOVE"
11138 (define_insn "*jcc<mode>_i387"
11140 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11141 [(match_operand:MODEF 1 "register_operand" "f")
11142 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11143 (label_ref (match_operand 3))
11145 (clobber (reg:CCFP FPSR_REG))
11146 (clobber (reg:CCFP FLAGS_REG))
11147 (clobber (match_scratch:HI 4 "=a"))]
11148 "TARGET_80387 && !TARGET_CMOVE"
11151 (define_insn "*jcc<mode>_r_i387"
11153 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11154 [(match_operand:MODEF 1 "register_operand" "f")
11155 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11157 (label_ref (match_operand 3))))
11158 (clobber (reg:CCFP FPSR_REG))
11159 (clobber (reg:CCFP FLAGS_REG))
11160 (clobber (match_scratch:HI 4 "=a"))]
11161 "TARGET_80387 && !TARGET_CMOVE"
11164 (define_insn "*jccu<mode>_i387"
11166 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11167 [(match_operand:X87MODEF 1 "register_operand" "f")
11168 (match_operand:X87MODEF 2 "register_operand" "f")])
11169 (label_ref (match_operand 3))
11171 (clobber (reg:CCFP FPSR_REG))
11172 (clobber (reg:CCFP FLAGS_REG))
11173 (clobber (match_scratch:HI 4 "=a"))]
11174 "TARGET_80387 && !TARGET_CMOVE"
11177 (define_insn "*jccu<mode>_r_i387"
11179 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11180 [(match_operand:X87MODEF 1 "register_operand" "f")
11181 (match_operand:X87MODEF 2 "register_operand" "f")])
11183 (label_ref (match_operand 3))))
11184 (clobber (reg:CCFP FPSR_REG))
11185 (clobber (reg:CCFP FLAGS_REG))
11186 (clobber (match_scratch:HI 4 "=a"))]
11187 "TARGET_80387 && !TARGET_CMOVE"
11192 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11193 [(match_operand:X87MODEF 1 "register_operand")
11194 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11196 (match_operand 4)))
11197 (clobber (reg:CCFP FPSR_REG))
11198 (clobber (reg:CCFP FLAGS_REG))]
11199 "TARGET_80387 && !TARGET_CMOVE
11200 && reload_completed"
11203 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11204 operands[3], operands[4], NULL_RTX);
11210 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11211 [(match_operand:X87MODEF 1 "register_operand")
11212 (match_operand:X87MODEF 2 "general_operand")])
11214 (match_operand 4)))
11215 (clobber (reg:CCFP FPSR_REG))
11216 (clobber (reg:CCFP FLAGS_REG))
11217 (clobber (match_scratch:HI 5))]
11218 "TARGET_80387 && !TARGET_CMOVE
11219 && reload_completed"
11222 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11223 operands[3], operands[4], operands[5]);
11227 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11228 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11229 ;; with a precedence over other operators and is always put in the first
11230 ;; place. Swap condition and operands to match ficom instruction.
11232 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11235 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11236 [(match_operator:X87MODEF 1 "float_operator"
11237 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11238 (match_operand:X87MODEF 3 "register_operand" "f")])
11239 (label_ref (match_operand 4))
11241 (clobber (reg:CCFP FPSR_REG))
11242 (clobber (reg:CCFP FLAGS_REG))
11243 (clobber (match_scratch:HI 5 "=a"))]
11244 "TARGET_80387 && !TARGET_CMOVE
11245 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11246 || optimize_function_for_size_p (cfun))"
11249 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11252 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11253 [(match_operator:X87MODEF 1 "float_operator"
11254 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11255 (match_operand:X87MODEF 3 "register_operand" "f")])
11257 (label_ref (match_operand 4))))
11258 (clobber (reg:CCFP FPSR_REG))
11259 (clobber (reg:CCFP FLAGS_REG))
11260 (clobber (match_scratch:HI 5 "=a"))]
11261 "TARGET_80387 && !TARGET_CMOVE
11262 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11263 || optimize_function_for_size_p (cfun))"
11269 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11270 [(match_operator:X87MODEF 1 "float_operator"
11271 [(match_operand:SWI24 2 "memory_operand")])
11272 (match_operand:X87MODEF 3 "register_operand")])
11274 (match_operand 5)))
11275 (clobber (reg:CCFP FPSR_REG))
11276 (clobber (reg:CCFP FLAGS_REG))
11277 (clobber (match_scratch:HI 6))]
11278 "TARGET_80387 && !TARGET_CMOVE
11279 && reload_completed"
11282 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11283 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11284 operands[4], operands[5], operands[6]);
11288 ;; Unconditional and other jump instructions
11290 (define_insn "jump"
11292 (label_ref (match_operand 0)))]
11295 [(set_attr "type" "ibr")
11296 (set (attr "length")
11297 (if_then_else (and (ge (minus (match_dup 0) (pc))
11299 (lt (minus (match_dup 0) (pc))
11303 (set_attr "modrm" "0")])
11305 (define_expand "indirect_jump"
11306 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11310 operands[0] = convert_memory_address (word_mode, operands[0]);
11313 (define_insn "*indirect_jump"
11314 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11317 [(set_attr "type" "ibr")
11318 (set_attr "length_immediate" "0")])
11320 (define_expand "tablejump"
11321 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11322 (use (label_ref (match_operand 1)))])]
11325 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11326 relative. Convert the relative address to an absolute address. */
11330 enum rtx_code code;
11332 /* We can't use @GOTOFF for text labels on VxWorks;
11333 see gotoff_operand. */
11334 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11338 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11340 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11344 op1 = pic_offset_table_rtx;
11349 op0 = pic_offset_table_rtx;
11353 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11358 operands[0] = convert_memory_address (word_mode, operands[0]);
11361 (define_insn "*tablejump_1"
11362 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11363 (use (label_ref (match_operand 1)))]
11366 [(set_attr "type" "ibr")
11367 (set_attr "length_immediate" "0")])
11369 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11372 [(set (reg FLAGS_REG) (match_operand 0))
11373 (set (match_operand:QI 1 "register_operand")
11374 (match_operator:QI 2 "ix86_comparison_operator"
11375 [(reg FLAGS_REG) (const_int 0)]))
11376 (set (match_operand 3 "q_regs_operand")
11377 (zero_extend (match_dup 1)))]
11378 "(peep2_reg_dead_p (3, operands[1])
11379 || operands_match_p (operands[1], operands[3]))
11380 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11381 [(set (match_dup 4) (match_dup 0))
11382 (set (strict_low_part (match_dup 5))
11385 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11386 operands[5] = gen_lowpart (QImode, operands[3]);
11387 ix86_expand_clear (operands[3]);
11391 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11392 (match_operand 4)])
11393 (set (match_operand:QI 1 "register_operand")
11394 (match_operator:QI 2 "ix86_comparison_operator"
11395 [(reg FLAGS_REG) (const_int 0)]))
11396 (set (match_operand 3 "q_regs_operand")
11397 (zero_extend (match_dup 1)))]
11398 "(peep2_reg_dead_p (3, operands[1])
11399 || operands_match_p (operands[1], operands[3]))
11400 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11401 [(parallel [(set (match_dup 5) (match_dup 0))
11403 (set (strict_low_part (match_dup 6))
11406 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11407 operands[6] = gen_lowpart (QImode, operands[3]);
11408 ix86_expand_clear (operands[3]);
11411 ;; Similar, but match zero extend with andsi3.
11414 [(set (reg FLAGS_REG) (match_operand 0))
11415 (set (match_operand:QI 1 "register_operand")
11416 (match_operator:QI 2 "ix86_comparison_operator"
11417 [(reg FLAGS_REG) (const_int 0)]))
11418 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11419 (and:SI (match_dup 3) (const_int 255)))
11420 (clobber (reg:CC FLAGS_REG))])]
11421 "REGNO (operands[1]) == REGNO (operands[3])
11422 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11423 [(set (match_dup 4) (match_dup 0))
11424 (set (strict_low_part (match_dup 5))
11427 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11428 operands[5] = gen_lowpart (QImode, operands[3]);
11429 ix86_expand_clear (operands[3]);
11433 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11434 (match_operand 4)])
11435 (set (match_operand:QI 1 "register_operand")
11436 (match_operator:QI 2 "ix86_comparison_operator"
11437 [(reg FLAGS_REG) (const_int 0)]))
11438 (parallel [(set (match_operand 3 "q_regs_operand")
11439 (zero_extend (match_dup 1)))
11440 (clobber (reg:CC FLAGS_REG))])]
11441 "(peep2_reg_dead_p (3, operands[1])
11442 || operands_match_p (operands[1], operands[3]))
11443 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11444 [(parallel [(set (match_dup 5) (match_dup 0))
11446 (set (strict_low_part (match_dup 6))
11449 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11450 operands[6] = gen_lowpart (QImode, operands[3]);
11451 ix86_expand_clear (operands[3]);
11454 ;; Call instructions.
11456 ;; The predicates normally associated with named expanders are not properly
11457 ;; checked for calls. This is a bug in the generic code, but it isn't that
11458 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11460 ;; P6 processors will jump to the address after the decrement when %esp
11461 ;; is used as a call operand, so they will execute return address as a code.
11462 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11464 ;; Register constraint for call instruction.
11465 (define_mode_attr c [(SI "l") (DI "r")])
11467 ;; Call subroutine returning no value.
11469 (define_expand "call"
11470 [(call (match_operand:QI 0)
11472 (use (match_operand 2))]
11475 ix86_expand_call (NULL, operands[0], operands[1],
11476 operands[2], NULL, false);
11480 (define_expand "sibcall"
11481 [(call (match_operand:QI 0)
11483 (use (match_operand 2))]
11486 ix86_expand_call (NULL, operands[0], operands[1],
11487 operands[2], NULL, true);
11491 (define_insn "*call"
11492 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11493 (match_operand 1))]
11494 "!SIBLING_CALL_P (insn)"
11495 "* return ix86_output_call_insn (insn, operands[0]);"
11496 [(set_attr "type" "call")])
11498 (define_insn "*sibcall"
11499 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11500 (match_operand 1))]
11501 "SIBLING_CALL_P (insn)"
11502 "* return ix86_output_call_insn (insn, operands[0]);"
11503 [(set_attr "type" "call")])
11505 (define_insn "*sibcall_memory"
11506 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11508 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11510 "* return ix86_output_call_insn (insn, operands[0]);"
11511 [(set_attr "type" "call")])
11514 [(set (match_operand:W 0 "register_operand")
11515 (match_operand:W 1 "memory_operand"))
11516 (call (mem:QI (match_dup 0))
11517 (match_operand 3))]
11518 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11519 && peep2_reg_dead_p (2, operands[0])"
11520 [(parallel [(call (mem:QI (match_dup 1))
11522 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11525 [(set (match_operand:W 0 "register_operand")
11526 (match_operand:W 1 "memory_operand"))
11527 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11528 (call (mem:QI (match_dup 0))
11529 (match_operand 3))]
11530 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11531 && peep2_reg_dead_p (3, operands[0])"
11532 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11533 (parallel [(call (mem:QI (match_dup 1))
11535 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11537 (define_expand "call_pop"
11538 [(parallel [(call (match_operand:QI 0)
11539 (match_operand:SI 1))
11540 (set (reg:SI SP_REG)
11541 (plus:SI (reg:SI SP_REG)
11542 (match_operand:SI 3)))])]
11545 ix86_expand_call (NULL, operands[0], operands[1],
11546 operands[2], operands[3], false);
11550 (define_insn "*call_pop"
11551 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11553 (set (reg:SI SP_REG)
11554 (plus:SI (reg:SI SP_REG)
11555 (match_operand:SI 2 "immediate_operand" "i")))]
11556 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11557 "* return ix86_output_call_insn (insn, operands[0]);"
11558 [(set_attr "type" "call")])
11560 (define_insn "*sibcall_pop"
11561 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11563 (set (reg:SI SP_REG)
11564 (plus:SI (reg:SI SP_REG)
11565 (match_operand:SI 2 "immediate_operand" "i")))]
11566 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11567 "* return ix86_output_call_insn (insn, operands[0]);"
11568 [(set_attr "type" "call")])
11570 (define_insn "*sibcall_pop_memory"
11571 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11573 (set (reg:SI SP_REG)
11574 (plus:SI (reg:SI SP_REG)
11575 (match_operand:SI 2 "immediate_operand" "i")))
11576 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11578 "* return ix86_output_call_insn (insn, operands[0]);"
11579 [(set_attr "type" "call")])
11582 [(set (match_operand:SI 0 "register_operand")
11583 (match_operand:SI 1 "memory_operand"))
11584 (parallel [(call (mem:QI (match_dup 0))
11586 (set (reg:SI SP_REG)
11587 (plus:SI (reg:SI SP_REG)
11588 (match_operand:SI 4 "immediate_operand")))])]
11589 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11590 && peep2_reg_dead_p (2, operands[0])"
11591 [(parallel [(call (mem:QI (match_dup 1))
11593 (set (reg:SI SP_REG)
11594 (plus:SI (reg:SI SP_REG)
11596 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11599 [(set (match_operand:SI 0 "register_operand")
11600 (match_operand:SI 1 "memory_operand"))
11601 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11602 (parallel [(call (mem:QI (match_dup 0))
11604 (set (reg:SI SP_REG)
11605 (plus:SI (reg:SI SP_REG)
11606 (match_operand:SI 4 "immediate_operand")))])]
11607 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11608 && peep2_reg_dead_p (3, operands[0])"
11609 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11610 (parallel [(call (mem:QI (match_dup 1))
11612 (set (reg:SI SP_REG)
11613 (plus:SI (reg:SI SP_REG)
11615 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11617 ;; Combining simple memory jump instruction
11620 [(set (match_operand:W 0 "register_operand")
11621 (match_operand:W 1 "memory_operand"))
11622 (set (pc) (match_dup 0))]
11623 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11624 [(set (pc) (match_dup 1))])
11626 ;; Call subroutine, returning value in operand 0
11628 (define_expand "call_value"
11629 [(set (match_operand 0)
11630 (call (match_operand:QI 1)
11631 (match_operand 2)))
11632 (use (match_operand 3))]
11635 ix86_expand_call (operands[0], operands[1], operands[2],
11636 operands[3], NULL, false);
11640 (define_expand "sibcall_value"
11641 [(set (match_operand 0)
11642 (call (match_operand:QI 1)
11643 (match_operand 2)))
11644 (use (match_operand 3))]
11647 ix86_expand_call (operands[0], operands[1], operands[2],
11648 operands[3], NULL, true);
11652 (define_insn "*call_value"
11653 [(set (match_operand 0)
11654 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11655 (match_operand 2)))]
11656 "!SIBLING_CALL_P (insn)"
11657 "* return ix86_output_call_insn (insn, operands[1]);"
11658 [(set_attr "type" "callv")])
11660 (define_insn "*sibcall_value"
11661 [(set (match_operand 0)
11662 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11663 (match_operand 2)))]
11664 "SIBLING_CALL_P (insn)"
11665 "* return ix86_output_call_insn (insn, operands[1]);"
11666 [(set_attr "type" "callv")])
11668 (define_insn "*sibcall_value_memory"
11669 [(set (match_operand 0)
11670 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11671 (match_operand 2)))
11672 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11674 "* return ix86_output_call_insn (insn, operands[1]);"
11675 [(set_attr "type" "callv")])
11678 [(set (match_operand:W 0 "register_operand")
11679 (match_operand:W 1 "memory_operand"))
11680 (set (match_operand 2)
11681 (call (mem:QI (match_dup 0))
11682 (match_operand 3)))]
11683 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11684 && peep2_reg_dead_p (2, operands[0])"
11685 [(parallel [(set (match_dup 2)
11686 (call (mem:QI (match_dup 1))
11688 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11691 [(set (match_operand:W 0 "register_operand")
11692 (match_operand:W 1 "memory_operand"))
11693 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11694 (set (match_operand 2)
11695 (call (mem:QI (match_dup 0))
11696 (match_operand 3)))]
11697 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11698 && peep2_reg_dead_p (3, operands[0])"
11699 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11700 (parallel [(set (match_dup 2)
11701 (call (mem:QI (match_dup 1))
11703 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11705 (define_expand "call_value_pop"
11706 [(parallel [(set (match_operand 0)
11707 (call (match_operand:QI 1)
11708 (match_operand:SI 2)))
11709 (set (reg:SI SP_REG)
11710 (plus:SI (reg:SI SP_REG)
11711 (match_operand:SI 4)))])]
11714 ix86_expand_call (operands[0], operands[1], operands[2],
11715 operands[3], operands[4], false);
11719 (define_insn "*call_value_pop"
11720 [(set (match_operand 0)
11721 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11722 (match_operand 2)))
11723 (set (reg:SI SP_REG)
11724 (plus:SI (reg:SI SP_REG)
11725 (match_operand:SI 3 "immediate_operand" "i")))]
11726 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11727 "* return ix86_output_call_insn (insn, operands[1]);"
11728 [(set_attr "type" "callv")])
11730 (define_insn "*sibcall_value_pop"
11731 [(set (match_operand 0)
11732 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11733 (match_operand 2)))
11734 (set (reg:SI SP_REG)
11735 (plus:SI (reg:SI SP_REG)
11736 (match_operand:SI 3 "immediate_operand" "i")))]
11737 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11738 "* return ix86_output_call_insn (insn, operands[1]);"
11739 [(set_attr "type" "callv")])
11741 (define_insn "*sibcall_value_pop_memory"
11742 [(set (match_operand 0)
11743 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11744 (match_operand 2)))
11745 (set (reg:SI SP_REG)
11746 (plus:SI (reg:SI SP_REG)
11747 (match_operand:SI 3 "immediate_operand" "i")))
11748 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11750 "* return ix86_output_call_insn (insn, operands[1]);"
11751 [(set_attr "type" "callv")])
11754 [(set (match_operand:SI 0 "register_operand")
11755 (match_operand:SI 1 "memory_operand"))
11756 (parallel [(set (match_operand 2)
11757 (call (mem:QI (match_dup 0))
11758 (match_operand 3)))
11759 (set (reg:SI SP_REG)
11760 (plus:SI (reg:SI SP_REG)
11761 (match_operand:SI 4 "immediate_operand")))])]
11762 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11763 && peep2_reg_dead_p (2, operands[0])"
11764 [(parallel [(set (match_dup 2)
11765 (call (mem:QI (match_dup 1))
11767 (set (reg:SI SP_REG)
11768 (plus:SI (reg:SI SP_REG)
11770 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11773 [(set (match_operand:SI 0 "register_operand")
11774 (match_operand:SI 1 "memory_operand"))
11775 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11776 (parallel [(set (match_operand 2)
11777 (call (mem:QI (match_dup 0))
11778 (match_operand 3)))
11779 (set (reg:SI SP_REG)
11780 (plus:SI (reg:SI SP_REG)
11781 (match_operand:SI 4 "immediate_operand")))])]
11782 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11783 && peep2_reg_dead_p (3, operands[0])"
11784 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11785 (parallel [(set (match_dup 2)
11786 (call (mem:QI (match_dup 1))
11788 (set (reg:SI SP_REG)
11789 (plus:SI (reg:SI SP_REG)
11791 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11793 ;; Call subroutine returning any type.
11795 (define_expand "untyped_call"
11796 [(parallel [(call (match_operand 0)
11799 (match_operand 2)])]
11804 /* In order to give reg-stack an easier job in validating two
11805 coprocessor registers as containing a possible return value,
11806 simply pretend the untyped call returns a complex long double
11809 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11810 and should have the default ABI. */
11812 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11813 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11814 operands[0], const0_rtx,
11815 GEN_INT ((TARGET_64BIT
11816 ? (ix86_abi == SYSV_ABI
11817 ? X86_64_SSE_REGPARM_MAX
11818 : X86_64_MS_SSE_REGPARM_MAX)
11819 : X86_32_SSE_REGPARM_MAX)
11823 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11825 rtx set = XVECEXP (operands[2], 0, i);
11826 emit_move_insn (SET_DEST (set), SET_SRC (set));
11829 /* The optimizer does not know that the call sets the function value
11830 registers we stored in the result block. We avoid problems by
11831 claiming that all hard registers are used and clobbered at this
11833 emit_insn (gen_blockage ());
11838 ;; Prologue and epilogue instructions
11840 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11841 ;; all of memory. This blocks insns from being moved across this point.
11843 (define_insn "blockage"
11844 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11847 [(set_attr "length" "0")])
11849 ;; Do not schedule instructions accessing memory across this point.
11851 (define_expand "memory_blockage"
11852 [(set (match_dup 0)
11853 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11856 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11857 MEM_VOLATILE_P (operands[0]) = 1;
11860 (define_insn "*memory_blockage"
11861 [(set (match_operand:BLK 0)
11862 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11865 [(set_attr "length" "0")])
11867 ;; As USE insns aren't meaningful after reload, this is used instead
11868 ;; to prevent deleting instructions setting registers for PIC code
11869 (define_insn "prologue_use"
11870 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11873 [(set_attr "length" "0")])
11875 ;; Insn emitted into the body of a function to return from a function.
11876 ;; This is only done if the function's epilogue is known to be simple.
11877 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11879 (define_expand "return"
11881 "ix86_can_use_return_insn_p ()"
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 ;; We need to disable this for TARGET_SEH, as otherwise
11892 ;; shrink-wrapped prologue gets enabled too. This might exceed
11893 ;; the maximum size of prologue in unwind information.
11895 (define_expand "simple_return"
11899 if (crtl->args.pops_args)
11901 rtx popc = GEN_INT (crtl->args.pops_args);
11902 emit_jump_insn (gen_simple_return_pop_internal (popc));
11907 (define_insn "simple_return_internal"
11911 [(set_attr "length" "1")
11912 (set_attr "atom_unit" "jeu")
11913 (set_attr "length_immediate" "0")
11914 (set_attr "modrm" "0")])
11916 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11917 ;; instruction Athlon and K8 have.
11919 (define_insn "simple_return_internal_long"
11921 (unspec [(const_int 0)] UNSPEC_REP)]
11924 [(set_attr "length" "2")
11925 (set_attr "atom_unit" "jeu")
11926 (set_attr "length_immediate" "0")
11927 (set_attr "prefix_rep" "1")
11928 (set_attr "modrm" "0")])
11930 (define_insn "simple_return_pop_internal"
11932 (use (match_operand:SI 0 "const_int_operand"))]
11935 [(set_attr "length" "3")
11936 (set_attr "atom_unit" "jeu")
11937 (set_attr "length_immediate" "2")
11938 (set_attr "modrm" "0")])
11940 (define_insn "simple_return_indirect_internal"
11942 (use (match_operand:SI 0 "register_operand" "r"))]
11945 [(set_attr "type" "ibr")
11946 (set_attr "length_immediate" "0")])
11952 [(set_attr "length" "1")
11953 (set_attr "length_immediate" "0")
11954 (set_attr "modrm" "0")])
11956 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11957 (define_insn "nops"
11958 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11962 int num = INTVAL (operands[0]);
11964 gcc_assert (IN_RANGE (num, 1, 8));
11967 fputs ("\tnop\n", asm_out_file);
11971 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11972 (set_attr "length_immediate" "0")
11973 (set_attr "modrm" "0")])
11975 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11976 ;; branch prediction penalty for the third jump in a 16-byte
11980 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11983 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11984 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11986 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11987 The align insn is used to avoid 3 jump instructions in the row to improve
11988 branch prediction and the benefits hardly outweigh the cost of extra 8
11989 nops on the average inserted by full alignment pseudo operation. */
11993 [(set_attr "length" "16")])
11995 (define_expand "prologue"
11998 "ix86_expand_prologue (); DONE;")
12000 (define_insn "set_got"
12001 [(set (match_operand:SI 0 "register_operand" "=r")
12002 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12003 (clobber (reg:CC FLAGS_REG))]
12005 "* return output_set_got (operands[0], NULL_RTX);"
12006 [(set_attr "type" "multi")
12007 (set_attr "length" "12")])
12009 (define_insn "set_got_labelled"
12010 [(set (match_operand:SI 0 "register_operand" "=r")
12011 (unspec:SI [(label_ref (match_operand 1))]
12013 (clobber (reg:CC FLAGS_REG))]
12015 "* return output_set_got (operands[0], operands[1]);"
12016 [(set_attr "type" "multi")
12017 (set_attr "length" "12")])
12019 (define_insn "set_got_rex64"
12020 [(set (match_operand:DI 0 "register_operand" "=r")
12021 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12023 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12024 [(set_attr "type" "lea")
12025 (set_attr "length_address" "4")
12026 (set_attr "mode" "DI")])
12028 (define_insn "set_rip_rex64"
12029 [(set (match_operand:DI 0 "register_operand" "=r")
12030 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12032 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12033 [(set_attr "type" "lea")
12034 (set_attr "length_address" "4")
12035 (set_attr "mode" "DI")])
12037 (define_insn "set_got_offset_rex64"
12038 [(set (match_operand:DI 0 "register_operand" "=r")
12040 [(label_ref (match_operand 1))]
12041 UNSPEC_SET_GOT_OFFSET))]
12043 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12044 [(set_attr "type" "imov")
12045 (set_attr "length_immediate" "0")
12046 (set_attr "length_address" "8")
12047 (set_attr "mode" "DI")])
12049 (define_expand "epilogue"
12052 "ix86_expand_epilogue (1); DONE;")
12054 (define_expand "sibcall_epilogue"
12057 "ix86_expand_epilogue (0); DONE;")
12059 (define_expand "eh_return"
12060 [(use (match_operand 0 "register_operand"))]
12063 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12065 /* Tricky bit: we write the address of the handler to which we will
12066 be returning into someone else's stack frame, one word below the
12067 stack address we wish to restore. */
12068 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12069 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12070 tmp = gen_rtx_MEM (Pmode, tmp);
12071 emit_move_insn (tmp, ra);
12073 emit_jump_insn (gen_eh_return_internal ());
12078 (define_insn_and_split "eh_return_internal"
12082 "epilogue_completed"
12084 "ix86_expand_epilogue (2); DONE;")
12086 (define_insn "leave"
12087 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12088 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12089 (clobber (mem:BLK (scratch)))]
12092 [(set_attr "type" "leave")])
12094 (define_insn "leave_rex64"
12095 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12096 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12097 (clobber (mem:BLK (scratch)))]
12100 [(set_attr "type" "leave")])
12102 ;; Handle -fsplit-stack.
12104 (define_expand "split_stack_prologue"
12108 ix86_expand_split_stack_prologue ();
12112 ;; In order to support the call/return predictor, we use a return
12113 ;; instruction which the middle-end doesn't see.
12114 (define_insn "split_stack_return"
12115 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12116 UNSPECV_SPLIT_STACK_RETURN)]
12119 if (operands[0] == const0_rtx)
12124 [(set_attr "atom_unit" "jeu")
12125 (set_attr "modrm" "0")
12126 (set (attr "length")
12127 (if_then_else (match_operand:SI 0 "const0_operand")
12130 (set (attr "length_immediate")
12131 (if_then_else (match_operand:SI 0 "const0_operand")
12135 ;; If there are operand 0 bytes available on the stack, jump to
12138 (define_expand "split_stack_space_check"
12139 [(set (pc) (if_then_else
12140 (ltu (minus (reg SP_REG)
12141 (match_operand 0 "register_operand"))
12142 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12143 (label_ref (match_operand 1))
12147 rtx reg, size, limit;
12149 reg = gen_reg_rtx (Pmode);
12150 size = force_reg (Pmode, operands[0]);
12151 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12152 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12153 UNSPEC_STACK_CHECK);
12154 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12155 ix86_expand_branch (GEU, reg, limit, operands[1]);
12160 ;; Bit manipulation instructions.
12162 (define_expand "ffs<mode>2"
12163 [(set (match_dup 2) (const_int -1))
12164 (parallel [(set (match_dup 3) (match_dup 4))
12165 (set (match_operand:SWI48 0 "register_operand")
12167 (match_operand:SWI48 1 "nonimmediate_operand")))])
12168 (set (match_dup 0) (if_then_else:SWI48
12169 (eq (match_dup 3) (const_int 0))
12172 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12173 (clobber (reg:CC FLAGS_REG))])]
12176 machine_mode flags_mode;
12178 if (<MODE>mode == SImode && !TARGET_CMOVE)
12180 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12185 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12187 operands[2] = gen_reg_rtx (<MODE>mode);
12188 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12189 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12192 (define_insn_and_split "ffssi2_no_cmove"
12193 [(set (match_operand:SI 0 "register_operand" "=r")
12194 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12195 (clobber (match_scratch:SI 2 "=&q"))
12196 (clobber (reg:CC FLAGS_REG))]
12199 "&& reload_completed"
12200 [(parallel [(set (match_dup 4) (match_dup 5))
12201 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12202 (set (strict_low_part (match_dup 3))
12203 (eq:QI (match_dup 4) (const_int 0)))
12204 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12205 (clobber (reg:CC FLAGS_REG))])
12206 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12207 (clobber (reg:CC FLAGS_REG))])
12208 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12209 (clobber (reg:CC FLAGS_REG))])]
12211 machine_mode flags_mode
12212 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12214 operands[3] = gen_lowpart (QImode, operands[2]);
12215 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12216 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12218 ix86_expand_clear (operands[2]);
12221 (define_insn "*tzcnt<mode>_1"
12222 [(set (reg:CCC FLAGS_REG)
12223 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12225 (set (match_operand:SWI48 0 "register_operand" "=r")
12226 (ctz:SWI48 (match_dup 1)))]
12227 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12228 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12229 [(set_attr "type" "alu1")
12230 (set_attr "prefix_0f" "1")
12231 (set_attr "prefix_rep" "1")
12232 (set_attr "btver2_decode" "double")
12233 (set_attr "mode" "<MODE>")])
12235 (define_insn "*bsf<mode>_1"
12236 [(set (reg:CCZ FLAGS_REG)
12237 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12239 (set (match_operand:SWI48 0 "register_operand" "=r")
12240 (ctz:SWI48 (match_dup 1)))]
12242 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12243 [(set_attr "type" "alu1")
12244 (set_attr "prefix_0f" "1")
12245 (set_attr "btver2_decode" "double")
12246 (set_attr "mode" "<MODE>")])
12248 (define_expand "ctz<mode>2"
12250 [(set (match_operand:SWI248 0 "register_operand")
12252 (match_operand:SWI248 1 "nonimmediate_operand")))
12253 (clobber (reg:CC FLAGS_REG))])])
12255 ; False dependency happens when destination is only updated by tzcnt,
12256 ; lzcnt or popcnt. There is no false dependency when destination is
12257 ; also used in source.
12258 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12259 [(set (match_operand:SWI48 0 "register_operand" "=r")
12261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "(TARGET_BMI || TARGET_GENERIC)
12264 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12266 "&& reload_completed"
12268 [(set (match_dup 0)
12269 (ctz:SWI48 (match_dup 1)))
12270 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12271 (clobber (reg:CC FLAGS_REG))])]
12273 if (!reg_mentioned_p (operands[0], operands[1]))
12274 ix86_expand_clear (operands[0]);
12277 (define_insn "*ctz<mode>2_falsedep"
12278 [(set (match_operand:SWI48 0 "register_operand" "=r")
12280 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12281 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12282 UNSPEC_INSN_FALSE_DEP)
12283 (clobber (reg:CC FLAGS_REG))]
12287 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12288 else if (TARGET_GENERIC)
12289 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12290 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12292 gcc_unreachable ();
12294 [(set_attr "type" "alu1")
12295 (set_attr "prefix_0f" "1")
12296 (set_attr "prefix_rep" "1")
12297 (set_attr "mode" "<MODE>")])
12299 (define_insn "*ctz<mode>2"
12300 [(set (match_operand:SWI248 0 "register_operand" "=r")
12301 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12302 (clobber (reg:CC FLAGS_REG))]
12306 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12307 else if (optimize_function_for_size_p (cfun))
12309 else if (TARGET_GENERIC)
12310 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12311 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12313 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12315 [(set_attr "type" "alu1")
12316 (set_attr "prefix_0f" "1")
12317 (set (attr "prefix_rep")
12319 (ior (match_test "TARGET_BMI")
12320 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12321 (match_test "TARGET_GENERIC")))
12323 (const_string "0")))
12324 (set_attr "mode" "<MODE>")])
12326 (define_expand "clz<mode>2"
12328 [(set (match_operand:SWI248 0 "register_operand")
12331 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12332 (clobber (reg:CC FLAGS_REG))])
12334 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12335 (clobber (reg:CC FLAGS_REG))])]
12340 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12343 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12346 (define_expand "clz<mode>2_lzcnt"
12348 [(set (match_operand:SWI248 0 "register_operand")
12350 (match_operand:SWI248 1 "nonimmediate_operand")))
12351 (clobber (reg:CC FLAGS_REG))])]
12354 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12355 [(set (match_operand:SWI48 0 "register_operand" "=r")
12357 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12358 (clobber (reg:CC FLAGS_REG))]
12360 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12362 "&& reload_completed"
12364 [(set (match_dup 0)
12365 (clz:SWI48 (match_dup 1)))
12366 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12367 (clobber (reg:CC FLAGS_REG))])]
12369 if (!reg_mentioned_p (operands[0], operands[1]))
12370 ix86_expand_clear (operands[0]);
12373 (define_insn "*clz<mode>2_lzcnt_falsedep"
12374 [(set (match_operand:SWI48 0 "register_operand" "=r")
12376 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12377 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12378 UNSPEC_INSN_FALSE_DEP)
12379 (clobber (reg:CC FLAGS_REG))]
12381 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12382 [(set_attr "prefix_rep" "1")
12383 (set_attr "type" "bitmanip")
12384 (set_attr "mode" "<MODE>")])
12386 (define_insn "*clz<mode>2_lzcnt"
12387 [(set (match_operand:SWI248 0 "register_operand" "=r")
12388 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12389 (clobber (reg:CC FLAGS_REG))]
12391 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12392 [(set_attr "prefix_rep" "1")
12393 (set_attr "type" "bitmanip")
12394 (set_attr "mode" "<MODE>")])
12396 ;; BMI instructions.
12397 (define_insn "*bmi_andn_<mode>"
12398 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12401 (match_operand:SWI48 1 "register_operand" "r,r"))
12402 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12403 (clobber (reg:CC FLAGS_REG))]
12405 "andn\t{%2, %1, %0|%0, %1, %2}"
12406 [(set_attr "type" "bitmanip")
12407 (set_attr "btver2_decode" "direct, double")
12408 (set_attr "mode" "<MODE>")])
12410 (define_insn "bmi_bextr_<mode>"
12411 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12412 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12413 (match_operand:SWI48 2 "register_operand" "r,r")]
12415 (clobber (reg:CC FLAGS_REG))]
12417 "bextr\t{%2, %1, %0|%0, %1, %2}"
12418 [(set_attr "type" "bitmanip")
12419 (set_attr "btver2_decode" "direct, double")
12420 (set_attr "mode" "<MODE>")])
12422 (define_insn "*bmi_blsi_<mode>"
12423 [(set (match_operand:SWI48 0 "register_operand" "=r")
12426 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12428 (clobber (reg:CC FLAGS_REG))]
12430 "blsi\t{%1, %0|%0, %1}"
12431 [(set_attr "type" "bitmanip")
12432 (set_attr "btver2_decode" "double")
12433 (set_attr "mode" "<MODE>")])
12435 (define_insn "*bmi_blsmsk_<mode>"
12436 [(set (match_operand:SWI48 0 "register_operand" "=r")
12439 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12442 (clobber (reg:CC FLAGS_REG))]
12444 "blsmsk\t{%1, %0|%0, %1}"
12445 [(set_attr "type" "bitmanip")
12446 (set_attr "btver2_decode" "double")
12447 (set_attr "mode" "<MODE>")])
12449 (define_insn "*bmi_blsr_<mode>"
12450 [(set (match_operand:SWI48 0 "register_operand" "=r")
12453 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12456 (clobber (reg:CC FLAGS_REG))]
12458 "blsr\t{%1, %0|%0, %1}"
12459 [(set_attr "type" "bitmanip")
12460 (set_attr "btver2_decode" "double")
12461 (set_attr "mode" "<MODE>")])
12463 ;; BMI2 instructions.
12464 (define_insn "bmi2_bzhi_<mode>3"
12465 [(set (match_operand:SWI48 0 "register_operand" "=r")
12466 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12467 (match_operand:SWI48 2 "register_operand" "r"))
12468 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12469 (clobber (reg:CC FLAGS_REG))]
12471 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12472 [(set_attr "type" "bitmanip")
12473 (set_attr "prefix" "vex")
12474 (set_attr "mode" "<MODE>")])
12476 (define_insn "bmi2_pdep_<mode>3"
12477 [(set (match_operand:SWI48 0 "register_operand" "=r")
12478 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12479 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12482 "pdep\t{%2, %1, %0|%0, %1, %2}"
12483 [(set_attr "type" "bitmanip")
12484 (set_attr "prefix" "vex")
12485 (set_attr "mode" "<MODE>")])
12487 (define_insn "bmi2_pext_<mode>3"
12488 [(set (match_operand:SWI48 0 "register_operand" "=r")
12489 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12490 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12493 "pext\t{%2, %1, %0|%0, %1, %2}"
12494 [(set_attr "type" "bitmanip")
12495 (set_attr "prefix" "vex")
12496 (set_attr "mode" "<MODE>")])
12498 ;; TBM instructions.
12499 (define_insn "tbm_bextri_<mode>"
12500 [(set (match_operand:SWI48 0 "register_operand" "=r")
12501 (zero_extract:SWI48
12502 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12503 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12504 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12505 (clobber (reg:CC FLAGS_REG))]
12508 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12509 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12511 [(set_attr "type" "bitmanip")
12512 (set_attr "mode" "<MODE>")])
12514 (define_insn "*tbm_blcfill_<mode>"
12515 [(set (match_operand:SWI48 0 "register_operand" "=r")
12518 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12521 (clobber (reg:CC FLAGS_REG))]
12523 "blcfill\t{%1, %0|%0, %1}"
12524 [(set_attr "type" "bitmanip")
12525 (set_attr "mode" "<MODE>")])
12527 (define_insn "*tbm_blci_<mode>"
12528 [(set (match_operand:SWI48 0 "register_operand" "=r")
12532 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12535 (clobber (reg:CC FLAGS_REG))]
12537 "blci\t{%1, %0|%0, %1}"
12538 [(set_attr "type" "bitmanip")
12539 (set_attr "mode" "<MODE>")])
12541 (define_insn "*tbm_blcic_<mode>"
12542 [(set (match_operand:SWI48 0 "register_operand" "=r")
12545 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12549 (clobber (reg:CC FLAGS_REG))]
12551 "blcic\t{%1, %0|%0, %1}"
12552 [(set_attr "type" "bitmanip")
12553 (set_attr "mode" "<MODE>")])
12555 (define_insn "*tbm_blcmsk_<mode>"
12556 [(set (match_operand:SWI48 0 "register_operand" "=r")
12559 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12562 (clobber (reg:CC FLAGS_REG))]
12564 "blcmsk\t{%1, %0|%0, %1}"
12565 [(set_attr "type" "bitmanip")
12566 (set_attr "mode" "<MODE>")])
12568 (define_insn "*tbm_blcs_<mode>"
12569 [(set (match_operand:SWI48 0 "register_operand" "=r")
12572 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12575 (clobber (reg:CC FLAGS_REG))]
12577 "blcs\t{%1, %0|%0, %1}"
12578 [(set_attr "type" "bitmanip")
12579 (set_attr "mode" "<MODE>")])
12581 (define_insn "*tbm_blsfill_<mode>"
12582 [(set (match_operand:SWI48 0 "register_operand" "=r")
12585 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12588 (clobber (reg:CC FLAGS_REG))]
12590 "blsfill\t{%1, %0|%0, %1}"
12591 [(set_attr "type" "bitmanip")
12592 (set_attr "mode" "<MODE>")])
12594 (define_insn "*tbm_blsic_<mode>"
12595 [(set (match_operand:SWI48 0 "register_operand" "=r")
12598 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12602 (clobber (reg:CC FLAGS_REG))]
12604 "blsic\t{%1, %0|%0, %1}"
12605 [(set_attr "type" "bitmanip")
12606 (set_attr "mode" "<MODE>")])
12608 (define_insn "*tbm_t1mskc_<mode>"
12609 [(set (match_operand:SWI48 0 "register_operand" "=r")
12612 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12616 (clobber (reg:CC FLAGS_REG))]
12618 "t1mskc\t{%1, %0|%0, %1}"
12619 [(set_attr "type" "bitmanip")
12620 (set_attr "mode" "<MODE>")])
12622 (define_insn "*tbm_tzmsk_<mode>"
12623 [(set (match_operand:SWI48 0 "register_operand" "=r")
12626 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12630 (clobber (reg:CC FLAGS_REG))]
12632 "tzmsk\t{%1, %0|%0, %1}"
12633 [(set_attr "type" "bitmanip")
12634 (set_attr "mode" "<MODE>")])
12636 (define_insn "bsr_rex64"
12637 [(set (match_operand:DI 0 "register_operand" "=r")
12638 (minus:DI (const_int 63)
12639 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12640 (clobber (reg:CC FLAGS_REG))]
12642 "bsr{q}\t{%1, %0|%0, %1}"
12643 [(set_attr "type" "alu1")
12644 (set_attr "prefix_0f" "1")
12645 (set_attr "mode" "DI")])
12648 [(set (match_operand:SI 0 "register_operand" "=r")
12649 (minus:SI (const_int 31)
12650 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12651 (clobber (reg:CC FLAGS_REG))]
12653 "bsr{l}\t{%1, %0|%0, %1}"
12654 [(set_attr "type" "alu1")
12655 (set_attr "prefix_0f" "1")
12656 (set_attr "mode" "SI")])
12658 (define_insn "*bsrhi"
12659 [(set (match_operand:HI 0 "register_operand" "=r")
12660 (minus:HI (const_int 15)
12661 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12662 (clobber (reg:CC FLAGS_REG))]
12664 "bsr{w}\t{%1, %0|%0, %1}"
12665 [(set_attr "type" "alu1")
12666 (set_attr "prefix_0f" "1")
12667 (set_attr "mode" "HI")])
12669 (define_expand "popcount<mode>2"
12671 [(set (match_operand:SWI248 0 "register_operand")
12673 (match_operand:SWI248 1 "nonimmediate_operand")))
12674 (clobber (reg:CC FLAGS_REG))])]
12677 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12678 [(set (match_operand:SWI48 0 "register_operand" "=r")
12680 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12681 (clobber (reg:CC FLAGS_REG))]
12683 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12685 "&& reload_completed"
12687 [(set (match_dup 0)
12688 (popcount:SWI48 (match_dup 1)))
12689 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12690 (clobber (reg:CC FLAGS_REG))])]
12692 if (!reg_mentioned_p (operands[0], operands[1]))
12693 ix86_expand_clear (operands[0]);
12696 (define_insn "*popcount<mode>2_falsedep"
12697 [(set (match_operand:SWI48 0 "register_operand" "=r")
12699 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12700 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12701 UNSPEC_INSN_FALSE_DEP)
12702 (clobber (reg:CC FLAGS_REG))]
12706 return "popcnt\t{%1, %0|%0, %1}";
12708 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12711 [(set_attr "prefix_rep" "1")
12712 (set_attr "type" "bitmanip")
12713 (set_attr "mode" "<MODE>")])
12715 (define_insn "*popcount<mode>2"
12716 [(set (match_operand:SWI248 0 "register_operand" "=r")
12718 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12719 (clobber (reg:CC FLAGS_REG))]
12723 return "popcnt\t{%1, %0|%0, %1}";
12725 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12728 [(set_attr "prefix_rep" "1")
12729 (set_attr "type" "bitmanip")
12730 (set_attr "mode" "<MODE>")])
12732 (define_expand "bswapdi2"
12733 [(set (match_operand:DI 0 "register_operand")
12734 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12738 operands[1] = force_reg (DImode, operands[1]);
12741 (define_expand "bswapsi2"
12742 [(set (match_operand:SI 0 "register_operand")
12743 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12748 else if (TARGET_BSWAP)
12749 operands[1] = force_reg (SImode, operands[1]);
12752 rtx x = operands[0];
12754 emit_move_insn (x, operands[1]);
12755 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12756 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12757 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12762 (define_insn "*bswap<mode>2_movbe"
12763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12764 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12766 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12769 movbe\t{%1, %0|%0, %1}
12770 movbe\t{%1, %0|%0, %1}"
12771 [(set_attr "type" "bitmanip,imov,imov")
12772 (set_attr "modrm" "0,1,1")
12773 (set_attr "prefix_0f" "*,1,1")
12774 (set_attr "prefix_extra" "*,1,1")
12775 (set_attr "mode" "<MODE>")])
12777 (define_insn "*bswap<mode>2"
12778 [(set (match_operand:SWI48 0 "register_operand" "=r")
12779 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12782 [(set_attr "type" "bitmanip")
12783 (set_attr "modrm" "0")
12784 (set_attr "mode" "<MODE>")])
12786 (define_insn "*bswaphi_lowpart_1"
12787 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12788 (bswap:HI (match_dup 0)))
12789 (clobber (reg:CC FLAGS_REG))]
12790 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12792 xchg{b}\t{%h0, %b0|%b0, %h0}
12793 rol{w}\t{$8, %0|%0, 8}"
12794 [(set_attr "length" "2,4")
12795 (set_attr "mode" "QI,HI")])
12797 (define_insn "bswaphi_lowpart"
12798 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12799 (bswap:HI (match_dup 0)))
12800 (clobber (reg:CC FLAGS_REG))]
12802 "rol{w}\t{$8, %0|%0, 8}"
12803 [(set_attr "length" "4")
12804 (set_attr "mode" "HI")])
12806 (define_expand "paritydi2"
12807 [(set (match_operand:DI 0 "register_operand")
12808 (parity:DI (match_operand:DI 1 "register_operand")))]
12811 rtx scratch = gen_reg_rtx (QImode);
12814 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12815 NULL_RTX, operands[1]));
12817 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12818 gen_rtx_REG (CCmode, FLAGS_REG),
12820 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12823 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12826 rtx tmp = gen_reg_rtx (SImode);
12828 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12829 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12834 (define_expand "paritysi2"
12835 [(set (match_operand:SI 0 "register_operand")
12836 (parity:SI (match_operand:SI 1 "register_operand")))]
12839 rtx scratch = gen_reg_rtx (QImode);
12842 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12844 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12845 gen_rtx_REG (CCmode, FLAGS_REG),
12847 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12849 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12853 (define_insn_and_split "paritydi2_cmp"
12854 [(set (reg:CC FLAGS_REG)
12855 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12857 (clobber (match_scratch:DI 0 "=r"))
12858 (clobber (match_scratch:SI 1 "=&r"))
12859 (clobber (match_scratch:HI 2 "=Q"))]
12862 "&& reload_completed"
12864 [(set (match_dup 1)
12865 (xor:SI (match_dup 1) (match_dup 4)))
12866 (clobber (reg:CC FLAGS_REG))])
12868 [(set (reg:CC FLAGS_REG)
12869 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12870 (clobber (match_dup 1))
12871 (clobber (match_dup 2))])]
12873 operands[4] = gen_lowpart (SImode, operands[3]);
12877 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12878 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12881 operands[1] = gen_highpart (SImode, operands[3]);
12884 (define_insn_and_split "paritysi2_cmp"
12885 [(set (reg:CC FLAGS_REG)
12886 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12888 (clobber (match_scratch:SI 0 "=r"))
12889 (clobber (match_scratch:HI 1 "=&Q"))]
12892 "&& reload_completed"
12894 [(set (match_dup 1)
12895 (xor:HI (match_dup 1) (match_dup 3)))
12896 (clobber (reg:CC FLAGS_REG))])
12898 [(set (reg:CC FLAGS_REG)
12899 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12900 (clobber (match_dup 1))])]
12902 operands[3] = gen_lowpart (HImode, operands[2]);
12904 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12905 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12908 (define_insn "*parityhi2_cmp"
12909 [(set (reg:CC FLAGS_REG)
12910 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12912 (clobber (match_scratch:HI 0 "=Q"))]
12914 "xor{b}\t{%h0, %b0|%b0, %h0}"
12915 [(set_attr "length" "2")
12916 (set_attr "mode" "HI")])
12919 ;; Thread-local storage patterns for ELF.
12921 ;; Note that these code sequences must appear exactly as shown
12922 ;; in order to allow linker relaxation.
12924 (define_insn "*tls_global_dynamic_32_gnu"
12925 [(set (match_operand:SI 0 "register_operand" "=a")
12927 [(match_operand:SI 1 "register_operand" "b")
12928 (match_operand 2 "tls_symbolic_operand")
12929 (match_operand 3 "constant_call_address_operand" "Bz")
12932 (clobber (match_scratch:SI 4 "=d"))
12933 (clobber (match_scratch:SI 5 "=c"))
12934 (clobber (reg:CC FLAGS_REG))]
12935 "!TARGET_64BIT && TARGET_GNU_TLS"
12938 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12939 if (TARGET_SUN_TLS)
12940 #ifdef HAVE_AS_IX86_TLSGDPLT
12941 return "call\t%a2@tlsgdplt";
12943 return "call\t%p3@plt";
12945 return "call\t%P3";
12947 [(set_attr "type" "multi")
12948 (set_attr "length" "12")])
12950 (define_expand "tls_global_dynamic_32"
12952 [(set (match_operand:SI 0 "register_operand")
12953 (unspec:SI [(match_operand:SI 2 "register_operand")
12954 (match_operand 1 "tls_symbolic_operand")
12955 (match_operand 3 "constant_call_address_operand")
12958 (clobber (match_scratch:SI 4))
12959 (clobber (match_scratch:SI 5))
12960 (clobber (reg:CC FLAGS_REG))])]
12962 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12964 (define_insn "*tls_global_dynamic_64_<mode>"
12965 [(set (match_operand:P 0 "register_operand" "=a")
12967 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12968 (match_operand 3)))
12969 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12974 fputs (ASM_BYTE "0x66\n", asm_out_file);
12976 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12977 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12978 fputs ("\trex64\n", asm_out_file);
12979 if (TARGET_SUN_TLS)
12980 return "call\t%p2@plt";
12981 return "call\t%P2";
12983 [(set_attr "type" "multi")
12984 (set (attr "length")
12985 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12987 (define_insn "*tls_global_dynamic_64_largepic"
12988 [(set (match_operand:DI 0 "register_operand" "=a")
12990 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12991 (match_operand:DI 3 "immediate_operand" "i")))
12992 (match_operand 4)))
12993 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12995 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12996 && GET_CODE (operands[3]) == CONST
12997 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12998 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13001 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13002 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13003 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13004 return "call\t{*%%rax|rax}";
13006 [(set_attr "type" "multi")
13007 (set_attr "length" "22")])
13009 (define_expand "tls_global_dynamic_64_<mode>"
13011 [(set (match_operand:P 0 "register_operand")
13013 (mem:QI (match_operand 2))
13015 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13018 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13020 (define_insn "*tls_local_dynamic_base_32_gnu"
13021 [(set (match_operand:SI 0 "register_operand" "=a")
13023 [(match_operand:SI 1 "register_operand" "b")
13024 (match_operand 2 "constant_call_address_operand" "Bz")
13026 UNSPEC_TLS_LD_BASE))
13027 (clobber (match_scratch:SI 3 "=d"))
13028 (clobber (match_scratch:SI 4 "=c"))
13029 (clobber (reg:CC FLAGS_REG))]
13030 "!TARGET_64BIT && TARGET_GNU_TLS"
13033 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13034 if (TARGET_SUN_TLS)
13036 if (HAVE_AS_IX86_TLSLDMPLT)
13037 return "call\t%&@tlsldmplt";
13039 return "call\t%p2@plt";
13041 return "call\t%P2";
13043 [(set_attr "type" "multi")
13044 (set_attr "length" "11")])
13046 (define_expand "tls_local_dynamic_base_32"
13048 [(set (match_operand:SI 0 "register_operand")
13050 [(match_operand:SI 1 "register_operand")
13051 (match_operand 2 "constant_call_address_operand")
13053 UNSPEC_TLS_LD_BASE))
13054 (clobber (match_scratch:SI 3))
13055 (clobber (match_scratch:SI 4))
13056 (clobber (reg:CC FLAGS_REG))])]
13058 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13060 (define_insn "*tls_local_dynamic_base_64_<mode>"
13061 [(set (match_operand:P 0 "register_operand" "=a")
13063 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13064 (match_operand 2)))
13065 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13069 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13070 if (TARGET_SUN_TLS)
13071 return "call\t%p1@plt";
13072 return "call\t%P1";
13074 [(set_attr "type" "multi")
13075 (set_attr "length" "12")])
13077 (define_insn "*tls_local_dynamic_base_64_largepic"
13078 [(set (match_operand:DI 0 "register_operand" "=a")
13080 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13081 (match_operand:DI 2 "immediate_operand" "i")))
13082 (match_operand 3)))
13083 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13084 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13085 && GET_CODE (operands[2]) == CONST
13086 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13087 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13090 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13091 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13092 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13093 return "call\t{*%%rax|rax}";
13095 [(set_attr "type" "multi")
13096 (set_attr "length" "22")])
13098 (define_expand "tls_local_dynamic_base_64_<mode>"
13100 [(set (match_operand:P 0 "register_operand")
13102 (mem:QI (match_operand 1))
13104 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13106 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13108 ;; Local dynamic of a single variable is a lose. Show combine how
13109 ;; to convert that back to global dynamic.
13111 (define_insn_and_split "*tls_local_dynamic_32_once"
13112 [(set (match_operand:SI 0 "register_operand" "=a")
13114 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13115 (match_operand 2 "constant_call_address_operand" "Bz")
13117 UNSPEC_TLS_LD_BASE)
13118 (const:SI (unspec:SI
13119 [(match_operand 3 "tls_symbolic_operand")]
13121 (clobber (match_scratch:SI 4 "=d"))
13122 (clobber (match_scratch:SI 5 "=c"))
13123 (clobber (reg:CC FLAGS_REG))]
13128 [(set (match_dup 0)
13129 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13132 (clobber (match_dup 4))
13133 (clobber (match_dup 5))
13134 (clobber (reg:CC FLAGS_REG))])])
13136 ;; Segment register for the thread base ptr load
13137 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13139 ;; Load and add the thread base pointer from %<tp_seg>:0.
13140 (define_insn "*load_tp_x32"
13141 [(set (match_operand:SI 0 "register_operand" "=r")
13142 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13144 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13145 [(set_attr "type" "imov")
13146 (set_attr "modrm" "0")
13147 (set_attr "length" "7")
13148 (set_attr "memory" "load")
13149 (set_attr "imm_disp" "false")])
13151 (define_insn "*load_tp_x32_zext"
13152 [(set (match_operand:DI 0 "register_operand" "=r")
13153 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13155 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13156 [(set_attr "type" "imov")
13157 (set_attr "modrm" "0")
13158 (set_attr "length" "7")
13159 (set_attr "memory" "load")
13160 (set_attr "imm_disp" "false")])
13162 (define_insn "*load_tp_<mode>"
13163 [(set (match_operand:P 0 "register_operand" "=r")
13164 (unspec:P [(const_int 0)] UNSPEC_TP))]
13166 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13167 [(set_attr "type" "imov")
13168 (set_attr "modrm" "0")
13169 (set_attr "length" "7")
13170 (set_attr "memory" "load")
13171 (set_attr "imm_disp" "false")])
13173 (define_insn "*add_tp_x32"
13174 [(set (match_operand:SI 0 "register_operand" "=r")
13175 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13176 (match_operand:SI 1 "register_operand" "0")))
13177 (clobber (reg:CC FLAGS_REG))]
13179 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13180 [(set_attr "type" "alu")
13181 (set_attr "modrm" "0")
13182 (set_attr "length" "7")
13183 (set_attr "memory" "load")
13184 (set_attr "imm_disp" "false")])
13186 (define_insn "*add_tp_x32_zext"
13187 [(set (match_operand:DI 0 "register_operand" "=r")
13189 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13190 (match_operand:SI 1 "register_operand" "0"))))
13191 (clobber (reg:CC FLAGS_REG))]
13193 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13194 [(set_attr "type" "alu")
13195 (set_attr "modrm" "0")
13196 (set_attr "length" "7")
13197 (set_attr "memory" "load")
13198 (set_attr "imm_disp" "false")])
13200 (define_insn "*add_tp_<mode>"
13201 [(set (match_operand:P 0 "register_operand" "=r")
13202 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13203 (match_operand:P 1 "register_operand" "0")))
13204 (clobber (reg:CC FLAGS_REG))]
13206 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13207 [(set_attr "type" "alu")
13208 (set_attr "modrm" "0")
13209 (set_attr "length" "7")
13210 (set_attr "memory" "load")
13211 (set_attr "imm_disp" "false")])
13213 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13214 ;; %rax as destination of the initial executable code sequence.
13215 (define_insn "tls_initial_exec_64_sun"
13216 [(set (match_operand:DI 0 "register_operand" "=a")
13218 [(match_operand 1 "tls_symbolic_operand")]
13219 UNSPEC_TLS_IE_SUN))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "TARGET_64BIT && TARGET_SUN_TLS"
13224 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13225 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13227 [(set_attr "type" "multi")])
13229 ;; GNU2 TLS patterns can be split.
13231 (define_expand "tls_dynamic_gnu2_32"
13232 [(set (match_dup 3)
13233 (plus:SI (match_operand:SI 2 "register_operand")
13235 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13238 [(set (match_operand:SI 0 "register_operand")
13239 (unspec:SI [(match_dup 1) (match_dup 3)
13240 (match_dup 2) (reg:SI SP_REG)]
13242 (clobber (reg:CC FLAGS_REG))])]
13243 "!TARGET_64BIT && TARGET_GNU2_TLS"
13245 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13246 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13249 (define_insn "*tls_dynamic_gnu2_lea_32"
13250 [(set (match_operand:SI 0 "register_operand" "=r")
13251 (plus:SI (match_operand:SI 1 "register_operand" "b")
13253 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13254 UNSPEC_TLSDESC))))]
13255 "!TARGET_64BIT && TARGET_GNU2_TLS"
13256 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13257 [(set_attr "type" "lea")
13258 (set_attr "mode" "SI")
13259 (set_attr "length" "6")
13260 (set_attr "length_address" "4")])
13262 (define_insn "*tls_dynamic_gnu2_call_32"
13263 [(set (match_operand:SI 0 "register_operand" "=a")
13264 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13265 (match_operand:SI 2 "register_operand" "0")
13266 ;; we have to make sure %ebx still points to the GOT
13267 (match_operand:SI 3 "register_operand" "b")
13270 (clobber (reg:CC FLAGS_REG))]
13271 "!TARGET_64BIT && TARGET_GNU2_TLS"
13272 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13273 [(set_attr "type" "call")
13274 (set_attr "length" "2")
13275 (set_attr "length_address" "0")])
13277 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13278 [(set (match_operand:SI 0 "register_operand" "=&a")
13280 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13281 (match_operand:SI 4)
13282 (match_operand:SI 2 "register_operand" "b")
13285 (const:SI (unspec:SI
13286 [(match_operand 1 "tls_symbolic_operand")]
13288 (clobber (reg:CC FLAGS_REG))]
13289 "!TARGET_64BIT && TARGET_GNU2_TLS"
13292 [(set (match_dup 0) (match_dup 5))]
13294 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13295 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13298 (define_expand "tls_dynamic_gnu2_64"
13299 [(set (match_dup 2)
13300 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13303 [(set (match_operand:DI 0 "register_operand")
13304 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13306 (clobber (reg:CC FLAGS_REG))])]
13307 "TARGET_64BIT && TARGET_GNU2_TLS"
13309 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13310 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13313 (define_insn "*tls_dynamic_gnu2_lea_64"
13314 [(set (match_operand:DI 0 "register_operand" "=r")
13315 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13317 "TARGET_64BIT && TARGET_GNU2_TLS"
13318 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13319 [(set_attr "type" "lea")
13320 (set_attr "mode" "DI")
13321 (set_attr "length" "7")
13322 (set_attr "length_address" "4")])
13324 (define_insn "*tls_dynamic_gnu2_call_64"
13325 [(set (match_operand:DI 0 "register_operand" "=a")
13326 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13327 (match_operand:DI 2 "register_operand" "0")
13330 (clobber (reg:CC FLAGS_REG))]
13331 "TARGET_64BIT && TARGET_GNU2_TLS"
13332 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13333 [(set_attr "type" "call")
13334 (set_attr "length" "2")
13335 (set_attr "length_address" "0")])
13337 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13338 [(set (match_operand:DI 0 "register_operand" "=&a")
13340 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13341 (match_operand:DI 3)
13344 (const:DI (unspec:DI
13345 [(match_operand 1 "tls_symbolic_operand")]
13347 (clobber (reg:CC FLAGS_REG))]
13348 "TARGET_64BIT && TARGET_GNU2_TLS"
13351 [(set (match_dup 0) (match_dup 4))]
13353 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13354 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13357 ;; These patterns match the binary 387 instructions for addM3, subM3,
13358 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13359 ;; SFmode. The first is the normal insn, the second the same insn but
13360 ;; with one operand a conversion, and the third the same insn but with
13361 ;; the other operand a conversion. The conversion may be SFmode or
13362 ;; SImode if the target mode DFmode, but only SImode if the target mode
13365 ;; Gcc is slightly more smart about handling normal two address instructions
13366 ;; so use special patterns for add and mull.
13368 (define_insn "*fop_<mode>_comm_mixed"
13369 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13370 (match_operator:MODEF 3 "binary_fp_operator"
13371 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13372 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13373 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13374 && COMMUTATIVE_ARITH_P (operands[3])
13375 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13376 "* return output_387_binary_op (insn, operands);"
13377 [(set (attr "type")
13378 (if_then_else (eq_attr "alternative" "1,2")
13379 (if_then_else (match_operand:MODEF 3 "mult_operator")
13380 (const_string "ssemul")
13381 (const_string "sseadd"))
13382 (if_then_else (match_operand:MODEF 3 "mult_operator")
13383 (const_string "fmul")
13384 (const_string "fop"))))
13385 (set_attr "isa" "*,noavx,avx")
13386 (set_attr "prefix" "orig,orig,vex")
13387 (set_attr "mode" "<MODE>")])
13389 (define_insn "*fop_<mode>_comm_sse"
13390 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13391 (match_operator:MODEF 3 "binary_fp_operator"
13392 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13393 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13394 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13395 && COMMUTATIVE_ARITH_P (operands[3])
13396 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13397 "* return output_387_binary_op (insn, operands);"
13398 [(set (attr "type")
13399 (if_then_else (match_operand:MODEF 3 "mult_operator")
13400 (const_string "ssemul")
13401 (const_string "sseadd")))
13402 (set_attr "isa" "noavx,avx")
13403 (set_attr "prefix" "orig,vex")
13404 (set_attr "mode" "<MODE>")])
13406 (define_insn "*fop_<mode>_comm_i387"
13407 [(set (match_operand:MODEF 0 "register_operand" "=f")
13408 (match_operator:MODEF 3 "binary_fp_operator"
13409 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13410 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13411 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13412 && COMMUTATIVE_ARITH_P (operands[3])
13413 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13414 "* return output_387_binary_op (insn, operands);"
13415 [(set (attr "type")
13416 (if_then_else (match_operand:MODEF 3 "mult_operator")
13417 (const_string "fmul")
13418 (const_string "fop")))
13419 (set_attr "mode" "<MODE>")])
13421 (define_insn "*fop_<mode>_1_mixed"
13422 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13423 (match_operator:MODEF 3 "binary_fp_operator"
13424 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13425 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13427 && !COMMUTATIVE_ARITH_P (operands[3])
13428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13429 "* return output_387_binary_op (insn, operands);"
13430 [(set (attr "type")
13431 (cond [(and (eq_attr "alternative" "2,3")
13432 (match_operand:MODEF 3 "mult_operator"))
13433 (const_string "ssemul")
13434 (and (eq_attr "alternative" "2,3")
13435 (match_operand:MODEF 3 "div_operator"))
13436 (const_string "ssediv")
13437 (eq_attr "alternative" "2,3")
13438 (const_string "sseadd")
13439 (match_operand:MODEF 3 "mult_operator")
13440 (const_string "fmul")
13441 (match_operand:MODEF 3 "div_operator")
13442 (const_string "fdiv")
13444 (const_string "fop")))
13445 (set_attr "isa" "*,*,noavx,avx")
13446 (set_attr "prefix" "orig,orig,orig,vex")
13447 (set_attr "mode" "<MODE>")])
13449 (define_insn "*rcpsf2_sse"
13450 [(set (match_operand:SF 0 "register_operand" "=x")
13451 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13454 "%vrcpss\t{%1, %d0|%d0, %1}"
13455 [(set_attr "type" "sse")
13456 (set_attr "atom_sse_attr" "rcp")
13457 (set_attr "btver2_sse_attr" "rcp")
13458 (set_attr "prefix" "maybe_vex")
13459 (set_attr "mode" "SF")])
13461 (define_insn "*fop_<mode>_1_sse"
13462 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13463 (match_operator:MODEF 3 "binary_fp_operator"
13464 [(match_operand:MODEF 1 "register_operand" "0,x")
13465 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13466 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13467 && !COMMUTATIVE_ARITH_P (operands[3])"
13468 "* return output_387_binary_op (insn, operands);"
13469 [(set (attr "type")
13470 (cond [(match_operand:MODEF 3 "mult_operator")
13471 (const_string "ssemul")
13472 (match_operand:MODEF 3 "div_operator")
13473 (const_string "ssediv")
13475 (const_string "sseadd")))
13476 (set_attr "isa" "noavx,avx")
13477 (set_attr "prefix" "orig,vex")
13478 (set_attr "mode" "<MODE>")])
13480 ;; This pattern is not fully shadowed by the pattern above.
13481 (define_insn "*fop_<mode>_1_i387"
13482 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13483 (match_operator:MODEF 3 "binary_fp_operator"
13484 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13485 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13486 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13487 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13488 && !COMMUTATIVE_ARITH_P (operands[3])
13489 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13490 "* return output_387_binary_op (insn, operands);"
13491 [(set (attr "type")
13492 (cond [(match_operand:MODEF 3 "mult_operator")
13493 (const_string "fmul")
13494 (match_operand:MODEF 3 "div_operator")
13495 (const_string "fdiv")
13497 (const_string "fop")))
13498 (set_attr "mode" "<MODE>")])
13500 ;; ??? Add SSE splitters for these!
13501 (define_insn "*fop_<MODEF:mode>_2_i387"
13502 [(set (match_operand:MODEF 0 "register_operand" "=f")
13503 (match_operator:MODEF 3 "binary_fp_operator"
13505 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13506 (match_operand:MODEF 2 "register_operand" "0")]))]
13507 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13508 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13509 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13510 || optimize_function_for_size_p (cfun))"
13511 { return output_387_binary_op (insn, operands); }
13512 [(set (attr "type")
13513 (cond [(match_operand:MODEF 3 "mult_operator")
13514 (const_string "fmul")
13515 (match_operand:MODEF 3 "div_operator")
13516 (const_string "fdiv")
13518 (const_string "fop")))
13519 (set_attr "fp_int_src" "true")
13520 (set_attr "mode" "<SWI24:MODE>")])
13522 (define_insn "*fop_<MODEF:mode>_3_i387"
13523 [(set (match_operand:MODEF 0 "register_operand" "=f")
13524 (match_operator:MODEF 3 "binary_fp_operator"
13525 [(match_operand:MODEF 1 "register_operand" "0")
13527 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13528 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13529 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13530 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13531 || optimize_function_for_size_p (cfun))"
13532 { return output_387_binary_op (insn, operands); }
13533 [(set (attr "type")
13534 (cond [(match_operand:MODEF 3 "mult_operator")
13535 (const_string "fmul")
13536 (match_operand:MODEF 3 "div_operator")
13537 (const_string "fdiv")
13539 (const_string "fop")))
13540 (set_attr "fp_int_src" "true")
13541 (set_attr "mode" "<MODE>")])
13543 (define_insn "*fop_df_4_i387"
13544 [(set (match_operand:DF 0 "register_operand" "=f,f")
13545 (match_operator:DF 3 "binary_fp_operator"
13547 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13548 (match_operand:DF 2 "register_operand" "0,f")]))]
13549 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13550 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13551 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13552 "* return output_387_binary_op (insn, operands);"
13553 [(set (attr "type")
13554 (cond [(match_operand:DF 3 "mult_operator")
13555 (const_string "fmul")
13556 (match_operand:DF 3 "div_operator")
13557 (const_string "fdiv")
13559 (const_string "fop")))
13560 (set_attr "mode" "SF")])
13562 (define_insn "*fop_df_5_i387"
13563 [(set (match_operand:DF 0 "register_operand" "=f,f")
13564 (match_operator:DF 3 "binary_fp_operator"
13565 [(match_operand:DF 1 "register_operand" "0,f")
13567 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13568 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13569 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13570 "* return output_387_binary_op (insn, operands);"
13571 [(set (attr "type")
13572 (cond [(match_operand:DF 3 "mult_operator")
13573 (const_string "fmul")
13574 (match_operand:DF 3 "div_operator")
13575 (const_string "fdiv")
13577 (const_string "fop")))
13578 (set_attr "mode" "SF")])
13580 (define_insn "*fop_df_6_i387"
13581 [(set (match_operand:DF 0 "register_operand" "=f,f")
13582 (match_operator:DF 3 "binary_fp_operator"
13584 (match_operand:SF 1 "register_operand" "0,f"))
13586 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13587 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13588 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13589 "* return output_387_binary_op (insn, operands);"
13590 [(set (attr "type")
13591 (cond [(match_operand:DF 3 "mult_operator")
13592 (const_string "fmul")
13593 (match_operand:DF 3 "div_operator")
13594 (const_string "fdiv")
13596 (const_string "fop")))
13597 (set_attr "mode" "SF")])
13599 (define_insn "*fop_xf_comm_i387"
13600 [(set (match_operand:XF 0 "register_operand" "=f")
13601 (match_operator:XF 3 "binary_fp_operator"
13602 [(match_operand:XF 1 "register_operand" "%0")
13603 (match_operand:XF 2 "register_operand" "f")]))]
13605 && COMMUTATIVE_ARITH_P (operands[3])"
13606 "* return output_387_binary_op (insn, operands);"
13607 [(set (attr "type")
13608 (if_then_else (match_operand:XF 3 "mult_operator")
13609 (const_string "fmul")
13610 (const_string "fop")))
13611 (set_attr "mode" "XF")])
13613 (define_insn "*fop_xf_1_i387"
13614 [(set (match_operand:XF 0 "register_operand" "=f,f")
13615 (match_operator:XF 3 "binary_fp_operator"
13616 [(match_operand:XF 1 "register_operand" "0,f")
13617 (match_operand:XF 2 "register_operand" "f,0")]))]
13619 && !COMMUTATIVE_ARITH_P (operands[3])"
13620 "* return output_387_binary_op (insn, operands);"
13621 [(set (attr "type")
13622 (cond [(match_operand:XF 3 "mult_operator")
13623 (const_string "fmul")
13624 (match_operand:XF 3 "div_operator")
13625 (const_string "fdiv")
13627 (const_string "fop")))
13628 (set_attr "mode" "XF")])
13630 (define_insn "*fop_xf_2_i387"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13632 (match_operator:XF 3 "binary_fp_operator"
13634 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13635 (match_operand:XF 2 "register_operand" "0")]))]
13637 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13638 { return output_387_binary_op (insn, operands); }
13639 [(set (attr "type")
13640 (cond [(match_operand:XF 3 "mult_operator")
13641 (const_string "fmul")
13642 (match_operand:XF 3 "div_operator")
13643 (const_string "fdiv")
13645 (const_string "fop")))
13646 (set_attr "fp_int_src" "true")
13647 (set_attr "mode" "<MODE>")])
13649 (define_insn "*fop_xf_3_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (match_operator:XF 3 "binary_fp_operator"
13652 [(match_operand:XF 1 "register_operand" "0")
13654 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13656 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13657 { return output_387_binary_op (insn, operands); }
13658 [(set (attr "type")
13659 (cond [(match_operand:XF 3 "mult_operator")
13660 (const_string "fmul")
13661 (match_operand:XF 3 "div_operator")
13662 (const_string "fdiv")
13664 (const_string "fop")))
13665 (set_attr "fp_int_src" "true")
13666 (set_attr "mode" "<MODE>")])
13668 (define_insn "*fop_xf_4_i387"
13669 [(set (match_operand:XF 0 "register_operand" "=f,f")
13670 (match_operator:XF 3 "binary_fp_operator"
13672 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13673 (match_operand:XF 2 "register_operand" "0,f")]))]
13675 "* return output_387_binary_op (insn, operands);"
13676 [(set (attr "type")
13677 (cond [(match_operand:XF 3 "mult_operator")
13678 (const_string "fmul")
13679 (match_operand:XF 3 "div_operator")
13680 (const_string "fdiv")
13682 (const_string "fop")))
13683 (set_attr "mode" "<MODE>")])
13685 (define_insn "*fop_xf_5_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f,f")
13687 (match_operator:XF 3 "binary_fp_operator"
13688 [(match_operand:XF 1 "register_operand" "0,f")
13690 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13692 "* return output_387_binary_op (insn, operands);"
13693 [(set (attr "type")
13694 (cond [(match_operand:XF 3 "mult_operator")
13695 (const_string "fmul")
13696 (match_operand:XF 3 "div_operator")
13697 (const_string "fdiv")
13699 (const_string "fop")))
13700 (set_attr "mode" "<MODE>")])
13702 (define_insn "*fop_xf_6_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f,f")
13704 (match_operator:XF 3 "binary_fp_operator"
13706 (match_operand:MODEF 1 "register_operand" "0,f"))
13708 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13710 "* return output_387_binary_op (insn, operands);"
13711 [(set (attr "type")
13712 (cond [(match_operand:XF 3 "mult_operator")
13713 (const_string "fmul")
13714 (match_operand:XF 3 "div_operator")
13715 (const_string "fdiv")
13717 (const_string "fop")))
13718 (set_attr "mode" "<MODE>")])
13720 ;; FPU special functions.
13722 ;; This pattern implements a no-op XFmode truncation for
13723 ;; all fancy i386 XFmode math functions.
13725 (define_insn "truncxf<mode>2_i387_noop_unspec"
13726 [(set (match_operand:MODEF 0 "register_operand" "=f")
13727 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13728 UNSPEC_TRUNC_NOOP))]
13729 "TARGET_USE_FANCY_MATH_387"
13730 "* return output_387_reg_move (insn, operands);"
13731 [(set_attr "type" "fmov")
13732 (set_attr "mode" "<MODE>")])
13734 (define_insn "sqrtxf2"
13735 [(set (match_operand:XF 0 "register_operand" "=f")
13736 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13737 "TARGET_USE_FANCY_MATH_387"
13739 [(set_attr "type" "fpspc")
13740 (set_attr "mode" "XF")
13741 (set_attr "athlon_decode" "direct")
13742 (set_attr "amdfam10_decode" "direct")
13743 (set_attr "bdver1_decode" "direct")])
13745 (define_insn "sqrt_extend<mode>xf2_i387"
13746 [(set (match_operand:XF 0 "register_operand" "=f")
13749 (match_operand:MODEF 1 "register_operand" "0"))))]
13750 "TARGET_USE_FANCY_MATH_387"
13752 [(set_attr "type" "fpspc")
13753 (set_attr "mode" "XF")
13754 (set_attr "athlon_decode" "direct")
13755 (set_attr "amdfam10_decode" "direct")
13756 (set_attr "bdver1_decode" "direct")])
13758 (define_insn "*rsqrtsf2_sse"
13759 [(set (match_operand:SF 0 "register_operand" "=x")
13760 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13763 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13764 [(set_attr "type" "sse")
13765 (set_attr "atom_sse_attr" "rcp")
13766 (set_attr "btver2_sse_attr" "rcp")
13767 (set_attr "prefix" "maybe_vex")
13768 (set_attr "mode" "SF")])
13770 (define_expand "rsqrtsf2"
13771 [(set (match_operand:SF 0 "register_operand")
13772 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13776 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13780 (define_insn "*sqrt<mode>2_sse"
13781 [(set (match_operand:MODEF 0 "register_operand" "=x")
13783 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13784 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13785 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13786 [(set_attr "type" "sse")
13787 (set_attr "atom_sse_attr" "sqrt")
13788 (set_attr "btver2_sse_attr" "sqrt")
13789 (set_attr "prefix" "maybe_vex")
13790 (set_attr "mode" "<MODE>")
13791 (set_attr "athlon_decode" "*")
13792 (set_attr "amdfam10_decode" "*")
13793 (set_attr "bdver1_decode" "*")])
13795 (define_expand "sqrt<mode>2"
13796 [(set (match_operand:MODEF 0 "register_operand")
13798 (match_operand:MODEF 1 "nonimmediate_operand")))]
13799 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13800 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13802 if (<MODE>mode == SFmode
13804 && TARGET_RECIP_SQRT
13805 && !optimize_function_for_size_p (cfun)
13806 && flag_finite_math_only && !flag_trapping_math
13807 && flag_unsafe_math_optimizations)
13809 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13813 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13815 rtx op0 = gen_reg_rtx (XFmode);
13816 rtx op1 = force_reg (<MODE>mode, operands[1]);
13818 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13819 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13824 (define_insn "fpremxf4_i387"
13825 [(set (match_operand:XF 0 "register_operand" "=f")
13826 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13827 (match_operand:XF 3 "register_operand" "1")]
13829 (set (match_operand:XF 1 "register_operand" "=u")
13830 (unspec:XF [(match_dup 2) (match_dup 3)]
13832 (set (reg:CCFP FPSR_REG)
13833 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13835 "TARGET_USE_FANCY_MATH_387
13836 && flag_finite_math_only"
13838 [(set_attr "type" "fpspc")
13839 (set_attr "mode" "XF")])
13841 (define_expand "fmodxf3"
13842 [(use (match_operand:XF 0 "register_operand"))
13843 (use (match_operand:XF 1 "general_operand"))
13844 (use (match_operand:XF 2 "general_operand"))]
13845 "TARGET_USE_FANCY_MATH_387
13846 && flag_finite_math_only"
13848 rtx_code_label *label = gen_label_rtx ();
13850 rtx op1 = gen_reg_rtx (XFmode);
13851 rtx op2 = gen_reg_rtx (XFmode);
13853 emit_move_insn (op2, operands[2]);
13854 emit_move_insn (op1, operands[1]);
13856 emit_label (label);
13857 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13858 ix86_emit_fp_unordered_jump (label);
13859 LABEL_NUSES (label) = 1;
13861 emit_move_insn (operands[0], op1);
13865 (define_expand "fmod<mode>3"
13866 [(use (match_operand:MODEF 0 "register_operand"))
13867 (use (match_operand:MODEF 1 "general_operand"))
13868 (use (match_operand:MODEF 2 "general_operand"))]
13869 "TARGET_USE_FANCY_MATH_387
13870 && flag_finite_math_only"
13872 rtx (*gen_truncxf) (rtx, rtx);
13874 rtx_code_label *label = gen_label_rtx ();
13876 rtx op1 = gen_reg_rtx (XFmode);
13877 rtx op2 = gen_reg_rtx (XFmode);
13879 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13880 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13882 emit_label (label);
13883 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13884 ix86_emit_fp_unordered_jump (label);
13885 LABEL_NUSES (label) = 1;
13887 /* Truncate the result properly for strict SSE math. */
13888 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13889 && !TARGET_MIX_SSE_I387)
13890 gen_truncxf = gen_truncxf<mode>2;
13892 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13894 emit_insn (gen_truncxf (operands[0], op1));
13898 (define_insn "fprem1xf4_i387"
13899 [(set (match_operand:XF 0 "register_operand" "=f")
13900 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13901 (match_operand:XF 3 "register_operand" "1")]
13903 (set (match_operand:XF 1 "register_operand" "=u")
13904 (unspec:XF [(match_dup 2) (match_dup 3)]
13906 (set (reg:CCFP FPSR_REG)
13907 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_finite_math_only"
13912 [(set_attr "type" "fpspc")
13913 (set_attr "mode" "XF")])
13915 (define_expand "remainderxf3"
13916 [(use (match_operand:XF 0 "register_operand"))
13917 (use (match_operand:XF 1 "general_operand"))
13918 (use (match_operand:XF 2 "general_operand"))]
13919 "TARGET_USE_FANCY_MATH_387
13920 && flag_finite_math_only"
13922 rtx_code_label *label = gen_label_rtx ();
13924 rtx op1 = gen_reg_rtx (XFmode);
13925 rtx op2 = gen_reg_rtx (XFmode);
13927 emit_move_insn (op2, operands[2]);
13928 emit_move_insn (op1, operands[1]);
13930 emit_label (label);
13931 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13932 ix86_emit_fp_unordered_jump (label);
13933 LABEL_NUSES (label) = 1;
13935 emit_move_insn (operands[0], op1);
13939 (define_expand "remainder<mode>3"
13940 [(use (match_operand:MODEF 0 "register_operand"))
13941 (use (match_operand:MODEF 1 "general_operand"))
13942 (use (match_operand:MODEF 2 "general_operand"))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && flag_finite_math_only"
13946 rtx (*gen_truncxf) (rtx, rtx);
13948 rtx_code_label *label = gen_label_rtx ();
13950 rtx op1 = gen_reg_rtx (XFmode);
13951 rtx op2 = gen_reg_rtx (XFmode);
13953 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13954 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13956 emit_label (label);
13958 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13959 ix86_emit_fp_unordered_jump (label);
13960 LABEL_NUSES (label) = 1;
13962 /* Truncate the result properly for strict SSE math. */
13963 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13964 && !TARGET_MIX_SSE_I387)
13965 gen_truncxf = gen_truncxf<mode>2;
13967 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13969 emit_insn (gen_truncxf (operands[0], op1));
13973 (define_int_iterator SINCOS
13977 (define_int_attr sincos
13978 [(UNSPEC_SIN "sin")
13979 (UNSPEC_COS "cos")])
13981 (define_insn "*<sincos>xf2_i387"
13982 [(set (match_operand:XF 0 "register_operand" "=f")
13983 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13988 [(set_attr "type" "fpspc")
13989 (set_attr "mode" "XF")])
13991 (define_insn "*<sincos>_extend<mode>xf2_i387"
13992 [(set (match_operand:XF 0 "register_operand" "=f")
13993 (unspec:XF [(float_extend:XF
13994 (match_operand:MODEF 1 "register_operand" "0"))]
13996 "TARGET_USE_FANCY_MATH_387
13997 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13998 || TARGET_MIX_SSE_I387)
13999 && flag_unsafe_math_optimizations"
14001 [(set_attr "type" "fpspc")
14002 (set_attr "mode" "XF")])
14004 ;; When sincos pattern is defined, sin and cos builtin functions will be
14005 ;; expanded to sincos pattern with one of its outputs left unused.
14006 ;; CSE pass will figure out if two sincos patterns can be combined,
14007 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14008 ;; depending on the unused output.
14010 (define_insn "sincosxf3"
14011 [(set (match_operand:XF 0 "register_operand" "=f")
14012 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14013 UNSPEC_SINCOS_COS))
14014 (set (match_operand:XF 1 "register_operand" "=u")
14015 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14023 [(set (match_operand:XF 0 "register_operand")
14024 (unspec:XF [(match_operand:XF 2 "register_operand")]
14025 UNSPEC_SINCOS_COS))
14026 (set (match_operand:XF 1 "register_operand")
14027 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14028 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14029 && can_create_pseudo_p ()"
14030 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14033 [(set (match_operand:XF 0 "register_operand")
14034 (unspec:XF [(match_operand:XF 2 "register_operand")]
14035 UNSPEC_SINCOS_COS))
14036 (set (match_operand:XF 1 "register_operand")
14037 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14038 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14039 && can_create_pseudo_p ()"
14040 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14042 (define_insn "sincos_extend<mode>xf3_i387"
14043 [(set (match_operand:XF 0 "register_operand" "=f")
14044 (unspec:XF [(float_extend:XF
14045 (match_operand:MODEF 2 "register_operand" "0"))]
14046 UNSPEC_SINCOS_COS))
14047 (set (match_operand:XF 1 "register_operand" "=u")
14048 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14049 "TARGET_USE_FANCY_MATH_387
14050 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14051 || TARGET_MIX_SSE_I387)
14052 && flag_unsafe_math_optimizations"
14054 [(set_attr "type" "fpspc")
14055 (set_attr "mode" "XF")])
14058 [(set (match_operand:XF 0 "register_operand")
14059 (unspec:XF [(float_extend:XF
14060 (match_operand:MODEF 2 "register_operand"))]
14061 UNSPEC_SINCOS_COS))
14062 (set (match_operand:XF 1 "register_operand")
14063 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14064 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14065 && can_create_pseudo_p ()"
14066 [(set (match_dup 1)
14067 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14070 [(set (match_operand:XF 0 "register_operand")
14071 (unspec:XF [(float_extend:XF
14072 (match_operand:MODEF 2 "register_operand"))]
14073 UNSPEC_SINCOS_COS))
14074 (set (match_operand:XF 1 "register_operand")
14075 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14076 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14077 && can_create_pseudo_p ()"
14078 [(set (match_dup 0)
14079 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14081 (define_expand "sincos<mode>3"
14082 [(use (match_operand:MODEF 0 "register_operand"))
14083 (use (match_operand:MODEF 1 "register_operand"))
14084 (use (match_operand:MODEF 2 "register_operand"))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14087 || TARGET_MIX_SSE_I387)
14088 && flag_unsafe_math_optimizations"
14090 rtx op0 = gen_reg_rtx (XFmode);
14091 rtx op1 = gen_reg_rtx (XFmode);
14093 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14094 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14099 (define_insn "fptanxf4_i387"
14100 [(set (match_operand:XF 0 "register_operand" "=f")
14101 (match_operand:XF 3 "const_double_operand" "F"))
14102 (set (match_operand:XF 1 "register_operand" "=u")
14103 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14105 "TARGET_USE_FANCY_MATH_387
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_insn "fptan_extend<mode>xf4_i387"
14113 [(set (match_operand:MODEF 0 "register_operand" "=f")
14114 (match_operand:MODEF 3 "const_double_operand" "F"))
14115 (set (match_operand:XF 1 "register_operand" "=u")
14116 (unspec:XF [(float_extend:XF
14117 (match_operand:MODEF 2 "register_operand" "0"))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14121 || TARGET_MIX_SSE_I387)
14122 && flag_unsafe_math_optimizations
14123 && standard_80387_constant_p (operands[3]) == 2"
14125 [(set_attr "type" "fpspc")
14126 (set_attr "mode" "XF")])
14128 (define_expand "tanxf2"
14129 [(use (match_operand:XF 0 "register_operand"))
14130 (use (match_operand:XF 1 "register_operand"))]
14131 "TARGET_USE_FANCY_MATH_387
14132 && flag_unsafe_math_optimizations"
14134 rtx one = gen_reg_rtx (XFmode);
14135 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14137 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14141 (define_expand "tan<mode>2"
14142 [(use (match_operand:MODEF 0 "register_operand"))
14143 (use (match_operand:MODEF 1 "register_operand"))]
14144 "TARGET_USE_FANCY_MATH_387
14145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14146 || TARGET_MIX_SSE_I387)
14147 && flag_unsafe_math_optimizations"
14149 rtx op0 = gen_reg_rtx (XFmode);
14151 rtx one = gen_reg_rtx (<MODE>mode);
14152 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14154 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14155 operands[1], op2));
14156 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14160 (define_insn "*fpatanxf3_i387"
14161 [(set (match_operand:XF 0 "register_operand" "=f")
14162 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14163 (match_operand:XF 2 "register_operand" "u")]
14165 (clobber (match_scratch:XF 3 "=2"))]
14166 "TARGET_USE_FANCY_MATH_387
14167 && flag_unsafe_math_optimizations"
14169 [(set_attr "type" "fpspc")
14170 (set_attr "mode" "XF")])
14172 (define_insn "fpatan_extend<mode>xf3_i387"
14173 [(set (match_operand:XF 0 "register_operand" "=f")
14174 (unspec:XF [(float_extend:XF
14175 (match_operand:MODEF 1 "register_operand" "0"))
14177 (match_operand:MODEF 2 "register_operand" "u"))]
14179 (clobber (match_scratch:XF 3 "=2"))]
14180 "TARGET_USE_FANCY_MATH_387
14181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14182 || TARGET_MIX_SSE_I387)
14183 && flag_unsafe_math_optimizations"
14185 [(set_attr "type" "fpspc")
14186 (set_attr "mode" "XF")])
14188 (define_expand "atan2xf3"
14189 [(parallel [(set (match_operand:XF 0 "register_operand")
14190 (unspec:XF [(match_operand:XF 2 "register_operand")
14191 (match_operand:XF 1 "register_operand")]
14193 (clobber (match_scratch:XF 3))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations")
14197 (define_expand "atan2<mode>3"
14198 [(use (match_operand:MODEF 0 "register_operand"))
14199 (use (match_operand:MODEF 1 "register_operand"))
14200 (use (match_operand:MODEF 2 "register_operand"))]
14201 "TARGET_USE_FANCY_MATH_387
14202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14203 || TARGET_MIX_SSE_I387)
14204 && flag_unsafe_math_optimizations"
14206 rtx op0 = gen_reg_rtx (XFmode);
14208 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14213 (define_expand "atanxf2"
14214 [(parallel [(set (match_operand:XF 0 "register_operand")
14215 (unspec:XF [(match_dup 2)
14216 (match_operand:XF 1 "register_operand")]
14218 (clobber (match_scratch:XF 3))])]
14219 "TARGET_USE_FANCY_MATH_387
14220 && flag_unsafe_math_optimizations"
14222 operands[2] = gen_reg_rtx (XFmode);
14223 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14226 (define_expand "atan<mode>2"
14227 [(use (match_operand:MODEF 0 "register_operand"))
14228 (use (match_operand:MODEF 1 "register_operand"))]
14229 "TARGET_USE_FANCY_MATH_387
14230 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14231 || TARGET_MIX_SSE_I387)
14232 && flag_unsafe_math_optimizations"
14234 rtx op0 = gen_reg_rtx (XFmode);
14236 rtx op2 = gen_reg_rtx (<MODE>mode);
14237 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14239 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14244 (define_expand "asinxf2"
14245 [(set (match_dup 2)
14246 (mult:XF (match_operand:XF 1 "register_operand")
14248 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14249 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14250 (parallel [(set (match_operand:XF 0 "register_operand")
14251 (unspec:XF [(match_dup 5) (match_dup 1)]
14253 (clobber (match_scratch:XF 6))])]
14254 "TARGET_USE_FANCY_MATH_387
14255 && flag_unsafe_math_optimizations"
14259 if (optimize_insn_for_size_p ())
14262 for (i = 2; i < 6; i++)
14263 operands[i] = gen_reg_rtx (XFmode);
14265 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14268 (define_expand "asin<mode>2"
14269 [(use (match_operand:MODEF 0 "register_operand"))
14270 (use (match_operand:MODEF 1 "general_operand"))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273 || TARGET_MIX_SSE_I387)
14274 && flag_unsafe_math_optimizations"
14276 rtx op0 = gen_reg_rtx (XFmode);
14277 rtx op1 = gen_reg_rtx (XFmode);
14279 if (optimize_insn_for_size_p ())
14282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14283 emit_insn (gen_asinxf2 (op0, op1));
14284 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14288 (define_expand "acosxf2"
14289 [(set (match_dup 2)
14290 (mult:XF (match_operand:XF 1 "register_operand")
14292 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14293 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14294 (parallel [(set (match_operand:XF 0 "register_operand")
14295 (unspec:XF [(match_dup 1) (match_dup 5)]
14297 (clobber (match_scratch:XF 6))])]
14298 "TARGET_USE_FANCY_MATH_387
14299 && flag_unsafe_math_optimizations"
14303 if (optimize_insn_for_size_p ())
14306 for (i = 2; i < 6; i++)
14307 operands[i] = gen_reg_rtx (XFmode);
14309 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14312 (define_expand "acos<mode>2"
14313 [(use (match_operand:MODEF 0 "register_operand"))
14314 (use (match_operand:MODEF 1 "general_operand"))]
14315 "TARGET_USE_FANCY_MATH_387
14316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14317 || TARGET_MIX_SSE_I387)
14318 && flag_unsafe_math_optimizations"
14320 rtx op0 = gen_reg_rtx (XFmode);
14321 rtx op1 = gen_reg_rtx (XFmode);
14323 if (optimize_insn_for_size_p ())
14326 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14327 emit_insn (gen_acosxf2 (op0, op1));
14328 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14332 (define_insn "fyl2xxf3_i387"
14333 [(set (match_operand:XF 0 "register_operand" "=f")
14334 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14335 (match_operand:XF 2 "register_operand" "u")]
14337 (clobber (match_scratch:XF 3 "=2"))]
14338 "TARGET_USE_FANCY_MATH_387
14339 && flag_unsafe_math_optimizations"
14341 [(set_attr "type" "fpspc")
14342 (set_attr "mode" "XF")])
14344 (define_insn "fyl2x_extend<mode>xf3_i387"
14345 [(set (match_operand:XF 0 "register_operand" "=f")
14346 (unspec:XF [(float_extend:XF
14347 (match_operand:MODEF 1 "register_operand" "0"))
14348 (match_operand:XF 2 "register_operand" "u")]
14350 (clobber (match_scratch:XF 3 "=2"))]
14351 "TARGET_USE_FANCY_MATH_387
14352 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14353 || TARGET_MIX_SSE_I387)
14354 && flag_unsafe_math_optimizations"
14356 [(set_attr "type" "fpspc")
14357 (set_attr "mode" "XF")])
14359 (define_expand "logxf2"
14360 [(parallel [(set (match_operand:XF 0 "register_operand")
14361 (unspec:XF [(match_operand:XF 1 "register_operand")
14362 (match_dup 2)] UNSPEC_FYL2X))
14363 (clobber (match_scratch:XF 3))])]
14364 "TARGET_USE_FANCY_MATH_387
14365 && flag_unsafe_math_optimizations"
14367 operands[2] = gen_reg_rtx (XFmode);
14368 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14371 (define_expand "log<mode>2"
14372 [(use (match_operand:MODEF 0 "register_operand"))
14373 (use (match_operand:MODEF 1 "register_operand"))]
14374 "TARGET_USE_FANCY_MATH_387
14375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14376 || TARGET_MIX_SSE_I387)
14377 && flag_unsafe_math_optimizations"
14379 rtx op0 = gen_reg_rtx (XFmode);
14381 rtx op2 = gen_reg_rtx (XFmode);
14382 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14384 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14385 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14389 (define_expand "log10xf2"
14390 [(parallel [(set (match_operand:XF 0 "register_operand")
14391 (unspec:XF [(match_operand:XF 1 "register_operand")
14392 (match_dup 2)] UNSPEC_FYL2X))
14393 (clobber (match_scratch:XF 3))])]
14394 "TARGET_USE_FANCY_MATH_387
14395 && flag_unsafe_math_optimizations"
14397 operands[2] = gen_reg_rtx (XFmode);
14398 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14401 (define_expand "log10<mode>2"
14402 [(use (match_operand:MODEF 0 "register_operand"))
14403 (use (match_operand:MODEF 1 "register_operand"))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14406 || TARGET_MIX_SSE_I387)
14407 && flag_unsafe_math_optimizations"
14409 rtx op0 = gen_reg_rtx (XFmode);
14411 rtx op2 = gen_reg_rtx (XFmode);
14412 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14414 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14415 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14419 (define_expand "log2xf2"
14420 [(parallel [(set (match_operand:XF 0 "register_operand")
14421 (unspec:XF [(match_operand:XF 1 "register_operand")
14422 (match_dup 2)] UNSPEC_FYL2X))
14423 (clobber (match_scratch:XF 3))])]
14424 "TARGET_USE_FANCY_MATH_387
14425 && flag_unsafe_math_optimizations"
14427 operands[2] = gen_reg_rtx (XFmode);
14428 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14431 (define_expand "log2<mode>2"
14432 [(use (match_operand:MODEF 0 "register_operand"))
14433 (use (match_operand:MODEF 1 "register_operand"))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14436 || TARGET_MIX_SSE_I387)
14437 && flag_unsafe_math_optimizations"
14439 rtx op0 = gen_reg_rtx (XFmode);
14441 rtx op2 = gen_reg_rtx (XFmode);
14442 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14444 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14445 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14449 (define_insn "fyl2xp1xf3_i387"
14450 [(set (match_operand:XF 0 "register_operand" "=f")
14451 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14452 (match_operand:XF 2 "register_operand" "u")]
14454 (clobber (match_scratch:XF 3 "=2"))]
14455 "TARGET_USE_FANCY_MATH_387
14456 && flag_unsafe_math_optimizations"
14458 [(set_attr "type" "fpspc")
14459 (set_attr "mode" "XF")])
14461 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14462 [(set (match_operand:XF 0 "register_operand" "=f")
14463 (unspec:XF [(float_extend:XF
14464 (match_operand:MODEF 1 "register_operand" "0"))
14465 (match_operand:XF 2 "register_operand" "u")]
14467 (clobber (match_scratch:XF 3 "=2"))]
14468 "TARGET_USE_FANCY_MATH_387
14469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14470 || TARGET_MIX_SSE_I387)
14471 && flag_unsafe_math_optimizations"
14473 [(set_attr "type" "fpspc")
14474 (set_attr "mode" "XF")])
14476 (define_expand "log1pxf2"
14477 [(use (match_operand:XF 0 "register_operand"))
14478 (use (match_operand:XF 1 "register_operand"))]
14479 "TARGET_USE_FANCY_MATH_387
14480 && flag_unsafe_math_optimizations"
14482 if (optimize_insn_for_size_p ())
14485 ix86_emit_i387_log1p (operands[0], operands[1]);
14489 (define_expand "log1p<mode>2"
14490 [(use (match_operand:MODEF 0 "register_operand"))
14491 (use (match_operand:MODEF 1 "register_operand"))]
14492 "TARGET_USE_FANCY_MATH_387
14493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494 || TARGET_MIX_SSE_I387)
14495 && flag_unsafe_math_optimizations"
14499 if (optimize_insn_for_size_p ())
14502 op0 = gen_reg_rtx (XFmode);
14504 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14506 ix86_emit_i387_log1p (op0, operands[1]);
14507 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14511 (define_insn "fxtractxf3_i387"
14512 [(set (match_operand:XF 0 "register_operand" "=f")
14513 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14514 UNSPEC_XTRACT_FRACT))
14515 (set (match_operand:XF 1 "register_operand" "=u")
14516 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14517 "TARGET_USE_FANCY_MATH_387
14518 && flag_unsafe_math_optimizations"
14520 [(set_attr "type" "fpspc")
14521 (set_attr "mode" "XF")])
14523 (define_insn "fxtract_extend<mode>xf3_i387"
14524 [(set (match_operand:XF 0 "register_operand" "=f")
14525 (unspec:XF [(float_extend:XF
14526 (match_operand:MODEF 2 "register_operand" "0"))]
14527 UNSPEC_XTRACT_FRACT))
14528 (set (match_operand:XF 1 "register_operand" "=u")
14529 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14530 "TARGET_USE_FANCY_MATH_387
14531 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14532 || TARGET_MIX_SSE_I387)
14533 && flag_unsafe_math_optimizations"
14535 [(set_attr "type" "fpspc")
14536 (set_attr "mode" "XF")])
14538 (define_expand "logbxf2"
14539 [(parallel [(set (match_dup 2)
14540 (unspec:XF [(match_operand:XF 1 "register_operand")]
14541 UNSPEC_XTRACT_FRACT))
14542 (set (match_operand:XF 0 "register_operand")
14543 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14544 "TARGET_USE_FANCY_MATH_387
14545 && flag_unsafe_math_optimizations"
14546 "operands[2] = gen_reg_rtx (XFmode);")
14548 (define_expand "logb<mode>2"
14549 [(use (match_operand:MODEF 0 "register_operand"))
14550 (use (match_operand:MODEF 1 "register_operand"))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553 || TARGET_MIX_SSE_I387)
14554 && flag_unsafe_math_optimizations"
14556 rtx op0 = gen_reg_rtx (XFmode);
14557 rtx op1 = gen_reg_rtx (XFmode);
14559 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14560 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14564 (define_expand "ilogbxf2"
14565 [(use (match_operand:SI 0 "register_operand"))
14566 (use (match_operand:XF 1 "register_operand"))]
14567 "TARGET_USE_FANCY_MATH_387
14568 && flag_unsafe_math_optimizations"
14572 if (optimize_insn_for_size_p ())
14575 op0 = gen_reg_rtx (XFmode);
14576 op1 = gen_reg_rtx (XFmode);
14578 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14579 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14583 (define_expand "ilogb<mode>2"
14584 [(use (match_operand:SI 0 "register_operand"))
14585 (use (match_operand:MODEF 1 "register_operand"))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations"
14593 if (optimize_insn_for_size_p ())
14596 op0 = gen_reg_rtx (XFmode);
14597 op1 = gen_reg_rtx (XFmode);
14599 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14600 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14604 (define_insn "*f2xm1xf2_i387"
14605 [(set (match_operand:XF 0 "register_operand" "=f")
14606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14608 "TARGET_USE_FANCY_MATH_387
14609 && flag_unsafe_math_optimizations"
14611 [(set_attr "type" "fpspc")
14612 (set_attr "mode" "XF")])
14614 (define_insn "fscalexf4_i387"
14615 [(set (match_operand:XF 0 "register_operand" "=f")
14616 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14617 (match_operand:XF 3 "register_operand" "1")]
14618 UNSPEC_FSCALE_FRACT))
14619 (set (match_operand:XF 1 "register_operand" "=u")
14620 (unspec:XF [(match_dup 2) (match_dup 3)]
14621 UNSPEC_FSCALE_EXP))]
14622 "TARGET_USE_FANCY_MATH_387
14623 && flag_unsafe_math_optimizations"
14625 [(set_attr "type" "fpspc")
14626 (set_attr "mode" "XF")])
14628 (define_expand "expNcorexf3"
14629 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14630 (match_operand:XF 2 "register_operand")))
14631 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14632 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14633 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14634 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14635 (parallel [(set (match_operand:XF 0 "register_operand")
14636 (unspec:XF [(match_dup 8) (match_dup 4)]
14637 UNSPEC_FSCALE_FRACT))
14639 (unspec:XF [(match_dup 8) (match_dup 4)]
14640 UNSPEC_FSCALE_EXP))])]
14641 "TARGET_USE_FANCY_MATH_387
14642 && flag_unsafe_math_optimizations"
14646 if (optimize_insn_for_size_p ())
14649 for (i = 3; i < 10; i++)
14650 operands[i] = gen_reg_rtx (XFmode);
14652 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14655 (define_expand "expxf2"
14656 [(use (match_operand:XF 0 "register_operand"))
14657 (use (match_operand:XF 1 "register_operand"))]
14658 "TARGET_USE_FANCY_MATH_387
14659 && flag_unsafe_math_optimizations"
14663 if (optimize_insn_for_size_p ())
14666 op2 = gen_reg_rtx (XFmode);
14667 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14669 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14673 (define_expand "exp<mode>2"
14674 [(use (match_operand:MODEF 0 "register_operand"))
14675 (use (match_operand:MODEF 1 "general_operand"))]
14676 "TARGET_USE_FANCY_MATH_387
14677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14678 || TARGET_MIX_SSE_I387)
14679 && flag_unsafe_math_optimizations"
14683 if (optimize_insn_for_size_p ())
14686 op0 = gen_reg_rtx (XFmode);
14687 op1 = gen_reg_rtx (XFmode);
14689 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14690 emit_insn (gen_expxf2 (op0, op1));
14691 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14695 (define_expand "exp10xf2"
14696 [(use (match_operand:XF 0 "register_operand"))
14697 (use (match_operand:XF 1 "register_operand"))]
14698 "TARGET_USE_FANCY_MATH_387
14699 && flag_unsafe_math_optimizations"
14703 if (optimize_insn_for_size_p ())
14706 op2 = gen_reg_rtx (XFmode);
14707 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14709 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14713 (define_expand "exp10<mode>2"
14714 [(use (match_operand:MODEF 0 "register_operand"))
14715 (use (match_operand:MODEF 1 "general_operand"))]
14716 "TARGET_USE_FANCY_MATH_387
14717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14718 || TARGET_MIX_SSE_I387)
14719 && flag_unsafe_math_optimizations"
14723 if (optimize_insn_for_size_p ())
14726 op0 = gen_reg_rtx (XFmode);
14727 op1 = gen_reg_rtx (XFmode);
14729 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14730 emit_insn (gen_exp10xf2 (op0, op1));
14731 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14735 (define_expand "exp2xf2"
14736 [(use (match_operand:XF 0 "register_operand"))
14737 (use (match_operand:XF 1 "register_operand"))]
14738 "TARGET_USE_FANCY_MATH_387
14739 && flag_unsafe_math_optimizations"
14743 if (optimize_insn_for_size_p ())
14746 op2 = gen_reg_rtx (XFmode);
14747 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14749 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14753 (define_expand "exp2<mode>2"
14754 [(use (match_operand:MODEF 0 "register_operand"))
14755 (use (match_operand:MODEF 1 "general_operand"))]
14756 "TARGET_USE_FANCY_MATH_387
14757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14758 || TARGET_MIX_SSE_I387)
14759 && flag_unsafe_math_optimizations"
14763 if (optimize_insn_for_size_p ())
14766 op0 = gen_reg_rtx (XFmode);
14767 op1 = gen_reg_rtx (XFmode);
14769 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14770 emit_insn (gen_exp2xf2 (op0, op1));
14771 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14775 (define_expand "expm1xf2"
14776 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14778 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14779 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14780 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14781 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14782 (parallel [(set (match_dup 7)
14783 (unspec:XF [(match_dup 6) (match_dup 4)]
14784 UNSPEC_FSCALE_FRACT))
14786 (unspec:XF [(match_dup 6) (match_dup 4)]
14787 UNSPEC_FSCALE_EXP))])
14788 (parallel [(set (match_dup 10)
14789 (unspec:XF [(match_dup 9) (match_dup 8)]
14790 UNSPEC_FSCALE_FRACT))
14791 (set (match_dup 11)
14792 (unspec:XF [(match_dup 9) (match_dup 8)]
14793 UNSPEC_FSCALE_EXP))])
14794 (set (match_dup 12) (minus:XF (match_dup 10)
14795 (float_extend:XF (match_dup 13))))
14796 (set (match_operand:XF 0 "register_operand")
14797 (plus:XF (match_dup 12) (match_dup 7)))]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations"
14803 if (optimize_insn_for_size_p ())
14806 for (i = 2; i < 13; i++)
14807 operands[i] = gen_reg_rtx (XFmode);
14810 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14812 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14815 (define_expand "expm1<mode>2"
14816 [(use (match_operand:MODEF 0 "register_operand"))
14817 (use (match_operand:MODEF 1 "general_operand"))]
14818 "TARGET_USE_FANCY_MATH_387
14819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14820 || TARGET_MIX_SSE_I387)
14821 && flag_unsafe_math_optimizations"
14825 if (optimize_insn_for_size_p ())
14828 op0 = gen_reg_rtx (XFmode);
14829 op1 = gen_reg_rtx (XFmode);
14831 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14832 emit_insn (gen_expm1xf2 (op0, op1));
14833 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14837 (define_expand "ldexpxf3"
14838 [(match_operand:XF 0 "register_operand")
14839 (match_operand:XF 1 "register_operand")
14840 (match_operand:SI 2 "register_operand")]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations"
14845 if (optimize_insn_for_size_p ())
14848 tmp1 = gen_reg_rtx (XFmode);
14849 tmp2 = gen_reg_rtx (XFmode);
14851 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14852 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14853 operands[1], tmp1));
14857 (define_expand "ldexp<mode>3"
14858 [(use (match_operand:MODEF 0 "register_operand"))
14859 (use (match_operand:MODEF 1 "general_operand"))
14860 (use (match_operand:SI 2 "register_operand"))]
14861 "TARGET_USE_FANCY_MATH_387
14862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14863 || TARGET_MIX_SSE_I387)
14864 && flag_unsafe_math_optimizations"
14868 if (optimize_insn_for_size_p ())
14871 op0 = gen_reg_rtx (XFmode);
14872 op1 = gen_reg_rtx (XFmode);
14874 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14875 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14880 (define_expand "scalbxf3"
14881 [(parallel [(set (match_operand:XF 0 " register_operand")
14882 (unspec:XF [(match_operand:XF 1 "register_operand")
14883 (match_operand:XF 2 "register_operand")]
14884 UNSPEC_FSCALE_FRACT))
14886 (unspec:XF [(match_dup 1) (match_dup 2)]
14887 UNSPEC_FSCALE_EXP))])]
14888 "TARGET_USE_FANCY_MATH_387
14889 && flag_unsafe_math_optimizations"
14891 if (optimize_insn_for_size_p ())
14894 operands[3] = gen_reg_rtx (XFmode);
14897 (define_expand "scalb<mode>3"
14898 [(use (match_operand:MODEF 0 "register_operand"))
14899 (use (match_operand:MODEF 1 "general_operand"))
14900 (use (match_operand:MODEF 2 "general_operand"))]
14901 "TARGET_USE_FANCY_MATH_387
14902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14903 || TARGET_MIX_SSE_I387)
14904 && flag_unsafe_math_optimizations"
14908 if (optimize_insn_for_size_p ())
14911 op0 = gen_reg_rtx (XFmode);
14912 op1 = gen_reg_rtx (XFmode);
14913 op2 = gen_reg_rtx (XFmode);
14915 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14916 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14917 emit_insn (gen_scalbxf3 (op0, op1, op2));
14918 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14922 (define_expand "significandxf2"
14923 [(parallel [(set (match_operand:XF 0 "register_operand")
14924 (unspec:XF [(match_operand:XF 1 "register_operand")]
14925 UNSPEC_XTRACT_FRACT))
14927 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14928 "TARGET_USE_FANCY_MATH_387
14929 && flag_unsafe_math_optimizations"
14930 "operands[2] = gen_reg_rtx (XFmode);")
14932 (define_expand "significand<mode>2"
14933 [(use (match_operand:MODEF 0 "register_operand"))
14934 (use (match_operand:MODEF 1 "register_operand"))]
14935 "TARGET_USE_FANCY_MATH_387
14936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14937 || TARGET_MIX_SSE_I387)
14938 && flag_unsafe_math_optimizations"
14940 rtx op0 = gen_reg_rtx (XFmode);
14941 rtx op1 = gen_reg_rtx (XFmode);
14943 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14944 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949 (define_insn "sse4_1_round<mode>2"
14950 [(set (match_operand:MODEF 0 "register_operand" "=x")
14951 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14952 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14955 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14956 [(set_attr "type" "ssecvt")
14957 (set_attr "prefix_extra" "1")
14958 (set_attr "prefix" "maybe_vex")
14959 (set_attr "mode" "<MODE>")])
14961 (define_insn "rintxf2"
14962 [(set (match_operand:XF 0 "register_operand" "=f")
14963 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14965 "TARGET_USE_FANCY_MATH_387
14966 && flag_unsafe_math_optimizations"
14968 [(set_attr "type" "fpspc")
14969 (set_attr "mode" "XF")])
14971 (define_expand "rint<mode>2"
14972 [(use (match_operand:MODEF 0 "register_operand"))
14973 (use (match_operand:MODEF 1 "register_operand"))]
14974 "(TARGET_USE_FANCY_MATH_387
14975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14976 || TARGET_MIX_SSE_I387)
14977 && flag_unsafe_math_optimizations)
14978 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14979 && !flag_trapping_math)"
14981 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14982 && !flag_trapping_math)
14985 emit_insn (gen_sse4_1_round<mode>2
14986 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14987 else if (optimize_insn_for_size_p ())
14990 ix86_expand_rint (operands[0], operands[1]);
14994 rtx op0 = gen_reg_rtx (XFmode);
14995 rtx op1 = gen_reg_rtx (XFmode);
14997 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14998 emit_insn (gen_rintxf2 (op0, op1));
15000 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15005 (define_expand "round<mode>2"
15006 [(match_operand:X87MODEF 0 "register_operand")
15007 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15008 "(TARGET_USE_FANCY_MATH_387
15009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15010 || TARGET_MIX_SSE_I387)
15011 && flag_unsafe_math_optimizations)
15012 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15013 && !flag_trapping_math && !flag_rounding_math)"
15015 if (optimize_insn_for_size_p ())
15018 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15019 && !flag_trapping_math && !flag_rounding_math)
15023 operands[1] = force_reg (<MODE>mode, operands[1]);
15024 ix86_expand_round_sse4 (operands[0], operands[1]);
15026 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15027 ix86_expand_round (operands[0], operands[1]);
15029 ix86_expand_rounddf_32 (operands[0], operands[1]);
15033 operands[1] = force_reg (<MODE>mode, operands[1]);
15034 ix86_emit_i387_round (operands[0], operands[1]);
15039 (define_insn_and_split "*fistdi2_1"
15040 [(set (match_operand:DI 0 "nonimmediate_operand")
15041 (unspec:DI [(match_operand:XF 1 "register_operand")]
15043 "TARGET_USE_FANCY_MATH_387
15044 && can_create_pseudo_p ()"
15049 if (memory_operand (operands[0], VOIDmode))
15050 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15053 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15054 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15059 [(set_attr "type" "fpspc")
15060 (set_attr "mode" "DI")])
15062 (define_insn "fistdi2"
15063 [(set (match_operand:DI 0 "memory_operand" "=m")
15064 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15066 (clobber (match_scratch:XF 2 "=&1f"))]
15067 "TARGET_USE_FANCY_MATH_387"
15068 "* return output_fix_trunc (insn, operands, false);"
15069 [(set_attr "type" "fpspc")
15070 (set_attr "mode" "DI")])
15072 (define_insn "fistdi2_with_temp"
15073 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15074 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15076 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15077 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15078 "TARGET_USE_FANCY_MATH_387"
15080 [(set_attr "type" "fpspc")
15081 (set_attr "mode" "DI")])
15084 [(set (match_operand:DI 0 "register_operand")
15085 (unspec:DI [(match_operand:XF 1 "register_operand")]
15087 (clobber (match_operand:DI 2 "memory_operand"))
15088 (clobber (match_scratch 3))]
15090 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15091 (clobber (match_dup 3))])
15092 (set (match_dup 0) (match_dup 2))])
15095 [(set (match_operand:DI 0 "memory_operand")
15096 (unspec:DI [(match_operand:XF 1 "register_operand")]
15098 (clobber (match_operand:DI 2 "memory_operand"))
15099 (clobber (match_scratch 3))]
15101 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15102 (clobber (match_dup 3))])])
15104 (define_insn_and_split "*fist<mode>2_1"
15105 [(set (match_operand:SWI24 0 "register_operand")
15106 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15108 "TARGET_USE_FANCY_MATH_387
15109 && can_create_pseudo_p ()"
15114 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15115 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15119 [(set_attr "type" "fpspc")
15120 (set_attr "mode" "<MODE>")])
15122 (define_insn "fist<mode>2"
15123 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15124 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15126 "TARGET_USE_FANCY_MATH_387"
15127 "* return output_fix_trunc (insn, operands, false);"
15128 [(set_attr "type" "fpspc")
15129 (set_attr "mode" "<MODE>")])
15131 (define_insn "fist<mode>2_with_temp"
15132 [(set (match_operand:SWI24 0 "register_operand" "=r")
15133 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15135 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15136 "TARGET_USE_FANCY_MATH_387"
15138 [(set_attr "type" "fpspc")
15139 (set_attr "mode" "<MODE>")])
15142 [(set (match_operand:SWI24 0 "register_operand")
15143 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15145 (clobber (match_operand:SWI24 2 "memory_operand"))]
15147 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15148 (set (match_dup 0) (match_dup 2))])
15151 [(set (match_operand:SWI24 0 "memory_operand")
15152 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15154 (clobber (match_operand:SWI24 2 "memory_operand"))]
15156 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15158 (define_expand "lrintxf<mode>2"
15159 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15160 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15162 "TARGET_USE_FANCY_MATH_387")
15164 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15165 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15166 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15167 UNSPEC_FIX_NOTRUNC))]
15168 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15170 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15171 [(match_operand:SWI248x 0 "nonimmediate_operand")
15172 (match_operand:X87MODEF 1 "register_operand")]
15173 "(TARGET_USE_FANCY_MATH_387
15174 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15175 || TARGET_MIX_SSE_I387)
15176 && flag_unsafe_math_optimizations)
15177 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15178 && <SWI248x:MODE>mode != HImode
15179 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15180 && !flag_trapping_math && !flag_rounding_math)"
15182 if (optimize_insn_for_size_p ())
15185 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15186 && <SWI248x:MODE>mode != HImode
15187 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15188 && !flag_trapping_math && !flag_rounding_math)
15189 ix86_expand_lround (operands[0], operands[1]);
15191 ix86_emit_i387_round (operands[0], operands[1]);
15195 (define_int_iterator FRNDINT_ROUNDING
15196 [UNSPEC_FRNDINT_FLOOR
15197 UNSPEC_FRNDINT_CEIL
15198 UNSPEC_FRNDINT_TRUNC])
15200 (define_int_iterator FIST_ROUNDING
15204 ;; Base name for define_insn
15205 (define_int_attr rounding_insn
15206 [(UNSPEC_FRNDINT_FLOOR "floor")
15207 (UNSPEC_FRNDINT_CEIL "ceil")
15208 (UNSPEC_FRNDINT_TRUNC "btrunc")
15209 (UNSPEC_FIST_FLOOR "floor")
15210 (UNSPEC_FIST_CEIL "ceil")])
15212 (define_int_attr rounding
15213 [(UNSPEC_FRNDINT_FLOOR "floor")
15214 (UNSPEC_FRNDINT_CEIL "ceil")
15215 (UNSPEC_FRNDINT_TRUNC "trunc")
15216 (UNSPEC_FIST_FLOOR "floor")
15217 (UNSPEC_FIST_CEIL "ceil")])
15219 (define_int_attr ROUNDING
15220 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15221 (UNSPEC_FRNDINT_CEIL "CEIL")
15222 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15223 (UNSPEC_FIST_FLOOR "FLOOR")
15224 (UNSPEC_FIST_CEIL "CEIL")])
15226 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15227 (define_insn_and_split "frndintxf2_<rounding>"
15228 [(set (match_operand:XF 0 "register_operand")
15229 (unspec:XF [(match_operand:XF 1 "register_operand")]
15231 (clobber (reg:CC FLAGS_REG))]
15232 "TARGET_USE_FANCY_MATH_387
15233 && flag_unsafe_math_optimizations
15234 && can_create_pseudo_p ()"
15239 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15241 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15242 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15244 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15245 operands[2], operands[3]));
15248 [(set_attr "type" "frndint")
15249 (set_attr "i387_cw" "<rounding>")
15250 (set_attr "mode" "XF")])
15252 (define_insn "frndintxf2_<rounding>_i387"
15253 [(set (match_operand:XF 0 "register_operand" "=f")
15254 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15256 (use (match_operand:HI 2 "memory_operand" "m"))
15257 (use (match_operand:HI 3 "memory_operand" "m"))]
15258 "TARGET_USE_FANCY_MATH_387
15259 && flag_unsafe_math_optimizations"
15260 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15261 [(set_attr "type" "frndint")
15262 (set_attr "i387_cw" "<rounding>")
15263 (set_attr "mode" "XF")])
15265 (define_expand "<rounding_insn>xf2"
15266 [(parallel [(set (match_operand:XF 0 "register_operand")
15267 (unspec:XF [(match_operand:XF 1 "register_operand")]
15269 (clobber (reg:CC FLAGS_REG))])]
15270 "TARGET_USE_FANCY_MATH_387
15271 && flag_unsafe_math_optimizations
15272 && !optimize_insn_for_size_p ()")
15274 (define_expand "<rounding_insn><mode>2"
15275 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15276 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15278 (clobber (reg:CC FLAGS_REG))])]
15279 "(TARGET_USE_FANCY_MATH_387
15280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15281 || TARGET_MIX_SSE_I387)
15282 && flag_unsafe_math_optimizations)
15283 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15284 && !flag_trapping_math)"
15286 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15287 && !flag_trapping_math)
15290 emit_insn (gen_sse4_1_round<mode>2
15291 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15292 else if (optimize_insn_for_size_p ())
15294 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15296 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15297 ix86_expand_floorceil (operands[0], operands[1], true);
15298 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15299 ix86_expand_floorceil (operands[0], operands[1], false);
15300 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15301 ix86_expand_trunc (operands[0], operands[1]);
15303 gcc_unreachable ();
15307 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15308 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15309 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15310 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15311 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15312 ix86_expand_truncdf_32 (operands[0], operands[1]);
15314 gcc_unreachable ();
15321 if (optimize_insn_for_size_p ())
15324 op0 = gen_reg_rtx (XFmode);
15325 op1 = gen_reg_rtx (XFmode);
15326 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15327 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15329 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15334 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15335 (define_insn_and_split "frndintxf2_mask_pm"
15336 [(set (match_operand:XF 0 "register_operand")
15337 (unspec:XF [(match_operand:XF 1 "register_operand")]
15338 UNSPEC_FRNDINT_MASK_PM))
15339 (clobber (reg:CC FLAGS_REG))]
15340 "TARGET_USE_FANCY_MATH_387
15341 && flag_unsafe_math_optimizations
15342 && can_create_pseudo_p ()"
15347 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15349 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15350 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15352 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15353 operands[2], operands[3]));
15356 [(set_attr "type" "frndint")
15357 (set_attr "i387_cw" "mask_pm")
15358 (set_attr "mode" "XF")])
15360 (define_insn "frndintxf2_mask_pm_i387"
15361 [(set (match_operand:XF 0 "register_operand" "=f")
15362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15363 UNSPEC_FRNDINT_MASK_PM))
15364 (use (match_operand:HI 2 "memory_operand" "m"))
15365 (use (match_operand:HI 3 "memory_operand" "m"))]
15366 "TARGET_USE_FANCY_MATH_387
15367 && flag_unsafe_math_optimizations"
15368 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15369 [(set_attr "type" "frndint")
15370 (set_attr "i387_cw" "mask_pm")
15371 (set_attr "mode" "XF")])
15373 (define_expand "nearbyintxf2"
15374 [(parallel [(set (match_operand:XF 0 "register_operand")
15375 (unspec:XF [(match_operand:XF 1 "register_operand")]
15376 UNSPEC_FRNDINT_MASK_PM))
15377 (clobber (reg:CC FLAGS_REG))])]
15378 "TARGET_USE_FANCY_MATH_387
15379 && flag_unsafe_math_optimizations")
15381 (define_expand "nearbyint<mode>2"
15382 [(use (match_operand:MODEF 0 "register_operand"))
15383 (use (match_operand:MODEF 1 "register_operand"))]
15384 "TARGET_USE_FANCY_MATH_387
15385 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15386 || TARGET_MIX_SSE_I387)
15387 && flag_unsafe_math_optimizations"
15389 rtx op0 = gen_reg_rtx (XFmode);
15390 rtx op1 = gen_reg_rtx (XFmode);
15392 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15393 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15399 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15400 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15401 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15402 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15404 (clobber (reg:CC FLAGS_REG))]
15405 "TARGET_USE_FANCY_MATH_387
15406 && flag_unsafe_math_optimizations
15407 && can_create_pseudo_p ()"
15412 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15414 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15415 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15416 if (memory_operand (operands[0], VOIDmode))
15417 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15418 operands[2], operands[3]));
15421 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15422 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15423 (operands[0], operands[1], operands[2],
15424 operands[3], operands[4]));
15428 [(set_attr "type" "fistp")
15429 (set_attr "i387_cw" "<rounding>")
15430 (set_attr "mode" "<MODE>")])
15432 (define_insn "fistdi2_<rounding>"
15433 [(set (match_operand:DI 0 "memory_operand" "=m")
15434 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15436 (use (match_operand:HI 2 "memory_operand" "m"))
15437 (use (match_operand:HI 3 "memory_operand" "m"))
15438 (clobber (match_scratch:XF 4 "=&1f"))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && flag_unsafe_math_optimizations"
15441 "* return output_fix_trunc (insn, operands, false);"
15442 [(set_attr "type" "fistp")
15443 (set_attr "i387_cw" "<rounding>")
15444 (set_attr "mode" "DI")])
15446 (define_insn "fistdi2_<rounding>_with_temp"
15447 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15448 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15450 (use (match_operand:HI 2 "memory_operand" "m,m"))
15451 (use (match_operand:HI 3 "memory_operand" "m,m"))
15452 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15453 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations"
15457 [(set_attr "type" "fistp")
15458 (set_attr "i387_cw" "<rounding>")
15459 (set_attr "mode" "DI")])
15462 [(set (match_operand:DI 0 "register_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 4)
15471 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15472 (use (match_dup 2))
15473 (use (match_dup 3))
15474 (clobber (match_dup 5))])
15475 (set (match_dup 0) (match_dup 4))])
15478 [(set (match_operand:DI 0 "memory_operand")
15479 (unspec:DI [(match_operand:XF 1 "register_operand")]
15481 (use (match_operand:HI 2 "memory_operand"))
15482 (use (match_operand:HI 3 "memory_operand"))
15483 (clobber (match_operand:DI 4 "memory_operand"))
15484 (clobber (match_scratch 5))]
15486 [(parallel [(set (match_dup 0)
15487 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15488 (use (match_dup 2))
15489 (use (match_dup 3))
15490 (clobber (match_dup 5))])])
15492 (define_insn "fist<mode>2_<rounding>"
15493 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15494 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15496 (use (match_operand:HI 2 "memory_operand" "m"))
15497 (use (match_operand:HI 3 "memory_operand" "m"))]
15498 "TARGET_USE_FANCY_MATH_387
15499 && flag_unsafe_math_optimizations"
15500 "* return output_fix_trunc (insn, operands, false);"
15501 [(set_attr "type" "fistp")
15502 (set_attr "i387_cw" "<rounding>")
15503 (set_attr "mode" "<MODE>")])
15505 (define_insn "fist<mode>2_<rounding>_with_temp"
15506 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15507 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15509 (use (match_operand:HI 2 "memory_operand" "m,m"))
15510 (use (match_operand:HI 3 "memory_operand" "m,m"))
15511 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15512 "TARGET_USE_FANCY_MATH_387
15513 && flag_unsafe_math_optimizations"
15515 [(set_attr "type" "fistp")
15516 (set_attr "i387_cw" "<rounding>")
15517 (set_attr "mode" "<MODE>")])
15520 [(set (match_operand:SWI24 0 "register_operand")
15521 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15523 (use (match_operand:HI 2 "memory_operand"))
15524 (use (match_operand:HI 3 "memory_operand"))
15525 (clobber (match_operand:SWI24 4 "memory_operand"))]
15527 [(parallel [(set (match_dup 4)
15528 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15529 (use (match_dup 2))
15530 (use (match_dup 3))])
15531 (set (match_dup 0) (match_dup 4))])
15534 [(set (match_operand:SWI24 0 "memory_operand")
15535 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15537 (use (match_operand:HI 2 "memory_operand"))
15538 (use (match_operand:HI 3 "memory_operand"))
15539 (clobber (match_operand:SWI24 4 "memory_operand"))]
15541 [(parallel [(set (match_dup 0)
15542 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15543 (use (match_dup 2))
15544 (use (match_dup 3))])])
15546 (define_expand "l<rounding_insn>xf<mode>2"
15547 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15548 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15550 (clobber (reg:CC FLAGS_REG))])]
15551 "TARGET_USE_FANCY_MATH_387
15552 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15553 && flag_unsafe_math_optimizations")
15555 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15556 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15557 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15559 (clobber (reg:CC FLAGS_REG))])]
15560 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15561 && !flag_trapping_math"
15563 if (TARGET_64BIT && optimize_insn_for_size_p ())
15566 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15567 ix86_expand_lfloorceil (operands[0], operands[1], true);
15568 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15569 ix86_expand_lfloorceil (operands[0], operands[1], false);
15571 gcc_unreachable ();
15576 (define_insn "fxam<mode>2_i387"
15577 [(set (match_operand:HI 0 "register_operand" "=a")
15579 [(match_operand:X87MODEF 1 "register_operand" "f")]
15581 "TARGET_USE_FANCY_MATH_387"
15582 "fxam\n\tfnstsw\t%0"
15583 [(set_attr "type" "multi")
15584 (set_attr "length" "4")
15585 (set_attr "unit" "i387")
15586 (set_attr "mode" "<MODE>")])
15588 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15589 [(set (match_operand:HI 0 "register_operand")
15591 [(match_operand:MODEF 1 "memory_operand")]
15593 "TARGET_USE_FANCY_MATH_387
15594 && can_create_pseudo_p ()"
15597 [(set (match_dup 2)(match_dup 1))
15599 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15601 operands[2] = gen_reg_rtx (<MODE>mode);
15603 MEM_VOLATILE_P (operands[1]) = 1;
15605 [(set_attr "type" "multi")
15606 (set_attr "unit" "i387")
15607 (set_attr "mode" "<MODE>")])
15609 (define_expand "isinfxf2"
15610 [(use (match_operand:SI 0 "register_operand"))
15611 (use (match_operand:XF 1 "register_operand"))]
15612 "TARGET_USE_FANCY_MATH_387
15613 && ix86_libc_has_function (function_c99_misc)"
15615 rtx mask = GEN_INT (0x45);
15616 rtx val = GEN_INT (0x05);
15620 rtx scratch = gen_reg_rtx (HImode);
15621 rtx res = gen_reg_rtx (QImode);
15623 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15625 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15626 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15627 cond = gen_rtx_fmt_ee (EQ, QImode,
15628 gen_rtx_REG (CCmode, FLAGS_REG),
15630 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15631 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15635 (define_expand "isinf<mode>2"
15636 [(use (match_operand:SI 0 "register_operand"))
15637 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15638 "TARGET_USE_FANCY_MATH_387
15639 && ix86_libc_has_function (function_c99_misc)
15640 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15642 rtx mask = GEN_INT (0x45);
15643 rtx val = GEN_INT (0x05);
15647 rtx scratch = gen_reg_rtx (HImode);
15648 rtx res = gen_reg_rtx (QImode);
15650 /* Remove excess precision by forcing value through memory. */
15651 if (memory_operand (operands[1], VOIDmode))
15652 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15655 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15657 emit_move_insn (temp, operands[1]);
15658 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15661 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15662 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15663 cond = gen_rtx_fmt_ee (EQ, QImode,
15664 gen_rtx_REG (CCmode, FLAGS_REG),
15666 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15667 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15671 (define_expand "signbitxf2"
15672 [(use (match_operand:SI 0 "register_operand"))
15673 (use (match_operand:XF 1 "register_operand"))]
15674 "TARGET_USE_FANCY_MATH_387"
15676 rtx scratch = gen_reg_rtx (HImode);
15678 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15679 emit_insn (gen_andsi3 (operands[0],
15680 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15684 (define_insn "movmsk_df"
15685 [(set (match_operand:SI 0 "register_operand" "=r")
15687 [(match_operand:DF 1 "register_operand" "x")]
15689 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15690 "%vmovmskpd\t{%1, %0|%0, %1}"
15691 [(set_attr "type" "ssemov")
15692 (set_attr "prefix" "maybe_vex")
15693 (set_attr "mode" "DF")])
15695 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15696 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15697 (define_expand "signbitdf2"
15698 [(use (match_operand:SI 0 "register_operand"))
15699 (use (match_operand:DF 1 "register_operand"))]
15700 "TARGET_USE_FANCY_MATH_387
15701 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15703 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15705 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15706 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15710 rtx scratch = gen_reg_rtx (HImode);
15712 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15713 emit_insn (gen_andsi3 (operands[0],
15714 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15719 (define_expand "signbitsf2"
15720 [(use (match_operand:SI 0 "register_operand"))
15721 (use (match_operand:SF 1 "register_operand"))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15725 rtx scratch = gen_reg_rtx (HImode);
15727 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15728 emit_insn (gen_andsi3 (operands[0],
15729 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15733 ;; Block operation instructions
15736 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15739 [(set_attr "length" "1")
15740 (set_attr "length_immediate" "0")
15741 (set_attr "modrm" "0")])
15743 (define_expand "movmem<mode>"
15744 [(use (match_operand:BLK 0 "memory_operand"))
15745 (use (match_operand:BLK 1 "memory_operand"))
15746 (use (match_operand:SWI48 2 "nonmemory_operand"))
15747 (use (match_operand:SWI48 3 "const_int_operand"))
15748 (use (match_operand:SI 4 "const_int_operand"))
15749 (use (match_operand:SI 5 "const_int_operand"))
15750 (use (match_operand:SI 6 ""))
15751 (use (match_operand:SI 7 ""))
15752 (use (match_operand:SI 8 ""))]
15755 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15756 operands[2], NULL, operands[3],
15757 operands[4], operands[5],
15758 operands[6], operands[7],
15759 operands[8], false))
15765 ;; Most CPUs don't like single string operations
15766 ;; Handle this case here to simplify previous expander.
15768 (define_expand "strmov"
15769 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15770 (set (match_operand 1 "memory_operand") (match_dup 4))
15771 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15772 (clobber (reg:CC FLAGS_REG))])
15773 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15774 (clobber (reg:CC FLAGS_REG))])]
15777 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15779 /* If .md ever supports :P for Pmode, these can be directly
15780 in the pattern above. */
15781 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15782 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15784 /* Can't use this if the user has appropriated esi or edi. */
15785 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15786 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15788 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15789 operands[2], operands[3],
15790 operands[5], operands[6]));
15794 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15797 (define_expand "strmov_singleop"
15798 [(parallel [(set (match_operand 1 "memory_operand")
15799 (match_operand 3 "memory_operand"))
15800 (set (match_operand 0 "register_operand")
15802 (set (match_operand 2 "register_operand")
15803 (match_operand 5))])]
15805 "ix86_current_function_needs_cld = 1;")
15807 (define_insn "*strmovdi_rex_1"
15808 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15809 (mem:DI (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)
15817 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15819 [(set_attr "type" "str")
15820 (set_attr "memory" "both")
15821 (set_attr "mode" "DI")])
15823 (define_insn "*strmovsi_1"
15824 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15825 (mem:SI (match_operand:P 3 "register_operand" "1")))
15826 (set (match_operand:P 0 "register_operand" "=D")
15827 (plus:P (match_dup 2)
15829 (set (match_operand:P 1 "register_operand" "=S")
15830 (plus:P (match_dup 3)
15832 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15834 [(set_attr "type" "str")
15835 (set_attr "memory" "both")
15836 (set_attr "mode" "SI")])
15838 (define_insn "*strmovhi_1"
15839 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15840 (mem:HI (match_operand:P 3 "register_operand" "1")))
15841 (set (match_operand:P 0 "register_operand" "=D")
15842 (plus:P (match_dup 2)
15844 (set (match_operand:P 1 "register_operand" "=S")
15845 (plus:P (match_dup 3)
15847 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15849 [(set_attr "type" "str")
15850 (set_attr "memory" "both")
15851 (set_attr "mode" "HI")])
15853 (define_insn "*strmovqi_1"
15854 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15855 (mem:QI (match_operand:P 3 "register_operand" "1")))
15856 (set (match_operand:P 0 "register_operand" "=D")
15857 (plus:P (match_dup 2)
15859 (set (match_operand:P 1 "register_operand" "=S")
15860 (plus:P (match_dup 3)
15862 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15864 [(set_attr "type" "str")
15865 (set_attr "memory" "both")
15866 (set (attr "prefix_rex")
15868 (match_test "<P:MODE>mode == DImode")
15870 (const_string "*")))
15871 (set_attr "mode" "QI")])
15873 (define_expand "rep_mov"
15874 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15875 (set (match_operand 0 "register_operand")
15877 (set (match_operand 2 "register_operand")
15879 (set (match_operand 1 "memory_operand")
15880 (match_operand 3 "memory_operand"))
15881 (use (match_dup 4))])]
15883 "ix86_current_function_needs_cld = 1;")
15885 (define_insn "*rep_movdi_rex64"
15886 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15887 (set (match_operand:P 0 "register_operand" "=D")
15888 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15890 (match_operand:P 3 "register_operand" "0")))
15891 (set (match_operand:P 1 "register_operand" "=S")
15892 (plus:P (ashift:P (match_dup 5) (const_int 3))
15893 (match_operand:P 4 "register_operand" "1")))
15894 (set (mem:BLK (match_dup 3))
15895 (mem:BLK (match_dup 4)))
15896 (use (match_dup 5))]
15898 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15900 [(set_attr "type" "str")
15901 (set_attr "prefix_rep" "1")
15902 (set_attr "memory" "both")
15903 (set_attr "mode" "DI")])
15905 (define_insn "*rep_movsi"
15906 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15907 (set (match_operand:P 0 "register_operand" "=D")
15908 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15910 (match_operand:P 3 "register_operand" "0")))
15911 (set (match_operand:P 1 "register_operand" "=S")
15912 (plus:P (ashift:P (match_dup 5) (const_int 2))
15913 (match_operand:P 4 "register_operand" "1")))
15914 (set (mem:BLK (match_dup 3))
15915 (mem:BLK (match_dup 4)))
15916 (use (match_dup 5))]
15917 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15918 "%^rep{%;} movs{l|d}"
15919 [(set_attr "type" "str")
15920 (set_attr "prefix_rep" "1")
15921 (set_attr "memory" "both")
15922 (set_attr "mode" "SI")])
15924 (define_insn "*rep_movqi"
15925 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15926 (set (match_operand:P 0 "register_operand" "=D")
15927 (plus:P (match_operand:P 3 "register_operand" "0")
15928 (match_operand:P 5 "register_operand" "2")))
15929 (set (match_operand:P 1 "register_operand" "=S")
15930 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15931 (set (mem:BLK (match_dup 3))
15932 (mem:BLK (match_dup 4)))
15933 (use (match_dup 5))]
15934 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15936 [(set_attr "type" "str")
15937 (set_attr "prefix_rep" "1")
15938 (set_attr "memory" "both")
15939 (set_attr "mode" "QI")])
15941 (define_expand "setmem<mode>"
15942 [(use (match_operand:BLK 0 "memory_operand"))
15943 (use (match_operand:SWI48 1 "nonmemory_operand"))
15944 (use (match_operand:QI 2 "nonmemory_operand"))
15945 (use (match_operand 3 "const_int_operand"))
15946 (use (match_operand:SI 4 "const_int_operand"))
15947 (use (match_operand:SI 5 "const_int_operand"))
15948 (use (match_operand:SI 6 ""))
15949 (use (match_operand:SI 7 ""))
15950 (use (match_operand:SI 8 ""))]
15953 if (ix86_expand_set_or_movmem (operands[0], NULL,
15954 operands[1], operands[2],
15955 operands[3], operands[4],
15956 operands[5], operands[6],
15957 operands[7], operands[8], true))
15963 ;; Most CPUs don't like single string operations
15964 ;; Handle this case here to simplify previous expander.
15966 (define_expand "strset"
15967 [(set (match_operand 1 "memory_operand")
15968 (match_operand 2 "register_operand"))
15969 (parallel [(set (match_operand 0 "register_operand")
15971 (clobber (reg:CC FLAGS_REG))])]
15974 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15975 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15977 /* If .md ever supports :P for Pmode, this can be directly
15978 in the pattern above. */
15979 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15980 GEN_INT (GET_MODE_SIZE (GET_MODE
15982 /* Can't use this if the user has appropriated eax or edi. */
15983 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15984 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15986 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15992 (define_expand "strset_singleop"
15993 [(parallel [(set (match_operand 1 "memory_operand")
15994 (match_operand 2 "register_operand"))
15995 (set (match_operand 0 "register_operand")
15997 (unspec [(const_int 0)] UNSPEC_STOS)])]
15999 "ix86_current_function_needs_cld = 1;")
16001 (define_insn "*strsetdi_rex_1"
16002 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16003 (match_operand:DI 2 "register_operand" "a"))
16004 (set (match_operand:P 0 "register_operand" "=D")
16005 (plus:P (match_dup 1)
16007 (unspec [(const_int 0)] UNSPEC_STOS)]
16009 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16011 [(set_attr "type" "str")
16012 (set_attr "memory" "store")
16013 (set_attr "mode" "DI")])
16015 (define_insn "*strsetsi_1"
16016 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16017 (match_operand:SI 2 "register_operand" "a"))
16018 (set (match_operand:P 0 "register_operand" "=D")
16019 (plus:P (match_dup 1)
16021 (unspec [(const_int 0)] UNSPEC_STOS)]
16022 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16024 [(set_attr "type" "str")
16025 (set_attr "memory" "store")
16026 (set_attr "mode" "SI")])
16028 (define_insn "*strsethi_1"
16029 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16030 (match_operand:HI 2 "register_operand" "a"))
16031 (set (match_operand:P 0 "register_operand" "=D")
16032 (plus:P (match_dup 1)
16034 (unspec [(const_int 0)] UNSPEC_STOS)]
16035 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16037 [(set_attr "type" "str")
16038 (set_attr "memory" "store")
16039 (set_attr "mode" "HI")])
16041 (define_insn "*strsetqi_1"
16042 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16043 (match_operand:QI 2 "register_operand" "a"))
16044 (set (match_operand:P 0 "register_operand" "=D")
16045 (plus:P (match_dup 1)
16047 (unspec [(const_int 0)] UNSPEC_STOS)]
16048 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16050 [(set_attr "type" "str")
16051 (set_attr "memory" "store")
16052 (set (attr "prefix_rex")
16054 (match_test "<P:MODE>mode == DImode")
16056 (const_string "*")))
16057 (set_attr "mode" "QI")])
16059 (define_expand "rep_stos"
16060 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16061 (set (match_operand 0 "register_operand")
16063 (set (match_operand 2 "memory_operand") (const_int 0))
16064 (use (match_operand 3 "register_operand"))
16065 (use (match_dup 1))])]
16067 "ix86_current_function_needs_cld = 1;")
16069 (define_insn "*rep_stosdi_rex64"
16070 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16071 (set (match_operand:P 0 "register_operand" "=D")
16072 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16074 (match_operand:P 3 "register_operand" "0")))
16075 (set (mem:BLK (match_dup 3))
16077 (use (match_operand:DI 2 "register_operand" "a"))
16078 (use (match_dup 4))]
16080 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16082 [(set_attr "type" "str")
16083 (set_attr "prefix_rep" "1")
16084 (set_attr "memory" "store")
16085 (set_attr "mode" "DI")])
16087 (define_insn "*rep_stossi"
16088 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16089 (set (match_operand:P 0 "register_operand" "=D")
16090 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16092 (match_operand:P 3 "register_operand" "0")))
16093 (set (mem:BLK (match_dup 3))
16095 (use (match_operand:SI 2 "register_operand" "a"))
16096 (use (match_dup 4))]
16097 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16098 "%^rep{%;} stos{l|d}"
16099 [(set_attr "type" "str")
16100 (set_attr "prefix_rep" "1")
16101 (set_attr "memory" "store")
16102 (set_attr "mode" "SI")])
16104 (define_insn "*rep_stosqi"
16105 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16106 (set (match_operand:P 0 "register_operand" "=D")
16107 (plus:P (match_operand:P 3 "register_operand" "0")
16108 (match_operand:P 4 "register_operand" "1")))
16109 (set (mem:BLK (match_dup 3))
16111 (use (match_operand:QI 2 "register_operand" "a"))
16112 (use (match_dup 4))]
16113 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16115 [(set_attr "type" "str")
16116 (set_attr "prefix_rep" "1")
16117 (set_attr "memory" "store")
16118 (set (attr "prefix_rex")
16120 (match_test "<P:MODE>mode == DImode")
16122 (const_string "*")))
16123 (set_attr "mode" "QI")])
16125 (define_expand "cmpstrnsi"
16126 [(set (match_operand:SI 0 "register_operand")
16127 (compare:SI (match_operand:BLK 1 "general_operand")
16128 (match_operand:BLK 2 "general_operand")))
16129 (use (match_operand 3 "general_operand"))
16130 (use (match_operand 4 "immediate_operand"))]
16133 rtx addr1, addr2, out, outlow, count, countreg, align;
16135 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16138 /* Can't use this if the user has appropriated ecx, esi or edi. */
16139 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16144 out = gen_reg_rtx (SImode);
16146 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16147 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16148 if (addr1 != XEXP (operands[1], 0))
16149 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16150 if (addr2 != XEXP (operands[2], 0))
16151 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16153 count = operands[3];
16154 countreg = ix86_zero_extend_to_Pmode (count);
16156 /* %%% Iff we are testing strict equality, we can use known alignment
16157 to good advantage. This may be possible with combine, particularly
16158 once cc0 is dead. */
16159 align = operands[4];
16161 if (CONST_INT_P (count))
16163 if (INTVAL (count) == 0)
16165 emit_move_insn (operands[0], const0_rtx);
16168 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16169 operands[1], operands[2]));
16173 rtx (*gen_cmp) (rtx, rtx);
16175 gen_cmp = (TARGET_64BIT
16176 ? gen_cmpdi_1 : gen_cmpsi_1);
16178 emit_insn (gen_cmp (countreg, countreg));
16179 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16180 operands[1], operands[2]));
16183 outlow = gen_lowpart (QImode, out);
16184 emit_insn (gen_cmpintqi (outlow));
16185 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16187 if (operands[0] != out)
16188 emit_move_insn (operands[0], out);
16193 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16195 (define_expand "cmpintqi"
16196 [(set (match_dup 1)
16197 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16199 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16200 (parallel [(set (match_operand:QI 0 "register_operand")
16201 (minus:QI (match_dup 1)
16203 (clobber (reg:CC FLAGS_REG))])]
16206 operands[1] = gen_reg_rtx (QImode);
16207 operands[2] = gen_reg_rtx (QImode);
16210 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16211 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16213 (define_expand "cmpstrnqi_nz_1"
16214 [(parallel [(set (reg:CC FLAGS_REG)
16215 (compare:CC (match_operand 4 "memory_operand")
16216 (match_operand 5 "memory_operand")))
16217 (use (match_operand 2 "register_operand"))
16218 (use (match_operand:SI 3 "immediate_operand"))
16219 (clobber (match_operand 0 "register_operand"))
16220 (clobber (match_operand 1 "register_operand"))
16221 (clobber (match_dup 2))])]
16223 "ix86_current_function_needs_cld = 1;")
16225 (define_insn "*cmpstrnqi_nz_1"
16226 [(set (reg:CC FLAGS_REG)
16227 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16228 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16229 (use (match_operand:P 6 "register_operand" "2"))
16230 (use (match_operand:SI 3 "immediate_operand" "i"))
16231 (clobber (match_operand:P 0 "register_operand" "=S"))
16232 (clobber (match_operand:P 1 "register_operand" "=D"))
16233 (clobber (match_operand:P 2 "register_operand" "=c"))]
16234 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16236 [(set_attr "type" "str")
16237 (set_attr "mode" "QI")
16238 (set (attr "prefix_rex")
16240 (match_test "<P:MODE>mode == DImode")
16242 (const_string "*")))
16243 (set_attr "prefix_rep" "1")])
16245 ;; The same, but the count is not known to not be zero.
16247 (define_expand "cmpstrnqi_1"
16248 [(parallel [(set (reg:CC FLAGS_REG)
16249 (if_then_else:CC (ne (match_operand 2 "register_operand")
16251 (compare:CC (match_operand 4 "memory_operand")
16252 (match_operand 5 "memory_operand"))
16254 (use (match_operand:SI 3 "immediate_operand"))
16255 (use (reg:CC FLAGS_REG))
16256 (clobber (match_operand 0 "register_operand"))
16257 (clobber (match_operand 1 "register_operand"))
16258 (clobber (match_dup 2))])]
16260 "ix86_current_function_needs_cld = 1;")
16262 (define_insn "*cmpstrnqi_1"
16263 [(set (reg:CC FLAGS_REG)
16264 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16266 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16267 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16269 (use (match_operand:SI 3 "immediate_operand" "i"))
16270 (use (reg:CC FLAGS_REG))
16271 (clobber (match_operand:P 0 "register_operand" "=S"))
16272 (clobber (match_operand:P 1 "register_operand" "=D"))
16273 (clobber (match_operand:P 2 "register_operand" "=c"))]
16274 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16276 [(set_attr "type" "str")
16277 (set_attr "mode" "QI")
16278 (set (attr "prefix_rex")
16280 (match_test "<P:MODE>mode == DImode")
16282 (const_string "*")))
16283 (set_attr "prefix_rep" "1")])
16285 (define_expand "strlen<mode>"
16286 [(set (match_operand:P 0 "register_operand")
16287 (unspec:P [(match_operand:BLK 1 "general_operand")
16288 (match_operand:QI 2 "immediate_operand")
16289 (match_operand 3 "immediate_operand")]
16293 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16299 (define_expand "strlenqi_1"
16300 [(parallel [(set (match_operand 0 "register_operand")
16302 (clobber (match_operand 1 "register_operand"))
16303 (clobber (reg:CC FLAGS_REG))])]
16305 "ix86_current_function_needs_cld = 1;")
16307 (define_insn "*strlenqi_1"
16308 [(set (match_operand:P 0 "register_operand" "=&c")
16309 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16310 (match_operand:QI 2 "register_operand" "a")
16311 (match_operand:P 3 "immediate_operand" "i")
16312 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16313 (clobber (match_operand:P 1 "register_operand" "=D"))
16314 (clobber (reg:CC FLAGS_REG))]
16315 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16316 "%^repnz{%;} scasb"
16317 [(set_attr "type" "str")
16318 (set_attr "mode" "QI")
16319 (set (attr "prefix_rex")
16321 (match_test "<P:MODE>mode == DImode")
16323 (const_string "*")))
16324 (set_attr "prefix_rep" "1")])
16326 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16327 ;; handled in combine, but it is not currently up to the task.
16328 ;; When used for their truth value, the cmpstrn* expanders generate
16337 ;; The intermediate three instructions are unnecessary.
16339 ;; This one handles cmpstrn*_nz_1...
16342 (set (reg:CC FLAGS_REG)
16343 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16344 (mem:BLK (match_operand 5 "register_operand"))))
16345 (use (match_operand 6 "register_operand"))
16346 (use (match_operand:SI 3 "immediate_operand"))
16347 (clobber (match_operand 0 "register_operand"))
16348 (clobber (match_operand 1 "register_operand"))
16349 (clobber (match_operand 2 "register_operand"))])
16350 (set (match_operand:QI 7 "register_operand")
16351 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16352 (set (match_operand:QI 8 "register_operand")
16353 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16354 (set (reg FLAGS_REG)
16355 (compare (match_dup 7) (match_dup 8)))
16357 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16359 (set (reg:CC FLAGS_REG)
16360 (compare:CC (mem:BLK (match_dup 4))
16361 (mem:BLK (match_dup 5))))
16362 (use (match_dup 6))
16363 (use (match_dup 3))
16364 (clobber (match_dup 0))
16365 (clobber (match_dup 1))
16366 (clobber (match_dup 2))])])
16368 ;; ...and this one handles cmpstrn*_1.
16371 (set (reg:CC FLAGS_REG)
16372 (if_then_else:CC (ne (match_operand 6 "register_operand")
16374 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16375 (mem:BLK (match_operand 5 "register_operand")))
16377 (use (match_operand:SI 3 "immediate_operand"))
16378 (use (reg:CC FLAGS_REG))
16379 (clobber (match_operand 0 "register_operand"))
16380 (clobber (match_operand 1 "register_operand"))
16381 (clobber (match_operand 2 "register_operand"))])
16382 (set (match_operand:QI 7 "register_operand")
16383 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16384 (set (match_operand:QI 8 "register_operand")
16385 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16386 (set (reg FLAGS_REG)
16387 (compare (match_dup 7) (match_dup 8)))
16389 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16391 (set (reg:CC FLAGS_REG)
16392 (if_then_else:CC (ne (match_dup 6)
16394 (compare:CC (mem:BLK (match_dup 4))
16395 (mem:BLK (match_dup 5)))
16397 (use (match_dup 3))
16398 (use (reg:CC FLAGS_REG))
16399 (clobber (match_dup 0))
16400 (clobber (match_dup 1))
16401 (clobber (match_dup 2))])])
16403 ;; Conditional move instructions.
16405 (define_expand "mov<mode>cc"
16406 [(set (match_operand:SWIM 0 "register_operand")
16407 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16408 (match_operand:SWIM 2 "<general_operand>")
16409 (match_operand:SWIM 3 "<general_operand>")))]
16411 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16413 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16414 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16415 ;; So just document what we're doing explicitly.
16417 (define_expand "x86_mov<mode>cc_0_m1"
16419 [(set (match_operand:SWI48 0 "register_operand")
16420 (if_then_else:SWI48
16421 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16422 [(match_operand 1 "flags_reg_operand")
16426 (clobber (reg:CC FLAGS_REG))])])
16428 (define_insn "*x86_mov<mode>cc_0_m1"
16429 [(set (match_operand:SWI48 0 "register_operand" "=r")
16430 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16431 [(reg FLAGS_REG) (const_int 0)])
16434 (clobber (reg:CC FLAGS_REG))]
16436 "sbb{<imodesuffix>}\t%0, %0"
16437 ; Since we don't have the proper number of operands for an alu insn,
16438 ; fill in all the blanks.
16439 [(set_attr "type" "alu")
16440 (set_attr "use_carry" "1")
16441 (set_attr "pent_pair" "pu")
16442 (set_attr "memory" "none")
16443 (set_attr "imm_disp" "false")
16444 (set_attr "mode" "<MODE>")
16445 (set_attr "length_immediate" "0")])
16447 (define_insn "*x86_mov<mode>cc_0_m1_se"
16448 [(set (match_operand:SWI48 0 "register_operand" "=r")
16449 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16450 [(reg FLAGS_REG) (const_int 0)])
16453 (clobber (reg:CC FLAGS_REG))]
16455 "sbb{<imodesuffix>}\t%0, %0"
16456 [(set_attr "type" "alu")
16457 (set_attr "use_carry" "1")
16458 (set_attr "pent_pair" "pu")
16459 (set_attr "memory" "none")
16460 (set_attr "imm_disp" "false")
16461 (set_attr "mode" "<MODE>")
16462 (set_attr "length_immediate" "0")])
16464 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16465 [(set (match_operand:SWI48 0 "register_operand" "=r")
16466 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16467 [(reg FLAGS_REG) (const_int 0)])))
16468 (clobber (reg:CC FLAGS_REG))]
16470 "sbb{<imodesuffix>}\t%0, %0"
16471 [(set_attr "type" "alu")
16472 (set_attr "use_carry" "1")
16473 (set_attr "pent_pair" "pu")
16474 (set_attr "memory" "none")
16475 (set_attr "imm_disp" "false")
16476 (set_attr "mode" "<MODE>")
16477 (set_attr "length_immediate" "0")])
16479 (define_insn "*mov<mode>cc_noc"
16480 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16481 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)])
16483 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16484 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16485 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16487 cmov%O2%C1\t{%2, %0|%0, %2}
16488 cmov%O2%c1\t{%3, %0|%0, %3}"
16489 [(set_attr "type" "icmov")
16490 (set_attr "mode" "<MODE>")])
16492 ;; Don't do conditional moves with memory inputs. This splitter helps
16493 ;; register starved x86_32 by forcing inputs into registers before reload.
16495 [(set (match_operand:SWI248 0 "register_operand")
16496 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16497 [(reg FLAGS_REG) (const_int 0)])
16498 (match_operand:SWI248 2 "nonimmediate_operand")
16499 (match_operand:SWI248 3 "nonimmediate_operand")))]
16500 "!TARGET_64BIT && TARGET_CMOVE
16501 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16502 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16503 && can_create_pseudo_p ()
16504 && optimize_insn_for_speed_p ()"
16505 [(set (match_dup 0)
16506 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16508 if (MEM_P (operands[2]))
16509 operands[2] = force_reg (<MODE>mode, operands[2]);
16510 if (MEM_P (operands[3]))
16511 operands[3] = force_reg (<MODE>mode, operands[3]);
16514 (define_insn "*movqicc_noc"
16515 [(set (match_operand:QI 0 "register_operand" "=r,r")
16516 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16517 [(reg FLAGS_REG) (const_int 0)])
16518 (match_operand:QI 2 "register_operand" "r,0")
16519 (match_operand:QI 3 "register_operand" "0,r")))]
16520 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16522 [(set_attr "type" "icmov")
16523 (set_attr "mode" "QI")])
16526 [(set (match_operand:SWI12 0 "register_operand")
16527 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16528 [(reg FLAGS_REG) (const_int 0)])
16529 (match_operand:SWI12 2 "register_operand")
16530 (match_operand:SWI12 3 "register_operand")))]
16531 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16532 && reload_completed"
16533 [(set (match_dup 0)
16534 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16536 operands[0] = gen_lowpart (SImode, operands[0]);
16537 operands[2] = gen_lowpart (SImode, operands[2]);
16538 operands[3] = gen_lowpart (SImode, operands[3]);
16541 ;; Don't do conditional moves with memory inputs
16543 [(match_scratch:SWI248 2 "r")
16544 (set (match_operand:SWI248 0 "register_operand")
16545 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16546 [(reg FLAGS_REG) (const_int 0)])
16548 (match_operand:SWI248 3 "memory_operand")))]
16549 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16550 && optimize_insn_for_speed_p ()"
16551 [(set (match_dup 2) (match_dup 3))
16553 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16556 [(match_scratch:SWI248 2 "r")
16557 (set (match_operand:SWI248 0 "register_operand")
16558 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16559 [(reg FLAGS_REG) (const_int 0)])
16560 (match_operand:SWI248 3 "memory_operand")
16562 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16563 && optimize_insn_for_speed_p ()"
16564 [(set (match_dup 2) (match_dup 3))
16566 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16568 (define_expand "mov<mode>cc"
16569 [(set (match_operand:X87MODEF 0 "register_operand")
16570 (if_then_else:X87MODEF
16571 (match_operand 1 "comparison_operator")
16572 (match_operand:X87MODEF 2 "register_operand")
16573 (match_operand:X87MODEF 3 "register_operand")))]
16574 "(TARGET_80387 && TARGET_CMOVE)
16575 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16576 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16578 (define_insn "*movxfcc_1"
16579 [(set (match_operand:XF 0 "register_operand" "=f,f")
16580 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16581 [(reg FLAGS_REG) (const_int 0)])
16582 (match_operand:XF 2 "register_operand" "f,0")
16583 (match_operand:XF 3 "register_operand" "0,f")))]
16584 "TARGET_80387 && TARGET_CMOVE"
16586 fcmov%F1\t{%2, %0|%0, %2}
16587 fcmov%f1\t{%3, %0|%0, %3}"
16588 [(set_attr "type" "fcmov")
16589 (set_attr "mode" "XF")])
16591 (define_insn "*movdfcc_1"
16592 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16593 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16594 [(reg FLAGS_REG) (const_int 0)])
16595 (match_operand:DF 2 "nonimmediate_operand"
16597 (match_operand:DF 3 "nonimmediate_operand"
16598 "0 ,f,0 ,rm,0, rm")))]
16599 "TARGET_80387 && TARGET_CMOVE
16600 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16602 fcmov%F1\t{%2, %0|%0, %2}
16603 fcmov%f1\t{%3, %0|%0, %3}
16606 cmov%O2%C1\t{%2, %0|%0, %2}
16607 cmov%O2%c1\t{%3, %0|%0, %3}"
16608 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16609 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16610 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16613 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16614 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16615 [(reg FLAGS_REG) (const_int 0)])
16616 (match_operand:DF 2 "nonimmediate_operand")
16617 (match_operand:DF 3 "nonimmediate_operand")))]
16618 "!TARGET_64BIT && reload_completed"
16619 [(set (match_dup 2)
16620 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16622 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16624 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16625 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16628 (define_insn "*movsfcc_1_387"
16629 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16630 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16631 [(reg FLAGS_REG) (const_int 0)])
16632 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16633 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16634 "TARGET_80387 && TARGET_CMOVE
16635 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16637 fcmov%F1\t{%2, %0|%0, %2}
16638 fcmov%f1\t{%3, %0|%0, %3}
16639 cmov%O2%C1\t{%2, %0|%0, %2}
16640 cmov%O2%c1\t{%3, %0|%0, %3}"
16641 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16642 (set_attr "mode" "SF,SF,SI,SI")])
16644 ;; Don't do conditional moves with memory inputs. This splitter helps
16645 ;; register starved x86_32 by forcing inputs into registers before reload.
16647 [(set (match_operand:MODEF 0 "register_operand")
16648 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16649 [(reg FLAGS_REG) (const_int 0)])
16650 (match_operand:MODEF 2 "nonimmediate_operand")
16651 (match_operand:MODEF 3 "nonimmediate_operand")))]
16652 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16653 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16654 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16655 && can_create_pseudo_p ()
16656 && optimize_insn_for_speed_p ()"
16657 [(set (match_dup 0)
16658 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16660 if (MEM_P (operands[2]))
16661 operands[2] = force_reg (<MODE>mode, operands[2]);
16662 if (MEM_P (operands[3]))
16663 operands[3] = force_reg (<MODE>mode, operands[3]);
16666 ;; Don't do conditional moves with memory inputs
16668 [(match_scratch:MODEF 2 "r")
16669 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16670 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16671 [(reg FLAGS_REG) (const_int 0)])
16673 (match_operand:MODEF 3 "memory_operand")))]
16674 "(<MODE>mode != DFmode || TARGET_64BIT)
16675 && TARGET_80387 && TARGET_CMOVE
16676 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16677 && optimize_insn_for_speed_p ()"
16678 [(set (match_dup 2) (match_dup 3))
16680 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16683 [(match_scratch:MODEF 2 "r")
16684 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16685 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16686 [(reg FLAGS_REG) (const_int 0)])
16687 (match_operand:MODEF 3 "memory_operand")
16689 "(<MODE>mode != DFmode || TARGET_64BIT)
16690 && TARGET_80387 && TARGET_CMOVE
16691 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16692 && optimize_insn_for_speed_p ()"
16693 [(set (match_dup 2) (match_dup 3))
16695 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16697 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16698 ;; the scalar versions to have only XMM registers as operands.
16700 ;; XOP conditional move
16701 (define_insn "*xop_pcmov_<mode>"
16702 [(set (match_operand:MODEF 0 "register_operand" "=x")
16703 (if_then_else:MODEF
16704 (match_operand:MODEF 1 "register_operand" "x")
16705 (match_operand:MODEF 2 "register_operand" "x")
16706 (match_operand:MODEF 3 "register_operand" "x")))]
16708 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16709 [(set_attr "type" "sse4arg")])
16711 ;; These versions of the min/max patterns are intentionally ignorant of
16712 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16713 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16714 ;; are undefined in this condition, we're certain this is correct.
16716 (define_insn "<code><mode>3"
16717 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16719 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16720 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16721 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16723 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16724 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16725 [(set_attr "isa" "noavx,avx")
16726 (set_attr "prefix" "orig,vex")
16727 (set_attr "type" "sseadd")
16728 (set_attr "mode" "<MODE>")])
16730 ;; These versions of the min/max patterns implement exactly the operations
16731 ;; min = (op1 < op2 ? op1 : op2)
16732 ;; max = (!(op1 < op2) ? op1 : op2)
16733 ;; Their operands are not commutative, and thus they may be used in the
16734 ;; presence of -0.0 and NaN.
16736 (define_int_iterator IEEE_MAXMIN
16740 (define_int_attr ieee_maxmin
16741 [(UNSPEC_IEEE_MAX "max")
16742 (UNSPEC_IEEE_MIN "min")])
16744 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16745 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16747 [(match_operand:MODEF 1 "register_operand" "0,x")
16748 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16750 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16752 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16753 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16754 [(set_attr "isa" "noavx,avx")
16755 (set_attr "prefix" "orig,vex")
16756 (set_attr "type" "sseadd")
16757 (set_attr "mode" "<MODE>")])
16759 ;; Make two stack loads independent:
16761 ;; fld %st(0) -> fld bb
16762 ;; fmul bb fmul %st(1), %st
16764 ;; Actually we only match the last two instructions for simplicity.
16766 [(set (match_operand 0 "fp_register_operand")
16767 (match_operand 1 "fp_register_operand"))
16769 (match_operator 2 "binary_fp_operator"
16771 (match_operand 3 "memory_operand")]))]
16772 "REGNO (operands[0]) != REGNO (operands[1])"
16773 [(set (match_dup 0) (match_dup 3))
16774 (set (match_dup 0) (match_dup 4))]
16776 ;; The % modifier is not operational anymore in peephole2's, so we have to
16777 ;; swap the operands manually in the case of addition and multiplication.
16781 if (COMMUTATIVE_ARITH_P (operands[2]))
16782 op0 = operands[0], op1 = operands[1];
16784 op0 = operands[1], op1 = operands[0];
16786 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16787 GET_MODE (operands[2]),
16791 ;; Conditional addition patterns
16792 (define_expand "add<mode>cc"
16793 [(match_operand:SWI 0 "register_operand")
16794 (match_operand 1 "ordered_comparison_operator")
16795 (match_operand:SWI 2 "register_operand")
16796 (match_operand:SWI 3 "const_int_operand")]
16798 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16800 ;; Misc patterns (?)
16802 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16803 ;; Otherwise there will be nothing to keep
16805 ;; [(set (reg ebp) (reg esp))]
16806 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16807 ;; (clobber (eflags)]
16808 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16810 ;; in proper program order.
16812 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16813 [(set (match_operand:P 0 "register_operand" "=r,r")
16814 (plus:P (match_operand:P 1 "register_operand" "0,r")
16815 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16816 (clobber (reg:CC FLAGS_REG))
16817 (clobber (mem:BLK (scratch)))]
16820 switch (get_attr_type (insn))
16823 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16827 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16828 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16830 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16833 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16834 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16837 [(set (attr "type")
16838 (cond [(and (eq_attr "alternative" "0")
16839 (not (match_test "TARGET_OPT_AGU")))
16840 (const_string "alu")
16841 (match_operand:<MODE> 2 "const0_operand")
16842 (const_string "imov")
16844 (const_string "lea")))
16845 (set (attr "length_immediate")
16846 (cond [(eq_attr "type" "imov")
16848 (and (eq_attr "type" "alu")
16849 (match_operand 2 "const128_operand"))
16852 (const_string "*")))
16853 (set_attr "mode" "<MODE>")])
16855 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16856 [(set (match_operand:P 0 "register_operand" "=r")
16857 (minus:P (match_operand:P 1 "register_operand" "0")
16858 (match_operand:P 2 "register_operand" "r")))
16859 (clobber (reg:CC FLAGS_REG))
16860 (clobber (mem:BLK (scratch)))]
16862 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16863 [(set_attr "type" "alu")
16864 (set_attr "mode" "<MODE>")])
16866 (define_insn "allocate_stack_worker_probe_<mode>"
16867 [(set (match_operand:P 0 "register_operand" "=a")
16868 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16869 UNSPECV_STACK_PROBE))
16870 (clobber (reg:CC FLAGS_REG))]
16871 "ix86_target_stack_probe ()"
16872 "call\t___chkstk_ms"
16873 [(set_attr "type" "multi")
16874 (set_attr "length" "5")])
16876 (define_expand "allocate_stack"
16877 [(match_operand 0 "register_operand")
16878 (match_operand 1 "general_operand")]
16879 "ix86_target_stack_probe ()"
16883 #ifndef CHECK_STACK_LIMIT
16884 #define CHECK_STACK_LIMIT 0
16887 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16888 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16892 rtx (*insn) (rtx, rtx);
16894 x = copy_to_mode_reg (Pmode, operands[1]);
16896 insn = (TARGET_64BIT
16897 ? gen_allocate_stack_worker_probe_di
16898 : gen_allocate_stack_worker_probe_si);
16900 emit_insn (insn (x, x));
16903 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16904 stack_pointer_rtx, 0, OPTAB_DIRECT);
16906 if (x != stack_pointer_rtx)
16907 emit_move_insn (stack_pointer_rtx, x);
16909 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16913 ;; Use IOR for stack probes, this is shorter.
16914 (define_expand "probe_stack"
16915 [(match_operand 0 "memory_operand")]
16918 rtx (*gen_ior3) (rtx, rtx, rtx);
16920 gen_ior3 = (GET_MODE (operands[0]) == DImode
16921 ? gen_iordi3 : gen_iorsi3);
16923 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16927 (define_insn "adjust_stack_and_probe<mode>"
16928 [(set (match_operand:P 0 "register_operand" "=r")
16929 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16930 UNSPECV_PROBE_STACK_RANGE))
16931 (set (reg:P SP_REG)
16932 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16933 (clobber (reg:CC FLAGS_REG))
16934 (clobber (mem:BLK (scratch)))]
16936 "* return output_adjust_stack_and_probe (operands[0]);"
16937 [(set_attr "type" "multi")])
16939 (define_insn "probe_stack_range<mode>"
16940 [(set (match_operand:P 0 "register_operand" "=r")
16941 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16942 (match_operand:P 2 "const_int_operand" "n")]
16943 UNSPECV_PROBE_STACK_RANGE))
16944 (clobber (reg:CC FLAGS_REG))]
16946 "* return output_probe_stack_range (operands[0], operands[2]);"
16947 [(set_attr "type" "multi")])
16949 (define_expand "builtin_setjmp_receiver"
16950 [(label_ref (match_operand 0))]
16951 "!TARGET_64BIT && flag_pic"
16957 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16958 rtx_code_label *label_rtx = gen_label_rtx ();
16959 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16960 xops[0] = xops[1] = picreg;
16961 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16962 ix86_expand_binary_operator (MINUS, SImode, xops);
16966 emit_insn (gen_set_got (pic_offset_table_rtx));
16970 (define_insn_and_split "nonlocal_goto_receiver"
16971 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16972 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16974 "&& reload_completed"
16977 if (crtl->uses_pic_offset_table)
16980 rtx label_rtx = gen_label_rtx ();
16983 /* Get a new pic base. */
16984 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16985 /* Correct this with the offset from the new to the old. */
16986 xops[0] = xops[1] = pic_offset_table_rtx;
16987 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16988 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16989 UNSPEC_MACHOPIC_OFFSET);
16990 xops[2] = gen_rtx_CONST (Pmode, tmp);
16991 ix86_expand_binary_operator (MINUS, SImode, xops);
16994 /* No pic reg restore needed. */
16995 emit_note (NOTE_INSN_DELETED);
17000 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17001 ;; Do not split instructions with mask registers.
17003 [(set (match_operand 0 "general_reg_operand")
17004 (match_operator 3 "promotable_binary_operator"
17005 [(match_operand 1 "general_reg_operand")
17006 (match_operand 2 "aligned_operand")]))
17007 (clobber (reg:CC FLAGS_REG))]
17008 "! TARGET_PARTIAL_REG_STALL && reload_completed
17009 && ((GET_MODE (operands[0]) == HImode
17010 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17011 /* ??? next two lines just !satisfies_constraint_K (...) */
17012 || !CONST_INT_P (operands[2])
17013 || satisfies_constraint_K (operands[2])))
17014 || (GET_MODE (operands[0]) == QImode
17015 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17016 [(parallel [(set (match_dup 0)
17017 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17018 (clobber (reg:CC FLAGS_REG))])]
17020 operands[0] = gen_lowpart (SImode, operands[0]);
17021 operands[1] = gen_lowpart (SImode, operands[1]);
17022 if (GET_CODE (operands[3]) != ASHIFT)
17023 operands[2] = gen_lowpart (SImode, operands[2]);
17024 PUT_MODE (operands[3], SImode);
17027 ; Promote the QImode tests, as i386 has encoding of the AND
17028 ; instruction with 32-bit sign-extended immediate and thus the
17029 ; instruction size is unchanged, except in the %eax case for
17030 ; which it is increased by one byte, hence the ! optimize_size.
17032 [(set (match_operand 0 "flags_reg_operand")
17033 (match_operator 2 "compare_operator"
17034 [(and (match_operand 3 "aligned_operand")
17035 (match_operand 4 "const_int_operand"))
17037 (set (match_operand 1 "register_operand")
17038 (and (match_dup 3) (match_dup 4)))]
17039 "! TARGET_PARTIAL_REG_STALL && reload_completed
17040 && optimize_insn_for_speed_p ()
17041 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17042 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17043 /* Ensure that the operand will remain sign-extended immediate. */
17044 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17045 [(parallel [(set (match_dup 0)
17046 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17049 (and:SI (match_dup 3) (match_dup 4)))])]
17052 = gen_int_mode (INTVAL (operands[4])
17053 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17054 operands[1] = gen_lowpart (SImode, operands[1]);
17055 operands[3] = gen_lowpart (SImode, operands[3]);
17058 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17059 ; the TEST instruction with 32-bit sign-extended immediate and thus
17060 ; the instruction size would at least double, which is not what we
17061 ; want even with ! optimize_size.
17063 [(set (match_operand 0 "flags_reg_operand")
17064 (match_operator 1 "compare_operator"
17065 [(and (match_operand:HI 2 "aligned_operand")
17066 (match_operand:HI 3 "const_int_operand"))
17068 "! TARGET_PARTIAL_REG_STALL && reload_completed
17069 && ! TARGET_FAST_PREFIX
17070 && optimize_insn_for_speed_p ()
17071 /* Ensure that the operand will remain sign-extended immediate. */
17072 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17073 [(set (match_dup 0)
17074 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17078 = gen_int_mode (INTVAL (operands[3])
17079 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17080 operands[2] = gen_lowpart (SImode, operands[2]);
17084 [(set (match_operand 0 "register_operand")
17085 (neg (match_operand 1 "register_operand")))
17086 (clobber (reg:CC FLAGS_REG))]
17087 "! TARGET_PARTIAL_REG_STALL && reload_completed
17088 && (GET_MODE (operands[0]) == HImode
17089 || (GET_MODE (operands[0]) == QImode
17090 && (TARGET_PROMOTE_QImode
17091 || optimize_insn_for_size_p ())))"
17092 [(parallel [(set (match_dup 0)
17093 (neg:SI (match_dup 1)))
17094 (clobber (reg:CC FLAGS_REG))])]
17096 operands[0] = gen_lowpart (SImode, operands[0]);
17097 operands[1] = gen_lowpart (SImode, operands[1]);
17100 ;; Do not split instructions with mask regs.
17102 [(set (match_operand 0 "general_reg_operand")
17103 (not (match_operand 1 "general_reg_operand")))]
17104 "! TARGET_PARTIAL_REG_STALL && reload_completed
17105 && (GET_MODE (operands[0]) == HImode
17106 || (GET_MODE (operands[0]) == QImode
17107 && (TARGET_PROMOTE_QImode
17108 || optimize_insn_for_size_p ())))"
17109 [(set (match_dup 0)
17110 (not:SI (match_dup 1)))]
17112 operands[0] = gen_lowpart (SImode, operands[0]);
17113 operands[1] = gen_lowpart (SImode, operands[1]);
17116 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17117 ;; transform a complex memory operation into two memory to register operations.
17119 ;; Don't push memory operands
17121 [(set (match_operand:SWI 0 "push_operand")
17122 (match_operand:SWI 1 "memory_operand"))
17123 (match_scratch:SWI 2 "<r>")]
17124 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17125 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17126 [(set (match_dup 2) (match_dup 1))
17127 (set (match_dup 0) (match_dup 2))])
17129 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17132 [(set (match_operand:SF 0 "push_operand")
17133 (match_operand:SF 1 "memory_operand"))
17134 (match_scratch:SF 2 "r")]
17135 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17136 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17137 [(set (match_dup 2) (match_dup 1))
17138 (set (match_dup 0) (match_dup 2))])
17140 ;; Don't move an immediate directly to memory when the instruction
17141 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17143 [(match_scratch:SWI124 1 "<r>")
17144 (set (match_operand:SWI124 0 "memory_operand")
17146 "optimize_insn_for_speed_p ()
17147 && ((<MODE>mode == HImode
17148 && TARGET_LCP_STALL)
17149 || (!TARGET_USE_MOV0
17150 && TARGET_SPLIT_LONG_MOVES
17151 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17152 && peep2_regno_dead_p (0, FLAGS_REG)"
17153 [(parallel [(set (match_dup 2) (const_int 0))
17154 (clobber (reg:CC FLAGS_REG))])
17155 (set (match_dup 0) (match_dup 1))]
17156 "operands[2] = gen_lowpart (SImode, operands[1]);")
17159 [(match_scratch:SWI124 2 "<r>")
17160 (set (match_operand:SWI124 0 "memory_operand")
17161 (match_operand:SWI124 1 "immediate_operand"))]
17162 "optimize_insn_for_speed_p ()
17163 && ((<MODE>mode == HImode
17164 && TARGET_LCP_STALL)
17165 || (TARGET_SPLIT_LONG_MOVES
17166 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17167 [(set (match_dup 2) (match_dup 1))
17168 (set (match_dup 0) (match_dup 2))])
17170 ;; Don't compare memory with zero, load and use a test instead.
17172 [(set (match_operand 0 "flags_reg_operand")
17173 (match_operator 1 "compare_operator"
17174 [(match_operand:SI 2 "memory_operand")
17176 (match_scratch:SI 3 "r")]
17177 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17178 [(set (match_dup 3) (match_dup 2))
17179 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17181 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17182 ;; Don't split NOTs with a displacement operand, because resulting XOR
17183 ;; will not be pairable anyway.
17185 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17186 ;; represented using a modRM byte. The XOR replacement is long decoded,
17187 ;; so this split helps here as well.
17189 ;; Note: Can't do this as a regular split because we can't get proper
17190 ;; lifetime information then.
17193 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17194 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17195 "optimize_insn_for_speed_p ()
17196 && ((TARGET_NOT_UNPAIRABLE
17197 && (!MEM_P (operands[0])
17198 || !memory_displacement_operand (operands[0], <MODE>mode)))
17199 || (TARGET_NOT_VECTORMODE
17200 && long_memory_operand (operands[0], <MODE>mode)))
17201 && peep2_regno_dead_p (0, FLAGS_REG)"
17202 [(parallel [(set (match_dup 0)
17203 (xor:SWI124 (match_dup 1) (const_int -1)))
17204 (clobber (reg:CC FLAGS_REG))])])
17206 ;; Non pairable "test imm, reg" instructions can be translated to
17207 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17208 ;; byte opcode instead of two, have a short form for byte operands),
17209 ;; so do it for other CPUs as well. Given that the value was dead,
17210 ;; this should not create any new dependencies. Pass on the sub-word
17211 ;; versions if we're concerned about partial register stalls.
17214 [(set (match_operand 0 "flags_reg_operand")
17215 (match_operator 1 "compare_operator"
17216 [(and:SI (match_operand:SI 2 "register_operand")
17217 (match_operand:SI 3 "immediate_operand"))
17219 "ix86_match_ccmode (insn, CCNOmode)
17220 && (true_regnum (operands[2]) != AX_REG
17221 || satisfies_constraint_K (operands[3]))
17222 && peep2_reg_dead_p (1, operands[2])"
17224 [(set (match_dup 0)
17225 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17228 (and:SI (match_dup 2) (match_dup 3)))])])
17230 ;; We don't need to handle HImode case, because it will be promoted to SImode
17231 ;; on ! TARGET_PARTIAL_REG_STALL
17234 [(set (match_operand 0 "flags_reg_operand")
17235 (match_operator 1 "compare_operator"
17236 [(and:QI (match_operand:QI 2 "register_operand")
17237 (match_operand:QI 3 "immediate_operand"))
17239 "! TARGET_PARTIAL_REG_STALL
17240 && ix86_match_ccmode (insn, CCNOmode)
17241 && true_regnum (operands[2]) != AX_REG
17242 && peep2_reg_dead_p (1, operands[2])"
17244 [(set (match_dup 0)
17245 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17248 (and:QI (match_dup 2) (match_dup 3)))])])
17251 [(set (match_operand 0 "flags_reg_operand")
17252 (match_operator 1 "compare_operator"
17255 (match_operand 2 "ext_register_operand")
17258 (match_operand 3 "const_int_operand"))
17260 "! TARGET_PARTIAL_REG_STALL
17261 && ix86_match_ccmode (insn, CCNOmode)
17262 && true_regnum (operands[2]) != AX_REG
17263 && peep2_reg_dead_p (1, operands[2])"
17264 [(parallel [(set (match_dup 0)
17273 (set (zero_extract:SI (match_dup 2)
17281 (match_dup 3)))])])
17283 ;; Don't do logical operations with memory inputs.
17285 [(match_scratch:SI 2 "r")
17286 (parallel [(set (match_operand:SI 0 "register_operand")
17287 (match_operator:SI 3 "arith_or_logical_operator"
17289 (match_operand:SI 1 "memory_operand")]))
17290 (clobber (reg:CC FLAGS_REG))])]
17291 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17292 [(set (match_dup 2) (match_dup 1))
17293 (parallel [(set (match_dup 0)
17294 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17295 (clobber (reg:CC FLAGS_REG))])])
17298 [(match_scratch:SI 2 "r")
17299 (parallel [(set (match_operand:SI 0 "register_operand")
17300 (match_operator:SI 3 "arith_or_logical_operator"
17301 [(match_operand:SI 1 "memory_operand")
17303 (clobber (reg:CC FLAGS_REG))])]
17304 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17305 [(set (match_dup 2) (match_dup 1))
17306 (parallel [(set (match_dup 0)
17307 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17308 (clobber (reg:CC FLAGS_REG))])])
17310 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17311 ;; refers to the destination of the load!
17314 [(set (match_operand:SI 0 "register_operand")
17315 (match_operand:SI 1 "register_operand"))
17316 (parallel [(set (match_dup 0)
17317 (match_operator:SI 3 "commutative_operator"
17319 (match_operand:SI 2 "memory_operand")]))
17320 (clobber (reg:CC FLAGS_REG))])]
17321 "REGNO (operands[0]) != REGNO (operands[1])
17322 && GENERAL_REGNO_P (REGNO (operands[0]))
17323 && GENERAL_REGNO_P (REGNO (operands[1]))"
17324 [(set (match_dup 0) (match_dup 4))
17325 (parallel [(set (match_dup 0)
17326 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17327 (clobber (reg:CC FLAGS_REG))])]
17328 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17331 [(set (match_operand 0 "register_operand")
17332 (match_operand 1 "register_operand"))
17334 (match_operator 3 "commutative_operator"
17336 (match_operand 2 "memory_operand")]))]
17337 "REGNO (operands[0]) != REGNO (operands[1])
17338 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17339 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17340 [(set (match_dup 0) (match_dup 2))
17342 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17344 ; Don't do logical operations with memory outputs
17346 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17347 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17348 ; the same decoder scheduling characteristics as the original.
17351 [(match_scratch:SI 2 "r")
17352 (parallel [(set (match_operand:SI 0 "memory_operand")
17353 (match_operator:SI 3 "arith_or_logical_operator"
17355 (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 2) (match_dup 1)]))
17363 (clobber (reg:CC FLAGS_REG))])
17364 (set (match_dup 0) (match_dup 2))])
17367 [(match_scratch:SI 2 "r")
17368 (parallel [(set (match_operand:SI 0 "memory_operand")
17369 (match_operator:SI 3 "arith_or_logical_operator"
17370 [(match_operand:SI 1 "nonmemory_operand")
17372 (clobber (reg:CC FLAGS_REG))])]
17373 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17374 /* Do not split stack checking probes. */
17375 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17376 [(set (match_dup 2) (match_dup 0))
17377 (parallel [(set (match_dup 2)
17378 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17379 (clobber (reg:CC FLAGS_REG))])
17380 (set (match_dup 0) (match_dup 2))])
17382 ;; Attempt to use arith or logical operations with memory outputs with
17383 ;; setting of flags.
17385 [(set (match_operand:SWI 0 "register_operand")
17386 (match_operand:SWI 1 "memory_operand"))
17387 (parallel [(set (match_dup 0)
17388 (match_operator:SWI 3 "plusminuslogic_operator"
17390 (match_operand:SWI 2 "<nonmemory_operand>")]))
17391 (clobber (reg:CC FLAGS_REG))])
17392 (set (match_dup 1) (match_dup 0))
17393 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17394 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17395 && peep2_reg_dead_p (4, operands[0])
17396 && !reg_overlap_mentioned_p (operands[0], operands[1])
17397 && !reg_overlap_mentioned_p (operands[0], operands[2])
17398 && (<MODE>mode != QImode
17399 || immediate_operand (operands[2], QImode)
17400 || q_regs_operand (operands[2], QImode))
17401 && ix86_match_ccmode (peep2_next_insn (3),
17402 (GET_CODE (operands[3]) == PLUS
17403 || GET_CODE (operands[3]) == MINUS)
17404 ? CCGOCmode : CCNOmode)"
17405 [(parallel [(set (match_dup 4) (match_dup 5))
17406 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17407 (match_dup 2)]))])]
17409 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17410 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17411 copy_rtx (operands[1]),
17412 copy_rtx (operands[2]));
17413 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17414 operands[5], const0_rtx);
17418 [(parallel [(set (match_operand:SWI 0 "register_operand")
17419 (match_operator:SWI 2 "plusminuslogic_operator"
17421 (match_operand:SWI 1 "memory_operand")]))
17422 (clobber (reg:CC FLAGS_REG))])
17423 (set (match_dup 1) (match_dup 0))
17424 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17425 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17426 && GET_CODE (operands[2]) != MINUS
17427 && peep2_reg_dead_p (3, operands[0])
17428 && !reg_overlap_mentioned_p (operands[0], operands[1])
17429 && ix86_match_ccmode (peep2_next_insn (2),
17430 GET_CODE (operands[2]) == PLUS
17431 ? CCGOCmode : CCNOmode)"
17432 [(parallel [(set (match_dup 3) (match_dup 4))
17433 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17434 (match_dup 0)]))])]
17436 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17437 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17438 copy_rtx (operands[1]),
17439 copy_rtx (operands[0]));
17440 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17441 operands[4], const0_rtx);
17445 [(set (match_operand:SWI12 0 "register_operand")
17446 (match_operand:SWI12 1 "memory_operand"))
17447 (parallel [(set (match_operand:SI 4 "register_operand")
17448 (match_operator:SI 3 "plusminuslogic_operator"
17450 (match_operand:SI 2 "nonmemory_operand")]))
17451 (clobber (reg:CC FLAGS_REG))])
17452 (set (match_dup 1) (match_dup 0))
17453 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17454 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17455 && REG_P (operands[0]) && REG_P (operands[4])
17456 && REGNO (operands[0]) == REGNO (operands[4])
17457 && peep2_reg_dead_p (4, operands[0])
17458 && (<MODE>mode != QImode
17459 || immediate_operand (operands[2], SImode)
17460 || q_regs_operand (operands[2], SImode))
17461 && !reg_overlap_mentioned_p (operands[0], operands[1])
17462 && !reg_overlap_mentioned_p (operands[0], operands[2])
17463 && ix86_match_ccmode (peep2_next_insn (3),
17464 (GET_CODE (operands[3]) == PLUS
17465 || GET_CODE (operands[3]) == MINUS)
17466 ? CCGOCmode : CCNOmode)"
17467 [(parallel [(set (match_dup 4) (match_dup 5))
17468 (set (match_dup 1) (match_dup 6))])]
17470 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17471 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17472 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17473 copy_rtx (operands[1]), operands[2]);
17474 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17475 operands[5], const0_rtx);
17476 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17477 copy_rtx (operands[1]),
17478 copy_rtx (operands[2]));
17481 ;; Attempt to always use XOR for zeroing registers.
17483 [(set (match_operand 0 "register_operand")
17484 (match_operand 1 "const0_operand"))]
17485 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17486 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17487 && GENERAL_REG_P (operands[0])
17488 && peep2_regno_dead_p (0, FLAGS_REG)"
17489 [(parallel [(set (match_dup 0) (const_int 0))
17490 (clobber (reg:CC FLAGS_REG))])]
17491 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17494 [(set (strict_low_part (match_operand 0 "register_operand"))
17496 "(GET_MODE (operands[0]) == QImode
17497 || GET_MODE (operands[0]) == HImode)
17498 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17499 && peep2_regno_dead_p (0, FLAGS_REG)"
17500 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17501 (clobber (reg:CC FLAGS_REG))])])
17503 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17505 [(set (match_operand:SWI248 0 "register_operand")
17507 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17508 && peep2_regno_dead_p (0, FLAGS_REG)"
17509 [(parallel [(set (match_dup 0) (const_int -1))
17510 (clobber (reg:CC FLAGS_REG))])]
17512 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17513 operands[0] = gen_lowpart (SImode, operands[0]);
17516 ;; Attempt to convert simple lea to add/shift.
17517 ;; These can be created by move expanders.
17518 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17519 ;; relevant lea instructions were already split.
17522 [(set (match_operand:SWI48 0 "register_operand")
17523 (plus:SWI48 (match_dup 0)
17524 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17526 && peep2_regno_dead_p (0, FLAGS_REG)"
17527 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17528 (clobber (reg:CC FLAGS_REG))])])
17531 [(set (match_operand:SWI48 0 "register_operand")
17532 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17535 && peep2_regno_dead_p (0, FLAGS_REG)"
17536 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17537 (clobber (reg:CC FLAGS_REG))])])
17540 [(set (match_operand:DI 0 "register_operand")
17542 (plus:SI (match_operand:SI 1 "register_operand")
17543 (match_operand:SI 2 "nonmemory_operand"))))]
17544 "TARGET_64BIT && !TARGET_OPT_AGU
17545 && REGNO (operands[0]) == REGNO (operands[1])
17546 && peep2_regno_dead_p (0, FLAGS_REG)"
17547 [(parallel [(set (match_dup 0)
17548 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17549 (clobber (reg:CC FLAGS_REG))])])
17552 [(set (match_operand:DI 0 "register_operand")
17554 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17555 (match_operand:SI 2 "register_operand"))))]
17556 "TARGET_64BIT && !TARGET_OPT_AGU
17557 && REGNO (operands[0]) == REGNO (operands[2])
17558 && peep2_regno_dead_p (0, FLAGS_REG)"
17559 [(parallel [(set (match_dup 0)
17560 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17561 (clobber (reg:CC FLAGS_REG))])])
17564 [(set (match_operand:SWI48 0 "register_operand")
17565 (mult:SWI48 (match_dup 0)
17566 (match_operand:SWI48 1 "const_int_operand")))]
17567 "exact_log2 (INTVAL (operands[1])) >= 0
17568 && peep2_regno_dead_p (0, FLAGS_REG)"
17569 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17574 [(set (match_operand:DI 0 "register_operand")
17576 (mult:SI (match_operand:SI 1 "register_operand")
17577 (match_operand:SI 2 "const_int_operand"))))]
17579 && exact_log2 (INTVAL (operands[2])) >= 0
17580 && REGNO (operands[0]) == REGNO (operands[1])
17581 && peep2_regno_dead_p (0, FLAGS_REG)"
17582 [(parallel [(set (match_dup 0)
17583 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17584 (clobber (reg:CC FLAGS_REG))])]
17585 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17587 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17588 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17589 ;; On many CPUs it is also faster, since special hardware to avoid esp
17590 ;; dependencies is present.
17592 ;; While some of these conversions may be done using splitters, we use
17593 ;; peepholes in order to allow combine_stack_adjustments pass to see
17594 ;; nonobfuscated RTL.
17596 ;; Convert prologue esp subtractions to push.
17597 ;; We need register to push. In order to keep verify_flow_info happy we have
17599 ;; - use scratch and clobber it in order to avoid dependencies
17600 ;; - use already live register
17601 ;; We can't use the second way right now, since there is no reliable way how to
17602 ;; verify that given register is live. First choice will also most likely in
17603 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17604 ;; call clobbered registers are dead. We may want to use base pointer as an
17605 ;; alternative when no register is available later.
17608 [(match_scratch:W 1 "r")
17609 (parallel [(set (reg:P SP_REG)
17610 (plus:P (reg:P SP_REG)
17611 (match_operand:P 0 "const_int_operand")))
17612 (clobber (reg:CC FLAGS_REG))
17613 (clobber (mem:BLK (scratch)))])]
17614 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17615 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17616 [(clobber (match_dup 1))
17617 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17618 (clobber (mem:BLK (scratch)))])])
17621 [(match_scratch:W 1 "r")
17622 (parallel [(set (reg:P SP_REG)
17623 (plus:P (reg:P SP_REG)
17624 (match_operand:P 0 "const_int_operand")))
17625 (clobber (reg:CC FLAGS_REG))
17626 (clobber (mem:BLK (scratch)))])]
17627 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17628 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17629 [(clobber (match_dup 1))
17630 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17631 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17632 (clobber (mem:BLK (scratch)))])])
17634 ;; Convert esp subtractions to push.
17636 [(match_scratch:W 1 "r")
17637 (parallel [(set (reg:P SP_REG)
17638 (plus:P (reg:P SP_REG)
17639 (match_operand:P 0 "const_int_operand")))
17640 (clobber (reg:CC FLAGS_REG))])]
17641 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17642 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17643 [(clobber (match_dup 1))
17644 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17647 [(match_scratch:W 1 "r")
17648 (parallel [(set (reg:P SP_REG)
17649 (plus:P (reg:P SP_REG)
17650 (match_operand:P 0 "const_int_operand")))
17651 (clobber (reg:CC FLAGS_REG))])]
17652 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17653 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17654 [(clobber (match_dup 1))
17655 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17656 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17658 ;; Convert epilogue deallocator to pop.
17660 [(match_scratch:W 1 "r")
17661 (parallel [(set (reg:P SP_REG)
17662 (plus:P (reg:P SP_REG)
17663 (match_operand:P 0 "const_int_operand")))
17664 (clobber (reg:CC FLAGS_REG))
17665 (clobber (mem:BLK (scratch)))])]
17666 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17667 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17668 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17669 (clobber (mem:BLK (scratch)))])])
17671 ;; Two pops case is tricky, since pop causes dependency
17672 ;; on destination register. We use two registers if available.
17674 [(match_scratch:W 1 "r")
17675 (match_scratch:W 2 "r")
17676 (parallel [(set (reg:P SP_REG)
17677 (plus:P (reg:P SP_REG)
17678 (match_operand:P 0 "const_int_operand")))
17679 (clobber (reg:CC FLAGS_REG))
17680 (clobber (mem:BLK (scratch)))])]
17681 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17682 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17683 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17684 (clobber (mem:BLK (scratch)))])
17685 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17688 [(match_scratch:W 1 "r")
17689 (parallel [(set (reg:P SP_REG)
17690 (plus:P (reg:P SP_REG)
17691 (match_operand:P 0 "const_int_operand")))
17692 (clobber (reg:CC FLAGS_REG))
17693 (clobber (mem:BLK (scratch)))])]
17694 "optimize_insn_for_size_p ()
17695 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17696 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17697 (clobber (mem:BLK (scratch)))])
17698 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17700 ;; Convert esp additions to pop.
17702 [(match_scratch:W 1 "r")
17703 (parallel [(set (reg:P SP_REG)
17704 (plus:P (reg:P SP_REG)
17705 (match_operand:P 0 "const_int_operand")))
17706 (clobber (reg:CC FLAGS_REG))])]
17707 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17708 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17710 ;; Two pops case is tricky, since pop causes dependency
17711 ;; on destination register. We use two registers if available.
17713 [(match_scratch:W 1 "r")
17714 (match_scratch:W 2 "r")
17715 (parallel [(set (reg:P SP_REG)
17716 (plus:P (reg:P SP_REG)
17717 (match_operand:P 0 "const_int_operand")))
17718 (clobber (reg:CC FLAGS_REG))])]
17719 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17720 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17721 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17724 [(match_scratch:W 1 "r")
17725 (parallel [(set (reg:P SP_REG)
17726 (plus:P (reg:P SP_REG)
17727 (match_operand:P 0 "const_int_operand")))
17728 (clobber (reg:CC FLAGS_REG))])]
17729 "optimize_insn_for_size_p ()
17730 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17731 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17732 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17734 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17735 ;; required and register dies. Similarly for 128 to -128.
17737 [(set (match_operand 0 "flags_reg_operand")
17738 (match_operator 1 "compare_operator"
17739 [(match_operand 2 "register_operand")
17740 (match_operand 3 "const_int_operand")]))]
17741 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17742 && incdec_operand (operands[3], GET_MODE (operands[3])))
17743 || (!TARGET_FUSE_CMP_AND_BRANCH
17744 && INTVAL (operands[3]) == 128))
17745 && ix86_match_ccmode (insn, CCGCmode)
17746 && peep2_reg_dead_p (1, operands[2])"
17747 [(parallel [(set (match_dup 0)
17748 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17749 (clobber (match_dup 2))])])
17751 ;; Convert imul by three, five and nine into lea
17754 [(set (match_operand:SWI48 0 "register_operand")
17755 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17756 (match_operand:SWI48 2 "const359_operand")))
17757 (clobber (reg:CC FLAGS_REG))])]
17758 "!TARGET_PARTIAL_REG_STALL
17759 || <MODE>mode == SImode
17760 || optimize_function_for_size_p (cfun)"
17761 [(set (match_dup 0)
17762 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17764 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17768 [(set (match_operand:SWI48 0 "register_operand")
17769 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17770 (match_operand:SWI48 2 "const359_operand")))
17771 (clobber (reg:CC FLAGS_REG))])]
17772 "optimize_insn_for_speed_p ()
17773 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17774 [(set (match_dup 0) (match_dup 1))
17776 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17778 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17780 ;; imul $32bit_imm, mem, reg is vector decoded, while
17781 ;; imul $32bit_imm, reg, reg is direct decoded.
17783 [(match_scratch:SWI48 3 "r")
17784 (parallel [(set (match_operand:SWI48 0 "register_operand")
17785 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17786 (match_operand:SWI48 2 "immediate_operand")))
17787 (clobber (reg:CC FLAGS_REG))])]
17788 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17789 && !satisfies_constraint_K (operands[2])"
17790 [(set (match_dup 3) (match_dup 1))
17791 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17792 (clobber (reg:CC FLAGS_REG))])])
17795 [(match_scratch:SI 3 "r")
17796 (parallel [(set (match_operand:DI 0 "register_operand")
17798 (mult:SI (match_operand:SI 1 "memory_operand")
17799 (match_operand:SI 2 "immediate_operand"))))
17800 (clobber (reg:CC FLAGS_REG))])]
17802 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17803 && !satisfies_constraint_K (operands[2])"
17804 [(set (match_dup 3) (match_dup 1))
17805 (parallel [(set (match_dup 0)
17806 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17807 (clobber (reg:CC FLAGS_REG))])])
17809 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17810 ;; Convert it into imul reg, reg
17811 ;; It would be better to force assembler to encode instruction using long
17812 ;; immediate, but there is apparently no way to do so.
17814 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17816 (match_operand:SWI248 1 "nonimmediate_operand")
17817 (match_operand:SWI248 2 "const_int_operand")))
17818 (clobber (reg:CC FLAGS_REG))])
17819 (match_scratch:SWI248 3 "r")]
17820 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17821 && satisfies_constraint_K (operands[2])"
17822 [(set (match_dup 3) (match_dup 2))
17823 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17824 (clobber (reg:CC FLAGS_REG))])]
17826 if (!rtx_equal_p (operands[0], operands[1]))
17827 emit_move_insn (operands[0], operands[1]);
17830 ;; After splitting up read-modify operations, array accesses with memory
17831 ;; operands might end up in form:
17833 ;; movl 4(%esp), %edx
17835 ;; instead of pre-splitting:
17837 ;; addl 4(%esp), %eax
17839 ;; movl 4(%esp), %edx
17840 ;; leal (%edx,%eax,4), %eax
17843 [(match_scratch:W 5 "r")
17844 (parallel [(set (match_operand 0 "register_operand")
17845 (ashift (match_operand 1 "register_operand")
17846 (match_operand 2 "const_int_operand")))
17847 (clobber (reg:CC FLAGS_REG))])
17848 (parallel [(set (match_operand 3 "register_operand")
17849 (plus (match_dup 0)
17850 (match_operand 4 "x86_64_general_operand")))
17851 (clobber (reg:CC FLAGS_REG))])]
17852 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17853 /* Validate MODE for lea. */
17854 && ((!TARGET_PARTIAL_REG_STALL
17855 && (GET_MODE (operands[0]) == QImode
17856 || GET_MODE (operands[0]) == HImode))
17857 || GET_MODE (operands[0]) == SImode
17858 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17859 && (rtx_equal_p (operands[0], operands[3])
17860 || peep2_reg_dead_p (2, operands[0]))
17861 /* We reorder load and the shift. */
17862 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17863 [(set (match_dup 5) (match_dup 4))
17864 (set (match_dup 0) (match_dup 1))]
17866 machine_mode op1mode = GET_MODE (operands[1]);
17867 machine_mode mode = op1mode == DImode ? DImode : SImode;
17868 int scale = 1 << INTVAL (operands[2]);
17869 rtx index = gen_lowpart (word_mode, operands[1]);
17870 rtx base = gen_lowpart (word_mode, operands[5]);
17871 rtx dest = gen_lowpart (mode, operands[3]);
17873 operands[1] = gen_rtx_PLUS (word_mode, base,
17874 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17875 operands[5] = base;
17876 if (mode != word_mode)
17877 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17878 if (op1mode != word_mode)
17879 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17880 operands[0] = dest;
17883 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17884 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17885 ;; caught for use by garbage collectors and the like. Using an insn that
17886 ;; maps to SIGILL makes it more likely the program will rightfully die.
17887 ;; Keeping with tradition, "6" is in honor of #UD.
17888 (define_insn "trap"
17889 [(trap_if (const_int 1) (const_int 6))]
17892 #ifdef HAVE_AS_IX86_UD2
17895 return ASM_SHORT "0x0b0f";
17898 [(set_attr "length" "2")])
17900 (define_expand "prefetch"
17901 [(prefetch (match_operand 0 "address_operand")
17902 (match_operand:SI 1 "const_int_operand")
17903 (match_operand:SI 2 "const_int_operand"))]
17904 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17906 bool write = INTVAL (operands[1]) != 0;
17907 int locality = INTVAL (operands[2]);
17909 gcc_assert (IN_RANGE (locality, 0, 3));
17911 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17912 supported by SSE counterpart or the SSE prefetch is not available
17913 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17915 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17916 operands[2] = const2_rtx;
17917 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17918 operands[2] = GEN_INT (3);
17920 operands[1] = const0_rtx;
17923 (define_insn "*prefetch_sse"
17924 [(prefetch (match_operand 0 "address_operand" "p")
17926 (match_operand:SI 1 "const_int_operand"))]
17927 "TARGET_PREFETCH_SSE"
17929 static const char * const patterns[4] = {
17930 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17933 int locality = INTVAL (operands[1]);
17934 gcc_assert (IN_RANGE (locality, 0, 3));
17936 return patterns[locality];
17938 [(set_attr "type" "sse")
17939 (set_attr "atom_sse_attr" "prefetch")
17940 (set (attr "length_address")
17941 (symbol_ref "memory_address_length (operands[0], false)"))
17942 (set_attr "memory" "none")])
17944 (define_insn "*prefetch_3dnow"
17945 [(prefetch (match_operand 0 "address_operand" "p")
17946 (match_operand:SI 1 "const_int_operand" "n")
17950 if (INTVAL (operands[1]) == 0)
17951 return "prefetch\t%a0";
17953 return "prefetchw\t%a0";
17955 [(set_attr "type" "mmx")
17956 (set (attr "length_address")
17957 (symbol_ref "memory_address_length (operands[0], false)"))
17958 (set_attr "memory" "none")])
17960 (define_insn "*prefetch_prefetchwt1_<mode>"
17961 [(prefetch (match_operand:P 0 "address_operand" "p")
17964 "TARGET_PREFETCHWT1"
17965 "prefetchwt1\t%a0";
17966 [(set_attr "type" "sse")
17967 (set (attr "length_address")
17968 (symbol_ref "memory_address_length (operands[0], false)"))
17969 (set_attr "memory" "none")])
17971 (define_expand "stack_protect_set"
17972 [(match_operand 0 "memory_operand")
17973 (match_operand 1 "memory_operand")]
17974 "TARGET_SSP_TLS_GUARD"
17976 rtx (*insn)(rtx, rtx);
17978 #ifdef TARGET_THREAD_SSP_OFFSET
17979 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17980 insn = (TARGET_LP64
17981 ? gen_stack_tls_protect_set_di
17982 : gen_stack_tls_protect_set_si);
17984 insn = (TARGET_LP64
17985 ? gen_stack_protect_set_di
17986 : gen_stack_protect_set_si);
17989 emit_insn (insn (operands[0], operands[1]));
17993 (define_insn "stack_protect_set_<mode>"
17994 [(set (match_operand:PTR 0 "memory_operand" "=m")
17995 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17997 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17998 (clobber (reg:CC FLAGS_REG))]
17999 "TARGET_SSP_TLS_GUARD"
18000 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18001 [(set_attr "type" "multi")])
18003 (define_insn "stack_tls_protect_set_<mode>"
18004 [(set (match_operand:PTR 0 "memory_operand" "=m")
18005 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18006 UNSPEC_SP_TLS_SET))
18007 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18008 (clobber (reg:CC FLAGS_REG))]
18010 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18011 [(set_attr "type" "multi")])
18013 (define_expand "stack_protect_test"
18014 [(match_operand 0 "memory_operand")
18015 (match_operand 1 "memory_operand")
18017 "TARGET_SSP_TLS_GUARD"
18019 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18021 rtx (*insn)(rtx, rtx, rtx);
18023 #ifdef TARGET_THREAD_SSP_OFFSET
18024 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18025 insn = (TARGET_LP64
18026 ? gen_stack_tls_protect_test_di
18027 : gen_stack_tls_protect_test_si);
18029 insn = (TARGET_LP64
18030 ? gen_stack_protect_test_di
18031 : gen_stack_protect_test_si);
18034 emit_insn (insn (flags, operands[0], operands[1]));
18036 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18037 flags, const0_rtx, operands[2]));
18041 (define_insn "stack_protect_test_<mode>"
18042 [(set (match_operand:CCZ 0 "flags_reg_operand")
18043 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18044 (match_operand:PTR 2 "memory_operand" "m")]
18046 (clobber (match_scratch:PTR 3 "=&r"))]
18047 "TARGET_SSP_TLS_GUARD"
18048 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18049 [(set_attr "type" "multi")])
18051 (define_insn "stack_tls_protect_test_<mode>"
18052 [(set (match_operand:CCZ 0 "flags_reg_operand")
18053 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18054 (match_operand:PTR 2 "const_int_operand" "i")]
18055 UNSPEC_SP_TLS_TEST))
18056 (clobber (match_scratch:PTR 3 "=r"))]
18058 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18059 [(set_attr "type" "multi")])
18061 (define_insn "sse4_2_crc32<mode>"
18062 [(set (match_operand:SI 0 "register_operand" "=r")
18064 [(match_operand:SI 1 "register_operand" "0")
18065 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18067 "TARGET_SSE4_2 || TARGET_CRC32"
18068 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18069 [(set_attr "type" "sselog1")
18070 (set_attr "prefix_rep" "1")
18071 (set_attr "prefix_extra" "1")
18072 (set (attr "prefix_data16")
18073 (if_then_else (match_operand:HI 2)
18075 (const_string "*")))
18076 (set (attr "prefix_rex")
18077 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18079 (const_string "*")))
18080 (set_attr "mode" "SI")])
18082 (define_insn "sse4_2_crc32di"
18083 [(set (match_operand:DI 0 "register_operand" "=r")
18085 [(match_operand:DI 1 "register_operand" "0")
18086 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18088 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18089 "crc32{q}\t{%2, %0|%0, %2}"
18090 [(set_attr "type" "sselog1")
18091 (set_attr "prefix_rep" "1")
18092 (set_attr "prefix_extra" "1")
18093 (set_attr "mode" "DI")])
18095 (define_insn "rdpmc"
18096 [(set (match_operand:DI 0 "register_operand" "=A")
18097 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18101 [(set_attr "type" "other")
18102 (set_attr "length" "2")])
18104 (define_insn "rdpmc_rex64"
18105 [(set (match_operand:DI 0 "register_operand" "=a")
18106 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18108 (set (match_operand:DI 1 "register_operand" "=d")
18109 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18112 [(set_attr "type" "other")
18113 (set_attr "length" "2")])
18115 (define_insn "rdtsc"
18116 [(set (match_operand:DI 0 "register_operand" "=A")
18117 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18120 [(set_attr "type" "other")
18121 (set_attr "length" "2")])
18123 (define_insn "rdtsc_rex64"
18124 [(set (match_operand:DI 0 "register_operand" "=a")
18125 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18126 (set (match_operand:DI 1 "register_operand" "=d")
18127 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18130 [(set_attr "type" "other")
18131 (set_attr "length" "2")])
18133 (define_insn "rdtscp"
18134 [(set (match_operand:DI 0 "register_operand" "=A")
18135 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18136 (set (match_operand:SI 1 "register_operand" "=c")
18137 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18140 [(set_attr "type" "other")
18141 (set_attr "length" "3")])
18143 (define_insn "rdtscp_rex64"
18144 [(set (match_operand:DI 0 "register_operand" "=a")
18145 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18146 (set (match_operand:DI 1 "register_operand" "=d")
18147 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18148 (set (match_operand:SI 2 "register_operand" "=c")
18149 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18152 [(set_attr "type" "other")
18153 (set_attr "length" "3")])
18155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18157 ;; FXSR, XSAVE and XSAVEOPT instructions
18159 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18161 (define_insn "fxsave"
18162 [(set (match_operand:BLK 0 "memory_operand" "=m")
18163 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18166 [(set_attr "type" "other")
18167 (set_attr "memory" "store")
18168 (set (attr "length")
18169 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18171 (define_insn "fxsave64"
18172 [(set (match_operand:BLK 0 "memory_operand" "=m")
18173 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18174 "TARGET_64BIT && TARGET_FXSR"
18176 [(set_attr "type" "other")
18177 (set_attr "memory" "store")
18178 (set (attr "length")
18179 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18181 (define_insn "fxrstor"
18182 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18186 [(set_attr "type" "other")
18187 (set_attr "memory" "load")
18188 (set (attr "length")
18189 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18191 (define_insn "fxrstor64"
18192 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18193 UNSPECV_FXRSTOR64)]
18194 "TARGET_64BIT && TARGET_FXSR"
18196 [(set_attr "type" "other")
18197 (set_attr "memory" "load")
18198 (set (attr "length")
18199 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18201 (define_int_iterator ANY_XSAVE
18203 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18204 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18205 (UNSPECV_XSAVES "TARGET_XSAVES")])
18207 (define_int_iterator ANY_XSAVE64
18209 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18210 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18211 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18213 (define_int_attr xsave
18214 [(UNSPECV_XSAVE "xsave")
18215 (UNSPECV_XSAVE64 "xsave64")
18216 (UNSPECV_XSAVEOPT "xsaveopt")
18217 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18218 (UNSPECV_XSAVEC "xsavec")
18219 (UNSPECV_XSAVEC64 "xsavec64")
18220 (UNSPECV_XSAVES "xsaves")
18221 (UNSPECV_XSAVES64 "xsaves64")])
18223 (define_int_iterator ANY_XRSTOR
18225 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18227 (define_int_iterator ANY_XRSTOR64
18229 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18231 (define_int_attr xrstor
18232 [(UNSPECV_XRSTOR "xrstor")
18233 (UNSPECV_XRSTOR64 "xrstor")
18234 (UNSPECV_XRSTORS "xrstors")
18235 (UNSPECV_XRSTORS64 "xrstors")])
18237 (define_insn "<xsave>"
18238 [(set (match_operand:BLK 0 "memory_operand" "=m")
18239 (unspec_volatile:BLK
18240 [(match_operand:DI 1 "register_operand" "A")]
18242 "!TARGET_64BIT && TARGET_XSAVE"
18244 [(set_attr "type" "other")
18245 (set_attr "memory" "store")
18246 (set (attr "length")
18247 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18249 (define_insn "<xsave>_rex64"
18250 [(set (match_operand:BLK 0 "memory_operand" "=m")
18251 (unspec_volatile:BLK
18252 [(match_operand:SI 1 "register_operand" "a")
18253 (match_operand:SI 2 "register_operand" "d")]
18255 "TARGET_64BIT && TARGET_XSAVE"
18257 [(set_attr "type" "other")
18258 (set_attr "memory" "store")
18259 (set (attr "length")
18260 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18262 (define_insn "<xsave>"
18263 [(set (match_operand:BLK 0 "memory_operand" "=m")
18264 (unspec_volatile:BLK
18265 [(match_operand:SI 1 "register_operand" "a")
18266 (match_operand:SI 2 "register_operand" "d")]
18268 "TARGET_64BIT && TARGET_XSAVE"
18270 [(set_attr "type" "other")
18271 (set_attr "memory" "store")
18272 (set (attr "length")
18273 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18275 (define_insn "<xrstor>"
18276 [(unspec_volatile:BLK
18277 [(match_operand:BLK 0 "memory_operand" "m")
18278 (match_operand:DI 1 "register_operand" "A")]
18280 "!TARGET_64BIT && TARGET_XSAVE"
18282 [(set_attr "type" "other")
18283 (set_attr "memory" "load")
18284 (set (attr "length")
18285 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18287 (define_insn "<xrstor>_rex64"
18288 [(unspec_volatile:BLK
18289 [(match_operand:BLK 0 "memory_operand" "m")
18290 (match_operand:SI 1 "register_operand" "a")
18291 (match_operand:SI 2 "register_operand" "d")]
18293 "TARGET_64BIT && TARGET_XSAVE"
18295 [(set_attr "type" "other")
18296 (set_attr "memory" "load")
18297 (set (attr "length")
18298 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18300 (define_insn "<xrstor>64"
18301 [(unspec_volatile:BLK
18302 [(match_operand:BLK 0 "memory_operand" "m")
18303 (match_operand:SI 1 "register_operand" "a")
18304 (match_operand:SI 2 "register_operand" "d")]
18306 "TARGET_64BIT && TARGET_XSAVE"
18308 [(set_attr "type" "other")
18309 (set_attr "memory" "load")
18310 (set (attr "length")
18311 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18313 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18315 ;; Floating-point instructions for atomic compound assignments
18317 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18319 ; Clobber all floating-point registers on environment save and restore
18320 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18321 (define_insn "fnstenv"
18322 [(set (match_operand:BLK 0 "memory_operand" "=m")
18323 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18324 (clobber (reg:HI FPCR_REG))
18325 (clobber (reg:XF ST0_REG))
18326 (clobber (reg:XF ST1_REG))
18327 (clobber (reg:XF ST2_REG))
18328 (clobber (reg:XF ST3_REG))
18329 (clobber (reg:XF ST4_REG))
18330 (clobber (reg:XF ST5_REG))
18331 (clobber (reg:XF ST6_REG))
18332 (clobber (reg:XF ST7_REG))]
18335 [(set_attr "type" "other")
18336 (set_attr "memory" "store")
18337 (set (attr "length")
18338 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18340 (define_insn "fldenv"
18341 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18343 (clobber (reg:CCFP FPSR_REG))
18344 (clobber (reg:HI FPCR_REG))
18345 (clobber (reg:XF ST0_REG))
18346 (clobber (reg:XF ST1_REG))
18347 (clobber (reg:XF ST2_REG))
18348 (clobber (reg:XF ST3_REG))
18349 (clobber (reg:XF ST4_REG))
18350 (clobber (reg:XF ST5_REG))
18351 (clobber (reg:XF ST6_REG))
18352 (clobber (reg:XF ST7_REG))]
18355 [(set_attr "type" "other")
18356 (set_attr "memory" "load")
18357 (set (attr "length")
18358 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18360 (define_insn "fnstsw"
18361 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18362 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18365 [(set_attr "type" "other,other")
18366 (set_attr "memory" "none,store")
18367 (set (attr "length")
18368 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18370 (define_insn "fnclex"
18371 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18374 [(set_attr "type" "other")
18375 (set_attr "memory" "none")
18376 (set_attr "length" "2")])
18378 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18380 ;; LWP instructions
18382 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18384 (define_expand "lwp_llwpcb"
18385 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18386 UNSPECV_LLWP_INTRINSIC)]
18389 (define_insn "*lwp_llwpcb<mode>1"
18390 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18391 UNSPECV_LLWP_INTRINSIC)]
18394 [(set_attr "type" "lwp")
18395 (set_attr "mode" "<MODE>")
18396 (set_attr "length" "5")])
18398 (define_expand "lwp_slwpcb"
18399 [(set (match_operand 0 "register_operand" "=r")
18400 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18405 insn = (Pmode == DImode
18407 : gen_lwp_slwpcbsi);
18409 emit_insn (insn (operands[0]));
18413 (define_insn "lwp_slwpcb<mode>"
18414 [(set (match_operand:P 0 "register_operand" "=r")
18415 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18418 [(set_attr "type" "lwp")
18419 (set_attr "mode" "<MODE>")
18420 (set_attr "length" "5")])
18422 (define_expand "lwp_lwpval<mode>3"
18423 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18424 (match_operand:SI 2 "nonimmediate_operand" "rm")
18425 (match_operand:SI 3 "const_int_operand" "i")]
18426 UNSPECV_LWPVAL_INTRINSIC)]
18428 ;; Avoid unused variable warning.
18429 "(void) operands[0];")
18431 (define_insn "*lwp_lwpval<mode>3_1"
18432 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18433 (match_operand:SI 1 "nonimmediate_operand" "rm")
18434 (match_operand:SI 2 "const_int_operand" "i")]
18435 UNSPECV_LWPVAL_INTRINSIC)]
18437 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18438 [(set_attr "type" "lwp")
18439 (set_attr "mode" "<MODE>")
18440 (set (attr "length")
18441 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18443 (define_expand "lwp_lwpins<mode>3"
18444 [(set (reg:CCC FLAGS_REG)
18445 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18446 (match_operand:SI 2 "nonimmediate_operand" "rm")
18447 (match_operand:SI 3 "const_int_operand" "i")]
18448 UNSPECV_LWPINS_INTRINSIC))
18449 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18450 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18453 (define_insn "*lwp_lwpins<mode>3_1"
18454 [(set (reg:CCC FLAGS_REG)
18455 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18456 (match_operand:SI 1 "nonimmediate_operand" "rm")
18457 (match_operand:SI 2 "const_int_operand" "i")]
18458 UNSPECV_LWPINS_INTRINSIC))]
18460 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18461 [(set_attr "type" "lwp")
18462 (set_attr "mode" "<MODE>")
18463 (set (attr "length")
18464 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18466 (define_int_iterator RDFSGSBASE
18470 (define_int_iterator WRFSGSBASE
18474 (define_int_attr fsgs
18475 [(UNSPECV_RDFSBASE "fs")
18476 (UNSPECV_RDGSBASE "gs")
18477 (UNSPECV_WRFSBASE "fs")
18478 (UNSPECV_WRGSBASE "gs")])
18480 (define_insn "rd<fsgs>base<mode>"
18481 [(set (match_operand:SWI48 0 "register_operand" "=r")
18482 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18483 "TARGET_64BIT && TARGET_FSGSBASE"
18485 [(set_attr "type" "other")
18486 (set_attr "prefix_extra" "2")])
18488 (define_insn "wr<fsgs>base<mode>"
18489 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18491 "TARGET_64BIT && TARGET_FSGSBASE"
18493 [(set_attr "type" "other")
18494 (set_attr "prefix_extra" "2")])
18496 (define_insn "rdrand<mode>_1"
18497 [(set (match_operand:SWI248 0 "register_operand" "=r")
18498 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18499 (set (reg:CCC FLAGS_REG)
18500 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18503 [(set_attr "type" "other")
18504 (set_attr "prefix_extra" "1")])
18506 (define_insn "rdseed<mode>_1"
18507 [(set (match_operand:SWI248 0 "register_operand" "=r")
18508 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18509 (set (reg:CCC FLAGS_REG)
18510 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18513 [(set_attr "type" "other")
18514 (set_attr "prefix_extra" "1")])
18516 (define_expand "pause"
18517 [(set (match_dup 0)
18518 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18521 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18522 MEM_VOLATILE_P (operands[0]) = 1;
18525 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18526 ;; They have the same encoding.
18527 (define_insn "*pause"
18528 [(set (match_operand:BLK 0)
18529 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18532 [(set_attr "length" "2")
18533 (set_attr "memory" "unknown")])
18535 (define_expand "xbegin"
18536 [(set (match_operand:SI 0 "register_operand")
18537 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18540 rtx_code_label *label = gen_label_rtx ();
18542 /* xbegin is emitted as jump_insn, so reload won't be able
18543 to reload its operand. Force the value into AX hard register. */
18544 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18545 emit_move_insn (ax_reg, constm1_rtx);
18547 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18549 emit_label (label);
18550 LABEL_NUSES (label) = 1;
18552 emit_move_insn (operands[0], ax_reg);
18557 (define_insn "xbegin_1"
18559 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18561 (label_ref (match_operand 1))
18563 (set (match_operand:SI 0 "register_operand" "+a")
18564 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18567 [(set_attr "type" "other")
18568 (set_attr "length" "6")])
18570 (define_insn "xend"
18571 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18574 [(set_attr "type" "other")
18575 (set_attr "length" "3")])
18577 (define_insn "xabort"
18578 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18582 [(set_attr "type" "other")
18583 (set_attr "length" "3")])
18585 (define_expand "xtest"
18586 [(set (match_operand:QI 0 "register_operand")
18587 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18590 emit_insn (gen_xtest_1 ());
18592 ix86_expand_setcc (operands[0], NE,
18593 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18597 (define_insn "xtest_1"
18598 [(set (reg:CCZ FLAGS_REG)
18599 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18602 [(set_attr "type" "other")
18603 (set_attr "length" "3")])
18605 (define_insn "clflushopt"
18606 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18607 UNSPECV_CLFLUSHOPT)]
18608 "TARGET_CLFLUSHOPT"
18610 [(set_attr "type" "sse")
18611 (set_attr "atom_sse_attr" "fence")
18612 (set_attr "memory" "unknown")])
18616 (include "sync.md")