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
109 UNSPEC_MS_TO_SYSV_CALL
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"
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")
780 ;; Describe a user's asm statement.
781 (define_asm_attributes
782 [(set_attr "length" "128")
783 (set_attr "type" "multi")])
785 (define_code_iterator plusminus [plus minus])
787 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
789 (define_code_iterator multdiv [mult div])
791 ;; Base name for define_insn
792 (define_code_attr plusminus_insn
793 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
794 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
796 ;; Base name for insn mnemonic.
797 (define_code_attr plusminus_mnemonic
798 [(plus "add") (ss_plus "adds") (us_plus "addus")
799 (minus "sub") (ss_minus "subs") (us_minus "subus")])
800 (define_code_attr plusminus_carry_mnemonic
801 [(plus "adc") (minus "sbb")])
802 (define_code_attr multdiv_mnemonic
803 [(mult "mul") (div "div")])
805 ;; Mark commutative operators as such in constraints.
806 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
807 (minus "") (ss_minus "") (us_minus "")])
809 ;; Mapping of max and min
810 (define_code_iterator maxmin [smax smin umax umin])
812 ;; Mapping of signed max and min
813 (define_code_iterator smaxmin [smax smin])
815 ;; Mapping of unsigned max and min
816 (define_code_iterator umaxmin [umax umin])
818 ;; Base name for integer and FP insn mnemonic
819 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
820 (umax "maxu") (umin "minu")])
821 (define_code_attr maxmin_float [(smax "max") (smin "min")])
823 ;; Mapping of logic operators
824 (define_code_iterator any_logic [and ior xor])
825 (define_code_iterator any_or [ior xor])
826 (define_code_iterator fpint_logic [and xor])
828 ;; Base name for insn mnemonic.
829 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
831 ;; Mapping of logic-shift operators
832 (define_code_iterator any_lshift [ashift lshiftrt])
834 ;; Mapping of shift-right operators
835 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
837 ;; Mapping of all shift operators
838 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
840 ;; Base name for define_insn
841 (define_code_attr shift_insn
842 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
844 ;; Base name for insn mnemonic.
845 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
846 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
848 ;; Mapping of rotate operators
849 (define_code_iterator any_rotate [rotate rotatert])
851 ;; Base name for define_insn
852 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
854 ;; Base name for insn mnemonic.
855 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
857 ;; Mapping of abs neg operators
858 (define_code_iterator absneg [abs neg])
860 ;; Base name for x87 insn mnemonic.
861 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
863 ;; Used in signed and unsigned widening multiplications.
864 (define_code_iterator any_extend [sign_extend zero_extend])
866 ;; Prefix for insn menmonic.
867 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
869 ;; Prefix for define_insn
870 (define_code_attr u [(sign_extend "") (zero_extend "u")])
871 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
872 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
874 ;; Used in signed and unsigned truncations.
875 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
876 ;; Instruction suffix for truncations.
877 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
879 ;; Used in signed and unsigned fix.
880 (define_code_iterator any_fix [fix unsigned_fix])
881 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
883 ;; All integer modes.
884 (define_mode_iterator SWI1248x [QI HI SI DI])
886 ;; All integer modes without QImode.
887 (define_mode_iterator SWI248x [HI SI DI])
889 ;; All integer modes without QImode and HImode.
890 (define_mode_iterator SWI48x [SI DI])
892 ;; All integer modes without SImode and DImode.
893 (define_mode_iterator SWI12 [QI HI])
895 ;; All integer modes without DImode.
896 (define_mode_iterator SWI124 [QI HI SI])
898 ;; All integer modes without QImode and DImode.
899 (define_mode_iterator SWI24 [HI SI])
901 ;; Single word integer modes.
902 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
904 ;; Single word integer modes without QImode.
905 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
907 ;; Single word integer modes without QImode and HImode.
908 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
910 ;; All math-dependant single and double word integer modes.
911 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
912 (HI "TARGET_HIMODE_MATH")
913 SI DI (TI "TARGET_64BIT")])
915 ;; Math-dependant single word integer modes.
916 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
917 (HI "TARGET_HIMODE_MATH")
918 SI (DI "TARGET_64BIT")])
920 ;; Math-dependant integer modes without DImode.
921 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
922 (HI "TARGET_HIMODE_MATH")
925 ;; Math-dependant single word integer modes without QImode.
926 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
927 SI (DI "TARGET_64BIT")])
929 ;; Double word integer modes.
930 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
931 (TI "TARGET_64BIT")])
933 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
934 ;; compile time constant, it is faster to use <MODE_SIZE> than
935 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
936 ;; command line options just use GET_MODE_SIZE macro.
937 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
938 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
939 (V16QI "16") (V32QI "32") (V64QI "64")
940 (V8HI "16") (V16HI "32") (V32HI "64")
941 (V4SI "16") (V8SI "32") (V16SI "64")
942 (V2DI "16") (V4DI "32") (V8DI "64")
943 (V1TI "16") (V2TI "32") (V4TI "64")
944 (V2DF "16") (V4DF "32") (V8DF "64")
945 (V4SF "16") (V8SF "32") (V16SF "64")])
947 ;; Double word integer modes as mode attribute.
948 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
949 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
951 ;; Half mode for double word integer modes.
952 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
953 (DI "TARGET_64BIT")])
955 ;; Instruction suffix for integer modes.
956 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
958 ;; Instruction suffix for masks.
959 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
961 ;; Pointer size prefix for integer modes (Intel asm dialect)
962 (define_mode_attr iptrsize [(QI "BYTE")
967 ;; Register class for integer modes.
968 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
970 ;; Immediate operand constraint for integer modes.
971 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
973 ;; General operand constraint for word modes.
974 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
976 ;; Immediate operand constraint for double integer modes.
977 (define_mode_attr di [(SI "nF") (DI "e")])
979 ;; Immediate operand constraint for shifts.
980 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
982 ;; General operand predicate for integer modes.
983 (define_mode_attr general_operand
984 [(QI "general_operand")
985 (HI "general_operand")
986 (SI "x86_64_general_operand")
987 (DI "x86_64_general_operand")
988 (TI "x86_64_general_operand")])
990 ;; General sign extend operand predicate for integer modes,
991 ;; which disallows VOIDmode operands and thus it is suitable
992 ;; for use inside sign_extend.
993 (define_mode_attr general_sext_operand
996 (SI "x86_64_sext_operand")
997 (DI "x86_64_sext_operand")])
999 ;; General sign/zero extend operand predicate for integer modes.
1000 (define_mode_attr general_szext_operand
1001 [(QI "general_operand")
1002 (HI "general_operand")
1003 (SI "x86_64_szext_general_operand")
1004 (DI "x86_64_szext_general_operand")])
1006 ;; Immediate operand predicate for integer modes.
1007 (define_mode_attr immediate_operand
1008 [(QI "immediate_operand")
1009 (HI "immediate_operand")
1010 (SI "x86_64_immediate_operand")
1011 (DI "x86_64_immediate_operand")])
1013 ;; Nonmemory operand predicate for integer modes.
1014 (define_mode_attr nonmemory_operand
1015 [(QI "nonmemory_operand")
1016 (HI "nonmemory_operand")
1017 (SI "x86_64_nonmemory_operand")
1018 (DI "x86_64_nonmemory_operand")])
1020 ;; Operand predicate for shifts.
1021 (define_mode_attr shift_operand
1022 [(QI "nonimmediate_operand")
1023 (HI "nonimmediate_operand")
1024 (SI "nonimmediate_operand")
1025 (DI "shiftdi_operand")
1026 (TI "register_operand")])
1028 ;; Operand predicate for shift argument.
1029 (define_mode_attr shift_immediate_operand
1030 [(QI "const_1_to_31_operand")
1031 (HI "const_1_to_31_operand")
1032 (SI "const_1_to_31_operand")
1033 (DI "const_1_to_63_operand")])
1035 ;; Input operand predicate for arithmetic left shifts.
1036 (define_mode_attr ashl_input_operand
1037 [(QI "nonimmediate_operand")
1038 (HI "nonimmediate_operand")
1039 (SI "nonimmediate_operand")
1040 (DI "ashldi_input_operand")
1041 (TI "reg_or_pm1_operand")])
1043 ;; SSE and x87 SFmode and DFmode floating point modes
1044 (define_mode_iterator MODEF [SF DF])
1046 ;; All x87 floating point modes
1047 (define_mode_iterator X87MODEF [SF DF XF])
1049 ;; SSE instruction suffix for various modes
1050 (define_mode_attr ssemodesuffix
1051 [(SF "ss") (DF "sd")
1052 (V16SF "ps") (V8DF "pd")
1053 (V8SF "ps") (V4DF "pd")
1054 (V4SF "ps") (V2DF "pd")
1055 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1056 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1057 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1059 ;; SSE vector suffix for floating point modes
1060 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1062 ;; SSE vector mode corresponding to a scalar mode
1063 (define_mode_attr ssevecmode
1064 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1065 (define_mode_attr ssevecmodelower
1066 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1068 ;; Instruction suffix for REX 64bit operators.
1069 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1071 ;; This mode iterator allows :P to be used for patterns that operate on
1072 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1073 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1075 ;; This mode iterator allows :W to be used for patterns that operate on
1076 ;; word_mode sized quantities.
1077 (define_mode_iterator W
1078 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1080 ;; This mode iterator allows :PTR to be used for patterns that operate on
1081 ;; ptr_mode sized quantities.
1082 (define_mode_iterator PTR
1083 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1085 ;; Scheduling descriptions
1087 (include "pentium.md")
1090 (include "athlon.md")
1091 (include "bdver1.md")
1092 (include "bdver3.md")
1093 (include "btver2.md")
1094 (include "geode.md")
1097 (include "core2.md")
1100 ;; Operand and operator predicates and constraints
1102 (include "predicates.md")
1103 (include "constraints.md")
1106 ;; Compare and branch/compare and store instructions.
1108 (define_expand "cbranch<mode>4"
1109 [(set (reg:CC FLAGS_REG)
1110 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1111 (match_operand:SDWIM 2 "<general_operand>")))
1112 (set (pc) (if_then_else
1113 (match_operator 0 "ordered_comparison_operator"
1114 [(reg:CC FLAGS_REG) (const_int 0)])
1115 (label_ref (match_operand 3))
1119 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1120 operands[1] = force_reg (<MODE>mode, operands[1]);
1121 ix86_expand_branch (GET_CODE (operands[0]),
1122 operands[1], operands[2], operands[3]);
1126 (define_expand "cstore<mode>4"
1127 [(set (reg:CC FLAGS_REG)
1128 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1129 (match_operand:SWIM 3 "<general_operand>")))
1130 (set (match_operand:QI 0 "register_operand")
1131 (match_operator 1 "ordered_comparison_operator"
1132 [(reg:CC FLAGS_REG) (const_int 0)]))]
1135 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1136 operands[2] = force_reg (<MODE>mode, operands[2]);
1137 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1138 operands[2], operands[3]);
1142 (define_expand "cmp<mode>_1"
1143 [(set (reg:CC FLAGS_REG)
1144 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1145 (match_operand:SWI48 1 "<general_operand>")))])
1147 (define_insn "*cmp<mode>_ccno_1"
1148 [(set (reg FLAGS_REG)
1149 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1150 (match_operand:SWI 1 "const0_operand")))]
1151 "ix86_match_ccmode (insn, CCNOmode)"
1153 test{<imodesuffix>}\t%0, %0
1154 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1155 [(set_attr "type" "test,icmp")
1156 (set_attr "length_immediate" "0,1")
1157 (set_attr "mode" "<MODE>")])
1159 (define_insn "*cmp<mode>_1"
1160 [(set (reg FLAGS_REG)
1161 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1162 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1163 "ix86_match_ccmode (insn, CCmode)"
1164 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1165 [(set_attr "type" "icmp")
1166 (set_attr "mode" "<MODE>")])
1168 (define_insn "*cmp<mode>_minus_1"
1169 [(set (reg FLAGS_REG)
1171 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1172 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1174 "ix86_match_ccmode (insn, CCGOCmode)"
1175 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1176 [(set_attr "type" "icmp")
1177 (set_attr "mode" "<MODE>")])
1179 (define_insn "*cmpqi_ext_1"
1180 [(set (reg FLAGS_REG)
1182 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1185 (match_operand 1 "ext_register_operand" "Q,Q")
1187 (const_int 8)) 0)))]
1188 "ix86_match_ccmode (insn, CCmode)"
1189 "cmp{b}\t{%h1, %0|%0, %h1}"
1190 [(set_attr "isa" "*,nox64")
1191 (set_attr "type" "icmp")
1192 (set_attr "mode" "QI")])
1194 (define_insn "*cmpqi_ext_2"
1195 [(set (reg FLAGS_REG)
1199 (match_operand 0 "ext_register_operand" "Q")
1202 (match_operand:QI 1 "const0_operand")))]
1203 "ix86_match_ccmode (insn, CCNOmode)"
1205 [(set_attr "type" "test")
1206 (set_attr "length_immediate" "0")
1207 (set_attr "mode" "QI")])
1209 (define_expand "cmpqi_ext_3"
1210 [(set (reg:CC FLAGS_REG)
1214 (match_operand 0 "ext_register_operand")
1217 (match_operand:QI 1 "const_int_operand")))])
1219 (define_insn "*cmpqi_ext_3"
1220 [(set (reg FLAGS_REG)
1224 (match_operand 0 "ext_register_operand" "Q,Q")
1227 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1228 "ix86_match_ccmode (insn, CCmode)"
1229 "cmp{b}\t{%1, %h0|%h0, %1}"
1230 [(set_attr "isa" "*,nox64")
1231 (set_attr "type" "icmp")
1232 (set_attr "modrm" "1")
1233 (set_attr "mode" "QI")])
1235 (define_insn "*cmpqi_ext_4"
1236 [(set (reg FLAGS_REG)
1240 (match_operand 0 "ext_register_operand" "Q")
1245 (match_operand 1 "ext_register_operand" "Q")
1247 (const_int 8)) 0)))]
1248 "ix86_match_ccmode (insn, CCmode)"
1249 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1250 [(set_attr "type" "icmp")
1251 (set_attr "mode" "QI")])
1253 ;; These implement float point compares.
1254 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1255 ;; which would allow mix and match FP modes on the compares. Which is what
1256 ;; the old patterns did, but with many more of them.
1258 (define_expand "cbranchxf4"
1259 [(set (reg:CC FLAGS_REG)
1260 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1261 (match_operand:XF 2 "nonmemory_operand")))
1262 (set (pc) (if_then_else
1263 (match_operator 0 "ix86_fp_comparison_operator"
1266 (label_ref (match_operand 3))
1270 ix86_expand_branch (GET_CODE (operands[0]),
1271 operands[1], operands[2], operands[3]);
1275 (define_expand "cstorexf4"
1276 [(set (reg:CC FLAGS_REG)
1277 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1278 (match_operand:XF 3 "nonmemory_operand")))
1279 (set (match_operand:QI 0 "register_operand")
1280 (match_operator 1 "ix86_fp_comparison_operator"
1285 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1286 operands[2], operands[3]);
1290 (define_expand "cbranch<mode>4"
1291 [(set (reg:CC FLAGS_REG)
1292 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1293 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1294 (set (pc) (if_then_else
1295 (match_operator 0 "ix86_fp_comparison_operator"
1298 (label_ref (match_operand 3))
1300 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1302 ix86_expand_branch (GET_CODE (operands[0]),
1303 operands[1], operands[2], operands[3]);
1307 (define_expand "cstore<mode>4"
1308 [(set (reg:CC FLAGS_REG)
1309 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1310 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1311 (set (match_operand:QI 0 "register_operand")
1312 (match_operator 1 "ix86_fp_comparison_operator"
1315 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1317 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1318 operands[2], operands[3]);
1322 (define_expand "cbranchcc4"
1323 [(set (pc) (if_then_else
1324 (match_operator 0 "comparison_operator"
1325 [(match_operand 1 "flags_reg_operand")
1326 (match_operand 2 "const0_operand")])
1327 (label_ref (match_operand 3))
1331 ix86_expand_branch (GET_CODE (operands[0]),
1332 operands[1], operands[2], operands[3]);
1336 (define_expand "cstorecc4"
1337 [(set (match_operand:QI 0 "register_operand")
1338 (match_operator 1 "comparison_operator"
1339 [(match_operand 2 "flags_reg_operand")
1340 (match_operand 3 "const0_operand")]))]
1343 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1344 operands[2], operands[3]);
1349 ;; FP compares, step 1:
1350 ;; Set the FP condition codes.
1352 ;; CCFPmode compare with exceptions
1353 ;; CCFPUmode compare with no exceptions
1355 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1356 ;; used to manage the reg stack popping would not be preserved.
1358 (define_insn "*cmp<mode>_0_i387"
1359 [(set (match_operand:HI 0 "register_operand" "=a")
1362 (match_operand:X87MODEF 1 "register_operand" "f")
1363 (match_operand:X87MODEF 2 "const0_operand"))]
1366 "* return output_fp_compare (insn, operands, false, false);"
1367 [(set_attr "type" "multi")
1368 (set_attr "unit" "i387")
1369 (set_attr "mode" "<MODE>")])
1371 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1372 [(set (reg:CCFP FLAGS_REG)
1374 (match_operand:X87MODEF 1 "register_operand" "f")
1375 (match_operand:X87MODEF 2 "const0_operand")))
1376 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1377 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1379 "&& reload_completed"
1382 [(compare:CCFP (match_dup 1)(match_dup 2))]
1384 (set (reg:CC FLAGS_REG)
1385 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1387 [(set_attr "type" "multi")
1388 (set_attr "unit" "i387")
1389 (set_attr "mode" "<MODE>")])
1391 (define_insn "*cmpxf_i387"
1392 [(set (match_operand:HI 0 "register_operand" "=a")
1395 (match_operand:XF 1 "register_operand" "f")
1396 (match_operand:XF 2 "register_operand" "f"))]
1399 "* return output_fp_compare (insn, operands, false, false);"
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set_attr "mode" "XF")])
1404 (define_insn_and_split "*cmpxf_cc_i387"
1405 [(set (reg:CCFP FLAGS_REG)
1407 (match_operand:XF 1 "register_operand" "f")
1408 (match_operand:XF 2 "register_operand" "f")))
1409 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1410 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1412 "&& reload_completed"
1415 [(compare:CCFP (match_dup 1)(match_dup 2))]
1417 (set (reg:CC FLAGS_REG)
1418 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1420 [(set_attr "type" "multi")
1421 (set_attr "unit" "i387")
1422 (set_attr "mode" "XF")])
1424 (define_insn "*cmp<mode>_i387"
1425 [(set (match_operand:HI 0 "register_operand" "=a")
1428 (match_operand:MODEF 1 "register_operand" "f")
1429 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1432 "* return output_fp_compare (insn, operands, false, false);"
1433 [(set_attr "type" "multi")
1434 (set_attr "unit" "i387")
1435 (set_attr "mode" "<MODE>")])
1437 (define_insn_and_split "*cmp<mode>_cc_i387"
1438 [(set (reg:CCFP FLAGS_REG)
1440 (match_operand:MODEF 1 "register_operand" "f")
1441 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1442 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1443 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1445 "&& reload_completed"
1448 [(compare:CCFP (match_dup 1)(match_dup 2))]
1450 (set (reg:CC FLAGS_REG)
1451 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1453 [(set_attr "type" "multi")
1454 (set_attr "unit" "i387")
1455 (set_attr "mode" "<MODE>")])
1457 (define_insn "*cmpu<mode>_i387"
1458 [(set (match_operand:HI 0 "register_operand" "=a")
1461 (match_operand:X87MODEF 1 "register_operand" "f")
1462 (match_operand:X87MODEF 2 "register_operand" "f"))]
1465 "* return output_fp_compare (insn, operands, false, true);"
1466 [(set_attr "type" "multi")
1467 (set_attr "unit" "i387")
1468 (set_attr "mode" "<MODE>")])
1470 (define_insn_and_split "*cmpu<mode>_cc_i387"
1471 [(set (reg:CCFPU FLAGS_REG)
1473 (match_operand:X87MODEF 1 "register_operand" "f")
1474 (match_operand:X87MODEF 2 "register_operand" "f")))
1475 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1476 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1478 "&& reload_completed"
1481 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1483 (set (reg:CC FLAGS_REG)
1484 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1486 [(set_attr "type" "multi")
1487 (set_attr "unit" "i387")
1488 (set_attr "mode" "<MODE>")])
1490 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1491 [(set (match_operand:HI 0 "register_operand" "=a")
1494 (match_operand:X87MODEF 1 "register_operand" "f")
1495 (match_operator:X87MODEF 3 "float_operator"
1496 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1499 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1500 || optimize_function_for_size_p (cfun))"
1501 "* return output_fp_compare (insn, operands, false, false);"
1502 [(set_attr "type" "multi")
1503 (set_attr "unit" "i387")
1504 (set_attr "fp_int_src" "true")
1505 (set_attr "mode" "<SWI24:MODE>")])
1507 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1508 [(set (reg:CCFP FLAGS_REG)
1510 (match_operand:X87MODEF 1 "register_operand" "f")
1511 (match_operator:X87MODEF 3 "float_operator"
1512 [(match_operand:SWI24 2 "memory_operand" "m")])))
1513 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1514 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1515 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1516 || optimize_function_for_size_p (cfun))"
1518 "&& reload_completed"
1523 (match_op_dup 3 [(match_dup 2)]))]
1525 (set (reg:CC FLAGS_REG)
1526 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1528 [(set_attr "type" "multi")
1529 (set_attr "unit" "i387")
1530 (set_attr "fp_int_src" "true")
1531 (set_attr "mode" "<SWI24:MODE>")])
1533 ;; FP compares, step 2
1534 ;; Move the fpsw to ax.
1536 (define_insn "x86_fnstsw_1"
1537 [(set (match_operand:HI 0 "register_operand" "=a")
1538 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1541 [(set_attr "length" "2")
1542 (set_attr "mode" "SI")
1543 (set_attr "unit" "i387")])
1545 ;; FP compares, step 3
1546 ;; Get ax into flags, general case.
1548 (define_insn "x86_sahf_1"
1549 [(set (reg:CC FLAGS_REG)
1550 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1554 #ifndef HAVE_AS_IX86_SAHF
1556 return ASM_BYTE "0x9e";
1561 [(set_attr "length" "1")
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "bdver1_decode" "direct")
1565 (set_attr "mode" "SI")])
1567 ;; Pentium Pro can do steps 1 through 3 in one go.
1568 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1569 ;; (these i387 instructions set flags directly)
1571 (define_mode_iterator FPCMP [CCFP CCFPU])
1572 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1574 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1575 [(set (reg:FPCMP FLAGS_REG)
1577 (match_operand:MODEF 0 "register_operand" "f,x")
1578 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1579 "TARGET_MIX_SSE_I387
1580 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1581 "* return output_fp_compare (insn, operands, true,
1582 <FPCMP:MODE>mode == CCFPUmode);"
1583 [(set_attr "type" "fcmp,ssecomi")
1584 (set_attr "prefix" "orig,maybe_vex")
1585 (set_attr "mode" "<MODEF:MODE>")
1586 (set (attr "prefix_rep")
1587 (if_then_else (eq_attr "type" "ssecomi")
1589 (const_string "*")))
1590 (set (attr "prefix_data16")
1591 (cond [(eq_attr "type" "fcmp")
1593 (eq_attr "mode" "DF")
1596 (const_string "0")))
1597 (set_attr "athlon_decode" "vector")
1598 (set_attr "amdfam10_decode" "direct")
1599 (set_attr "bdver1_decode" "double")])
1601 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1602 [(set (reg:FPCMP FLAGS_REG)
1604 (match_operand:MODEF 0 "register_operand" "x")
1605 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1607 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1608 "* return output_fp_compare (insn, operands, true,
1609 <FPCMP:MODE>mode == CCFPUmode);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1612 (set_attr "mode" "<MODEF:MODE>")
1613 (set_attr "prefix_rep" "0")
1614 (set (attr "prefix_data16")
1615 (if_then_else (eq_attr "mode" "DF")
1617 (const_string "0")))
1618 (set_attr "athlon_decode" "vector")
1619 (set_attr "amdfam10_decode" "direct")
1620 (set_attr "bdver1_decode" "double")])
1622 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1623 [(set (reg:FPCMP FLAGS_REG)
1625 (match_operand:X87MODEF 0 "register_operand" "f")
1626 (match_operand:X87MODEF 1 "register_operand" "f")))]
1627 "TARGET_80387 && TARGET_CMOVE
1628 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1629 "* return output_fp_compare (insn, operands, true,
1630 <FPCMP:MODE>mode == CCFPUmode);"
1631 [(set_attr "type" "fcmp")
1632 (set_attr "mode" "<X87MODEF:MODE>")
1633 (set_attr "athlon_decode" "vector")
1634 (set_attr "amdfam10_decode" "direct")
1635 (set_attr "bdver1_decode" "double")])
1637 ;; Push/pop instructions.
1639 (define_insn "*push<mode>2"
1640 [(set (match_operand:DWI 0 "push_operand" "=<")
1641 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1644 [(set_attr "type" "multi")
1645 (set_attr "mode" "<MODE>")])
1648 [(set (match_operand:TI 0 "push_operand")
1649 (match_operand:TI 1 "general_operand"))]
1650 "TARGET_64BIT && reload_completed
1651 && !SSE_REG_P (operands[1])"
1653 "ix86_split_long_move (operands); DONE;")
1655 (define_insn "*pushdi2_rex64"
1656 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1657 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1662 [(set_attr "type" "push,multi")
1663 (set_attr "mode" "DI")])
1665 ;; Convert impossible pushes of immediate to existing instructions.
1666 ;; First try to get scratch register and go through it. In case this
1667 ;; fails, push sign extended lower part first and then overwrite
1668 ;; upper part by 32bit move.
1670 [(match_scratch:DI 2 "r")
1671 (set (match_operand:DI 0 "push_operand")
1672 (match_operand:DI 1 "immediate_operand"))]
1673 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1674 && !x86_64_immediate_operand (operands[1], DImode)"
1675 [(set (match_dup 2) (match_dup 1))
1676 (set (match_dup 0) (match_dup 2))])
1678 ;; We need to define this as both peepholer and splitter for case
1679 ;; peephole2 pass is not run.
1680 ;; "&& 1" is needed to keep it from matching the previous pattern.
1682 [(set (match_operand:DI 0 "push_operand")
1683 (match_operand:DI 1 "immediate_operand"))]
1684 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1685 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1686 [(set (match_dup 0) (match_dup 1))
1687 (set (match_dup 2) (match_dup 3))]
1689 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1691 operands[1] = gen_lowpart (DImode, operands[2]);
1692 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1697 [(set (match_operand:DI 0 "push_operand")
1698 (match_operand:DI 1 "immediate_operand"))]
1699 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1700 ? epilogue_completed : reload_completed)
1701 && !symbolic_operand (operands[1], DImode)
1702 && !x86_64_immediate_operand (operands[1], DImode)"
1703 [(set (match_dup 0) (match_dup 1))
1704 (set (match_dup 2) (match_dup 3))]
1706 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1708 operands[1] = gen_lowpart (DImode, operands[2]);
1709 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1714 [(set (match_operand:DI 0 "push_operand")
1715 (match_operand:DI 1 "general_operand"))]
1716 "!TARGET_64BIT && reload_completed
1717 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1719 "ix86_split_long_move (operands); DONE;")
1721 (define_insn "*pushsi2"
1722 [(set (match_operand:SI 0 "push_operand" "=<")
1723 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1726 [(set_attr "type" "push")
1727 (set_attr "mode" "SI")])
1729 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1730 ;; "push a byte/word". But actually we use pushl, which has the effect
1731 ;; of rounding the amount pushed up to a word.
1733 ;; For TARGET_64BIT we always round up to 8 bytes.
1734 (define_insn "*push<mode>2_rex64"
1735 [(set (match_operand:SWI124 0 "push_operand" "=X")
1736 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1739 [(set_attr "type" "push")
1740 (set_attr "mode" "DI")])
1742 (define_insn "*push<mode>2"
1743 [(set (match_operand:SWI12 0 "push_operand" "=X")
1744 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1747 [(set_attr "type" "push")
1748 (set_attr "mode" "SI")])
1750 (define_insn "*push<mode>2_prologue"
1751 [(set (match_operand:W 0 "push_operand" "=<")
1752 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1753 (clobber (mem:BLK (scratch)))]
1755 "push{<imodesuffix>}\t%1"
1756 [(set_attr "type" "push")
1757 (set_attr "mode" "<MODE>")])
1759 (define_insn "*pop<mode>1"
1760 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1761 (match_operand:W 1 "pop_operand" ">"))]
1763 "pop{<imodesuffix>}\t%0"
1764 [(set_attr "type" "pop")
1765 (set_attr "mode" "<MODE>")])
1767 (define_insn "*pop<mode>1_epilogue"
1768 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1769 (match_operand:W 1 "pop_operand" ">"))
1770 (clobber (mem:BLK (scratch)))]
1772 "pop{<imodesuffix>}\t%0"
1773 [(set_attr "type" "pop")
1774 (set_attr "mode" "<MODE>")])
1776 (define_insn "*pushfl<mode>2"
1777 [(set (match_operand:W 0 "push_operand" "=<")
1778 (match_operand:W 1 "flags_reg_operand"))]
1780 "pushf{<imodesuffix>}"
1781 [(set_attr "type" "push")
1782 (set_attr "mode" "<MODE>")])
1784 (define_insn "*popfl<mode>1"
1785 [(set (match_operand:W 0 "flags_reg_operand")
1786 (match_operand:W 1 "pop_operand" ">"))]
1788 "popf{<imodesuffix>}"
1789 [(set_attr "type" "pop")
1790 (set_attr "mode" "<MODE>")])
1793 ;; Move instructions.
1795 (define_expand "movxi"
1796 [(set (match_operand:XI 0 "nonimmediate_operand")
1797 (match_operand:XI 1 "general_operand"))]
1799 "ix86_expand_move (XImode, operands); DONE;")
1801 ;; Reload patterns to support multi-word load/store
1802 ;; with non-offsetable address.
1803 (define_expand "reload_noff_store"
1804 [(parallel [(match_operand 0 "memory_operand" "=m")
1805 (match_operand 1 "register_operand" "r")
1806 (match_operand:DI 2 "register_operand" "=&r")])]
1809 rtx mem = operands[0];
1810 rtx addr = XEXP (mem, 0);
1812 emit_move_insn (operands[2], addr);
1813 mem = replace_equiv_address_nv (mem, operands[2]);
1815 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1819 (define_expand "reload_noff_load"
1820 [(parallel [(match_operand 0 "register_operand" "=r")
1821 (match_operand 1 "memory_operand" "m")
1822 (match_operand:DI 2 "register_operand" "=r")])]
1825 rtx mem = operands[1];
1826 rtx addr = XEXP (mem, 0);
1828 emit_move_insn (operands[2], addr);
1829 mem = replace_equiv_address_nv (mem, operands[2]);
1831 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1835 (define_expand "movoi"
1836 [(set (match_operand:OI 0 "nonimmediate_operand")
1837 (match_operand:OI 1 "general_operand"))]
1839 "ix86_expand_move (OImode, operands); DONE;")
1841 (define_expand "movti"
1842 [(set (match_operand:TI 0 "nonimmediate_operand")
1843 (match_operand:TI 1 "nonimmediate_operand"))]
1844 "TARGET_64BIT || TARGET_SSE"
1847 ix86_expand_move (TImode, operands);
1849 ix86_expand_vector_move (TImode, operands);
1853 ;; This expands to what emit_move_complex would generate if we didn't
1854 ;; have a movti pattern. Having this avoids problems with reload on
1855 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1856 ;; to have around all the time.
1857 (define_expand "movcdi"
1858 [(set (match_operand:CDI 0 "nonimmediate_operand")
1859 (match_operand:CDI 1 "general_operand"))]
1862 if (push_operand (operands[0], CDImode))
1863 emit_move_complex_push (CDImode, operands[0], operands[1]);
1865 emit_move_complex_parts (operands[0], operands[1]);
1869 (define_expand "mov<mode>"
1870 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1871 (match_operand:SWI1248x 1 "general_operand"))]
1873 "ix86_expand_move (<MODE>mode, operands); DONE;")
1875 (define_insn "*mov<mode>_xor"
1876 [(set (match_operand:SWI48 0 "register_operand" "=r")
1877 (match_operand:SWI48 1 "const0_operand"))
1878 (clobber (reg:CC FLAGS_REG))]
1881 [(set_attr "type" "alu1")
1882 (set_attr "mode" "SI")
1883 (set_attr "length_immediate" "0")])
1885 (define_insn "*mov<mode>_or"
1886 [(set (match_operand:SWI48 0 "register_operand" "=r")
1887 (match_operand:SWI48 1 "const_int_operand"))
1888 (clobber (reg:CC FLAGS_REG))]
1890 && operands[1] == constm1_rtx"
1891 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1892 [(set_attr "type" "alu1")
1893 (set_attr "mode" "<MODE>")
1894 (set_attr "length_immediate" "1")])
1896 (define_insn "*movxi_internal_avx512f"
1897 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1898 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1899 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1901 switch (which_alternative)
1904 return standard_sse_constant_opcode (insn, operands[1]);
1907 if (misaligned_operand (operands[0], XImode)
1908 || misaligned_operand (operands[1], XImode))
1909 return "vmovdqu32\t{%1, %0|%0, %1}";
1911 return "vmovdqa32\t{%1, %0|%0, %1}";
1916 [(set_attr "type" "sselog1,ssemov,ssemov")
1917 (set_attr "prefix" "evex")
1918 (set_attr "mode" "XI")])
1920 (define_insn "*movoi_internal_avx"
1921 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1922 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1923 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1925 switch (get_attr_type (insn))
1928 return standard_sse_constant_opcode (insn, operands[1]);
1931 if (misaligned_operand (operands[0], OImode)
1932 || misaligned_operand (operands[1], OImode))
1934 if (get_attr_mode (insn) == MODE_V8SF)
1935 return "vmovups\t{%1, %0|%0, %1}";
1937 return "vmovdqu\t{%1, %0|%0, %1}";
1941 if (get_attr_mode (insn) == MODE_V8SF)
1942 return "vmovaps\t{%1, %0|%0, %1}";
1944 return "vmovdqa\t{%1, %0|%0, %1}";
1951 [(set_attr "type" "sselog1,ssemov,ssemov")
1952 (set_attr "prefix" "vex")
1954 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1955 (const_string "V8SF")
1956 (and (eq_attr "alternative" "2")
1957 (match_test "TARGET_SSE_TYPELESS_STORES"))
1958 (const_string "V8SF")
1960 (const_string "OI")))])
1962 (define_insn "*movti_internal"
1963 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1964 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1965 "(TARGET_64BIT || TARGET_SSE)
1966 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1968 switch (get_attr_type (insn))
1974 return standard_sse_constant_opcode (insn, operands[1]);
1977 /* TDmode values are passed as TImode on the stack. Moving them
1978 to stack may result in unaligned memory access. */
1979 if (misaligned_operand (operands[0], TImode)
1980 || misaligned_operand (operands[1], TImode))
1982 if (get_attr_mode (insn) == MODE_V4SF)
1983 return "%vmovups\t{%1, %0|%0, %1}";
1985 return "%vmovdqu\t{%1, %0|%0, %1}";
1989 if (get_attr_mode (insn) == MODE_V4SF)
1990 return "%vmovaps\t{%1, %0|%0, %1}";
1992 return "%vmovdqa\t{%1, %0|%0, %1}";
1999 [(set_attr "isa" "x64,x64,*,*,*")
2000 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2001 (set (attr "prefix")
2002 (if_then_else (eq_attr "type" "sselog1,ssemov")
2003 (const_string "maybe_vex")
2004 (const_string "orig")))
2006 (cond [(eq_attr "alternative" "0,1")
2008 (ior (not (match_test "TARGET_SSE2"))
2009 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2010 (const_string "V4SF")
2011 (and (eq_attr "alternative" "4")
2012 (match_test "TARGET_SSE_TYPELESS_STORES"))
2013 (const_string "V4SF")
2014 (match_test "TARGET_AVX")
2016 (match_test "optimize_function_for_size_p (cfun)")
2017 (const_string "V4SF")
2019 (const_string "TI")))])
2022 [(set (match_operand:TI 0 "nonimmediate_operand")
2023 (match_operand:TI 1 "general_operand"))]
2025 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2027 "ix86_split_long_move (operands); DONE;")
2029 (define_insn "*movdi_internal"
2030 [(set (match_operand:DI 0 "nonimmediate_operand"
2031 "=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")
2032 (match_operand:DI 1 "general_operand"
2033 "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"))]
2034 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2036 switch (get_attr_type (insn))
2039 return "kmovq\t{%1, %0|%0, %1}";
2045 return "pxor\t%0, %0";
2048 /* Handle broken assemblers that require movd instead of movq. */
2049 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2050 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2051 return "movd\t{%1, %0|%0, %1}";
2052 return "movq\t{%1, %0|%0, %1}";
2055 if (GENERAL_REG_P (operands[0]))
2056 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2058 return standard_sse_constant_opcode (insn, operands[1]);
2061 switch (get_attr_mode (insn))
2064 /* Handle broken assemblers that require movd instead of movq. */
2065 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2066 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2067 return "%vmovd\t{%1, %0|%0, %1}";
2068 return "%vmovq\t{%1, %0|%0, %1}";
2070 return "%vmovdqa\t{%1, %0|%0, %1}";
2072 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2075 gcc_assert (!TARGET_AVX);
2076 return "movlps\t{%1, %0|%0, %1}";
2078 return "%vmovaps\t{%1, %0|%0, %1}";
2085 if (SSE_REG_P (operands[0]))
2086 return "movq2dq\t{%1, %0|%0, %1}";
2088 return "movdq2q\t{%1, %0|%0, %1}";
2091 return "lea{q}\t{%E1, %0|%0, %E1}";
2094 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2095 if (get_attr_mode (insn) == MODE_SI)
2096 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2097 else if (which_alternative == 4)
2098 return "movabs{q}\t{%1, %0|%0, %1}";
2099 else if (ix86_use_lea_for_mov (insn, operands))
2100 return "lea{q}\t{%E1, %0|%0, %E1}";
2102 return "mov{q}\t{%1, %0|%0, %1}";
2109 (cond [(eq_attr "alternative" "0,1")
2110 (const_string "nox64")
2111 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2112 (const_string "x64")
2113 (eq_attr "alternative" "17")
2114 (const_string "x64_sse4")
2116 (const_string "*")))
2118 (cond [(eq_attr "alternative" "0,1")
2119 (const_string "multi")
2120 (eq_attr "alternative" "6")
2121 (const_string "mmx")
2122 (eq_attr "alternative" "7,8,9,10,11")
2123 (const_string "mmxmov")
2124 (eq_attr "alternative" "12,17")
2125 (const_string "sselog1")
2126 (eq_attr "alternative" "13,14,15,16,18")
2127 (const_string "ssemov")
2128 (eq_attr "alternative" "19,20")
2129 (const_string "ssecvt")
2130 (eq_attr "alternative" "21,22,23,24")
2131 (const_string "mskmov")
2132 (match_operand 1 "pic_32bit_operand")
2133 (const_string "lea")
2135 (const_string "imov")))
2138 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2140 (const_string "*")))
2141 (set (attr "length_immediate")
2142 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2144 (eq_attr "alternative" "17")
2147 (const_string "*")))
2148 (set (attr "prefix_rex")
2149 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2151 (const_string "*")))
2152 (set (attr "prefix_extra")
2153 (if_then_else (eq_attr "alternative" "17")
2155 (const_string "*")))
2156 (set (attr "prefix")
2157 (if_then_else (eq_attr "type" "sselog1,ssemov")
2158 (const_string "maybe_vex")
2159 (const_string "orig")))
2160 (set (attr "prefix_data16")
2161 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2163 (const_string "*")))
2165 (cond [(eq_attr "alternative" "2")
2167 (eq_attr "alternative" "12,13")
2168 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2169 (match_operand 1 "ext_sse_reg_operand"))
2171 (ior (not (match_test "TARGET_SSE2"))
2172 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2173 (const_string "V4SF")
2174 (match_test "TARGET_AVX")
2176 (match_test "optimize_function_for_size_p (cfun)")
2177 (const_string "V4SF")
2179 (const_string "TI"))
2181 (and (eq_attr "alternative" "14,15")
2182 (not (match_test "TARGET_SSE2")))
2183 (const_string "V2SF")
2184 (eq_attr "alternative" "17")
2187 (const_string "DI")))])
2190 [(set (match_operand:DI 0 "nonimmediate_operand")
2191 (match_operand:DI 1 "general_operand"))]
2192 "!TARGET_64BIT && reload_completed
2193 && !(MMX_REG_P (operands[0])
2194 || SSE_REG_P (operands[0])
2195 || MASK_REG_P (operands[0]))
2196 && !(MMX_REG_P (operands[1])
2197 || SSE_REG_P (operands[1])
2198 || MASK_REG_P (operands[1]))"
2200 "ix86_split_long_move (operands); DONE;")
2202 (define_insn "*movsi_internal"
2203 [(set (match_operand:SI 0 "nonimmediate_operand"
2204 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2205 (match_operand:SI 1 "general_operand"
2206 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2209 switch (get_attr_type (insn))
2212 if (GENERAL_REG_P (operands[0]))
2213 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2215 return standard_sse_constant_opcode (insn, operands[1]);
2218 return "kmovd\t{%1, %0|%0, %1}";
2221 switch (get_attr_mode (insn))
2224 return "%vmovd\t{%1, %0|%0, %1}";
2226 return "%vmovdqa\t{%1, %0|%0, %1}";
2228 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2231 return "%vmovaps\t{%1, %0|%0, %1}";
2234 gcc_assert (!TARGET_AVX);
2235 return "movss\t{%1, %0|%0, %1}";
2242 return "pxor\t%0, %0";
2245 switch (get_attr_mode (insn))
2248 return "movq\t{%1, %0|%0, %1}";
2250 return "movd\t{%1, %0|%0, %1}";
2257 return "lea{l}\t{%E1, %0|%0, %E1}";
2260 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2261 if (ix86_use_lea_for_mov (insn, operands))
2262 return "lea{l}\t{%E1, %0|%0, %E1}";
2264 return "mov{l}\t{%1, %0|%0, %1}";
2271 (if_then_else (eq_attr "alternative" "11")
2272 (const_string "sse4")
2273 (const_string "*")))
2275 (cond [(eq_attr "alternative" "2")
2276 (const_string "mmx")
2277 (eq_attr "alternative" "3,4,5")
2278 (const_string "mmxmov")
2279 (eq_attr "alternative" "6,11")
2280 (const_string "sselog1")
2281 (eq_attr "alternative" "7,8,9,10,12")
2282 (const_string "ssemov")
2283 (eq_attr "alternative" "13,14")
2284 (const_string "mskmov")
2285 (match_operand 1 "pic_32bit_operand")
2286 (const_string "lea")
2288 (const_string "imov")))
2289 (set (attr "length_immediate")
2290 (if_then_else (eq_attr "alternative" "11")
2292 (const_string "*")))
2293 (set (attr "prefix_extra")
2294 (if_then_else (eq_attr "alternative" "11")
2296 (const_string "*")))
2297 (set (attr "prefix")
2298 (if_then_else (eq_attr "type" "sselog1,ssemov")
2299 (const_string "maybe_vex")
2300 (const_string "orig")))
2301 (set (attr "prefix_data16")
2302 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2304 (const_string "*")))
2306 (cond [(eq_attr "alternative" "2,3")
2308 (eq_attr "alternative" "6,7")
2309 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2310 (match_operand 1 "ext_sse_reg_operand"))
2312 (ior (not (match_test "TARGET_SSE2"))
2313 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2314 (const_string "V4SF")
2315 (match_test "TARGET_AVX")
2317 (match_test "optimize_function_for_size_p (cfun)")
2318 (const_string "V4SF")
2320 (const_string "TI"))
2322 (and (eq_attr "alternative" "8,9")
2323 (not (match_test "TARGET_SSE2")))
2325 (eq_attr "alternative" "11")
2328 (const_string "SI")))])
2330 (define_insn "kmovw"
2331 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2333 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2335 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2337 kmovw\t{%k1, %0|%0, %k1}
2338 kmovw\t{%1, %0|%0, %1}";
2339 [(set_attr "mode" "HI")
2340 (set_attr "type" "mskmov")
2341 (set_attr "prefix" "vex")])
2344 (define_insn "*movhi_internal"
2345 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2346 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2347 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2349 switch (get_attr_type (insn))
2352 /* movzwl is faster than movw on p2 due to partial word stalls,
2353 though not as fast as an aligned movl. */
2354 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2357 switch (which_alternative)
2359 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2360 case 5: return "kmovw\t{%1, %0|%0, %1}";
2361 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2362 default: gcc_unreachable ();
2366 if (get_attr_mode (insn) == MODE_SI)
2367 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2369 return "mov{w}\t{%1, %0|%0, %1}";
2373 (cond [(match_test "optimize_function_for_size_p (cfun)")
2374 (const_string "imov")
2375 (and (eq_attr "alternative" "0")
2376 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2377 (not (match_test "TARGET_HIMODE_MATH"))))
2378 (const_string "imov")
2379 (and (eq_attr "alternative" "1,2")
2380 (match_operand:HI 1 "aligned_operand"))
2381 (const_string "imov")
2382 (eq_attr "alternative" "4,5,6")
2383 (const_string "mskmov")
2384 (and (match_test "TARGET_MOVX")
2385 (eq_attr "alternative" "0,2"))
2386 (const_string "imovx")
2388 (const_string "imov")))
2389 (set (attr "prefix")
2390 (if_then_else (eq_attr "alternative" "4,5,6")
2391 (const_string "vex")
2392 (const_string "orig")))
2394 (cond [(eq_attr "type" "imovx")
2396 (and (eq_attr "alternative" "1,2")
2397 (match_operand:HI 1 "aligned_operand"))
2399 (and (eq_attr "alternative" "0")
2400 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2401 (not (match_test "TARGET_HIMODE_MATH"))))
2404 (const_string "HI")))])
2406 ;; Situation is quite tricky about when to choose full sized (SImode) move
2407 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2408 ;; partial register dependency machines (such as AMD Athlon), where QImode
2409 ;; moves issue extra dependency and for partial register stalls machines
2410 ;; that don't use QImode patterns (and QImode move cause stall on the next
2413 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2414 ;; register stall machines with, where we use QImode instructions, since
2415 ;; partial register stall can be caused there. Then we use movzx.
2417 (define_insn "*movqi_internal"
2418 [(set (match_operand:QI 0 "nonimmediate_operand"
2419 "=q,q ,q ,r,r ,?r,m ,k,k,r")
2420 (match_operand:QI 1 "general_operand"
2421 "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2422 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2424 switch (get_attr_type (insn))
2427 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2428 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2431 switch (which_alternative)
2433 case 7: return TARGET_AVX512BW ? "kmovb\t{%k1, %0|%0, %k1}"
2434 : "kmovw\t{%k1, %0|%0, %k1}";
2435 case 8: return TARGET_AVX512BW ? "kmovb\t{%1, %0|%0, %1}"
2436 : "kmovw\t{%1, %0|%0, %1}";
2437 case 9: return TARGET_AVX512BW ? "kmovb\t{%1, %k0|%k0, %1}"
2438 : "kmovw\t{%1, %k0|%k0, %1}";
2439 default: gcc_unreachable ();
2443 if (get_attr_mode (insn) == MODE_SI)
2444 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2446 return "mov{b}\t{%1, %0|%0, %1}";
2450 (cond [(and (eq_attr "alternative" "5")
2451 (not (match_operand:QI 1 "aligned_operand")))
2452 (const_string "imovx")
2453 (match_test "optimize_function_for_size_p (cfun)")
2454 (const_string "imov")
2455 (and (eq_attr "alternative" "3")
2456 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2457 (not (match_test "TARGET_QIMODE_MATH"))))
2458 (const_string "imov")
2459 (eq_attr "alternative" "3,5")
2460 (const_string "imovx")
2461 (eq_attr "alternative" "7,8,9")
2462 (const_string "mskmov")
2463 (and (match_test "TARGET_MOVX")
2464 (eq_attr "alternative" "2"))
2465 (const_string "imovx")
2467 (const_string "imov")))
2468 (set (attr "prefix")
2469 (if_then_else (eq_attr "alternative" "7,8,9")
2470 (const_string "vex")
2471 (const_string "orig")))
2473 (cond [(eq_attr "alternative" "3,4,5")
2475 (eq_attr "alternative" "6")
2477 (eq_attr "type" "imovx")
2479 (and (eq_attr "type" "imov")
2480 (and (eq_attr "alternative" "0,1")
2481 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2482 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2483 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2485 ;; Avoid partial register stalls when not using QImode arithmetic
2486 (and (eq_attr "type" "imov")
2487 (and (eq_attr "alternative" "0,1")
2488 (and (match_test "TARGET_PARTIAL_REG_STALL")
2489 (not (match_test "TARGET_QIMODE_MATH")))))
2492 (const_string "QI")))])
2494 ;; Stores and loads of ax to arbitrary constant address.
2495 ;; We fake an second form of instruction to force reload to load address
2496 ;; into register when rax is not available
2497 (define_insn "*movabs<mode>_1"
2498 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2499 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2500 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2502 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2503 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2504 [(set_attr "type" "imov")
2505 (set_attr "modrm" "0,*")
2506 (set_attr "length_address" "8,0")
2507 (set_attr "length_immediate" "0,*")
2508 (set_attr "memory" "store")
2509 (set_attr "mode" "<MODE>")])
2511 (define_insn "*movabs<mode>_2"
2512 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2513 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2514 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2516 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2517 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2518 [(set_attr "type" "imov")
2519 (set_attr "modrm" "0,*")
2520 (set_attr "length_address" "8,0")
2521 (set_attr "length_immediate" "0")
2522 (set_attr "memory" "load")
2523 (set_attr "mode" "<MODE>")])
2525 (define_insn "*swap<mode>"
2526 [(set (match_operand:SWI48 0 "register_operand" "+r")
2527 (match_operand:SWI48 1 "register_operand" "+r"))
2531 "xchg{<imodesuffix>}\t%1, %0"
2532 [(set_attr "type" "imov")
2533 (set_attr "mode" "<MODE>")
2534 (set_attr "pent_pair" "np")
2535 (set_attr "athlon_decode" "vector")
2536 (set_attr "amdfam10_decode" "double")
2537 (set_attr "bdver1_decode" "double")])
2539 (define_insn "*swap<mode>_1"
2540 [(set (match_operand:SWI12 0 "register_operand" "+r")
2541 (match_operand:SWI12 1 "register_operand" "+r"))
2544 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2546 [(set_attr "type" "imov")
2547 (set_attr "mode" "SI")
2548 (set_attr "pent_pair" "np")
2549 (set_attr "athlon_decode" "vector")
2550 (set_attr "amdfam10_decode" "double")
2551 (set_attr "bdver1_decode" "double")])
2553 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2554 ;; is disabled for AMDFAM10
2555 (define_insn "*swap<mode>_2"
2556 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2557 (match_operand:SWI12 1 "register_operand" "+<r>"))
2560 "TARGET_PARTIAL_REG_STALL"
2561 "xchg{<imodesuffix>}\t%1, %0"
2562 [(set_attr "type" "imov")
2563 (set_attr "mode" "<MODE>")
2564 (set_attr "pent_pair" "np")
2565 (set_attr "athlon_decode" "vector")])
2567 (define_expand "movstrict<mode>"
2568 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2569 (match_operand:SWI12 1 "general_operand"))]
2572 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2574 if (GET_CODE (operands[0]) == SUBREG
2575 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2577 /* Don't generate memory->memory moves, go through a register */
2578 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2579 operands[1] = force_reg (<MODE>mode, operands[1]);
2582 (define_insn "*movstrict<mode>_1"
2583 [(set (strict_low_part
2584 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2585 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2586 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2587 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2588 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2589 [(set_attr "type" "imov")
2590 (set_attr "mode" "<MODE>")])
2592 (define_insn "*movstrict<mode>_xor"
2593 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2594 (match_operand:SWI12 1 "const0_operand"))
2595 (clobber (reg:CC FLAGS_REG))]
2597 "xor{<imodesuffix>}\t%0, %0"
2598 [(set_attr "type" "alu1")
2599 (set_attr "mode" "<MODE>")
2600 (set_attr "length_immediate" "0")])
2602 (define_insn "*mov<mode>_extv_1"
2603 [(set (match_operand:SWI24 0 "register_operand" "=R")
2604 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2608 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2609 [(set_attr "type" "imovx")
2610 (set_attr "mode" "SI")])
2612 (define_insn "*movqi_extv_1"
2613 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2614 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2619 switch (get_attr_type (insn))
2622 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2624 return "mov{b}\t{%h1, %0|%0, %h1}";
2627 [(set_attr "isa" "*,*,nox64")
2629 (if_then_else (and (match_operand:QI 0 "register_operand")
2630 (ior (not (match_operand:QI 0 "QIreg_operand"))
2631 (match_test "TARGET_MOVX")))
2632 (const_string "imovx")
2633 (const_string "imov")))
2635 (if_then_else (eq_attr "type" "imovx")
2637 (const_string "QI")))])
2639 (define_insn "*mov<mode>_extzv_1"
2640 [(set (match_operand:SWI48 0 "register_operand" "=R")
2641 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2645 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2646 [(set_attr "type" "imovx")
2647 (set_attr "mode" "SI")])
2649 (define_insn "*movqi_extzv_2"
2650 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2652 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2657 switch (get_attr_type (insn))
2660 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2662 return "mov{b}\t{%h1, %0|%0, %h1}";
2665 [(set_attr "isa" "*,*,nox64")
2667 (if_then_else (and (match_operand:QI 0 "register_operand")
2668 (ior (not (match_operand:QI 0 "QIreg_operand"))
2669 (match_test "TARGET_MOVX")))
2670 (const_string "imovx")
2671 (const_string "imov")))
2673 (if_then_else (eq_attr "type" "imovx")
2675 (const_string "QI")))])
2677 (define_insn "mov<mode>_insv_1"
2678 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2681 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2684 if (CONST_INT_P (operands[1]))
2685 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2686 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2688 [(set_attr "isa" "*,nox64")
2689 (set_attr "type" "imov")
2690 (set_attr "mode" "QI")])
2692 (define_insn "*movqi_insv_2"
2693 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2696 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2699 "mov{b}\t{%h1, %h0|%h0, %h1}"
2700 [(set_attr "type" "imov")
2701 (set_attr "mode" "QI")])
2703 ;; Floating point push instructions.
2705 (define_insn "*pushtf"
2706 [(set (match_operand:TF 0 "push_operand" "=<,<")
2707 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2708 "TARGET_64BIT || TARGET_SSE"
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "isa" "*,x64")
2714 (set_attr "type" "multi")
2715 (set_attr "unit" "sse,*")
2716 (set_attr "mode" "TF,DI")])
2718 ;; %%% Kill this when call knows how to work this out.
2720 [(set (match_operand:TF 0 "push_operand")
2721 (match_operand:TF 1 "sse_reg_operand"))]
2722 "TARGET_SSE && reload_completed"
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2724 (set (match_dup 0) (match_dup 1))]
2726 /* Preserve memory attributes. */
2727 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2730 (define_insn "*pushxf"
2731 [(set (match_operand:XF 0 "push_operand" "=<,<")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2735 /* This insn should be already split before reg-stack. */
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*")
2741 (cond [(eq_attr "alternative" "1")
2742 (if_then_else (match_test "TARGET_64BIT")
2744 (const_string "SI"))
2746 (const_string "XF")))])
2748 ;; %%% Kill this when call knows how to work this out.
2750 [(set (match_operand:XF 0 "push_operand")
2751 (match_operand:XF 1 "fp_register_operand"))]
2753 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2754 (set (match_dup 0) (match_dup 1))]
2756 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2757 /* Preserve memory attributes. */
2758 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2761 (define_insn "*pushdf"
2762 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2763 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2766 /* This insn should be already split before reg-stack. */
2769 [(set_attr "isa" "*,nox64,x64,sse2")
2770 (set_attr "type" "multi")
2771 (set_attr "unit" "i387,*,*,sse")
2772 (set_attr "mode" "DF,SI,DI,DF")])
2774 ;; %%% Kill this when call knows how to work this out.
2776 [(set (match_operand:DF 0 "push_operand")
2777 (match_operand:DF 1 "any_fp_register_operand"))]
2779 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2780 (set (match_dup 0) (match_dup 1))]
2782 /* Preserve memory attributes. */
2783 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2786 (define_insn "*pushsf_rex64"
2787 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2788 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2791 /* Anything else should be already split before reg-stack. */
2792 gcc_assert (which_alternative == 1);
2793 return "push{q}\t%q1";
2795 [(set_attr "type" "multi,push,multi")
2796 (set_attr "unit" "i387,*,*")
2797 (set_attr "mode" "SF,DI,SF")])
2799 (define_insn "*pushsf"
2800 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2801 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2804 /* Anything else should be already split before reg-stack. */
2805 gcc_assert (which_alternative == 1);
2806 return "push{l}\t%1";
2808 [(set_attr "type" "multi,push,multi")
2809 (set_attr "unit" "i387,*,*")
2810 (set_attr "mode" "SF,SI,SF")])
2812 ;; %%% Kill this when call knows how to work this out.
2814 [(set (match_operand:SF 0 "push_operand")
2815 (match_operand:SF 1 "any_fp_register_operand"))]
2817 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2818 (set (match_dup 0) (match_dup 1))]
2820 rtx op = XEXP (operands[0], 0);
2821 if (GET_CODE (op) == PRE_DEC)
2823 gcc_assert (!TARGET_64BIT);
2828 op = XEXP (XEXP (op, 1), 1);
2829 gcc_assert (CONST_INT_P (op));
2832 /* Preserve memory attributes. */
2833 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2837 [(set (match_operand:SF 0 "push_operand")
2838 (match_operand:SF 1 "memory_operand"))]
2840 && (operands[2] = find_constant_src (insn))"
2841 [(set (match_dup 0) (match_dup 2))])
2844 [(set (match_operand 0 "push_operand")
2845 (match_operand 1 "general_operand"))]
2847 && (GET_MODE (operands[0]) == TFmode
2848 || GET_MODE (operands[0]) == XFmode
2849 || GET_MODE (operands[0]) == DFmode)
2850 && !ANY_FP_REG_P (operands[1])"
2852 "ix86_split_long_move (operands); DONE;")
2854 ;; Floating point move instructions.
2856 (define_expand "movtf"
2857 [(set (match_operand:TF 0 "nonimmediate_operand")
2858 (match_operand:TF 1 "nonimmediate_operand"))]
2859 "TARGET_64BIT || TARGET_SSE"
2860 "ix86_expand_move (TFmode, operands); DONE;")
2862 (define_expand "mov<mode>"
2863 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2864 (match_operand:X87MODEF 1 "general_operand"))]
2866 "ix86_expand_move (<MODE>mode, operands); DONE;")
2868 (define_insn "*movtf_internal"
2869 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2870 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2871 "(TARGET_64BIT || TARGET_SSE)
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && (!can_create_pseudo_p ()
2874 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2875 || GET_CODE (operands[1]) != CONST_DOUBLE
2876 || (optimize_function_for_size_p (cfun)
2877 && standard_sse_constant_p (operands[1])
2878 && !memory_operand (operands[0], TFmode))
2879 || (!TARGET_MEMORY_MISMATCH_STALL
2880 && memory_operand (operands[0], TFmode)))"
2882 switch (get_attr_type (insn))
2885 return standard_sse_constant_opcode (insn, operands[1]);
2888 /* Handle misaligned load/store since we
2889 don't have movmisaligntf pattern. */
2890 if (misaligned_operand (operands[0], TFmode)
2891 || misaligned_operand (operands[1], TFmode))
2893 if (get_attr_mode (insn) == MODE_V4SF)
2894 return "%vmovups\t{%1, %0|%0, %1}";
2896 return "%vmovdqu\t{%1, %0|%0, %1}";
2900 if (get_attr_mode (insn) == MODE_V4SF)
2901 return "%vmovaps\t{%1, %0|%0, %1}";
2903 return "%vmovdqa\t{%1, %0|%0, %1}";
2913 [(set_attr "isa" "*,*,*,x64,x64")
2914 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2915 (set (attr "prefix")
2916 (if_then_else (eq_attr "type" "sselog1,ssemov")
2917 (const_string "maybe_vex")
2918 (const_string "orig")))
2920 (cond [(eq_attr "alternative" "3,4")
2922 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2923 (const_string "V4SF")
2924 (and (eq_attr "alternative" "2")
2925 (match_test "TARGET_SSE_TYPELESS_STORES"))
2926 (const_string "V4SF")
2927 (match_test "TARGET_AVX")
2929 (ior (not (match_test "TARGET_SSE2"))
2930 (match_test "optimize_function_for_size_p (cfun)"))
2931 (const_string "V4SF")
2933 (const_string "TI")))])
2935 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2936 (define_insn "*movxf_internal"
2937 [(set (match_operand:XF 0 "nonimmediate_operand"
2938 "=f,m,f,?Yx*r ,!o ,!o")
2939 (match_operand:XF 1 "general_operand"
2940 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2941 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2942 && (!can_create_pseudo_p ()
2943 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2944 || GET_CODE (operands[1]) != CONST_DOUBLE
2945 || (optimize_function_for_size_p (cfun)
2946 && standard_80387_constant_p (operands[1]) > 0
2947 && !memory_operand (operands[0], XFmode))
2948 || (!TARGET_MEMORY_MISMATCH_STALL
2949 && memory_operand (operands[0], XFmode)))"
2951 switch (get_attr_type (insn))
2954 if (which_alternative == 2)
2955 return standard_80387_constant_opcode (operands[1]);
2956 return output_387_reg_move (insn, operands);
2965 [(set_attr "isa" "*,*,*,*,nox64,x64")
2966 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2968 (cond [(eq_attr "alternative" "3,4,5")
2969 (if_then_else (match_test "TARGET_64BIT")
2971 (const_string "SI"))
2973 (const_string "XF")))])
2975 ;; Possible store forwarding (partial memory) stall in alternative 4.
2976 (define_insn "*movdf_internal"
2977 [(set (match_operand:DF 0 "nonimmediate_operand"
2978 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2979 (match_operand:DF 1 "general_operand"
2980 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2981 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2982 && (!can_create_pseudo_p ()
2983 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2984 || GET_CODE (operands[1]) != CONST_DOUBLE
2985 || (optimize_function_for_size_p (cfun)
2986 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2987 && standard_80387_constant_p (operands[1]) > 0)
2988 || (TARGET_SSE2 && TARGET_SSE_MATH
2989 && standard_sse_constant_p (operands[1])))
2990 && !memory_operand (operands[0], DFmode))
2991 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2992 && memory_operand (operands[0], DFmode)))"
2994 switch (get_attr_type (insn))
2997 if (which_alternative == 2)
2998 return standard_80387_constant_opcode (operands[1]);
2999 return output_387_reg_move (insn, operands);
3005 if (get_attr_mode (insn) == MODE_SI)
3006 return "mov{l}\t{%1, %k0|%k0, %1}";
3007 else if (which_alternative == 8)
3008 return "movabs{q}\t{%1, %0|%0, %1}";
3010 return "mov{q}\t{%1, %0|%0, %1}";
3013 return standard_sse_constant_opcode (insn, operands[1]);
3016 switch (get_attr_mode (insn))
3019 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3020 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3021 return "%vmovsd\t{%1, %0|%0, %1}";
3024 return "%vmovaps\t{%1, %0|%0, %1}";
3026 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3028 return "%vmovapd\t{%1, %0|%0, %1}";
3031 gcc_assert (!TARGET_AVX);
3032 return "movlps\t{%1, %0|%0, %1}";
3034 gcc_assert (!TARGET_AVX);
3035 return "movlpd\t{%1, %0|%0, %1}";
3038 /* Handle broken assemblers that require movd instead of movq. */
3039 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3040 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3041 return "%vmovd\t{%1, %0|%0, %1}";
3042 return "%vmovq\t{%1, %0|%0, %1}";
3053 (cond [(eq_attr "alternative" "3,4")
3054 (const_string "nox64")
3055 (eq_attr "alternative" "5,6,7,8,17,18")
3056 (const_string "x64")
3057 (eq_attr "alternative" "9,10,11,12")
3058 (const_string "sse2")
3060 (const_string "*")))
3062 (cond [(eq_attr "alternative" "0,1,2")
3063 (const_string "fmov")
3064 (eq_attr "alternative" "3,4")
3065 (const_string "multi")
3066 (eq_attr "alternative" "5,6,7,8")
3067 (const_string "imov")
3068 (eq_attr "alternative" "9,13")
3069 (const_string "sselog1")
3071 (const_string "ssemov")))
3073 (if_then_else (eq_attr "alternative" "8")
3075 (const_string "*")))
3076 (set (attr "length_immediate")
3077 (if_then_else (eq_attr "alternative" "8")
3079 (const_string "*")))
3080 (set (attr "prefix")
3081 (if_then_else (eq_attr "type" "sselog1,ssemov")
3082 (const_string "maybe_vex")
3083 (const_string "orig")))
3084 (set (attr "prefix_data16")
3086 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3087 (eq_attr "mode" "V1DF"))
3089 (const_string "*")))
3091 (cond [(eq_attr "alternative" "3,4,7")
3093 (eq_attr "alternative" "5,6,8,17,18")
3096 /* xorps is one byte shorter for non-AVX targets. */
3097 (eq_attr "alternative" "9,13")
3098 (cond [(not (match_test "TARGET_SSE2"))
3099 (const_string "V4SF")
3100 (match_test "TARGET_AVX512F")
3102 (match_test "TARGET_AVX")
3103 (const_string "V2DF")
3104 (match_test "optimize_function_for_size_p (cfun)")
3105 (const_string "V4SF")
3106 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3109 (const_string "V2DF"))
3111 /* For architectures resolving dependencies on
3112 whole SSE registers use movapd to break dependency
3113 chains, otherwise use short move to avoid extra work. */
3115 /* movaps is one byte shorter for non-AVX targets. */
3116 (eq_attr "alternative" "10,14")
3117 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3118 (match_operand 1 "ext_sse_reg_operand"))
3119 (const_string "V8DF")
3120 (ior (not (match_test "TARGET_SSE2"))
3121 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3122 (const_string "V4SF")
3123 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3124 (const_string "V2DF")
3125 (match_test "TARGET_AVX")
3127 (match_test "optimize_function_for_size_p (cfun)")
3128 (const_string "V4SF")
3130 (const_string "DF"))
3132 /* For architectures resolving dependencies on register
3133 parts we may avoid extra work to zero out upper part
3135 (eq_attr "alternative" "11,15")
3136 (cond [(not (match_test "TARGET_SSE2"))
3137 (const_string "V2SF")
3138 (match_test "TARGET_AVX")
3140 (match_test "TARGET_SSE_SPLIT_REGS")
3141 (const_string "V1DF")
3143 (const_string "DF"))
3145 (and (eq_attr "alternative" "12,16")
3146 (not (match_test "TARGET_SSE2")))
3147 (const_string "V2SF")
3149 (const_string "DF")))])
3151 (define_insn "*movsf_internal"
3152 [(set (match_operand:SF 0 "nonimmediate_operand"
3153 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3154 (match_operand:SF 1 "general_operand"
3155 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3156 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3157 && (!can_create_pseudo_p ()
3158 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3159 || GET_CODE (operands[1]) != CONST_DOUBLE
3160 || (optimize_function_for_size_p (cfun)
3161 && ((!TARGET_SSE_MATH
3162 && standard_80387_constant_p (operands[1]) > 0)
3164 && standard_sse_constant_p (operands[1]))))
3165 || memory_operand (operands[0], SFmode))"
3167 switch (get_attr_type (insn))
3170 if (which_alternative == 2)
3171 return standard_80387_constant_opcode (operands[1]);
3172 return output_387_reg_move (insn, operands);
3175 return "mov{l}\t{%1, %0|%0, %1}";
3178 return standard_sse_constant_opcode (insn, operands[1]);
3181 switch (get_attr_mode (insn))
3184 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3185 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3186 return "%vmovss\t{%1, %0|%0, %1}";
3189 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3191 return "%vmovaps\t{%1, %0|%0, %1}";
3194 return "%vmovd\t{%1, %0|%0, %1}";
3201 switch (get_attr_mode (insn))
3204 return "movq\t{%1, %0|%0, %1}";
3206 return "movd\t{%1, %0|%0, %1}";
3217 (cond [(eq_attr "alternative" "0,1,2")
3218 (const_string "fmov")
3219 (eq_attr "alternative" "3,4")
3220 (const_string "imov")
3221 (eq_attr "alternative" "5")
3222 (const_string "sselog1")
3223 (eq_attr "alternative" "11,12,13,14,15")
3224 (const_string "mmxmov")
3226 (const_string "ssemov")))
3227 (set (attr "prefix")
3228 (if_then_else (eq_attr "type" "sselog1,ssemov")
3229 (const_string "maybe_vex")
3230 (const_string "orig")))
3231 (set (attr "prefix_data16")
3232 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3234 (const_string "*")))
3236 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3238 (eq_attr "alternative" "11")
3240 (eq_attr "alternative" "5")
3241 (cond [(not (match_test "TARGET_SSE2"))
3242 (const_string "V4SF")
3243 (match_test "TARGET_AVX512F")
3244 (const_string "V16SF")
3245 (match_test "TARGET_AVX")
3246 (const_string "V4SF")
3247 (match_test "optimize_function_for_size_p (cfun)")
3248 (const_string "V4SF")
3249 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3252 (const_string "V4SF"))
3254 /* For architectures resolving dependencies on
3255 whole SSE registers use APS move to break dependency
3256 chains, otherwise use short move to avoid extra work.
3258 Do the same for architectures resolving dependencies on
3259 the parts. While in DF mode it is better to always handle
3260 just register parts, the SF mode is different due to lack
3261 of instructions to load just part of the register. It is
3262 better to maintain the whole registers in single format
3263 to avoid problems on using packed logical operations. */
3264 (eq_attr "alternative" "6")
3265 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3266 (match_operand 1 "ext_sse_reg_operand"))
3267 (const_string "V16SF")
3268 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3269 (match_test "TARGET_SSE_SPLIT_REGS"))
3270 (const_string "V4SF")
3272 (const_string "SF"))
3274 (const_string "SF")))])
3277 [(set (match_operand 0 "any_fp_register_operand")
3278 (match_operand 1 "memory_operand"))]
3280 && (GET_MODE (operands[0]) == TFmode
3281 || GET_MODE (operands[0]) == XFmode
3282 || GET_MODE (operands[0]) == DFmode
3283 || GET_MODE (operands[0]) == SFmode)
3284 && (operands[2] = find_constant_src (insn))"
3285 [(set (match_dup 0) (match_dup 2))]
3287 rtx c = operands[2];
3288 int r = REGNO (operands[0]);
3290 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3291 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3296 [(set (match_operand 0 "any_fp_register_operand")
3297 (float_extend (match_operand 1 "memory_operand")))]
3299 && (GET_MODE (operands[0]) == TFmode
3300 || GET_MODE (operands[0]) == XFmode
3301 || GET_MODE (operands[0]) == DFmode)
3302 && (operands[2] = find_constant_src (insn))"
3303 [(set (match_dup 0) (match_dup 2))]
3305 rtx c = operands[2];
3306 int r = REGNO (operands[0]);
3308 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3309 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3313 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3315 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3316 (match_operand:X87MODEF 1 "immediate_operand"))]
3318 && (standard_80387_constant_p (operands[1]) == 8
3319 || standard_80387_constant_p (operands[1]) == 9)"
3320 [(set (match_dup 0)(match_dup 1))
3322 (neg:X87MODEF (match_dup 0)))]
3326 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3327 if (real_isnegzero (&r))
3328 operands[1] = CONST0_RTX (<MODE>mode);
3330 operands[1] = CONST1_RTX (<MODE>mode);
3334 [(set (match_operand 0 "nonimmediate_operand")
3335 (match_operand 1 "general_operand"))]
3337 && (GET_MODE (operands[0]) == TFmode
3338 || GET_MODE (operands[0]) == XFmode
3339 || GET_MODE (operands[0]) == DFmode)
3340 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3342 "ix86_split_long_move (operands); DONE;")
3344 (define_insn "swapxf"
3345 [(set (match_operand:XF 0 "register_operand" "+f")
3346 (match_operand:XF 1 "register_operand" "+f"))
3351 if (STACK_TOP_P (operands[0]))
3356 [(set_attr "type" "fxch")
3357 (set_attr "mode" "XF")])
3359 (define_insn "*swap<mode>"
3360 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3361 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3364 "TARGET_80387 || reload_completed"
3366 if (STACK_TOP_P (operands[0]))
3371 [(set_attr "type" "fxch")
3372 (set_attr "mode" "<MODE>")])
3374 ;; Zero extension instructions
3376 (define_expand "zero_extendsidi2"
3377 [(set (match_operand:DI 0 "nonimmediate_operand")
3378 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3380 (define_insn "*zero_extendsidi2"
3381 [(set (match_operand:DI 0 "nonimmediate_operand"
3382 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3384 (match_operand:SI 1 "x86_64_zext_operand"
3385 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3388 switch (get_attr_type (insn))
3391 if (ix86_use_lea_for_mov (insn, operands))
3392 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3394 return "mov{l}\t{%1, %k0|%k0, %1}";
3400 return "movd\t{%1, %0|%0, %1}";
3403 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3406 if (GENERAL_REG_P (operands[0]))
3407 return "%vmovd\t{%1, %k0|%k0, %1}";
3409 return "%vmovd\t{%1, %0|%0, %1}";
3416 (cond [(eq_attr "alternative" "0,1,2")
3417 (const_string "nox64")
3418 (eq_attr "alternative" "3,7")
3419 (const_string "x64")
3420 (eq_attr "alternative" "8")
3421 (const_string "x64_sse4")
3422 (eq_attr "alternative" "10")
3423 (const_string "sse2")
3425 (const_string "*")))
3427 (cond [(eq_attr "alternative" "0,1,2,4")
3428 (const_string "multi")
3429 (eq_attr "alternative" "5,6")
3430 (const_string "mmxmov")
3431 (eq_attr "alternative" "7,9,10")
3432 (const_string "ssemov")
3433 (eq_attr "alternative" "8")
3434 (const_string "sselog1")
3436 (const_string "imovx")))
3437 (set (attr "prefix_extra")
3438 (if_then_else (eq_attr "alternative" "8")
3440 (const_string "*")))
3441 (set (attr "length_immediate")
3442 (if_then_else (eq_attr "alternative" "8")
3444 (const_string "*")))
3445 (set (attr "prefix")
3446 (if_then_else (eq_attr "type" "ssemov,sselog1")
3447 (const_string "maybe_vex")
3448 (const_string "orig")))
3449 (set (attr "prefix_0f")
3450 (if_then_else (eq_attr "type" "imovx")
3452 (const_string "*")))
3454 (cond [(eq_attr "alternative" "5,6")
3456 (eq_attr "alternative" "7,8,9")
3459 (const_string "SI")))])
3462 [(set (match_operand:DI 0 "memory_operand")
3463 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3465 [(set (match_dup 4) (const_int 0))]
3466 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3469 [(set (match_operand:DI 0 "register_operand")
3470 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3471 "!TARGET_64BIT && reload_completed
3472 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3473 && true_regnum (operands[0]) == true_regnum (operands[1])"
3474 [(set (match_dup 4) (const_int 0))]
3475 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3478 [(set (match_operand:DI 0 "nonimmediate_operand")
3479 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3480 "!TARGET_64BIT && reload_completed
3481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3482 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3483 [(set (match_dup 3) (match_dup 1))
3484 (set (match_dup 4) (const_int 0))]
3485 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3487 (define_insn "zero_extend<mode>di2"
3488 [(set (match_operand:DI 0 "register_operand" "=r")
3490 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3492 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3493 [(set_attr "type" "imovx")
3494 (set_attr "mode" "SI")])
3496 (define_expand "zero_extend<mode>si2"
3497 [(set (match_operand:SI 0 "register_operand")
3498 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3501 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3503 operands[1] = force_reg (<MODE>mode, operands[1]);
3504 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3509 (define_insn_and_split "zero_extend<mode>si2_and"
3510 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3512 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3513 (clobber (reg:CC FLAGS_REG))]
3514 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3516 "&& reload_completed"
3517 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3518 (clobber (reg:CC FLAGS_REG))])]
3520 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3522 ix86_expand_clear (operands[0]);
3524 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3525 emit_insn (gen_movstrict<mode>
3526 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3530 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3532 [(set_attr "type" "alu1")
3533 (set_attr "mode" "SI")])
3535 (define_insn "*zero_extend<mode>si2"
3536 [(set (match_operand:SI 0 "register_operand" "=r")
3538 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3539 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3540 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3541 [(set_attr "type" "imovx")
3542 (set_attr "mode" "SI")])
3544 (define_expand "zero_extendqihi2"
3545 [(set (match_operand:HI 0 "register_operand")
3546 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3549 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3551 operands[1] = force_reg (QImode, operands[1]);
3552 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3557 (define_insn_and_split "zero_extendqihi2_and"
3558 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3559 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
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) (const_int 255)))
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_movstrictqi
3573 (gen_lowpart (QImode, operands[0]), operands[1]));
3577 operands[0] = gen_lowpart (SImode, operands[0]);
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "SI")])
3582 ; zero extend to SImode to avoid partial register stalls
3583 (define_insn "*zero_extendqihi2"
3584 [(set (match_operand:HI 0 "register_operand" "=r")
3585 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3586 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3587 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3588 [(set_attr "type" "imovx")
3589 (set_attr "mode" "SI")])
3591 ;; Sign extension instructions
3593 (define_expand "extendsidi2"
3594 [(set (match_operand:DI 0 "register_operand")
3595 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3600 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3605 (define_insn "*extendsidi2_rex64"
3606 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3607 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3611 movs{lq|x}\t{%1, %0|%0, %1}"
3612 [(set_attr "type" "imovx")
3613 (set_attr "mode" "DI")
3614 (set_attr "prefix_0f" "0")
3615 (set_attr "modrm" "0,1")])
3617 (define_insn "extendsidi2_1"
3618 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3619 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3620 (clobber (reg:CC FLAGS_REG))
3621 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3625 ;; Split the memory case. If the source register doesn't die, it will stay
3626 ;; this way, if it does die, following peephole2s take care of it.
3628 [(set (match_operand:DI 0 "memory_operand")
3629 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3630 (clobber (reg:CC FLAGS_REG))
3631 (clobber (match_operand:SI 2 "register_operand"))]
3635 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3637 emit_move_insn (operands[3], operands[1]);
3639 /* Generate a cltd if possible and doing so it profitable. */
3640 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3641 && true_regnum (operands[1]) == AX_REG
3642 && true_regnum (operands[2]) == DX_REG)
3644 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3648 emit_move_insn (operands[2], operands[1]);
3649 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3651 emit_move_insn (operands[4], operands[2]);
3655 ;; Peepholes for the case where the source register does die, after
3656 ;; being split with the above splitter.
3658 [(set (match_operand:SI 0 "memory_operand")
3659 (match_operand:SI 1 "register_operand"))
3660 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3661 (parallel [(set (match_dup 2)
3662 (ashiftrt:SI (match_dup 2) (const_int 31)))
3663 (clobber (reg:CC FLAGS_REG))])
3664 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3665 "REGNO (operands[1]) != REGNO (operands[2])
3666 && peep2_reg_dead_p (2, operands[1])
3667 && peep2_reg_dead_p (4, operands[2])
3668 && !reg_mentioned_p (operands[2], operands[3])"
3669 [(set (match_dup 0) (match_dup 1))
3670 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3671 (clobber (reg:CC FLAGS_REG))])
3672 (set (match_dup 3) (match_dup 1))])
3675 [(set (match_operand:SI 0 "memory_operand")
3676 (match_operand:SI 1 "register_operand"))
3677 (parallel [(set (match_operand:SI 2 "register_operand")
3678 (ashiftrt:SI (match_dup 1) (const_int 31)))
3679 (clobber (reg:CC FLAGS_REG))])
3680 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3681 "/* cltd is shorter than sarl $31, %eax */
3682 !optimize_function_for_size_p (cfun)
3683 && true_regnum (operands[1]) == AX_REG
3684 && true_regnum (operands[2]) == DX_REG
3685 && peep2_reg_dead_p (2, operands[1])
3686 && peep2_reg_dead_p (3, operands[2])
3687 && !reg_mentioned_p (operands[2], operands[3])"
3688 [(set (match_dup 0) (match_dup 1))
3689 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3690 (clobber (reg:CC FLAGS_REG))])
3691 (set (match_dup 3) (match_dup 1))])
3693 ;; Extend to register case. Optimize case where source and destination
3694 ;; registers match and cases where we can use cltd.
3696 [(set (match_operand:DI 0 "register_operand")
3697 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3698 (clobber (reg:CC FLAGS_REG))
3699 (clobber (match_scratch:SI 2))]
3703 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3705 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3706 emit_move_insn (operands[3], operands[1]);
3708 /* Generate a cltd if possible and doing so it profitable. */
3709 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3710 && true_regnum (operands[3]) == AX_REG
3711 && true_regnum (operands[4]) == DX_REG)
3713 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3717 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3718 emit_move_insn (operands[4], operands[1]);
3720 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3724 (define_insn "extend<mode>di2"
3725 [(set (match_operand:DI 0 "register_operand" "=r")
3727 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3729 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3730 [(set_attr "type" "imovx")
3731 (set_attr "mode" "DI")])
3733 (define_insn "extendhisi2"
3734 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3735 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3738 switch (get_attr_prefix_0f (insn))
3741 return "{cwtl|cwde}";
3743 return "movs{wl|x}\t{%1, %0|%0, %1}";
3746 [(set_attr "type" "imovx")
3747 (set_attr "mode" "SI")
3748 (set (attr "prefix_0f")
3749 ;; movsx is short decodable while cwtl is vector decoded.
3750 (if_then_else (and (eq_attr "cpu" "!k6")
3751 (eq_attr "alternative" "0"))
3753 (const_string "1")))
3755 (if_then_else (eq_attr "prefix_0f" "0")
3757 (const_string "1")))])
3759 (define_insn "*extendhisi2_zext"
3760 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3763 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3766 switch (get_attr_prefix_0f (insn))
3769 return "{cwtl|cwde}";
3771 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3774 [(set_attr "type" "imovx")
3775 (set_attr "mode" "SI")
3776 (set (attr "prefix_0f")
3777 ;; movsx is short decodable while cwtl is vector decoded.
3778 (if_then_else (and (eq_attr "cpu" "!k6")
3779 (eq_attr "alternative" "0"))
3781 (const_string "1")))
3783 (if_then_else (eq_attr "prefix_0f" "0")
3785 (const_string "1")))])
3787 (define_insn "extendqisi2"
3788 [(set (match_operand:SI 0 "register_operand" "=r")
3789 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3791 "movs{bl|x}\t{%1, %0|%0, %1}"
3792 [(set_attr "type" "imovx")
3793 (set_attr "mode" "SI")])
3795 (define_insn "*extendqisi2_zext"
3796 [(set (match_operand:DI 0 "register_operand" "=r")
3798 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3800 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "SI")])
3804 (define_insn "extendqihi2"
3805 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3806 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3809 switch (get_attr_prefix_0f (insn))
3812 return "{cbtw|cbw}";
3814 return "movs{bw|x}\t{%1, %0|%0, %1}";
3817 [(set_attr "type" "imovx")
3818 (set_attr "mode" "HI")
3819 (set (attr "prefix_0f")
3820 ;; movsx is short decodable while cwtl is vector decoded.
3821 (if_then_else (and (eq_attr "cpu" "!k6")
3822 (eq_attr "alternative" "0"))
3824 (const_string "1")))
3826 (if_then_else (eq_attr "prefix_0f" "0")
3828 (const_string "1")))])
3830 ;; Conversions between float and double.
3832 ;; These are all no-ops in the model used for the 80387.
3833 ;; So just emit moves.
3835 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3837 [(set (match_operand:DF 0 "push_operand")
3838 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3840 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3841 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3844 [(set (match_operand:XF 0 "push_operand")
3845 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3847 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3848 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3849 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3851 (define_expand "extendsfdf2"
3852 [(set (match_operand:DF 0 "nonimmediate_operand")
3853 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3854 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3856 /* ??? Needed for compress_float_constant since all fp constants
3857 are TARGET_LEGITIMATE_CONSTANT_P. */
3858 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3860 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3861 && standard_80387_constant_p (operands[1]) > 0)
3863 operands[1] = simplify_const_unary_operation
3864 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3865 emit_move_insn_1 (operands[0], operands[1]);
3868 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3872 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3874 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3876 We do the conversion post reload to avoid producing of 128bit spills
3877 that might lead to ICE on 32bit target. The sequence unlikely combine
3880 [(set (match_operand:DF 0 "register_operand")
3882 (match_operand:SF 1 "nonimmediate_operand")))]
3883 "TARGET_USE_VECTOR_FP_CONVERTS
3884 && optimize_insn_for_speed_p ()
3885 && reload_completed && SSE_REG_P (operands[0])"
3890 (parallel [(const_int 0) (const_int 1)]))))]
3892 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3893 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3894 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3895 Try to avoid move when unpacking can be done in source. */
3896 if (REG_P (operands[1]))
3898 /* If it is unsafe to overwrite upper half of source, we need
3899 to move to destination and unpack there. */
3900 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3901 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3902 && true_regnum (operands[0]) != true_regnum (operands[1]))
3904 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3905 emit_move_insn (tmp, operands[1]);
3908 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3909 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3913 emit_insn (gen_vec_setv4sf_0 (operands[3],
3914 CONST0_RTX (V4SFmode), operands[1]));
3917 ;; It's more profitable to split and then extend in the same register.
3919 [(set (match_operand:DF 0 "register_operand")
3921 (match_operand:SF 1 "memory_operand")))]
3922 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3923 && optimize_insn_for_speed_p ()
3924 && SSE_REG_P (operands[0])"
3925 [(set (match_dup 2) (match_dup 1))
3926 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3927 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3929 (define_insn "*extendsfdf2_mixed"
3930 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3932 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3933 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3935 switch (which_alternative)
3939 return output_387_reg_move (insn, operands);
3942 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3948 [(set_attr "type" "fmov,fmov,ssecvt")
3949 (set_attr "prefix" "orig,orig,maybe_vex")
3950 (set_attr "mode" "SF,XF,DF")])
3952 (define_insn "*extendsfdf2_sse"
3953 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3954 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3955 "TARGET_SSE2 && TARGET_SSE_MATH"
3956 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3957 [(set_attr "type" "ssecvt")
3958 (set_attr "prefix" "maybe_vex")
3959 (set_attr "mode" "DF")])
3961 (define_insn "*extendsfdf2_i387"
3962 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3963 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3965 "* return output_387_reg_move (insn, operands);"
3966 [(set_attr "type" "fmov")
3967 (set_attr "mode" "SF,XF")])
3969 (define_expand "extend<mode>xf2"
3970 [(set (match_operand:XF 0 "nonimmediate_operand")
3971 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3974 /* ??? Needed for compress_float_constant since all fp constants
3975 are TARGET_LEGITIMATE_CONSTANT_P. */
3976 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3978 if (standard_80387_constant_p (operands[1]) > 0)
3980 operands[1] = simplify_const_unary_operation
3981 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3982 emit_move_insn_1 (operands[0], operands[1]);
3985 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3989 (define_insn "*extend<mode>xf2_i387"
3990 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3992 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3994 "* return output_387_reg_move (insn, operands);"
3995 [(set_attr "type" "fmov")
3996 (set_attr "mode" "<MODE>,XF")])
3998 ;; %%% This seems bad bad news.
3999 ;; This cannot output into an f-reg because there is no way to be sure
4000 ;; of truncating in that case. Otherwise this is just like a simple move
4001 ;; insn. So we pretend we can output to a reg in order to get better
4002 ;; register preferencing, but we really use a stack slot.
4004 ;; Conversion from DFmode to SFmode.
4006 (define_expand "truncdfsf2"
4007 [(set (match_operand:SF 0 "nonimmediate_operand")
4009 (match_operand:DF 1 "nonimmediate_operand")))]
4010 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4012 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4014 else if (flag_unsafe_math_optimizations)
4018 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4019 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4024 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4026 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4028 We do the conversion post reload to avoid producing of 128bit spills
4029 that might lead to ICE on 32bit target. The sequence unlikely combine
4032 [(set (match_operand:SF 0 "register_operand")
4034 (match_operand:DF 1 "nonimmediate_operand")))]
4035 "TARGET_USE_VECTOR_FP_CONVERTS
4036 && optimize_insn_for_speed_p ()
4037 && reload_completed && SSE_REG_P (operands[0])"
4040 (float_truncate:V2SF
4044 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4045 operands[3] = CONST0_RTX (V2SFmode);
4046 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4047 /* Use movsd for loading from memory, unpcklpd for registers.
4048 Try to avoid move when unpacking can be done in source, or SSE3
4049 movddup is available. */
4050 if (REG_P (operands[1]))
4053 && true_regnum (operands[0]) != true_regnum (operands[1])
4054 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4055 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4057 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4058 emit_move_insn (tmp, operands[1]);
4061 else if (!TARGET_SSE3)
4062 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4063 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4066 emit_insn (gen_sse2_loadlpd (operands[4],
4067 CONST0_RTX (V2DFmode), operands[1]));
4070 ;; It's more profitable to split and then extend in the same register.
4072 [(set (match_operand:SF 0 "register_operand")
4074 (match_operand:DF 1 "memory_operand")))]
4075 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4076 && optimize_insn_for_speed_p ()
4077 && SSE_REG_P (operands[0])"
4078 [(set (match_dup 2) (match_dup 1))
4079 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4080 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4082 (define_expand "truncdfsf2_with_temp"
4083 [(parallel [(set (match_operand:SF 0)
4084 (float_truncate:SF (match_operand:DF 1)))
4085 (clobber (match_operand:SF 2))])])
4087 (define_insn "*truncdfsf_fast_mixed"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4090 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4091 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4093 switch (which_alternative)
4096 return output_387_reg_move (insn, operands);
4098 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4103 [(set_attr "type" "fmov,ssecvt")
4104 (set_attr "prefix" "orig,maybe_vex")
4105 (set_attr "mode" "SF")])
4107 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4108 ;; because nothing we do here is unsafe.
4109 (define_insn "*truncdfsf_fast_sse"
4110 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4112 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4113 "TARGET_SSE2 && TARGET_SSE_MATH"
4114 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4115 [(set_attr "type" "ssecvt")
4116 (set_attr "prefix" "maybe_vex")
4117 (set_attr "mode" "SF")])
4119 (define_insn "*truncdfsf_fast_i387"
4120 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4122 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4123 "TARGET_80387 && flag_unsafe_math_optimizations"
4124 "* return output_387_reg_move (insn, operands);"
4125 [(set_attr "type" "fmov")
4126 (set_attr "mode" "SF")])
4128 (define_insn "*truncdfsf_mixed"
4129 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4131 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4132 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4133 "TARGET_MIX_SSE_I387"
4135 switch (which_alternative)
4138 return output_387_reg_move (insn, operands);
4140 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4146 [(set_attr "isa" "*,sse2,*,*,*")
4147 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4148 (set_attr "unit" "*,*,i387,i387,i387")
4149 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4150 (set_attr "mode" "SF")])
4152 (define_insn "*truncdfsf_i387"
4153 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4155 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4156 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4159 switch (which_alternative)
4162 return output_387_reg_move (insn, operands);
4168 [(set_attr "type" "fmov,multi,multi,multi")
4169 (set_attr "unit" "*,i387,i387,i387")
4170 (set_attr "mode" "SF")])
4172 (define_insn "*truncdfsf2_i387_1"
4173 [(set (match_operand:SF 0 "memory_operand" "=m")
4175 (match_operand:DF 1 "register_operand" "f")))]
4177 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4178 && !TARGET_MIX_SSE_I387"
4179 "* return output_387_reg_move (insn, operands);"
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "SF")])
4184 [(set (match_operand:SF 0 "register_operand")
4186 (match_operand:DF 1 "fp_register_operand")))
4187 (clobber (match_operand 2))]
4189 [(set (match_dup 2) (match_dup 1))
4190 (set (match_dup 0) (match_dup 2))]
4191 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4193 ;; Conversion from XFmode to {SF,DF}mode
4195 (define_expand "truncxf<mode>2"
4196 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4197 (float_truncate:MODEF
4198 (match_operand:XF 1 "register_operand")))
4199 (clobber (match_dup 2))])]
4202 if (flag_unsafe_math_optimizations)
4204 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4205 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4206 if (reg != operands[0])
4207 emit_move_insn (operands[0], reg);
4211 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4214 (define_insn "*truncxfsf2_mixed"
4215 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4217 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4218 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4221 gcc_assert (!which_alternative);
4222 return output_387_reg_move (insn, operands);
4224 [(set_attr "type" "fmov,multi,multi,multi")
4225 (set_attr "unit" "*,i387,i387,i387")
4226 (set_attr "mode" "SF")])
4228 (define_insn "*truncxfdf2_mixed"
4229 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4231 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4232 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4235 gcc_assert (!which_alternative);
4236 return output_387_reg_move (insn, operands);
4238 [(set_attr "isa" "*,*,sse2,*")
4239 (set_attr "type" "fmov,multi,multi,multi")
4240 (set_attr "unit" "*,i387,i387,i387")
4241 (set_attr "mode" "DF")])
4243 (define_insn "truncxf<mode>2_i387_noop"
4244 [(set (match_operand:MODEF 0 "register_operand" "=f")
4245 (float_truncate:MODEF
4246 (match_operand:XF 1 "register_operand" "f")))]
4247 "TARGET_80387 && flag_unsafe_math_optimizations"
4248 "* return output_387_reg_move (insn, operands);"
4249 [(set_attr "type" "fmov")
4250 (set_attr "mode" "<MODE>")])
4252 (define_insn "*truncxf<mode>2_i387"
4253 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4254 (float_truncate:MODEF
4255 (match_operand:XF 1 "register_operand" "f")))]
4257 "* return output_387_reg_move (insn, operands);"
4258 [(set_attr "type" "fmov")
4259 (set_attr "mode" "<MODE>")])
4262 [(set (match_operand:MODEF 0 "register_operand")
4263 (float_truncate:MODEF
4264 (match_operand:XF 1 "register_operand")))
4265 (clobber (match_operand:MODEF 2 "memory_operand"))]
4266 "TARGET_80387 && reload_completed"
4267 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4268 (set (match_dup 0) (match_dup 2))])
4271 [(set (match_operand:MODEF 0 "memory_operand")
4272 (float_truncate:MODEF
4273 (match_operand:XF 1 "register_operand")))
4274 (clobber (match_operand:MODEF 2 "memory_operand"))]
4276 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4278 ;; Signed conversion to DImode.
4280 (define_expand "fix_truncxfdi2"
4281 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4282 (fix:DI (match_operand:XF 1 "register_operand")))
4283 (clobber (reg:CC FLAGS_REG))])]
4288 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4293 (define_expand "fix_trunc<mode>di2"
4294 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4295 (fix:DI (match_operand:MODEF 1 "register_operand")))
4296 (clobber (reg:CC FLAGS_REG))])]
4297 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4300 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4302 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4305 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4307 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4308 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4309 if (out != operands[0])
4310 emit_move_insn (operands[0], out);
4315 ;; Signed conversion to SImode.
4317 (define_expand "fix_truncxfsi2"
4318 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4319 (fix:SI (match_operand:XF 1 "register_operand")))
4320 (clobber (reg:CC FLAGS_REG))])]
4325 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4330 (define_expand "fix_trunc<mode>si2"
4331 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4332 (fix:SI (match_operand:MODEF 1 "register_operand")))
4333 (clobber (reg:CC FLAGS_REG))])]
4334 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4337 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4339 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4342 if (SSE_FLOAT_MODE_P (<MODE>mode))
4344 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4345 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4346 if (out != operands[0])
4347 emit_move_insn (operands[0], out);
4352 ;; Signed conversion to HImode.
4354 (define_expand "fix_trunc<mode>hi2"
4355 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4356 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4357 (clobber (reg:CC FLAGS_REG))])]
4359 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4363 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4368 ;; Unsigned conversion to SImode.
4370 (define_expand "fixuns_trunc<mode>si2"
4372 [(set (match_operand:SI 0 "register_operand")
4374 (match_operand:MODEF 1 "nonimmediate_operand")))
4376 (clobber (match_scratch:<ssevecmode> 3))
4377 (clobber (match_scratch:<ssevecmode> 4))])]
4378 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4380 enum machine_mode mode = <MODE>mode;
4381 enum machine_mode vecmode = <ssevecmode>mode;
4382 REAL_VALUE_TYPE TWO31r;
4385 if (optimize_insn_for_size_p ())
4388 real_ldexp (&TWO31r, &dconst1, 31);
4389 two31 = const_double_from_real_value (TWO31r, mode);
4390 two31 = ix86_build_const_vector (vecmode, true, two31);
4391 operands[2] = force_reg (vecmode, two31);
4394 (define_insn_and_split "*fixuns_trunc<mode>_1"
4395 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4397 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4398 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4399 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4400 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4401 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4402 && optimize_function_for_speed_p (cfun)"
4404 "&& reload_completed"
4407 ix86_split_convert_uns_si_sse (operands);
4411 ;; Unsigned conversion to HImode.
4412 ;; Without these patterns, we'll try the unsigned SI conversion which
4413 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4415 (define_expand "fixuns_trunc<mode>hi2"
4417 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4418 (set (match_operand:HI 0 "nonimmediate_operand")
4419 (subreg:HI (match_dup 2) 0))]
4420 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4421 "operands[2] = gen_reg_rtx (SImode);")
4423 ;; When SSE is available, it is always faster to use it!
4424 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4425 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4426 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4427 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4428 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4429 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4430 [(set_attr "type" "sseicvt")
4431 (set_attr "prefix" "maybe_vex")
4432 (set (attr "prefix_rex")
4434 (match_test "<SWI48:MODE>mode == DImode")
4436 (const_string "*")))
4437 (set_attr "mode" "<MODEF:MODE>")
4438 (set_attr "athlon_decode" "double,vector")
4439 (set_attr "amdfam10_decode" "double,double")
4440 (set_attr "bdver1_decode" "double,double")])
4442 ;; Avoid vector decoded forms of the instruction.
4444 [(match_scratch:MODEF 2 "x")
4445 (set (match_operand:SWI48 0 "register_operand")
4446 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4447 "TARGET_AVOID_VECTOR_DECODE
4448 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4449 && optimize_insn_for_speed_p ()"
4450 [(set (match_dup 2) (match_dup 1))
4451 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4453 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4454 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4455 (fix:SWI248x (match_operand 1 "register_operand")))]
4456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && (TARGET_64BIT || <MODE>mode != DImode))
4461 && can_create_pseudo_p ()"
4466 if (memory_operand (operands[0], VOIDmode))
4467 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4470 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4471 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4477 [(set_attr "type" "fisttp")
4478 (set_attr "mode" "<MODE>")])
4480 (define_insn "fix_trunc<mode>_i387_fisttp"
4481 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4482 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4483 (clobber (match_scratch:XF 2 "=&1f"))]
4484 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4486 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && (TARGET_64BIT || <MODE>mode != DImode))
4488 && TARGET_SSE_MATH)"
4489 "* return output_fix_trunc (insn, operands, true);"
4490 [(set_attr "type" "fisttp")
4491 (set_attr "mode" "<MODE>")])
4493 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4494 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4495 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4496 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4497 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4498 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4500 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501 && (TARGET_64BIT || <MODE>mode != DImode))
4502 && TARGET_SSE_MATH)"
4504 [(set_attr "type" "fisttp")
4505 (set_attr "mode" "<MODE>")])
4508 [(set (match_operand:SWI248x 0 "register_operand")
4509 (fix:SWI248x (match_operand 1 "register_operand")))
4510 (clobber (match_operand:SWI248x 2 "memory_operand"))
4511 (clobber (match_scratch 3))]
4513 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4514 (clobber (match_dup 3))])
4515 (set (match_dup 0) (match_dup 2))])
4518 [(set (match_operand:SWI248x 0 "memory_operand")
4519 (fix:SWI248x (match_operand 1 "register_operand")))
4520 (clobber (match_operand:SWI248x 2 "memory_operand"))
4521 (clobber (match_scratch 3))]
4523 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4524 (clobber (match_dup 3))])])
4526 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4527 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4528 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4529 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4530 ;; function in i386.c.
4531 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4532 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4533 (fix:SWI248x (match_operand 1 "register_operand")))
4534 (clobber (reg:CC FLAGS_REG))]
4535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4538 && (TARGET_64BIT || <MODE>mode != DImode))
4539 && can_create_pseudo_p ()"
4544 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4546 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4547 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4548 if (memory_operand (operands[0], VOIDmode))
4549 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4550 operands[2], operands[3]));
4553 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4554 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4555 operands[2], operands[3],
4560 [(set_attr "type" "fistp")
4561 (set_attr "i387_cw" "trunc")
4562 (set_attr "mode" "<MODE>")])
4564 (define_insn "fix_truncdi_i387"
4565 [(set (match_operand:DI 0 "memory_operand" "=m")
4566 (fix:DI (match_operand 1 "register_operand" "f")))
4567 (use (match_operand:HI 2 "memory_operand" "m"))
4568 (use (match_operand:HI 3 "memory_operand" "m"))
4569 (clobber (match_scratch:XF 4 "=&1f"))]
4570 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4572 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4573 "* return output_fix_trunc (insn, operands, false);"
4574 [(set_attr "type" "fistp")
4575 (set_attr "i387_cw" "trunc")
4576 (set_attr "mode" "DI")])
4578 (define_insn "fix_truncdi_i387_with_temp"
4579 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4580 (fix:DI (match_operand 1 "register_operand" "f,f")))
4581 (use (match_operand:HI 2 "memory_operand" "m,m"))
4582 (use (match_operand:HI 3 "memory_operand" "m,m"))
4583 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4584 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4585 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4587 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4589 [(set_attr "type" "fistp")
4590 (set_attr "i387_cw" "trunc")
4591 (set_attr "mode" "DI")])
4594 [(set (match_operand:DI 0 "register_operand")
4595 (fix:DI (match_operand 1 "register_operand")))
4596 (use (match_operand:HI 2 "memory_operand"))
4597 (use (match_operand:HI 3 "memory_operand"))
4598 (clobber (match_operand:DI 4 "memory_operand"))
4599 (clobber (match_scratch 5))]
4601 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4604 (clobber (match_dup 5))])
4605 (set (match_dup 0) (match_dup 4))])
4608 [(set (match_operand:DI 0 "memory_operand")
4609 (fix:DI (match_operand 1 "register_operand")))
4610 (use (match_operand:HI 2 "memory_operand"))
4611 (use (match_operand:HI 3 "memory_operand"))
4612 (clobber (match_operand:DI 4 "memory_operand"))
4613 (clobber (match_scratch 5))]
4615 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4618 (clobber (match_dup 5))])])
4620 (define_insn "fix_trunc<mode>_i387"
4621 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4622 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4623 (use (match_operand:HI 2 "memory_operand" "m"))
4624 (use (match_operand:HI 3 "memory_operand" "m"))]
4625 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4628 "* return output_fix_trunc (insn, operands, false);"
4629 [(set_attr "type" "fistp")
4630 (set_attr "i387_cw" "trunc")
4631 (set_attr "mode" "<MODE>")])
4633 (define_insn "fix_trunc<mode>_i387_with_temp"
4634 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4635 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4636 (use (match_operand:HI 2 "memory_operand" "m,m"))
4637 (use (match_operand:HI 3 "memory_operand" "m,m"))
4638 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4639 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4641 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4643 [(set_attr "type" "fistp")
4644 (set_attr "i387_cw" "trunc")
4645 (set_attr "mode" "<MODE>")])
4648 [(set (match_operand:SWI24 0 "register_operand")
4649 (fix:SWI24 (match_operand 1 "register_operand")))
4650 (use (match_operand:HI 2 "memory_operand"))
4651 (use (match_operand:HI 3 "memory_operand"))
4652 (clobber (match_operand:SWI24 4 "memory_operand"))]
4654 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4656 (use (match_dup 3))])
4657 (set (match_dup 0) (match_dup 4))])
4660 [(set (match_operand:SWI24 0 "memory_operand")
4661 (fix:SWI24 (match_operand 1 "register_operand")))
4662 (use (match_operand:HI 2 "memory_operand"))
4663 (use (match_operand:HI 3 "memory_operand"))
4664 (clobber (match_operand:SWI24 4 "memory_operand"))]
4666 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4668 (use (match_dup 3))])])
4670 (define_insn "x86_fnstcw_1"
4671 [(set (match_operand:HI 0 "memory_operand" "=m")
4672 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4675 [(set (attr "length")
4676 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4677 (set_attr "mode" "HI")
4678 (set_attr "unit" "i387")
4679 (set_attr "bdver1_decode" "vector")])
4681 (define_insn "x86_fldcw_1"
4682 [(set (reg:HI FPCR_REG)
4683 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4686 [(set (attr "length")
4687 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4688 (set_attr "mode" "HI")
4689 (set_attr "unit" "i387")
4690 (set_attr "athlon_decode" "vector")
4691 (set_attr "amdfam10_decode" "vector")
4692 (set_attr "bdver1_decode" "vector")])
4694 ;; Conversion between fixed point and floating point.
4696 ;; Even though we only accept memory inputs, the backend _really_
4697 ;; wants to be able to do this between registers. Thankfully, LRA
4698 ;; will fix this up for us during register allocation.
4700 (define_insn "floathi<mode>2"
4701 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4702 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4705 || TARGET_MIX_SSE_I387)"
4707 [(set_attr "type" "fmov")
4708 (set_attr "mode" "<MODE>")
4709 (set_attr "fp_int_src" "true")])
4711 (define_insn "float<SWI48x:mode>xf2"
4712 [(set (match_operand:XF 0 "register_operand" "=f")
4713 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4716 [(set_attr "type" "fmov")
4717 (set_attr "mode" "XF")
4718 (set_attr "fp_int_src" "true")])
4720 (define_expand "float<SWI48:mode><MODEF:mode>2"
4721 [(set (match_operand:MODEF 0 "register_operand")
4722 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4723 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4725 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4726 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4728 rtx reg = gen_reg_rtx (XFmode);
4729 rtx (*insn)(rtx, rtx);
4731 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4733 if (<MODEF:MODE>mode == SFmode)
4734 insn = gen_truncxfsf2;
4735 else if (<MODEF:MODE>mode == DFmode)
4736 insn = gen_truncxfdf2;
4740 emit_insn (insn (operands[0], reg));
4745 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4746 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4748 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4749 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4752 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4753 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4754 [(set_attr "type" "fmov,sseicvt,sseicvt")
4755 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4756 (set_attr "mode" "<MODEF:MODE>")
4757 (set (attr "prefix_rex")
4759 (and (eq_attr "prefix" "maybe_vex")
4760 (match_test "<SWI48:MODE>mode == DImode"))
4762 (const_string "*")))
4763 (set_attr "unit" "i387,*,*")
4764 (set_attr "athlon_decode" "*,double,direct")
4765 (set_attr "amdfam10_decode" "*,vector,double")
4766 (set_attr "bdver1_decode" "*,double,direct")
4767 (set_attr "fp_int_src" "true")
4768 (set (attr "enabled")
4769 (cond [(eq_attr "alternative" "0")
4770 (symbol_ref "TARGET_MIX_SSE_I387
4771 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4773 (eq_attr "alternative" "1")
4774 /* ??? For sched1 we need constrain_operands to be able to
4775 select an alternative. Leave this enabled before RA. */
4776 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS
4777 || optimize_function_for_size_p (cfun)
4778 || !(reload_completed
4779 || reload_in_progress
4780 || lra_in_progress)")
4782 (symbol_ref "true")))
4785 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4786 [(set (match_operand:MODEF 0 "register_operand" "=f")
4787 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4788 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4790 [(set_attr "type" "fmov")
4791 (set_attr "mode" "<MODEF:MODE>")
4792 (set_attr "fp_int_src" "true")])
4794 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4795 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4796 ;; alternative in sse2_loadld.
4798 [(set (match_operand:MODEF 0 "register_operand")
4799 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4800 "TARGET_SSE2 && TARGET_SSE_MATH
4801 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4802 && reload_completed && SSE_REG_P (operands[0])
4803 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4806 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4808 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4810 emit_insn (gen_sse2_loadld (operands[4],
4811 CONST0_RTX (V4SImode), operands[1]));
4813 if (<ssevecmode>mode == V4SFmode)
4814 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4816 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4820 ;; Avoid partial SSE register dependency stalls
4822 [(set (match_operand:MODEF 0 "register_operand")
4823 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4824 "TARGET_SSE2 && TARGET_SSE_MATH
4825 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4826 && optimize_function_for_speed_p (cfun)
4827 && reload_completed && SSE_REG_P (operands[0])"
4830 const enum machine_mode vmode = <MODEF:ssevecmode>mode;
4831 const enum machine_mode mode = <MODEF:MODE>mode;
4832 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4834 emit_move_insn (op0, CONST0_RTX (vmode));
4836 t = gen_rtx_FLOAT (mode, operands[1]);
4837 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4838 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4839 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4843 ;; Break partial reg stall for cvtsd2ss.
4846 [(set (match_operand:SF 0 "register_operand")
4848 (match_operand:DF 1 "nonimmediate_operand")))]
4849 "TARGET_SSE2 && TARGET_SSE_MATH
4850 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4851 && optimize_function_for_speed_p (cfun)
4852 && SSE_REG_P (operands[0])
4853 && (!SSE_REG_P (operands[1])
4854 || REGNO (operands[0]) != REGNO (operands[1]))"
4858 (float_truncate:V2SF
4863 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4865 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4867 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4870 ;; Break partial reg stall for cvtss2sd.
4873 [(set (match_operand:DF 0 "register_operand")
4875 (match_operand:SF 1 "nonimmediate_operand")))]
4876 "TARGET_SSE2 && TARGET_SSE_MATH
4877 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4878 && optimize_function_for_speed_p (cfun)
4879 && SSE_REG_P (operands[0])
4880 && (!SSE_REG_P (operands[1])
4881 || REGNO (operands[0]) != REGNO (operands[1]))"
4887 (parallel [(const_int 0) (const_int 1)])))
4891 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4893 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4895 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4898 ;; Avoid store forwarding (partial memory) stall penalty
4899 ;; by passing DImode value through XMM registers. */
4901 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4902 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4904 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4905 (clobber (match_scratch:V4SI 3 "=X,x"))
4906 (clobber (match_scratch:V4SI 4 "=X,x"))
4907 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4908 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4909 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4910 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4912 [(set_attr "type" "multi")
4913 (set_attr "mode" "<X87MODEF:MODE>")
4914 (set_attr "unit" "i387")
4915 (set_attr "fp_int_src" "true")])
4918 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4919 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4920 (clobber (match_scratch:V4SI 3))
4921 (clobber (match_scratch:V4SI 4))
4922 (clobber (match_operand:DI 2 "memory_operand"))]
4923 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4924 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4925 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4926 && reload_completed"
4927 [(set (match_dup 2) (match_dup 3))
4928 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4930 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4931 Assemble the 64-bit DImode value in an xmm register. */
4932 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4933 gen_rtx_SUBREG (SImode, operands[1], 0)));
4934 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4935 gen_rtx_SUBREG (SImode, operands[1], 4)));
4936 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4939 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4943 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4944 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4945 (clobber (match_scratch:V4SI 3))
4946 (clobber (match_scratch:V4SI 4))
4947 (clobber (match_operand:DI 2 "memory_operand"))]
4948 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4949 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4950 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4951 && reload_completed"
4952 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4954 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4955 [(set (match_operand:MODEF 0 "register_operand")
4956 (unsigned_float:MODEF
4957 (match_operand:SWI12 1 "nonimmediate_operand")))]
4959 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4961 operands[1] = convert_to_mode (SImode, operands[1], 1);
4962 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4966 ;; Avoid store forwarding (partial memory) stall penalty by extending
4967 ;; SImode value to DImode through XMM register instead of pushing two
4968 ;; SImode values to stack. Also note that fild loads from memory only.
4970 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
4971 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4972 (unsigned_float:X87MODEF
4973 (match_operand:SI 1 "nonimmediate_operand" "rm")))
4974 (clobber (match_scratch:DI 3 "=x"))
4975 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
4977 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4978 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
4980 "&& reload_completed"
4981 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
4982 (set (match_dup 2) (match_dup 3))
4984 (float:X87MODEF (match_dup 2)))]
4986 [(set_attr "type" "multi")
4987 (set_attr "mode" "<MODE>")])
4989 (define_expand "floatunssi<mode>2"
4991 [(set (match_operand:X87MODEF 0 "register_operand")
4992 (unsigned_float:X87MODEF
4993 (match_operand:SI 1 "nonimmediate_operand")))
4994 (clobber (match_scratch:DI 3))
4995 (clobber (match_dup 2))])]
4997 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4998 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
4999 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5001 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5003 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5007 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5010 (define_expand "floatunsdisf2"
5011 [(use (match_operand:SF 0 "register_operand"))
5012 (use (match_operand:DI 1 "nonimmediate_operand"))]
5013 "TARGET_64BIT && TARGET_SSE_MATH"
5014 "x86_emit_floatuns (operands); DONE;")
5016 (define_expand "floatunsdidf2"
5017 [(use (match_operand:DF 0 "register_operand"))
5018 (use (match_operand:DI 1 "nonimmediate_operand"))]
5019 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5020 && TARGET_SSE2 && TARGET_SSE_MATH"
5023 x86_emit_floatuns (operands);
5025 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5029 ;; Load effective address instructions
5031 (define_insn_and_split "*lea<mode>"
5032 [(set (match_operand:SWI48 0 "register_operand" "=r")
5033 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5036 if (SImode_address_operand (operands[1], VOIDmode))
5038 gcc_assert (TARGET_64BIT);
5039 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5042 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5044 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5047 enum machine_mode mode = <MODE>mode;
5050 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5051 change operands[] array behind our back. */
5052 pat = PATTERN (curr_insn);
5054 operands[0] = SET_DEST (pat);
5055 operands[1] = SET_SRC (pat);
5057 /* Emit all operations in SImode for zero-extended addresses. */
5058 if (SImode_address_operand (operands[1], VOIDmode))
5061 ix86_split_lea_for_addr (curr_insn, operands, mode);
5063 /* Zero-extend return register to DImode for zero-extended addresses. */
5064 if (mode != <MODE>mode)
5065 emit_insn (gen_zero_extendsidi2
5066 (operands[0], gen_lowpart (mode, operands[0])));
5070 [(set_attr "type" "lea")
5073 (match_operand 1 "SImode_address_operand")
5075 (const_string "<MODE>")))])
5079 (define_expand "add<mode>3"
5080 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5081 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5082 (match_operand:SDWIM 2 "<general_operand>")))]
5084 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5086 (define_insn_and_split "*add<dwi>3_doubleword"
5087 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5089 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5090 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5091 (clobber (reg:CC FLAGS_REG))]
5092 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5095 [(parallel [(set (reg:CC FLAGS_REG)
5096 (unspec:CC [(match_dup 1) (match_dup 2)]
5099 (plus:DWIH (match_dup 1) (match_dup 2)))])
5100 (parallel [(set (match_dup 3)
5104 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5106 (clobber (reg:CC FLAGS_REG))])]
5107 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5109 (define_insn "*add<mode>3_cc"
5110 [(set (reg:CC FLAGS_REG)
5112 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5113 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5115 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5116 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5117 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5118 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5119 [(set_attr "type" "alu")
5120 (set_attr "mode" "<MODE>")])
5122 (define_insn "addqi3_cc"
5123 [(set (reg:CC FLAGS_REG)
5125 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5126 (match_operand:QI 2 "general_operand" "qn,qm")]
5128 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5129 (plus:QI (match_dup 1) (match_dup 2)))]
5130 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131 "add{b}\t{%2, %0|%0, %2}"
5132 [(set_attr "type" "alu")
5133 (set_attr "mode" "QI")])
5135 (define_insn "*add<mode>_1"
5136 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5138 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5139 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5140 (clobber (reg:CC FLAGS_REG))]
5141 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5143 switch (get_attr_type (insn))
5149 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5150 if (operands[2] == const1_rtx)
5151 return "inc{<imodesuffix>}\t%0";
5154 gcc_assert (operands[2] == constm1_rtx);
5155 return "dec{<imodesuffix>}\t%0";
5159 /* For most processors, ADD is faster than LEA. This alternative
5160 was added to use ADD as much as possible. */
5161 if (which_alternative == 2)
5164 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5167 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5169 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5171 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5175 (cond [(eq_attr "alternative" "3")
5176 (const_string "lea")
5177 (match_operand:SWI48 2 "incdec_operand")
5178 (const_string "incdec")
5180 (const_string "alu")))
5181 (set (attr "length_immediate")
5183 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5185 (const_string "*")))
5186 (set_attr "mode" "<MODE>")])
5188 ;; It may seem that nonimmediate operand is proper one for operand 1.
5189 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5190 ;; we take care in ix86_binary_operator_ok to not allow two memory
5191 ;; operands so proper swapping will be done in reload. This allow
5192 ;; patterns constructed from addsi_1 to match.
5194 (define_insn "addsi_1_zext"
5195 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5197 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5198 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5199 (clobber (reg:CC FLAGS_REG))]
5200 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5202 switch (get_attr_type (insn))
5208 if (operands[2] == const1_rtx)
5209 return "inc{l}\t%k0";
5212 gcc_assert (operands[2] == constm1_rtx);
5213 return "dec{l}\t%k0";
5217 /* For most processors, ADD is faster than LEA. This alternative
5218 was added to use ADD as much as possible. */
5219 if (which_alternative == 1)
5222 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5225 if (x86_maybe_negate_const_int (&operands[2], SImode))
5226 return "sub{l}\t{%2, %k0|%k0, %2}";
5228 return "add{l}\t{%2, %k0|%k0, %2}";
5232 (cond [(eq_attr "alternative" "2")
5233 (const_string "lea")
5234 (match_operand:SI 2 "incdec_operand")
5235 (const_string "incdec")
5237 (const_string "alu")))
5238 (set (attr "length_immediate")
5240 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5242 (const_string "*")))
5243 (set_attr "mode" "SI")])
5245 (define_insn "*addhi_1"
5246 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5247 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5248 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5249 (clobber (reg:CC FLAGS_REG))]
5250 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5252 switch (get_attr_type (insn))
5258 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5259 if (operands[2] == const1_rtx)
5260 return "inc{w}\t%0";
5263 gcc_assert (operands[2] == constm1_rtx);
5264 return "dec{w}\t%0";
5268 /* For most processors, ADD is faster than LEA. This alternative
5269 was added to use ADD as much as possible. */
5270 if (which_alternative == 2)
5273 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5276 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277 if (x86_maybe_negate_const_int (&operands[2], HImode))
5278 return "sub{w}\t{%2, %0|%0, %2}";
5280 return "add{w}\t{%2, %0|%0, %2}";
5284 (cond [(eq_attr "alternative" "3")
5285 (const_string "lea")
5286 (match_operand:HI 2 "incdec_operand")
5287 (const_string "incdec")
5289 (const_string "alu")))
5290 (set (attr "length_immediate")
5292 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5294 (const_string "*")))
5295 (set_attr "mode" "HI,HI,HI,SI")])
5297 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5298 (define_insn "*addqi_1"
5299 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5300 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5301 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5302 (clobber (reg:CC FLAGS_REG))]
5303 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5305 bool widen = (which_alternative == 3 || which_alternative == 4);
5307 switch (get_attr_type (insn))
5313 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5314 if (operands[2] == const1_rtx)
5315 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5318 gcc_assert (operands[2] == constm1_rtx);
5319 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5323 /* For most processors, ADD is faster than LEA. These alternatives
5324 were added to use ADD as much as possible. */
5325 if (which_alternative == 2 || which_alternative == 4)
5328 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332 if (x86_maybe_negate_const_int (&operands[2], QImode))
5335 return "sub{l}\t{%2, %k0|%k0, %2}";
5337 return "sub{b}\t{%2, %0|%0, %2}";
5340 return "add{l}\t{%k2, %k0|%k0, %k2}";
5342 return "add{b}\t{%2, %0|%0, %2}";
5346 (cond [(eq_attr "alternative" "5")
5347 (const_string "lea")
5348 (match_operand:QI 2 "incdec_operand")
5349 (const_string "incdec")
5351 (const_string "alu")))
5352 (set (attr "length_immediate")
5354 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5356 (const_string "*")))
5357 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5359 (define_insn "*addqi_1_slp"
5360 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5361 (plus:QI (match_dup 0)
5362 (match_operand:QI 1 "general_operand" "qn,qm")))
5363 (clobber (reg:CC FLAGS_REG))]
5364 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5367 switch (get_attr_type (insn))
5370 if (operands[1] == const1_rtx)
5371 return "inc{b}\t%0";
5374 gcc_assert (operands[1] == constm1_rtx);
5375 return "dec{b}\t%0";
5379 if (x86_maybe_negate_const_int (&operands[1], QImode))
5380 return "sub{b}\t{%1, %0|%0, %1}";
5382 return "add{b}\t{%1, %0|%0, %1}";
5386 (if_then_else (match_operand:QI 1 "incdec_operand")
5387 (const_string "incdec")
5388 (const_string "alu1")))
5389 (set (attr "memory")
5390 (if_then_else (match_operand 1 "memory_operand")
5391 (const_string "load")
5392 (const_string "none")))
5393 (set_attr "mode" "QI")])
5395 ;; Split non destructive adds if we cannot use lea.
5397 [(set (match_operand:SWI48 0 "register_operand")
5398 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5399 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5402 [(set (match_dup 0) (match_dup 1))
5403 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5404 (clobber (reg:CC FLAGS_REG))])])
5406 ;; Convert add to the lea pattern to avoid flags dependency.
5408 [(set (match_operand:SWI 0 "register_operand")
5409 (plus:SWI (match_operand:SWI 1 "register_operand")
5410 (match_operand:SWI 2 "<nonmemory_operand>")))
5411 (clobber (reg:CC FLAGS_REG))]
5412 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5415 enum machine_mode mode = <MODE>mode;
5418 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5421 operands[0] = gen_lowpart (mode, operands[0]);
5422 operands[1] = gen_lowpart (mode, operands[1]);
5423 operands[2] = gen_lowpart (mode, operands[2]);
5426 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5432 ;; Split non destructive adds if we cannot use lea.
5434 [(set (match_operand:DI 0 "register_operand")
5436 (plus:SI (match_operand:SI 1 "register_operand")
5437 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5438 (clobber (reg:CC FLAGS_REG))]
5440 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5441 [(set (match_dup 3) (match_dup 1))
5442 (parallel [(set (match_dup 0)
5443 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5444 (clobber (reg:CC FLAGS_REG))])]
5445 "operands[3] = gen_lowpart (SImode, operands[0]);")
5447 ;; Convert add to the lea pattern to avoid flags dependency.
5449 [(set (match_operand:DI 0 "register_operand")
5451 (plus:SI (match_operand:SI 1 "register_operand")
5452 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5453 (clobber (reg:CC FLAGS_REG))]
5454 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5456 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5458 (define_insn "*add<mode>_2"
5459 [(set (reg FLAGS_REG)
5462 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5463 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5465 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5466 (plus:SWI (match_dup 1) (match_dup 2)))]
5467 "ix86_match_ccmode (insn, CCGOCmode)
5468 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5470 switch (get_attr_type (insn))
5473 if (operands[2] == const1_rtx)
5474 return "inc{<imodesuffix>}\t%0";
5477 gcc_assert (operands[2] == constm1_rtx);
5478 return "dec{<imodesuffix>}\t%0";
5482 if (which_alternative == 2)
5485 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5488 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5489 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5490 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5492 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5496 (if_then_else (match_operand:SWI 2 "incdec_operand")
5497 (const_string "incdec")
5498 (const_string "alu")))
5499 (set (attr "length_immediate")
5501 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5503 (const_string "*")))
5504 (set_attr "mode" "<MODE>")])
5506 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5507 (define_insn "*addsi_2_zext"
5508 [(set (reg FLAGS_REG)
5510 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5511 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5513 (set (match_operand:DI 0 "register_operand" "=r,r")
5514 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5515 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5516 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5518 switch (get_attr_type (insn))
5521 if (operands[2] == const1_rtx)
5522 return "inc{l}\t%k0";
5525 gcc_assert (operands[2] == constm1_rtx);
5526 return "dec{l}\t%k0";
5530 if (which_alternative == 1)
5533 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5536 if (x86_maybe_negate_const_int (&operands[2], SImode))
5537 return "sub{l}\t{%2, %k0|%k0, %2}";
5539 return "add{l}\t{%2, %k0|%k0, %2}";
5543 (if_then_else (match_operand:SI 2 "incdec_operand")
5544 (const_string "incdec")
5545 (const_string "alu")))
5546 (set (attr "length_immediate")
5548 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5550 (const_string "*")))
5551 (set_attr "mode" "SI")])
5553 (define_insn "*add<mode>_3"
5554 [(set (reg FLAGS_REG)
5556 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5557 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5558 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5559 "ix86_match_ccmode (insn, CCZmode)
5560 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5562 switch (get_attr_type (insn))
5565 if (operands[2] == const1_rtx)
5566 return "inc{<imodesuffix>}\t%0";
5569 gcc_assert (operands[2] == constm1_rtx);
5570 return "dec{<imodesuffix>}\t%0";
5574 if (which_alternative == 1)
5577 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5580 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5582 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5584 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5588 (if_then_else (match_operand:SWI 2 "incdec_operand")
5589 (const_string "incdec")
5590 (const_string "alu")))
5591 (set (attr "length_immediate")
5593 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5595 (const_string "*")))
5596 (set_attr "mode" "<MODE>")])
5598 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5599 (define_insn "*addsi_3_zext"
5600 [(set (reg FLAGS_REG)
5602 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5603 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5604 (set (match_operand:DI 0 "register_operand" "=r,r")
5605 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5606 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5607 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5609 switch (get_attr_type (insn))
5612 if (operands[2] == const1_rtx)
5613 return "inc{l}\t%k0";
5616 gcc_assert (operands[2] == constm1_rtx);
5617 return "dec{l}\t%k0";
5621 if (which_alternative == 1)
5624 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5627 if (x86_maybe_negate_const_int (&operands[2], SImode))
5628 return "sub{l}\t{%2, %k0|%k0, %2}";
5630 return "add{l}\t{%2, %k0|%k0, %2}";
5634 (if_then_else (match_operand:SI 2 "incdec_operand")
5635 (const_string "incdec")
5636 (const_string "alu")))
5637 (set (attr "length_immediate")
5639 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5641 (const_string "*")))
5642 (set_attr "mode" "SI")])
5644 ; For comparisons against 1, -1 and 128, we may generate better code
5645 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5646 ; is matched then. We can't accept general immediate, because for
5647 ; case of overflows, the result is messed up.
5648 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5649 ; only for comparisons not depending on it.
5651 (define_insn "*adddi_4"
5652 [(set (reg FLAGS_REG)
5654 (match_operand:DI 1 "nonimmediate_operand" "0")
5655 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5656 (clobber (match_scratch:DI 0 "=rm"))]
5658 && ix86_match_ccmode (insn, CCGCmode)"
5660 switch (get_attr_type (insn))
5663 if (operands[2] == constm1_rtx)
5664 return "inc{q}\t%0";
5667 gcc_assert (operands[2] == const1_rtx);
5668 return "dec{q}\t%0";
5672 if (x86_maybe_negate_const_int (&operands[2], DImode))
5673 return "add{q}\t{%2, %0|%0, %2}";
5675 return "sub{q}\t{%2, %0|%0, %2}";
5679 (if_then_else (match_operand:DI 2 "incdec_operand")
5680 (const_string "incdec")
5681 (const_string "alu")))
5682 (set (attr "length_immediate")
5684 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5686 (const_string "*")))
5687 (set_attr "mode" "DI")])
5689 ; For comparisons against 1, -1 and 128, we may generate better code
5690 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5691 ; is matched then. We can't accept general immediate, because for
5692 ; case of overflows, the result is messed up.
5693 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5694 ; only for comparisons not depending on it.
5696 (define_insn "*add<mode>_4"
5697 [(set (reg FLAGS_REG)
5699 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5700 (match_operand:SWI124 2 "const_int_operand" "n")))
5701 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5702 "ix86_match_ccmode (insn, CCGCmode)"
5704 switch (get_attr_type (insn))
5707 if (operands[2] == constm1_rtx)
5708 return "inc{<imodesuffix>}\t%0";
5711 gcc_assert (operands[2] == const1_rtx);
5712 return "dec{<imodesuffix>}\t%0";
5716 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5717 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5719 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5723 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5724 (const_string "incdec")
5725 (const_string "alu")))
5726 (set (attr "length_immediate")
5728 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5730 (const_string "*")))
5731 (set_attr "mode" "<MODE>")])
5733 (define_insn "*add<mode>_5"
5734 [(set (reg FLAGS_REG)
5737 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5738 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5740 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5741 "ix86_match_ccmode (insn, CCGOCmode)
5742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5744 switch (get_attr_type (insn))
5747 if (operands[2] == const1_rtx)
5748 return "inc{<imodesuffix>}\t%0";
5751 gcc_assert (operands[2] == constm1_rtx);
5752 return "dec{<imodesuffix>}\t%0";
5756 if (which_alternative == 1)
5759 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5762 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5763 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5764 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5766 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5770 (if_then_else (match_operand:SWI 2 "incdec_operand")
5771 (const_string "incdec")
5772 (const_string "alu")))
5773 (set (attr "length_immediate")
5775 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5777 (const_string "*")))
5778 (set_attr "mode" "<MODE>")])
5780 (define_insn "addqi_ext_1"
5781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5786 (match_operand 1 "ext_register_operand" "0,0")
5789 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5790 (clobber (reg:CC FLAGS_REG))]
5793 switch (get_attr_type (insn))
5796 if (operands[2] == const1_rtx)
5797 return "inc{b}\t%h0";
5800 gcc_assert (operands[2] == constm1_rtx);
5801 return "dec{b}\t%h0";
5805 return "add{b}\t{%2, %h0|%h0, %2}";
5808 [(set_attr "isa" "*,nox64")
5810 (if_then_else (match_operand:QI 2 "incdec_operand")
5811 (const_string "incdec")
5812 (const_string "alu")))
5813 (set_attr "modrm" "1")
5814 (set_attr "mode" "QI")])
5816 (define_insn "*addqi_ext_2"
5817 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5822 (match_operand 1 "ext_register_operand" "%0")
5826 (match_operand 2 "ext_register_operand" "Q")
5829 (clobber (reg:CC FLAGS_REG))]
5831 "add{b}\t{%h2, %h0|%h0, %h2}"
5832 [(set_attr "type" "alu")
5833 (set_attr "mode" "QI")])
5835 ;; Add with jump on overflow.
5836 (define_expand "addv<mode>4"
5837 [(parallel [(set (reg:CCO FLAGS_REG)
5840 (match_operand:SWI 1 "nonimmediate_operand"))
5843 (plus:SWI (match_dup 1)
5844 (match_operand:SWI 2
5845 "<general_operand>")))))
5846 (set (match_operand:SWI 0 "register_operand")
5847 (plus:SWI (match_dup 1) (match_dup 2)))])
5848 (set (pc) (if_then_else
5849 (eq (reg:CCO FLAGS_REG) (const_int 0))
5850 (label_ref (match_operand 3))
5854 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5855 if (CONST_INT_P (operands[2]))
5856 operands[4] = operands[2];
5858 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5861 (define_insn "*addv<mode>4"
5862 [(set (reg:CCO FLAGS_REG)
5865 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5867 (match_operand:SWI 2 "<general_sext_operand>"
5870 (plus:SWI (match_dup 1) (match_dup 2)))))
5871 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5872 (plus:SWI (match_dup 1) (match_dup 2)))]
5873 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5874 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5875 [(set_attr "type" "alu")
5876 (set_attr "mode" "<MODE>")])
5878 (define_insn "*addv<mode>4_1"
5879 [(set (reg:CCO FLAGS_REG)
5882 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5883 (match_operand:<DWI> 3 "const_int_operand" "i"))
5885 (plus:SWI (match_dup 1)
5886 (match_operand:SWI 2 "x86_64_immediate_operand"
5888 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5889 (plus:SWI (match_dup 1) (match_dup 2)))]
5890 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5891 && CONST_INT_P (operands[2])
5892 && INTVAL (operands[2]) == INTVAL (operands[3])"
5893 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5894 [(set_attr "type" "alu")
5895 (set_attr "mode" "<MODE>")
5896 (set (attr "length_immediate")
5897 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5899 (match_test "<MODE_SIZE> == 8")
5901 (const_string "<MODE_SIZE>")))])
5903 ;; The lea patterns for modes less than 32 bits need to be matched by
5904 ;; several insns converted to real lea by splitters.
5906 (define_insn_and_split "*lea_general_1"
5907 [(set (match_operand 0 "register_operand" "=r")
5908 (plus (plus (match_operand 1 "index_register_operand" "l")
5909 (match_operand 2 "register_operand" "r"))
5910 (match_operand 3 "immediate_operand" "i")))]
5911 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5912 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5913 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5914 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5915 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5916 || GET_MODE (operands[3]) == VOIDmode)"
5918 "&& reload_completed"
5921 enum machine_mode mode = SImode;
5924 operands[0] = gen_lowpart (mode, operands[0]);
5925 operands[1] = gen_lowpart (mode, operands[1]);
5926 operands[2] = gen_lowpart (mode, operands[2]);
5927 operands[3] = gen_lowpart (mode, operands[3]);
5929 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5932 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5935 [(set_attr "type" "lea")
5936 (set_attr "mode" "SI")])
5938 (define_insn_and_split "*lea_general_2"
5939 [(set (match_operand 0 "register_operand" "=r")
5940 (plus (mult (match_operand 1 "index_register_operand" "l")
5941 (match_operand 2 "const248_operand" "n"))
5942 (match_operand 3 "nonmemory_operand" "ri")))]
5943 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5944 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5945 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5946 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5947 || GET_MODE (operands[3]) == VOIDmode)"
5949 "&& reload_completed"
5952 enum machine_mode mode = SImode;
5955 operands[0] = gen_lowpart (mode, operands[0]);
5956 operands[1] = gen_lowpart (mode, operands[1]);
5957 operands[3] = gen_lowpart (mode, operands[3]);
5959 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5962 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5965 [(set_attr "type" "lea")
5966 (set_attr "mode" "SI")])
5968 (define_insn_and_split "*lea_general_3"
5969 [(set (match_operand 0 "register_operand" "=r")
5970 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5971 (match_operand 2 "const248_operand" "n"))
5972 (match_operand 3 "register_operand" "r"))
5973 (match_operand 4 "immediate_operand" "i")))]
5974 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5975 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5976 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5977 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5979 "&& reload_completed"
5982 enum machine_mode mode = SImode;
5985 operands[0] = gen_lowpart (mode, operands[0]);
5986 operands[1] = gen_lowpart (mode, operands[1]);
5987 operands[3] = gen_lowpart (mode, operands[3]);
5988 operands[4] = gen_lowpart (mode, operands[4]);
5990 pat = gen_rtx_PLUS (mode,
5992 gen_rtx_MULT (mode, operands[1],
5997 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6000 [(set_attr "type" "lea")
6001 (set_attr "mode" "SI")])
6003 (define_insn_and_split "*lea_general_4"
6004 [(set (match_operand 0 "register_operand" "=r")
6006 (match_operand 1 "index_register_operand" "l")
6007 (match_operand 2 "const_int_operand" "n"))
6008 (match_operand 3 "const_int_operand" "n")))]
6009 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6010 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6011 || GET_MODE (operands[0]) == SImode
6012 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6013 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6014 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6015 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6016 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6018 "&& reload_completed"
6021 enum machine_mode mode = GET_MODE (operands[0]);
6024 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6027 operands[0] = gen_lowpart (mode, operands[0]);
6028 operands[1] = gen_lowpart (mode, operands[1]);
6031 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6033 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6034 INTVAL (operands[3]));
6036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6039 [(set_attr "type" "lea")
6041 (if_then_else (match_operand:DI 0)
6043 (const_string "SI")))])
6045 ;; Subtract instructions
6047 (define_expand "sub<mode>3"
6048 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6049 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6050 (match_operand:SDWIM 2 "<general_operand>")))]
6052 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6054 (define_insn_and_split "*sub<dwi>3_doubleword"
6055 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6057 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6058 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6059 (clobber (reg:CC FLAGS_REG))]
6060 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6063 [(parallel [(set (reg:CC FLAGS_REG)
6064 (compare:CC (match_dup 1) (match_dup 2)))
6066 (minus:DWIH (match_dup 1) (match_dup 2)))])
6067 (parallel [(set (match_dup 3)
6071 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6073 (clobber (reg:CC FLAGS_REG))])]
6074 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6076 (define_insn "*sub<mode>_1"
6077 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6079 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6080 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6081 (clobber (reg:CC FLAGS_REG))]
6082 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6083 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6084 [(set_attr "type" "alu")
6085 (set_attr "mode" "<MODE>")])
6087 (define_insn "*subsi_1_zext"
6088 [(set (match_operand:DI 0 "register_operand" "=r")
6090 (minus:SI (match_operand:SI 1 "register_operand" "0")
6091 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6092 (clobber (reg:CC FLAGS_REG))]
6093 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6094 "sub{l}\t{%2, %k0|%k0, %2}"
6095 [(set_attr "type" "alu")
6096 (set_attr "mode" "SI")])
6098 (define_insn "*subqi_1_slp"
6099 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6100 (minus:QI (match_dup 0)
6101 (match_operand:QI 1 "general_operand" "qn,qm")))
6102 (clobber (reg:CC FLAGS_REG))]
6103 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6104 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6105 "sub{b}\t{%1, %0|%0, %1}"
6106 [(set_attr "type" "alu1")
6107 (set_attr "mode" "QI")])
6109 (define_insn "*sub<mode>_2"
6110 [(set (reg FLAGS_REG)
6113 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6114 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6116 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6117 (minus:SWI (match_dup 1) (match_dup 2)))]
6118 "ix86_match_ccmode (insn, CCGOCmode)
6119 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6120 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6121 [(set_attr "type" "alu")
6122 (set_attr "mode" "<MODE>")])
6124 (define_insn "*subsi_2_zext"
6125 [(set (reg FLAGS_REG)
6127 (minus:SI (match_operand:SI 1 "register_operand" "0")
6128 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6130 (set (match_operand:DI 0 "register_operand" "=r")
6132 (minus:SI (match_dup 1)
6134 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6135 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6136 "sub{l}\t{%2, %k0|%k0, %2}"
6137 [(set_attr "type" "alu")
6138 (set_attr "mode" "SI")])
6140 ;; Subtract with jump on overflow.
6141 (define_expand "subv<mode>4"
6142 [(parallel [(set (reg:CCO FLAGS_REG)
6143 (eq:CCO (minus:<DWI>
6145 (match_operand:SWI 1 "nonimmediate_operand"))
6148 (minus:SWI (match_dup 1)
6149 (match_operand:SWI 2
6150 "<general_operand>")))))
6151 (set (match_operand:SWI 0 "register_operand")
6152 (minus:SWI (match_dup 1) (match_dup 2)))])
6153 (set (pc) (if_then_else
6154 (eq (reg:CCO FLAGS_REG) (const_int 0))
6155 (label_ref (match_operand 3))
6159 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6160 if (CONST_INT_P (operands[2]))
6161 operands[4] = operands[2];
6163 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6166 (define_insn "*subv<mode>4"
6167 [(set (reg:CCO FLAGS_REG)
6168 (eq:CCO (minus:<DWI>
6170 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6172 (match_operand:SWI 2 "<general_sext_operand>"
6175 (minus:SWI (match_dup 1) (match_dup 2)))))
6176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6177 (minus:SWI (match_dup 1) (match_dup 2)))]
6178 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6179 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6180 [(set_attr "type" "alu")
6181 (set_attr "mode" "<MODE>")])
6183 (define_insn "*subv<mode>4_1"
6184 [(set (reg:CCO FLAGS_REG)
6185 (eq:CCO (minus:<DWI>
6187 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6188 (match_operand:<DWI> 3 "const_int_operand" "i"))
6190 (minus:SWI (match_dup 1)
6191 (match_operand:SWI 2 "x86_64_immediate_operand"
6193 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6194 (minus:SWI (match_dup 1) (match_dup 2)))]
6195 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6196 && CONST_INT_P (operands[2])
6197 && INTVAL (operands[2]) == INTVAL (operands[3])"
6198 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6199 [(set_attr "type" "alu")
6200 (set_attr "mode" "<MODE>")
6201 (set (attr "length_immediate")
6202 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6204 (match_test "<MODE_SIZE> == 8")
6206 (const_string "<MODE_SIZE>")))])
6208 (define_insn "*sub<mode>_3"
6209 [(set (reg FLAGS_REG)
6210 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6211 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6212 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6213 (minus:SWI (match_dup 1) (match_dup 2)))]
6214 "ix86_match_ccmode (insn, CCmode)
6215 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6216 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6217 [(set_attr "type" "alu")
6218 (set_attr "mode" "<MODE>")])
6220 (define_insn "*subsi_3_zext"
6221 [(set (reg FLAGS_REG)
6222 (compare (match_operand:SI 1 "register_operand" "0")
6223 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6224 (set (match_operand:DI 0 "register_operand" "=r")
6226 (minus:SI (match_dup 1)
6228 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6229 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6230 "sub{l}\t{%2, %1|%1, %2}"
6231 [(set_attr "type" "alu")
6232 (set_attr "mode" "SI")])
6234 ;; Add with carry and subtract with borrow
6236 (define_expand "<plusminus_insn><mode>3_carry"
6238 [(set (match_operand:SWI 0 "nonimmediate_operand")
6240 (match_operand:SWI 1 "nonimmediate_operand")
6241 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6242 [(match_operand 3 "flags_reg_operand")
6244 (match_operand:SWI 2 "<general_operand>"))))
6245 (clobber (reg:CC FLAGS_REG))])]
6246 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6248 (define_insn "*<plusminus_insn><mode>3_carry"
6249 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6251 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6253 (match_operator 3 "ix86_carry_flag_operator"
6254 [(reg FLAGS_REG) (const_int 0)])
6255 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6256 (clobber (reg:CC FLAGS_REG))]
6257 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6258 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6259 [(set_attr "type" "alu")
6260 (set_attr "use_carry" "1")
6261 (set_attr "pent_pair" "pu")
6262 (set_attr "mode" "<MODE>")])
6264 (define_insn "*addsi3_carry_zext"
6265 [(set (match_operand:DI 0 "register_operand" "=r")
6267 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6268 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6269 [(reg FLAGS_REG) (const_int 0)])
6270 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6271 (clobber (reg:CC FLAGS_REG))]
6272 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6273 "adc{l}\t{%2, %k0|%k0, %2}"
6274 [(set_attr "type" "alu")
6275 (set_attr "use_carry" "1")
6276 (set_attr "pent_pair" "pu")
6277 (set_attr "mode" "SI")])
6279 (define_insn "*subsi3_carry_zext"
6280 [(set (match_operand:DI 0 "register_operand" "=r")
6282 (minus:SI (match_operand:SI 1 "register_operand" "0")
6283 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6284 [(reg FLAGS_REG) (const_int 0)])
6285 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6286 (clobber (reg:CC FLAGS_REG))]
6287 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6288 "sbb{l}\t{%2, %k0|%k0, %2}"
6289 [(set_attr "type" "alu")
6290 (set_attr "pent_pair" "pu")
6291 (set_attr "mode" "SI")])
6295 (define_insn "adcx<mode>3"
6296 [(set (reg:CCC FLAGS_REG)
6299 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6301 (match_operator 4 "ix86_carry_flag_operator"
6302 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6303 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6305 (set (match_operand:SWI48 0 "register_operand" "=r")
6306 (plus:SWI48 (match_dup 1)
6307 (plus:SWI48 (match_op_dup 4
6308 [(match_dup 3) (const_int 0)])
6310 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6311 "adcx\t{%2, %0|%0, %2}"
6312 [(set_attr "type" "alu")
6313 (set_attr "use_carry" "1")
6314 (set_attr "mode" "<MODE>")])
6316 ;; Overflow setting add instructions
6318 (define_insn "*add<mode>3_cconly_overflow"
6319 [(set (reg:CCC FLAGS_REG)
6322 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6323 (match_operand:SWI 2 "<general_operand>" "<g>"))
6325 (clobber (match_scratch:SWI 0 "=<r>"))]
6326 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6327 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6328 [(set_attr "type" "alu")
6329 (set_attr "mode" "<MODE>")])
6331 (define_insn "*add<mode>3_cc_overflow"
6332 [(set (reg:CCC FLAGS_REG)
6335 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6336 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6338 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6339 (plus:SWI (match_dup 1) (match_dup 2)))]
6340 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6341 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6342 [(set_attr "type" "alu")
6343 (set_attr "mode" "<MODE>")])
6345 (define_insn "*addsi3_zext_cc_overflow"
6346 [(set (reg:CCC FLAGS_REG)
6349 (match_operand:SI 1 "nonimmediate_operand" "%0")
6350 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6352 (set (match_operand:DI 0 "register_operand" "=r")
6353 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6354 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6355 "add{l}\t{%2, %k0|%k0, %2}"
6356 [(set_attr "type" "alu")
6357 (set_attr "mode" "SI")])
6359 ;; The patterns that match these are at the end of this file.
6361 (define_expand "<plusminus_insn>xf3"
6362 [(set (match_operand:XF 0 "register_operand")
6364 (match_operand:XF 1 "register_operand")
6365 (match_operand:XF 2 "register_operand")))]
6368 (define_expand "<plusminus_insn><mode>3"
6369 [(set (match_operand:MODEF 0 "register_operand")
6371 (match_operand:MODEF 1 "register_operand")
6372 (match_operand:MODEF 2 "nonimmediate_operand")))]
6373 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6374 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6376 ;; Multiply instructions
6378 (define_expand "mul<mode>3"
6379 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6381 (match_operand:SWIM248 1 "register_operand")
6382 (match_operand:SWIM248 2 "<general_operand>")))
6383 (clobber (reg:CC FLAGS_REG))])])
6385 (define_expand "mulqi3"
6386 [(parallel [(set (match_operand:QI 0 "register_operand")
6388 (match_operand:QI 1 "register_operand")
6389 (match_operand:QI 2 "nonimmediate_operand")))
6390 (clobber (reg:CC FLAGS_REG))])]
6391 "TARGET_QIMODE_MATH")
6394 ;; IMUL reg32/64, reg32/64, imm8 Direct
6395 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6396 ;; IMUL reg32/64, reg32/64, imm32 Direct
6397 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6398 ;; IMUL reg32/64, reg32/64 Direct
6399 ;; IMUL reg32/64, mem32/64 Direct
6401 ;; On BDVER1, all above IMULs use DirectPath
6403 (define_insn "*mul<mode>3_1"
6404 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6406 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6407 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6408 (clobber (reg:CC FLAGS_REG))]
6409 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6411 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6412 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6413 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6414 [(set_attr "type" "imul")
6415 (set_attr "prefix_0f" "0,0,1")
6416 (set (attr "athlon_decode")
6417 (cond [(eq_attr "cpu" "athlon")
6418 (const_string "vector")
6419 (eq_attr "alternative" "1")
6420 (const_string "vector")
6421 (and (eq_attr "alternative" "2")
6422 (match_operand 1 "memory_operand"))
6423 (const_string "vector")]
6424 (const_string "direct")))
6425 (set (attr "amdfam10_decode")
6426 (cond [(and (eq_attr "alternative" "0,1")
6427 (match_operand 1 "memory_operand"))
6428 (const_string "vector")]
6429 (const_string "direct")))
6430 (set_attr "bdver1_decode" "direct")
6431 (set_attr "mode" "<MODE>")])
6433 (define_insn "*mulsi3_1_zext"
6434 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6436 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6437 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6438 (clobber (reg:CC FLAGS_REG))]
6440 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6442 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6443 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6444 imul{l}\t{%2, %k0|%k0, %2}"
6445 [(set_attr "type" "imul")
6446 (set_attr "prefix_0f" "0,0,1")
6447 (set (attr "athlon_decode")
6448 (cond [(eq_attr "cpu" "athlon")
6449 (const_string "vector")
6450 (eq_attr "alternative" "1")
6451 (const_string "vector")
6452 (and (eq_attr "alternative" "2")
6453 (match_operand 1 "memory_operand"))
6454 (const_string "vector")]
6455 (const_string "direct")))
6456 (set (attr "amdfam10_decode")
6457 (cond [(and (eq_attr "alternative" "0,1")
6458 (match_operand 1 "memory_operand"))
6459 (const_string "vector")]
6460 (const_string "direct")))
6461 (set_attr "bdver1_decode" "direct")
6462 (set_attr "mode" "SI")])
6465 ;; IMUL reg16, reg16, imm8 VectorPath
6466 ;; IMUL reg16, mem16, imm8 VectorPath
6467 ;; IMUL reg16, reg16, imm16 VectorPath
6468 ;; IMUL reg16, mem16, imm16 VectorPath
6469 ;; IMUL reg16, reg16 Direct
6470 ;; IMUL reg16, mem16 Direct
6472 ;; On BDVER1, all HI MULs use DoublePath
6474 (define_insn "*mulhi3_1"
6475 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6476 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6477 (match_operand:HI 2 "general_operand" "K,n,mr")))
6478 (clobber (reg:CC FLAGS_REG))]
6480 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6482 imul{w}\t{%2, %1, %0|%0, %1, %2}
6483 imul{w}\t{%2, %1, %0|%0, %1, %2}
6484 imul{w}\t{%2, %0|%0, %2}"
6485 [(set_attr "type" "imul")
6486 (set_attr "prefix_0f" "0,0,1")
6487 (set (attr "athlon_decode")
6488 (cond [(eq_attr "cpu" "athlon")
6489 (const_string "vector")
6490 (eq_attr "alternative" "1,2")
6491 (const_string "vector")]
6492 (const_string "direct")))
6493 (set (attr "amdfam10_decode")
6494 (cond [(eq_attr "alternative" "0,1")
6495 (const_string "vector")]
6496 (const_string "direct")))
6497 (set_attr "bdver1_decode" "double")
6498 (set_attr "mode" "HI")])
6500 ;;On AMDFAM10 and BDVER1
6504 (define_insn "*mulqi3_1"
6505 [(set (match_operand:QI 0 "register_operand" "=a")
6506 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6507 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6508 (clobber (reg:CC FLAGS_REG))]
6510 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6512 [(set_attr "type" "imul")
6513 (set_attr "length_immediate" "0")
6514 (set (attr "athlon_decode")
6515 (if_then_else (eq_attr "cpu" "athlon")
6516 (const_string "vector")
6517 (const_string "direct")))
6518 (set_attr "amdfam10_decode" "direct")
6519 (set_attr "bdver1_decode" "direct")
6520 (set_attr "mode" "QI")])
6522 ;; Multiply with jump on overflow.
6523 (define_expand "mulv<mode>4"
6524 [(parallel [(set (reg:CCO FLAGS_REG)
6527 (match_operand:SWI48 1 "register_operand"))
6530 (mult:SWI48 (match_dup 1)
6531 (match_operand:SWI48 2
6532 "<general_operand>")))))
6533 (set (match_operand:SWI48 0 "register_operand")
6534 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6535 (set (pc) (if_then_else
6536 (eq (reg:CCO FLAGS_REG) (const_int 0))
6537 (label_ref (match_operand 3))
6541 if (CONST_INT_P (operands[2]))
6542 operands[4] = operands[2];
6544 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6547 (define_insn "*mulv<mode>4"
6548 [(set (reg:CCO FLAGS_REG)
6551 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6553 (match_operand:SWI48 2 "<general_sext_operand>"
6556 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6557 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6558 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6559 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6561 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6562 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "imul")
6564 (set_attr "prefix_0f" "0,1")
6565 (set (attr "athlon_decode")
6566 (cond [(eq_attr "cpu" "athlon")
6567 (const_string "vector")
6568 (eq_attr "alternative" "0")
6569 (const_string "vector")
6570 (and (eq_attr "alternative" "1")
6571 (match_operand 1 "memory_operand"))
6572 (const_string "vector")]
6573 (const_string "direct")))
6574 (set (attr "amdfam10_decode")
6575 (cond [(and (eq_attr "alternative" "1")
6576 (match_operand 1 "memory_operand"))
6577 (const_string "vector")]
6578 (const_string "direct")))
6579 (set_attr "bdver1_decode" "direct")
6580 (set_attr "mode" "<MODE>")])
6582 (define_insn "*mulv<mode>4_1"
6583 [(set (reg:CCO FLAGS_REG)
6586 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6587 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6589 (mult:SWI48 (match_dup 1)
6590 (match_operand:SWI 2 "x86_64_immediate_operand"
6592 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6593 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6594 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6595 && CONST_INT_P (operands[2])
6596 && INTVAL (operands[2]) == INTVAL (operands[3])"
6598 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6599 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6600 [(set_attr "type" "imul")
6601 (set (attr "athlon_decode")
6602 (cond [(eq_attr "cpu" "athlon")
6603 (const_string "vector")
6604 (eq_attr "alternative" "1")
6605 (const_string "vector")]
6606 (const_string "direct")))
6607 (set (attr "amdfam10_decode")
6608 (cond [(match_operand 1 "memory_operand")
6609 (const_string "vector")]
6610 (const_string "direct")))
6611 (set_attr "bdver1_decode" "direct")
6612 (set_attr "mode" "<MODE>")
6613 (set (attr "length_immediate")
6614 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6616 (match_test "<MODE_SIZE> == 8")
6618 (const_string "<MODE_SIZE>")))])
6620 (define_expand "<u>mul<mode><dwi>3"
6621 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6624 (match_operand:DWIH 1 "nonimmediate_operand"))
6626 (match_operand:DWIH 2 "register_operand"))))
6627 (clobber (reg:CC FLAGS_REG))])])
6629 (define_expand "<u>mulqihi3"
6630 [(parallel [(set (match_operand:HI 0 "register_operand")
6633 (match_operand:QI 1 "nonimmediate_operand"))
6635 (match_operand:QI 2 "register_operand"))))
6636 (clobber (reg:CC FLAGS_REG))])]
6637 "TARGET_QIMODE_MATH")
6639 (define_insn "*bmi2_umulditi3_1"
6640 [(set (match_operand:DI 0 "register_operand" "=r")
6642 (match_operand:DI 2 "nonimmediate_operand" "%d")
6643 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6644 (set (match_operand:DI 1 "register_operand" "=r")
6647 (mult:TI (zero_extend:TI (match_dup 2))
6648 (zero_extend:TI (match_dup 3)))
6650 "TARGET_64BIT && TARGET_BMI2
6651 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6652 "mulx\t{%3, %0, %1|%1, %0, %3}"
6653 [(set_attr "type" "imulx")
6654 (set_attr "prefix" "vex")
6655 (set_attr "mode" "DI")])
6657 (define_insn "*bmi2_umulsidi3_1"
6658 [(set (match_operand:SI 0 "register_operand" "=r")
6660 (match_operand:SI 2 "nonimmediate_operand" "%d")
6661 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6662 (set (match_operand:SI 1 "register_operand" "=r")
6665 (mult:DI (zero_extend:DI (match_dup 2))
6666 (zero_extend:DI (match_dup 3)))
6668 "!TARGET_64BIT && TARGET_BMI2
6669 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6670 "mulx\t{%3, %0, %1|%1, %0, %3}"
6671 [(set_attr "type" "imulx")
6672 (set_attr "prefix" "vex")
6673 (set_attr "mode" "SI")])
6675 (define_insn "*umul<mode><dwi>3_1"
6676 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6679 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6681 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6682 (clobber (reg:CC FLAGS_REG))]
6683 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6686 mul{<imodesuffix>}\t%2"
6687 [(set_attr "isa" "bmi2,*")
6688 (set_attr "type" "imulx,imul")
6689 (set_attr "length_immediate" "*,0")
6690 (set (attr "athlon_decode")
6691 (cond [(eq_attr "alternative" "1")
6692 (if_then_else (eq_attr "cpu" "athlon")
6693 (const_string "vector")
6694 (const_string "double"))]
6695 (const_string "*")))
6696 (set_attr "amdfam10_decode" "*,double")
6697 (set_attr "bdver1_decode" "*,direct")
6698 (set_attr "prefix" "vex,orig")
6699 (set_attr "mode" "<MODE>")])
6701 ;; Convert mul to the mulx pattern to avoid flags dependency.
6703 [(set (match_operand:<DWI> 0 "register_operand")
6706 (match_operand:DWIH 1 "register_operand"))
6708 (match_operand:DWIH 2 "nonimmediate_operand"))))
6709 (clobber (reg:CC FLAGS_REG))]
6710 "TARGET_BMI2 && reload_completed
6711 && true_regnum (operands[1]) == DX_REG"
6712 [(parallel [(set (match_dup 3)
6713 (mult:DWIH (match_dup 1) (match_dup 2)))
6717 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6718 (zero_extend:<DWI> (match_dup 2)))
6721 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6723 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6726 (define_insn "*mul<mode><dwi>3_1"
6727 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6730 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6732 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6733 (clobber (reg:CC FLAGS_REG))]
6734 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735 "imul{<imodesuffix>}\t%2"
6736 [(set_attr "type" "imul")
6737 (set_attr "length_immediate" "0")
6738 (set (attr "athlon_decode")
6739 (if_then_else (eq_attr "cpu" "athlon")
6740 (const_string "vector")
6741 (const_string "double")))
6742 (set_attr "amdfam10_decode" "double")
6743 (set_attr "bdver1_decode" "direct")
6744 (set_attr "mode" "<MODE>")])
6746 (define_insn "*<u>mulqihi3_1"
6747 [(set (match_operand:HI 0 "register_operand" "=a")
6750 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6752 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6753 (clobber (reg:CC FLAGS_REG))]
6755 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756 "<sgnprefix>mul{b}\t%2"
6757 [(set_attr "type" "imul")
6758 (set_attr "length_immediate" "0")
6759 (set (attr "athlon_decode")
6760 (if_then_else (eq_attr "cpu" "athlon")
6761 (const_string "vector")
6762 (const_string "direct")))
6763 (set_attr "amdfam10_decode" "direct")
6764 (set_attr "bdver1_decode" "direct")
6765 (set_attr "mode" "QI")])
6767 (define_expand "<s>mul<mode>3_highpart"
6768 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6773 (match_operand:SWI48 1 "nonimmediate_operand"))
6775 (match_operand:SWI48 2 "register_operand")))
6777 (clobber (match_scratch:SWI48 3))
6778 (clobber (reg:CC FLAGS_REG))])]
6780 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6782 (define_insn "*<s>muldi3_highpart_1"
6783 [(set (match_operand:DI 0 "register_operand" "=d")
6788 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6790 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6792 (clobber (match_scratch:DI 3 "=1"))
6793 (clobber (reg:CC FLAGS_REG))]
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 "<sgnprefix>mul{q}\t%2"
6797 [(set_attr "type" "imul")
6798 (set_attr "length_immediate" "0")
6799 (set (attr "athlon_decode")
6800 (if_then_else (eq_attr "cpu" "athlon")
6801 (const_string "vector")
6802 (const_string "double")))
6803 (set_attr "amdfam10_decode" "double")
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "DI")])
6807 (define_insn "*<s>mulsi3_highpart_1"
6808 [(set (match_operand:SI 0 "register_operand" "=d")
6813 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6815 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6817 (clobber (match_scratch:SI 3 "=1"))
6818 (clobber (reg:CC FLAGS_REG))]
6819 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6820 "<sgnprefix>mul{l}\t%2"
6821 [(set_attr "type" "imul")
6822 (set_attr "length_immediate" "0")
6823 (set (attr "athlon_decode")
6824 (if_then_else (eq_attr "cpu" "athlon")
6825 (const_string "vector")
6826 (const_string "double")))
6827 (set_attr "amdfam10_decode" "double")
6828 (set_attr "bdver1_decode" "direct")
6829 (set_attr "mode" "SI")])
6831 (define_insn "*<s>mulsi3_highpart_zext"
6832 [(set (match_operand:DI 0 "register_operand" "=d")
6833 (zero_extend:DI (truncate:SI
6835 (mult:DI (any_extend:DI
6836 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6838 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6840 (clobber (match_scratch:SI 3 "=1"))
6841 (clobber (reg:CC FLAGS_REG))]
6843 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6844 "<sgnprefix>mul{l}\t%2"
6845 [(set_attr "type" "imul")
6846 (set_attr "length_immediate" "0")
6847 (set (attr "athlon_decode")
6848 (if_then_else (eq_attr "cpu" "athlon")
6849 (const_string "vector")
6850 (const_string "double")))
6851 (set_attr "amdfam10_decode" "double")
6852 (set_attr "bdver1_decode" "direct")
6853 (set_attr "mode" "SI")])
6855 ;; The patterns that match these are at the end of this file.
6857 (define_expand "mulxf3"
6858 [(set (match_operand:XF 0 "register_operand")
6859 (mult:XF (match_operand:XF 1 "register_operand")
6860 (match_operand:XF 2 "register_operand")))]
6863 (define_expand "mul<mode>3"
6864 [(set (match_operand:MODEF 0 "register_operand")
6865 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6866 (match_operand:MODEF 2 "nonimmediate_operand")))]
6867 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6868 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6870 ;; Divide instructions
6872 ;; The patterns that match these are at the end of this file.
6874 (define_expand "divxf3"
6875 [(set (match_operand:XF 0 "register_operand")
6876 (div:XF (match_operand:XF 1 "register_operand")
6877 (match_operand:XF 2 "register_operand")))]
6880 (define_expand "divdf3"
6881 [(set (match_operand:DF 0 "register_operand")
6882 (div:DF (match_operand:DF 1 "register_operand")
6883 (match_operand:DF 2 "nonimmediate_operand")))]
6884 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6885 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6887 (define_expand "divsf3"
6888 [(set (match_operand:SF 0 "register_operand")
6889 (div:SF (match_operand:SF 1 "register_operand")
6890 (match_operand:SF 2 "nonimmediate_operand")))]
6891 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6896 && optimize_insn_for_speed_p ()
6897 && flag_finite_math_only && !flag_trapping_math
6898 && flag_unsafe_math_optimizations)
6900 ix86_emit_swdivsf (operands[0], operands[1],
6901 operands[2], SFmode);
6906 ;; Divmod instructions.
6908 (define_expand "divmod<mode>4"
6909 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6911 (match_operand:SWIM248 1 "register_operand")
6912 (match_operand:SWIM248 2 "nonimmediate_operand")))
6913 (set (match_operand:SWIM248 3 "register_operand")
6914 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6915 (clobber (reg:CC FLAGS_REG))])])
6917 ;; Split with 8bit unsigned divide:
6918 ;; if (dividend an divisor are in [0-255])
6919 ;; use 8bit unsigned integer divide
6921 ;; use original integer divide
6923 [(set (match_operand:SWI48 0 "register_operand")
6924 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6925 (match_operand:SWI48 3 "nonimmediate_operand")))
6926 (set (match_operand:SWI48 1 "register_operand")
6927 (mod:SWI48 (match_dup 2) (match_dup 3)))
6928 (clobber (reg:CC FLAGS_REG))]
6929 "TARGET_USE_8BIT_IDIV
6930 && TARGET_QIMODE_MATH
6931 && can_create_pseudo_p ()
6932 && !optimize_insn_for_size_p ()"
6934 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6936 (define_insn_and_split "divmod<mode>4_1"
6937 [(set (match_operand:SWI48 0 "register_operand" "=a")
6938 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6939 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6940 (set (match_operand:SWI48 1 "register_operand" "=&d")
6941 (mod:SWI48 (match_dup 2) (match_dup 3)))
6942 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6943 (clobber (reg:CC FLAGS_REG))]
6947 [(parallel [(set (match_dup 1)
6948 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6949 (clobber (reg:CC FLAGS_REG))])
6950 (parallel [(set (match_dup 0)
6951 (div:SWI48 (match_dup 2) (match_dup 3)))
6953 (mod:SWI48 (match_dup 2) (match_dup 3)))
6955 (clobber (reg:CC FLAGS_REG))])]
6957 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6959 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6960 operands[4] = operands[2];
6963 /* Avoid use of cltd in favor of a mov+shift. */
6964 emit_move_insn (operands[1], operands[2]);
6965 operands[4] = operands[1];
6968 [(set_attr "type" "multi")
6969 (set_attr "mode" "<MODE>")])
6971 (define_insn_and_split "*divmod<mode>4"
6972 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6973 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6974 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6975 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6976 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6977 (clobber (reg:CC FLAGS_REG))]
6981 [(parallel [(set (match_dup 1)
6982 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6983 (clobber (reg:CC FLAGS_REG))])
6984 (parallel [(set (match_dup 0)
6985 (div:SWIM248 (match_dup 2) (match_dup 3)))
6987 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6989 (clobber (reg:CC FLAGS_REG))])]
6991 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6993 if (<MODE>mode != HImode
6994 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6995 operands[4] = operands[2];
6998 /* Avoid use of cltd in favor of a mov+shift. */
6999 emit_move_insn (operands[1], operands[2]);
7000 operands[4] = operands[1];
7003 [(set_attr "type" "multi")
7004 (set_attr "mode" "<MODE>")])
7006 (define_insn "*divmod<mode>4_noext"
7007 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7008 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7009 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7010 (set (match_operand:SWIM248 1 "register_operand" "=d")
7011 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7012 (use (match_operand:SWIM248 4 "register_operand" "1"))
7013 (clobber (reg:CC FLAGS_REG))]
7015 "idiv{<imodesuffix>}\t%3"
7016 [(set_attr "type" "idiv")
7017 (set_attr "mode" "<MODE>")])
7019 (define_expand "divmodqi4"
7020 [(parallel [(set (match_operand:QI 0 "register_operand")
7022 (match_operand:QI 1 "register_operand")
7023 (match_operand:QI 2 "nonimmediate_operand")))
7024 (set (match_operand:QI 3 "register_operand")
7025 (mod:QI (match_dup 1) (match_dup 2)))
7026 (clobber (reg:CC FLAGS_REG))])]
7027 "TARGET_QIMODE_MATH"
7032 tmp0 = gen_reg_rtx (HImode);
7033 tmp1 = gen_reg_rtx (HImode);
7035 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7037 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7038 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7040 /* Extract remainder from AH. */
7041 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7042 insn = emit_move_insn (operands[3], tmp1);
7044 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7045 set_unique_reg_note (insn, REG_EQUAL, mod);
7047 /* Extract quotient from AL. */
7048 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7050 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7051 set_unique_reg_note (insn, REG_EQUAL, div);
7056 ;; Divide AX by r/m8, with result stored in
7059 ;; Change div/mod to HImode and extend the second argument to HImode
7060 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7061 ;; combine may fail.
7062 (define_insn "divmodhiqi3"
7063 [(set (match_operand:HI 0 "register_operand" "=a")
7068 (mod:HI (match_operand:HI 1 "register_operand" "0")
7070 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7074 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7075 (clobber (reg:CC FLAGS_REG))]
7076 "TARGET_QIMODE_MATH"
7078 [(set_attr "type" "idiv")
7079 (set_attr "mode" "QI")])
7081 (define_expand "udivmod<mode>4"
7082 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7084 (match_operand:SWIM248 1 "register_operand")
7085 (match_operand:SWIM248 2 "nonimmediate_operand")))
7086 (set (match_operand:SWIM248 3 "register_operand")
7087 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7088 (clobber (reg:CC FLAGS_REG))])])
7090 ;; Split with 8bit unsigned divide:
7091 ;; if (dividend an divisor are in [0-255])
7092 ;; use 8bit unsigned integer divide
7094 ;; use original integer divide
7096 [(set (match_operand:SWI48 0 "register_operand")
7097 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7098 (match_operand:SWI48 3 "nonimmediate_operand")))
7099 (set (match_operand:SWI48 1 "register_operand")
7100 (umod:SWI48 (match_dup 2) (match_dup 3)))
7101 (clobber (reg:CC FLAGS_REG))]
7102 "TARGET_USE_8BIT_IDIV
7103 && TARGET_QIMODE_MATH
7104 && can_create_pseudo_p ()
7105 && !optimize_insn_for_size_p ()"
7107 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7109 (define_insn_and_split "udivmod<mode>4_1"
7110 [(set (match_operand:SWI48 0 "register_operand" "=a")
7111 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7112 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7113 (set (match_operand:SWI48 1 "register_operand" "=&d")
7114 (umod:SWI48 (match_dup 2) (match_dup 3)))
7115 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7116 (clobber (reg:CC FLAGS_REG))]
7120 [(set (match_dup 1) (const_int 0))
7121 (parallel [(set (match_dup 0)
7122 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7124 (umod:SWI48 (match_dup 2) (match_dup 3)))
7126 (clobber (reg:CC FLAGS_REG))])]
7128 [(set_attr "type" "multi")
7129 (set_attr "mode" "<MODE>")])
7131 (define_insn_and_split "*udivmod<mode>4"
7132 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7133 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7134 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7135 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7136 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7137 (clobber (reg:CC FLAGS_REG))]
7141 [(set (match_dup 1) (const_int 0))
7142 (parallel [(set (match_dup 0)
7143 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7145 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7147 (clobber (reg:CC FLAGS_REG))])]
7149 [(set_attr "type" "multi")
7150 (set_attr "mode" "<MODE>")])
7152 (define_insn "*udivmod<mode>4_noext"
7153 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7154 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7155 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWIM248 1 "register_operand" "=d")
7157 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7158 (use (match_operand:SWIM248 4 "register_operand" "1"))
7159 (clobber (reg:CC FLAGS_REG))]
7161 "div{<imodesuffix>}\t%3"
7162 [(set_attr "type" "idiv")
7163 (set_attr "mode" "<MODE>")])
7165 (define_expand "udivmodqi4"
7166 [(parallel [(set (match_operand:QI 0 "register_operand")
7168 (match_operand:QI 1 "register_operand")
7169 (match_operand:QI 2 "nonimmediate_operand")))
7170 (set (match_operand:QI 3 "register_operand")
7171 (umod:QI (match_dup 1) (match_dup 2)))
7172 (clobber (reg:CC FLAGS_REG))])]
7173 "TARGET_QIMODE_MATH"
7178 tmp0 = gen_reg_rtx (HImode);
7179 tmp1 = gen_reg_rtx (HImode);
7181 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7183 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7184 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7186 /* Extract remainder from AH. */
7187 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7188 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7189 insn = emit_move_insn (operands[3], tmp1);
7191 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7192 set_unique_reg_note (insn, REG_EQUAL, mod);
7194 /* Extract quotient from AL. */
7195 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7197 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7198 set_unique_reg_note (insn, REG_EQUAL, div);
7203 (define_insn "udivmodhiqi3"
7204 [(set (match_operand:HI 0 "register_operand" "=a")
7209 (mod:HI (match_operand:HI 1 "register_operand" "0")
7211 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7215 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7216 (clobber (reg:CC FLAGS_REG))]
7217 "TARGET_QIMODE_MATH"
7219 [(set_attr "type" "idiv")
7220 (set_attr "mode" "QI")])
7222 ;; We cannot use div/idiv for double division, because it causes
7223 ;; "division by zero" on the overflow and that's not what we expect
7224 ;; from truncate. Because true (non truncating) double division is
7225 ;; never generated, we can't create this insn anyway.
7228 ; [(set (match_operand:SI 0 "register_operand" "=a")
7230 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7232 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7233 ; (set (match_operand:SI 3 "register_operand" "=d")
7235 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7236 ; (clobber (reg:CC FLAGS_REG))]
7238 ; "div{l}\t{%2, %0|%0, %2}"
7239 ; [(set_attr "type" "idiv")])
7241 ;;- Logical AND instructions
7243 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7244 ;; Note that this excludes ah.
7246 (define_expand "testsi_ccno_1"
7247 [(set (reg:CCNO FLAGS_REG)
7249 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7250 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7253 (define_expand "testqi_ccz_1"
7254 [(set (reg:CCZ FLAGS_REG)
7255 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7256 (match_operand:QI 1 "nonmemory_operand"))
7259 (define_expand "testdi_ccno_1"
7260 [(set (reg:CCNO FLAGS_REG)
7262 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7263 (match_operand:DI 1 "x86_64_szext_general_operand"))
7265 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7267 (define_insn "*testdi_1"
7268 [(set (reg FLAGS_REG)
7271 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7272 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7274 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7275 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7277 test{l}\t{%k1, %k0|%k0, %k1}
7278 test{l}\t{%k1, %k0|%k0, %k1}
7279 test{q}\t{%1, %0|%0, %1}
7280 test{q}\t{%1, %0|%0, %1}
7281 test{q}\t{%1, %0|%0, %1}"
7282 [(set_attr "type" "test")
7283 (set_attr "modrm" "0,1,0,1,1")
7284 (set_attr "mode" "SI,SI,DI,DI,DI")])
7286 (define_insn "*testqi_1_maybe_si"
7287 [(set (reg FLAGS_REG)
7290 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7291 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7293 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7294 && ix86_match_ccmode (insn,
7295 CONST_INT_P (operands[1])
7296 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7298 if (which_alternative == 3)
7300 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7301 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7302 return "test{l}\t{%1, %k0|%k0, %1}";
7304 return "test{b}\t{%1, %0|%0, %1}";
7306 [(set_attr "type" "test")
7307 (set_attr "modrm" "0,1,1,1")
7308 (set_attr "mode" "QI,QI,QI,SI")
7309 (set_attr "pent_pair" "uv,np,uv,np")])
7311 (define_insn "*test<mode>_1"
7312 [(set (reg FLAGS_REG)
7315 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7316 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7318 "ix86_match_ccmode (insn, CCNOmode)
7319 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7320 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7321 [(set_attr "type" "test")
7322 (set_attr "modrm" "0,1,1")
7323 (set_attr "mode" "<MODE>")
7324 (set_attr "pent_pair" "uv,np,uv")])
7326 (define_expand "testqi_ext_ccno_0"
7327 [(set (reg:CCNO FLAGS_REG)
7331 (match_operand 0 "ext_register_operand")
7334 (match_operand 1 "const_int_operand"))
7337 (define_insn "*testqi_ext_0"
7338 [(set (reg FLAGS_REG)
7342 (match_operand 0 "ext_register_operand" "Q")
7345 (match_operand 1 "const_int_operand" "n"))
7347 "ix86_match_ccmode (insn, CCNOmode)"
7348 "test{b}\t{%1, %h0|%h0, %1}"
7349 [(set_attr "type" "test")
7350 (set_attr "mode" "QI")
7351 (set_attr "length_immediate" "1")
7352 (set_attr "modrm" "1")
7353 (set_attr "pent_pair" "np")])
7355 (define_insn "*testqi_ext_1"
7356 [(set (reg FLAGS_REG)
7360 (match_operand 0 "ext_register_operand" "Q,Q")
7364 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7366 "ix86_match_ccmode (insn, CCNOmode)"
7367 "test{b}\t{%1, %h0|%h0, %1}"
7368 [(set_attr "isa" "*,nox64")
7369 (set_attr "type" "test")
7370 (set_attr "mode" "QI")])
7372 (define_insn "*testqi_ext_2"
7373 [(set (reg FLAGS_REG)
7377 (match_operand 0 "ext_register_operand" "Q")
7381 (match_operand 1 "ext_register_operand" "Q")
7385 "ix86_match_ccmode (insn, CCNOmode)"
7386 "test{b}\t{%h1, %h0|%h0, %h1}"
7387 [(set_attr "type" "test")
7388 (set_attr "mode" "QI")])
7390 ;; Combine likes to form bit extractions for some tests. Humor it.
7391 (define_insn "*testqi_ext_3"
7392 [(set (reg FLAGS_REG)
7393 (compare (zero_extract:SWI48
7394 (match_operand 0 "nonimmediate_operand" "rm")
7395 (match_operand:SWI48 1 "const_int_operand")
7396 (match_operand:SWI48 2 "const_int_operand"))
7398 "ix86_match_ccmode (insn, CCNOmode)
7399 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7400 || GET_MODE (operands[0]) == SImode
7401 || GET_MODE (operands[0]) == HImode
7402 || GET_MODE (operands[0]) == QImode)
7403 /* Ensure that resulting mask is zero or sign extended operand. */
7404 && INTVAL (operands[2]) >= 0
7405 && ((INTVAL (operands[1]) > 0
7406 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7407 || (<MODE>mode == DImode
7408 && INTVAL (operands[1]) > 32
7409 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7413 [(set (match_operand 0 "flags_reg_operand")
7414 (match_operator 1 "compare_operator"
7416 (match_operand 2 "nonimmediate_operand")
7417 (match_operand 3 "const_int_operand")
7418 (match_operand 4 "const_int_operand"))
7420 "ix86_match_ccmode (insn, CCNOmode)"
7421 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7423 rtx val = operands[2];
7424 HOST_WIDE_INT len = INTVAL (operands[3]);
7425 HOST_WIDE_INT pos = INTVAL (operands[4]);
7427 enum machine_mode mode, submode;
7429 mode = GET_MODE (val);
7432 /* ??? Combine likes to put non-volatile mem extractions in QImode
7433 no matter the size of the test. So find a mode that works. */
7434 if (! MEM_VOLATILE_P (val))
7436 mode = smallest_mode_for_size (pos + len, MODE_INT);
7437 val = adjust_address (val, mode, 0);
7440 else if (GET_CODE (val) == SUBREG
7441 && (submode = GET_MODE (SUBREG_REG (val)),
7442 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7443 && pos + len <= GET_MODE_BITSIZE (submode)
7444 && GET_MODE_CLASS (submode) == MODE_INT)
7446 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7448 val = SUBREG_REG (val);
7450 else if (mode == HImode && pos + len <= 8)
7452 /* Small HImode tests can be converted to QImode. */
7454 val = gen_lowpart (QImode, val);
7457 if (len == HOST_BITS_PER_WIDE_INT)
7460 mask = ((HOST_WIDE_INT)1 << len) - 1;
7463 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7466 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7467 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7468 ;; this is relatively important trick.
7469 ;; Do the conversion only post-reload to avoid limiting of the register class
7472 [(set (match_operand 0 "flags_reg_operand")
7473 (match_operator 1 "compare_operator"
7474 [(and (match_operand 2 "register_operand")
7475 (match_operand 3 "const_int_operand"))
7478 && QI_REG_P (operands[2])
7479 && GET_MODE (operands[2]) != QImode
7480 && ((ix86_match_ccmode (insn, CCZmode)
7481 && !(INTVAL (operands[3]) & ~(255 << 8)))
7482 || (ix86_match_ccmode (insn, CCNOmode)
7483 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7486 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7490 operands[2] = gen_lowpart (SImode, operands[2]);
7491 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7495 [(set (match_operand 0 "flags_reg_operand")
7496 (match_operator 1 "compare_operator"
7497 [(and (match_operand 2 "nonimmediate_operand")
7498 (match_operand 3 "const_int_operand"))
7501 && GET_MODE (operands[2]) != QImode
7502 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7503 && ((ix86_match_ccmode (insn, CCZmode)
7504 && !(INTVAL (operands[3]) & ~255))
7505 || (ix86_match_ccmode (insn, CCNOmode)
7506 && !(INTVAL (operands[3]) & ~127)))"
7508 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7511 operands[2] = gen_lowpart (QImode, operands[2]);
7512 operands[3] = gen_lowpart (QImode, operands[3]);
7516 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7517 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7518 (match_operand:SWI1248x 2 "mask_reg_operand")))
7519 (clobber (reg:CC FLAGS_REG))]
7520 "TARGET_AVX512F && reload_completed"
7522 (any_logic:SWI1248x (match_dup 1)
7525 ;; TODO: It seems to be possible to macroize following
7527 (define_insn "*k<logic>qi"
7528 [(set (match_operand:QI 0 "mask_reg_operand" "=k")
7529 (any_logic:QI (match_operand:QI 1 "mask_reg_operand" "k")
7530 (match_operand:QI 2 "mask_reg_operand" "k")))]
7533 return TARGET_AVX512DQ ? "k<logic>b\t{%2, %1, %0|%0, %1, %2}"
7534 : "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7536 [(set_attr "mode" "QI")
7537 (set_attr "type" "msklog")
7538 (set_attr "prefix" "vex")])
7540 (define_insn "*k<logic>hi"
7541 [(set (match_operand:HI 0 "mask_reg_operand" "=k")
7542 (any_logic:HI (match_operand:HI 1 "mask_reg_operand" "k")
7543 (match_operand:HI 2 "mask_reg_operand" "k")))]
7545 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7546 [(set_attr "mode" "HI")
7547 (set_attr "type" "msklog")
7548 (set_attr "prefix" "vex")])
7550 (define_insn "*k<logic><mode>"
7551 [(set (match_operand:SWI48x 0 "mask_reg_operand" "=k")
7552 (any_logic:SWI48x (match_operand:SWI48x 1 "mask_reg_operand" "k")
7553 (match_operand:SWI48x 2 "mask_reg_operand" "k")))]
7555 "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7556 [(set_attr "mode" "<MODE>")
7557 (set_attr "type" "msklog")
7558 (set_attr "prefix" "vex")])
7560 ;; %%% This used to optimize known byte-wide and operations to memory,
7561 ;; and sometimes to QImode registers. If this is considered useful,
7562 ;; it should be done with splitters.
7564 (define_expand "and<mode>3"
7565 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7566 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7567 (match_operand:SWIM 2 "<general_szext_operand>")))]
7570 enum machine_mode mode = <MODE>mode;
7571 rtx (*insn) (rtx, rtx);
7573 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7575 HOST_WIDE_INT ival = INTVAL (operands[2]);
7577 if (ival == (HOST_WIDE_INT) 0xffffffff)
7579 else if (ival == 0xffff)
7581 else if (ival == 0xff)
7585 if (mode == <MODE>mode)
7587 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7591 if (<MODE>mode == DImode)
7592 insn = (mode == SImode)
7593 ? gen_zero_extendsidi2
7595 ? gen_zero_extendhidi2
7596 : gen_zero_extendqidi2;
7597 else if (<MODE>mode == SImode)
7598 insn = (mode == HImode)
7599 ? gen_zero_extendhisi2
7600 : gen_zero_extendqisi2;
7601 else if (<MODE>mode == HImode)
7602 insn = gen_zero_extendqihi2;
7606 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7610 (define_insn "*anddi_1"
7611 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7613 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7614 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7615 (clobber (reg:CC FLAGS_REG))]
7616 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7618 switch (get_attr_type (insn))
7624 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7627 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7628 if (get_attr_mode (insn) == MODE_SI)
7629 return "and{l}\t{%k2, %k0|%k0, %k2}";
7631 return "and{q}\t{%2, %0|%0, %2}";
7634 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7635 (set_attr "length_immediate" "*,*,*,0,0")
7636 (set (attr "prefix_rex")
7638 (and (eq_attr "type" "imovx")
7639 (and (match_test "INTVAL (operands[2]) == 0xff")
7640 (match_operand 1 "ext_QIreg_operand")))
7642 (const_string "*")))
7643 (set_attr "mode" "SI,DI,DI,SI,DI")])
7645 (define_insn "*andsi_1"
7646 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7647 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7648 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7649 (clobber (reg:CC FLAGS_REG))]
7650 "ix86_binary_operator_ok (AND, SImode, operands)"
7652 switch (get_attr_type (insn))
7658 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7662 return "and{l}\t{%2, %0|%0, %2}";
7665 [(set_attr "type" "alu,alu,imovx,msklog")
7666 (set (attr "prefix_rex")
7668 (and (eq_attr "type" "imovx")
7669 (and (match_test "INTVAL (operands[2]) == 0xff")
7670 (match_operand 1 "ext_QIreg_operand")))
7672 (const_string "*")))
7673 (set_attr "length_immediate" "*,*,0,0")
7674 (set_attr "mode" "SI")])
7676 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7677 (define_insn "*andsi_1_zext"
7678 [(set (match_operand:DI 0 "register_operand" "=r")
7680 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7681 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7682 (clobber (reg:CC FLAGS_REG))]
7683 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7684 "and{l}\t{%2, %k0|%k0, %2}"
7685 [(set_attr "type" "alu")
7686 (set_attr "mode" "SI")])
7688 (define_insn "*andhi_1"
7689 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7690 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7691 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7692 (clobber (reg:CC FLAGS_REG))]
7693 "ix86_binary_operator_ok (AND, HImode, operands)"
7695 switch (get_attr_type (insn))
7701 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705 return "and{w}\t{%2, %0|%0, %2}";
7708 [(set_attr "type" "alu,alu,imovx,msklog")
7709 (set_attr "length_immediate" "*,*,0,*")
7710 (set (attr "prefix_rex")
7712 (and (eq_attr "type" "imovx")
7713 (match_operand 1 "ext_QIreg_operand"))
7715 (const_string "*")))
7716 (set_attr "mode" "HI,HI,SI,HI")])
7718 ;; %%% Potential partial reg stall on alternative 2. What to do?
7719 (define_insn "*andqi_1"
7720 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7721 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7722 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7723 (clobber (reg:CC FLAGS_REG))]
7724 "ix86_binary_operator_ok (AND, QImode, operands)"
7726 switch (which_alternative)
7730 return "and{b}\t{%2, %0|%0, %2}";
7732 return "and{l}\t{%k2, %k0|%k0, %k2}";
7734 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7735 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7740 [(set_attr "type" "alu,alu,alu,msklog")
7741 (set_attr "mode" "QI,QI,SI,HI")])
7743 (define_insn "*andqi_1_slp"
7744 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7745 (and:QI (match_dup 0)
7746 (match_operand:QI 1 "general_operand" "qn,qmn")))
7747 (clobber (reg:CC FLAGS_REG))]
7748 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7749 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7750 "and{b}\t{%1, %0|%0, %1}"
7751 [(set_attr "type" "alu1")
7752 (set_attr "mode" "QI")])
7754 (define_insn "kandn<mode>"
7755 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7758 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7759 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7760 (clobber (reg:CC FLAGS_REG))]
7763 switch (which_alternative)
7766 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7770 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7771 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7773 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7778 [(set_attr "isa" "bmi,*,avx512f")
7779 (set_attr "type" "bitmanip,*,msklog")
7780 (set_attr "prefix" "*,*,vex")
7781 (set_attr "btver2_decode" "direct,*,*")
7782 (set_attr "mode" "<MODE>")])
7785 [(set (match_operand:SWI12 0 "general_reg_operand")
7789 (match_operand:SWI12 1 "general_reg_operand")))
7790 (clobber (reg:CC FLAGS_REG))]
7791 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7793 (not:HI (match_dup 0)))
7794 (parallel [(set (match_dup 0)
7795 (and:HI (match_dup 0)
7797 (clobber (reg:CC FLAGS_REG))])])
7799 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7801 [(set (match_operand:DI 0 "register_operand")
7802 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7803 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7804 (clobber (reg:CC FLAGS_REG))]
7806 [(parallel [(set (match_dup 0)
7807 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7808 (clobber (reg:CC FLAGS_REG))])]
7809 "operands[2] = gen_lowpart (SImode, operands[2]);")
7812 [(set (match_operand:SWI248 0 "register_operand")
7813 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7814 (match_operand:SWI248 2 "const_int_operand")))
7815 (clobber (reg:CC FLAGS_REG))]
7817 && true_regnum (operands[0]) != true_regnum (operands[1])"
7820 HOST_WIDE_INT ival = INTVAL (operands[2]);
7821 enum machine_mode mode;
7822 rtx (*insn) (rtx, rtx);
7824 if (ival == (HOST_WIDE_INT) 0xffffffff)
7826 else if (ival == 0xffff)
7830 gcc_assert (ival == 0xff);
7834 if (<MODE>mode == DImode)
7835 insn = (mode == SImode)
7836 ? gen_zero_extendsidi2
7838 ? gen_zero_extendhidi2
7839 : gen_zero_extendqidi2;
7842 if (<MODE>mode != SImode)
7843 /* Zero extend to SImode to avoid partial register stalls. */
7844 operands[0] = gen_lowpart (SImode, operands[0]);
7846 insn = (mode == HImode)
7847 ? gen_zero_extendhisi2
7848 : gen_zero_extendqisi2;
7850 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7855 [(set (match_operand 0 "register_operand")
7857 (const_int -65536)))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7860 || optimize_function_for_size_p (cfun)"
7861 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7862 "operands[1] = gen_lowpart (HImode, operands[0]);")
7865 [(set (match_operand 0 "ext_register_operand")
7868 (clobber (reg:CC FLAGS_REG))]
7869 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7870 && reload_completed"
7871 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7872 "operands[1] = gen_lowpart (QImode, operands[0]);")
7875 [(set (match_operand 0 "ext_register_operand")
7877 (const_int -65281)))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7880 && reload_completed"
7881 [(parallel [(set (zero_extract:SI (match_dup 0)
7885 (zero_extract:SI (match_dup 0)
7888 (zero_extract:SI (match_dup 0)
7891 (clobber (reg:CC FLAGS_REG))])]
7892 "operands[0] = gen_lowpart (SImode, operands[0]);")
7894 (define_insn "*anddi_2"
7895 [(set (reg FLAGS_REG)
7898 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7899 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7901 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7902 (and:DI (match_dup 1) (match_dup 2)))]
7904 && ix86_match_ccmode
7906 /* If we are going to emit andl instead of andq, and the operands[2]
7907 constant might have the SImode sign bit set, make sure the sign
7908 flag isn't tested, because the instruction will set the sign flag
7909 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7910 conservatively assume it might have bit 31 set. */
7911 (satisfies_constraint_Z (operands[2])
7912 && (!CONST_INT_P (operands[2])
7913 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7914 ? CCZmode : CCNOmode)
7915 && ix86_binary_operator_ok (AND, DImode, operands)"
7917 and{l}\t{%k2, %k0|%k0, %k2}
7918 and{q}\t{%2, %0|%0, %2}
7919 and{q}\t{%2, %0|%0, %2}"
7920 [(set_attr "type" "alu")
7921 (set_attr "mode" "SI,DI,DI")])
7923 (define_insn "*andqi_2_maybe_si"
7924 [(set (reg FLAGS_REG)
7926 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7927 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7929 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7930 (and:QI (match_dup 1) (match_dup 2)))]
7931 "ix86_binary_operator_ok (AND, QImode, operands)
7932 && ix86_match_ccmode (insn,
7933 CONST_INT_P (operands[2])
7934 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7936 if (which_alternative == 2)
7938 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7939 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7940 return "and{l}\t{%2, %k0|%k0, %2}";
7942 return "and{b}\t{%2, %0|%0, %2}";
7944 [(set_attr "type" "alu")
7945 (set_attr "mode" "QI,QI,SI")])
7947 (define_insn "*and<mode>_2"
7948 [(set (reg FLAGS_REG)
7949 (compare (and:SWI124
7950 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7951 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7953 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7954 (and:SWI124 (match_dup 1) (match_dup 2)))]
7955 "ix86_match_ccmode (insn, CCNOmode)
7956 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7957 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7958 [(set_attr "type" "alu")
7959 (set_attr "mode" "<MODE>")])
7961 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7962 (define_insn "*andsi_2_zext"
7963 [(set (reg FLAGS_REG)
7965 (match_operand:SI 1 "nonimmediate_operand" "%0")
7966 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7968 (set (match_operand:DI 0 "register_operand" "=r")
7969 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7970 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7971 && ix86_binary_operator_ok (AND, SImode, operands)"
7972 "and{l}\t{%2, %k0|%k0, %2}"
7973 [(set_attr "type" "alu")
7974 (set_attr "mode" "SI")])
7976 (define_insn "*andqi_2_slp"
7977 [(set (reg FLAGS_REG)
7979 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7980 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7982 (set (strict_low_part (match_dup 0))
7983 (and:QI (match_dup 0) (match_dup 1)))]
7984 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7985 && ix86_match_ccmode (insn, CCNOmode)
7986 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7987 "and{b}\t{%1, %0|%0, %1}"
7988 [(set_attr "type" "alu1")
7989 (set_attr "mode" "QI")])
7991 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7992 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7993 ;; for a QImode operand, which of course failed.
7994 (define_insn "andqi_ext_0"
7995 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8000 (match_operand 1 "ext_register_operand" "0")
8003 (match_operand 2 "const_int_operand" "n")))
8004 (clobber (reg:CC FLAGS_REG))]
8006 "and{b}\t{%2, %h0|%h0, %2}"
8007 [(set_attr "type" "alu")
8008 (set_attr "length_immediate" "1")
8009 (set_attr "modrm" "1")
8010 (set_attr "mode" "QI")])
8012 ;; Generated by peephole translating test to and. This shows up
8013 ;; often in fp comparisons.
8014 (define_insn "*andqi_ext_0_cc"
8015 [(set (reg FLAGS_REG)
8019 (match_operand 1 "ext_register_operand" "0")
8022 (match_operand 2 "const_int_operand" "n"))
8024 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8033 "ix86_match_ccmode (insn, CCNOmode)"
8034 "and{b}\t{%2, %h0|%h0, %2}"
8035 [(set_attr "type" "alu")
8036 (set_attr "length_immediate" "1")
8037 (set_attr "modrm" "1")
8038 (set_attr "mode" "QI")])
8040 (define_insn "*andqi_ext_1"
8041 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8046 (match_operand 1 "ext_register_operand" "0,0")
8050 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8051 (clobber (reg:CC FLAGS_REG))]
8053 "and{b}\t{%2, %h0|%h0, %2}"
8054 [(set_attr "isa" "*,nox64")
8055 (set_attr "type" "alu")
8056 (set_attr "length_immediate" "0")
8057 (set_attr "mode" "QI")])
8059 (define_insn "*andqi_ext_2"
8060 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8065 (match_operand 1 "ext_register_operand" "%0")
8069 (match_operand 2 "ext_register_operand" "Q")
8072 (clobber (reg:CC FLAGS_REG))]
8074 "and{b}\t{%h2, %h0|%h0, %h2}"
8075 [(set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8079 ;; Convert wide AND instructions with immediate operand to shorter QImode
8080 ;; equivalents when possible.
8081 ;; Don't do the splitting with memory operands, since it introduces risk
8082 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8083 ;; for size, but that can (should?) be handled by generic code instead.
8085 [(set (match_operand 0 "register_operand")
8086 (and (match_operand 1 "register_operand")
8087 (match_operand 2 "const_int_operand")))
8088 (clobber (reg:CC FLAGS_REG))]
8090 && QI_REG_P (operands[0])
8091 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8092 && !(~INTVAL (operands[2]) & ~(255 << 8))
8093 && GET_MODE (operands[0]) != QImode"
8094 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8095 (and:SI (zero_extract:SI (match_dup 1)
8096 (const_int 8) (const_int 8))
8098 (clobber (reg:CC FLAGS_REG))])]
8100 operands[0] = gen_lowpart (SImode, operands[0]);
8101 operands[1] = gen_lowpart (SImode, operands[1]);
8102 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8105 ;; Since AND can be encoded with sign extended immediate, this is only
8106 ;; profitable when 7th bit is not set.
8108 [(set (match_operand 0 "register_operand")
8109 (and (match_operand 1 "general_operand")
8110 (match_operand 2 "const_int_operand")))
8111 (clobber (reg:CC FLAGS_REG))]
8113 && ANY_QI_REG_P (operands[0])
8114 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8115 && !(~INTVAL (operands[2]) & ~255)
8116 && !(INTVAL (operands[2]) & 128)
8117 && GET_MODE (operands[0]) != QImode"
8118 [(parallel [(set (strict_low_part (match_dup 0))
8119 (and:QI (match_dup 1)
8121 (clobber (reg:CC FLAGS_REG))])]
8123 operands[0] = gen_lowpart (QImode, operands[0]);
8124 operands[1] = gen_lowpart (QImode, operands[1]);
8125 operands[2] = gen_lowpart (QImode, operands[2]);
8128 ;; Logical inclusive and exclusive OR instructions
8130 ;; %%% This used to optimize known byte-wide and operations to memory.
8131 ;; If this is considered useful, it should be done with splitters.
8133 (define_expand "<code><mode>3"
8134 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8135 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8136 (match_operand:SWIM 2 "<general_operand>")))]
8138 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8140 (define_insn "*<code><mode>_1"
8141 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8143 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8144 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8145 (clobber (reg:CC FLAGS_REG))]
8146 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8148 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8149 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8150 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8151 [(set_attr "type" "alu,alu,msklog")
8152 (set_attr "mode" "<MODE>")])
8154 (define_insn "*<code>hi_1"
8155 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8157 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8158 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8159 (clobber (reg:CC FLAGS_REG))]
8160 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8162 <logic>{w}\t{%2, %0|%0, %2}
8163 <logic>{w}\t{%2, %0|%0, %2}
8164 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8165 [(set_attr "type" "alu,alu,msklog")
8166 (set_attr "mode" "HI")])
8168 ;; %%% Potential partial reg stall on alternative 2. What to do?
8169 (define_insn "*<code>qi_1"
8170 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8171 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8172 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8173 (clobber (reg:CC FLAGS_REG))]
8174 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8176 <logic>{b}\t{%2, %0|%0, %2}
8177 <logic>{b}\t{%2, %0|%0, %2}
8178 <logic>{l}\t{%k2, %k0|%k0, %k2}
8179 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8180 [(set_attr "type" "alu,alu,alu,msklog")
8181 (set_attr "mode" "QI,QI,SI,HI")])
8183 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8184 (define_insn "*<code>si_1_zext"
8185 [(set (match_operand:DI 0 "register_operand" "=r")
8187 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8188 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8189 (clobber (reg:CC FLAGS_REG))]
8190 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8191 "<logic>{l}\t{%2, %k0|%k0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "SI")])
8195 (define_insn "*<code>si_1_zext_imm"
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8198 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8199 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202 "<logic>{l}\t{%2, %k0|%k0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "SI")])
8206 (define_insn "*<code>qi_1_slp"
8207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8208 (any_or:QI (match_dup 0)
8209 (match_operand:QI 1 "general_operand" "qmn,qn")))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8212 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8213 "<logic>{b}\t{%1, %0|%0, %1}"
8214 [(set_attr "type" "alu1")
8215 (set_attr "mode" "QI")])
8217 (define_insn "*<code><mode>_2"
8218 [(set (reg FLAGS_REG)
8219 (compare (any_or:SWI
8220 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8221 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8223 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8224 (any_or:SWI (match_dup 1) (match_dup 2)))]
8225 "ix86_match_ccmode (insn, CCNOmode)
8226 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8227 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8228 [(set_attr "type" "alu")
8229 (set_attr "mode" "<MODE>")])
8231 (define_insn "kxnor<mode>"
8232 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8235 (match_operand:SWI12 1 "register_operand" "0,k")
8236 (match_operand:SWI12 2 "register_operand" "r,k"))))
8237 (clobber (reg:CC FLAGS_REG))]
8240 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8241 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8242 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8244 [(set_attr "type" "*,msklog")
8245 (set_attr "prefix" "*,vex")
8246 (set_attr "mode" "<MODE>")])
8248 (define_insn "kxnor<mode>"
8249 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8252 (match_operand:SWI48x 1 "register_operand" "0,k")
8253 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8254 (clobber (reg:CC FLAGS_REG))]
8258 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8259 [(set_attr "type" "*,msklog")
8260 (set_attr "prefix" "*,vex")
8261 (set_attr "mode" "<MODE>")])
8264 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8268 (match_operand:SWI1248x 1 "general_reg_operand"))))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "TARGET_AVX512F && reload_completed"
8271 [(parallel [(set (match_dup 0)
8272 (xor:HI (match_dup 0)
8274 (clobber (reg:CC FLAGS_REG))])
8276 (not:HI (match_dup 0)))])
8278 ;;There are kortrest[bdq] but no intrinsics for them.
8279 ;;We probably don't need to implement them.
8280 (define_insn "kortestzhi"
8281 [(set (reg:CCZ FLAGS_REG)
8284 (match_operand:HI 0 "register_operand" "k")
8285 (match_operand:HI 1 "register_operand" "k"))
8287 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8288 "kortestw\t{%1, %0|%0, %1}"
8289 [(set_attr "mode" "HI")
8290 (set_attr "type" "msklog")
8291 (set_attr "prefix" "vex")])
8293 (define_insn "kortestchi"
8294 [(set (reg:CCC FLAGS_REG)
8297 (match_operand:HI 0 "register_operand" "k")
8298 (match_operand:HI 1 "register_operand" "k"))
8300 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8301 "kortestw\t{%1, %0|%0, %1}"
8302 [(set_attr "mode" "HI")
8303 (set_attr "type" "msklog")
8304 (set_attr "prefix" "vex")])
8306 (define_insn "kunpckhi"
8307 [(set (match_operand:HI 0 "register_operand" "=k")
8310 (match_operand:HI 1 "register_operand" "k")
8312 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8314 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8315 [(set_attr "mode" "HI")
8316 (set_attr "type" "msklog")
8317 (set_attr "prefix" "vex")])
8319 (define_insn "kunpcksi"
8320 [(set (match_operand:SI 0 "register_operand" "=k")
8323 (match_operand:SI 1 "register_operand" "k")
8325 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8327 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8328 [(set_attr "mode" "SI")])
8330 (define_insn "kunpckdi"
8331 [(set (match_operand:DI 0 "register_operand" "=k")
8334 (match_operand:DI 1 "register_operand" "k")
8336 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8338 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8339 [(set_attr "mode" "DI")])
8341 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8342 ;; ??? Special case for immediate operand is missing - it is tricky.
8343 (define_insn "*<code>si_2_zext"
8344 [(set (reg FLAGS_REG)
8345 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8346 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8348 (set (match_operand:DI 0 "register_operand" "=r")
8349 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8350 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8352 "<logic>{l}\t{%2, %k0|%k0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "SI")])
8356 (define_insn "*<code>si_2_zext_imm"
8357 [(set (reg FLAGS_REG)
8359 (match_operand:SI 1 "nonimmediate_operand" "%0")
8360 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8362 (set (match_operand:DI 0 "register_operand" "=r")
8363 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8364 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8365 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8366 "<logic>{l}\t{%2, %k0|%k0, %2}"
8367 [(set_attr "type" "alu")
8368 (set_attr "mode" "SI")])
8370 (define_insn "*<code>qi_2_slp"
8371 [(set (reg FLAGS_REG)
8372 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8373 (match_operand:QI 1 "general_operand" "qmn,qn"))
8375 (set (strict_low_part (match_dup 0))
8376 (any_or:QI (match_dup 0) (match_dup 1)))]
8377 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8378 && ix86_match_ccmode (insn, CCNOmode)
8379 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8380 "<logic>{b}\t{%1, %0|%0, %1}"
8381 [(set_attr "type" "alu1")
8382 (set_attr "mode" "QI")])
8384 (define_insn "*<code><mode>_3"
8385 [(set (reg FLAGS_REG)
8386 (compare (any_or:SWI
8387 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8388 (match_operand:SWI 2 "<general_operand>" "<g>"))
8390 (clobber (match_scratch:SWI 0 "=<r>"))]
8391 "ix86_match_ccmode (insn, CCNOmode)
8392 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8393 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "mode" "<MODE>")])
8397 (define_insn "*<code>qi_ext_0"
8398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403 (match_operand 1 "ext_register_operand" "0")
8406 (match_operand 2 "const_int_operand" "n")))
8407 (clobber (reg:CC FLAGS_REG))]
8408 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8409 "<logic>{b}\t{%2, %h0|%h0, %2}"
8410 [(set_attr "type" "alu")
8411 (set_attr "length_immediate" "1")
8412 (set_attr "modrm" "1")
8413 (set_attr "mode" "QI")])
8415 (define_insn "*<code>qi_ext_1"
8416 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8421 (match_operand 1 "ext_register_operand" "0,0")
8425 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8426 (clobber (reg:CC FLAGS_REG))]
8427 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8428 "<logic>{b}\t{%2, %h0|%h0, %2}"
8429 [(set_attr "isa" "*,nox64")
8430 (set_attr "type" "alu")
8431 (set_attr "length_immediate" "0")
8432 (set_attr "mode" "QI")])
8434 (define_insn "*<code>qi_ext_2"
8435 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8439 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8442 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8445 (clobber (reg:CC FLAGS_REG))]
8446 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8447 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8448 [(set_attr "type" "alu")
8449 (set_attr "length_immediate" "0")
8450 (set_attr "mode" "QI")])
8453 [(set (match_operand 0 "register_operand")
8454 (any_or (match_operand 1 "register_operand")
8455 (match_operand 2 "const_int_operand")))
8456 (clobber (reg:CC FLAGS_REG))]
8458 && QI_REG_P (operands[0])
8459 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8460 && !(INTVAL (operands[2]) & ~(255 << 8))
8461 && GET_MODE (operands[0]) != QImode"
8462 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8463 (any_or:SI (zero_extract:SI (match_dup 1)
8464 (const_int 8) (const_int 8))
8466 (clobber (reg:CC FLAGS_REG))])]
8468 operands[0] = gen_lowpart (SImode, operands[0]);
8469 operands[1] = gen_lowpart (SImode, operands[1]);
8470 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8473 ;; Since OR can be encoded with sign extended immediate, this is only
8474 ;; profitable when 7th bit is set.
8476 [(set (match_operand 0 "register_operand")
8477 (any_or (match_operand 1 "general_operand")
8478 (match_operand 2 "const_int_operand")))
8479 (clobber (reg:CC FLAGS_REG))]
8481 && ANY_QI_REG_P (operands[0])
8482 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8483 && !(INTVAL (operands[2]) & ~255)
8484 && (INTVAL (operands[2]) & 128)
8485 && GET_MODE (operands[0]) != QImode"
8486 [(parallel [(set (strict_low_part (match_dup 0))
8487 (any_or:QI (match_dup 1)
8489 (clobber (reg:CC FLAGS_REG))])]
8491 operands[0] = gen_lowpart (QImode, operands[0]);
8492 operands[1] = gen_lowpart (QImode, operands[1]);
8493 operands[2] = gen_lowpart (QImode, operands[2]);
8496 (define_expand "xorqi_cc_ext_1"
8498 (set (reg:CCNO FLAGS_REG)
8502 (match_operand 1 "ext_register_operand")
8505 (match_operand:QI 2 "const_int_operand"))
8507 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8517 (define_insn "*xorqi_cc_ext_1"
8518 [(set (reg FLAGS_REG)
8522 (match_operand 1 "ext_register_operand" "0,0")
8525 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8527 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8536 "ix86_match_ccmode (insn, CCNOmode)"
8537 "xor{b}\t{%2, %h0|%h0, %2}"
8538 [(set_attr "isa" "*,nox64")
8539 (set_attr "type" "alu")
8540 (set_attr "modrm" "1")
8541 (set_attr "mode" "QI")])
8543 ;; Negation instructions
8545 (define_expand "neg<mode>2"
8546 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8547 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8549 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8551 (define_insn_and_split "*neg<dwi>2_doubleword"
8552 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8553 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8559 [(set (reg:CCZ FLAGS_REG)
8560 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8561 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8564 (plus:DWIH (match_dup 3)
8565 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8567 (clobber (reg:CC FLAGS_REG))])
8570 (neg:DWIH (match_dup 2)))
8571 (clobber (reg:CC FLAGS_REG))])]
8572 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8574 (define_insn "*neg<mode>2_1"
8575 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8576 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8579 "neg{<imodesuffix>}\t%0"
8580 [(set_attr "type" "negnot")
8581 (set_attr "mode" "<MODE>")])
8583 ;; Combine is quite creative about this pattern.
8584 (define_insn "*negsi2_1_zext"
8585 [(set (match_operand:DI 0 "register_operand" "=r")
8587 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8590 (clobber (reg:CC FLAGS_REG))]
8591 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8593 [(set_attr "type" "negnot")
8594 (set_attr "mode" "SI")])
8596 ;; The problem with neg is that it does not perform (compare x 0),
8597 ;; it really performs (compare 0 x), which leaves us with the zero
8598 ;; flag being the only useful item.
8600 (define_insn "*neg<mode>2_cmpz"
8601 [(set (reg:CCZ FLAGS_REG)
8603 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8605 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8606 (neg:SWI (match_dup 1)))]
8607 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8608 "neg{<imodesuffix>}\t%0"
8609 [(set_attr "type" "negnot")
8610 (set_attr "mode" "<MODE>")])
8612 (define_insn "*negsi2_cmpz_zext"
8613 [(set (reg:CCZ FLAGS_REG)
8617 (match_operand:DI 1 "register_operand" "0")
8621 (set (match_operand:DI 0 "register_operand" "=r")
8622 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8625 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8627 [(set_attr "type" "negnot")
8628 (set_attr "mode" "SI")])
8630 ;; Negate with jump on overflow.
8631 (define_expand "negv<mode>3"
8632 [(parallel [(set (reg:CCO FLAGS_REG)
8633 (ne:CCO (match_operand:SWI 1 "register_operand")
8635 (set (match_operand:SWI 0 "register_operand")
8636 (neg:SWI (match_dup 1)))])
8637 (set (pc) (if_then_else
8638 (eq (reg:CCO FLAGS_REG) (const_int 0))
8639 (label_ref (match_operand 2))
8644 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8648 (define_insn "*negv<mode>3"
8649 [(set (reg:CCO FLAGS_REG)
8650 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8651 (match_operand:SWI 2 "const_int_operand")))
8652 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8653 (neg:SWI (match_dup 1)))]
8654 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8655 && mode_signbit_p (<MODE>mode, operands[2])"
8656 "neg{<imodesuffix>}\t%0"
8657 [(set_attr "type" "negnot")
8658 (set_attr "mode" "<MODE>")])
8660 ;; Changing of sign for FP values is doable using integer unit too.
8662 (define_expand "<code><mode>2"
8663 [(set (match_operand:X87MODEF 0 "register_operand")
8664 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8665 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8666 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8668 (define_insn "*absneg<mode>2_mixed"
8669 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8670 (match_operator:MODEF 3 "absneg_operator"
8671 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8672 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8677 (define_insn "*absneg<mode>2_sse"
8678 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8679 (match_operator:MODEF 3 "absneg_operator"
8680 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8681 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8682 (clobber (reg:CC FLAGS_REG))]
8683 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8686 (define_insn "*absneg<mode>2_i387"
8687 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8688 (match_operator:X87MODEF 3 "absneg_operator"
8689 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8690 (use (match_operand 2))
8691 (clobber (reg:CC FLAGS_REG))]
8692 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8695 (define_expand "<code>tf2"
8696 [(set (match_operand:TF 0 "register_operand")
8697 (absneg:TF (match_operand:TF 1 "register_operand")))]
8699 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8701 (define_insn "*absnegtf2_sse"
8702 [(set (match_operand:TF 0 "register_operand" "=x,x")
8703 (match_operator:TF 3 "absneg_operator"
8704 [(match_operand:TF 1 "register_operand" "0,x")]))
8705 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8706 (clobber (reg:CC FLAGS_REG))]
8710 ;; Splitters for fp abs and neg.
8713 [(set (match_operand 0 "fp_register_operand")
8714 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8715 (use (match_operand 2))
8716 (clobber (reg:CC FLAGS_REG))]
8718 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8721 [(set (match_operand 0 "register_operand")
8722 (match_operator 3 "absneg_operator"
8723 [(match_operand 1 "register_operand")]))
8724 (use (match_operand 2 "nonimmediate_operand"))
8725 (clobber (reg:CC FLAGS_REG))]
8726 "reload_completed && SSE_REG_P (operands[0])"
8727 [(set (match_dup 0) (match_dup 3))]
8729 enum machine_mode mode = GET_MODE (operands[0]);
8730 enum machine_mode vmode = GET_MODE (operands[2]);
8733 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8734 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8735 if (operands_match_p (operands[0], operands[2]))
8738 operands[1] = operands[2];
8741 if (GET_CODE (operands[3]) == ABS)
8742 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8744 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8749 [(set (match_operand:SF 0 "register_operand")
8750 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8751 (use (match_operand:V4SF 2))
8752 (clobber (reg:CC FLAGS_REG))]
8754 [(parallel [(set (match_dup 0) (match_dup 1))
8755 (clobber (reg:CC FLAGS_REG))])]
8758 operands[0] = gen_lowpart (SImode, operands[0]);
8759 if (GET_CODE (operands[1]) == ABS)
8761 tmp = gen_int_mode (0x7fffffff, SImode);
8762 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8766 tmp = gen_int_mode (0x80000000, SImode);
8767 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8773 [(set (match_operand:DF 0 "register_operand")
8774 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8775 (use (match_operand 2))
8776 (clobber (reg:CC FLAGS_REG))]
8778 [(parallel [(set (match_dup 0) (match_dup 1))
8779 (clobber (reg:CC FLAGS_REG))])]
8784 tmp = gen_lowpart (DImode, operands[0]);
8785 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8788 if (GET_CODE (operands[1]) == ABS)
8791 tmp = gen_rtx_NOT (DImode, tmp);
8795 operands[0] = gen_highpart (SImode, operands[0]);
8796 if (GET_CODE (operands[1]) == ABS)
8798 tmp = gen_int_mode (0x7fffffff, SImode);
8799 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8803 tmp = gen_int_mode (0x80000000, SImode);
8804 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8811 [(set (match_operand:XF 0 "register_operand")
8812 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8813 (use (match_operand 2))
8814 (clobber (reg:CC FLAGS_REG))]
8816 [(parallel [(set (match_dup 0) (match_dup 1))
8817 (clobber (reg:CC FLAGS_REG))])]
8820 operands[0] = gen_rtx_REG (SImode,
8821 true_regnum (operands[0])
8822 + (TARGET_64BIT ? 1 : 2));
8823 if (GET_CODE (operands[1]) == ABS)
8825 tmp = GEN_INT (0x7fff);
8826 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8830 tmp = GEN_INT (0x8000);
8831 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8836 ;; Conditionalize these after reload. If they match before reload, we
8837 ;; lose the clobber and ability to use integer instructions.
8839 (define_insn "*<code><mode>2_1"
8840 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8841 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8843 && (reload_completed
8844 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8845 "f<absneg_mnemonic>"
8846 [(set_attr "type" "fsgn")
8847 (set_attr "mode" "<MODE>")])
8849 (define_insn "*<code>extendsfdf2"
8850 [(set (match_operand:DF 0 "register_operand" "=f")
8851 (absneg:DF (float_extend:DF
8852 (match_operand:SF 1 "register_operand" "0"))))]
8853 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8854 "f<absneg_mnemonic>"
8855 [(set_attr "type" "fsgn")
8856 (set_attr "mode" "DF")])
8858 (define_insn "*<code>extendsfxf2"
8859 [(set (match_operand:XF 0 "register_operand" "=f")
8860 (absneg:XF (float_extend:XF
8861 (match_operand:SF 1 "register_operand" "0"))))]
8863 "f<absneg_mnemonic>"
8864 [(set_attr "type" "fsgn")
8865 (set_attr "mode" "XF")])
8867 (define_insn "*<code>extenddfxf2"
8868 [(set (match_operand:XF 0 "register_operand" "=f")
8869 (absneg:XF (float_extend:XF
8870 (match_operand:DF 1 "register_operand" "0"))))]
8872 "f<absneg_mnemonic>"
8873 [(set_attr "type" "fsgn")
8874 (set_attr "mode" "XF")])
8876 ;; Copysign instructions
8878 (define_mode_iterator CSGNMODE [SF DF TF])
8879 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8881 (define_expand "copysign<mode>3"
8882 [(match_operand:CSGNMODE 0 "register_operand")
8883 (match_operand:CSGNMODE 1 "nonmemory_operand")
8884 (match_operand:CSGNMODE 2 "register_operand")]
8885 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8886 || (TARGET_SSE && (<MODE>mode == TFmode))"
8887 "ix86_expand_copysign (operands); DONE;")
8889 (define_insn_and_split "copysign<mode>3_const"
8890 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8892 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8893 (match_operand:CSGNMODE 2 "register_operand" "0")
8894 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8896 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8897 || (TARGET_SSE && (<MODE>mode == TFmode))"
8899 "&& reload_completed"
8901 "ix86_split_copysign_const (operands); DONE;")
8903 (define_insn "copysign<mode>3_var"
8904 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8906 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8907 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8908 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8909 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8911 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8912 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8913 || (TARGET_SSE && (<MODE>mode == TFmode))"
8917 [(set (match_operand:CSGNMODE 0 "register_operand")
8919 [(match_operand:CSGNMODE 2 "register_operand")
8920 (match_operand:CSGNMODE 3 "register_operand")
8921 (match_operand:<CSGNVMODE> 4)
8922 (match_operand:<CSGNVMODE> 5)]
8924 (clobber (match_scratch:<CSGNVMODE> 1))]
8925 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8926 || (TARGET_SSE && (<MODE>mode == TFmode)))
8927 && reload_completed"
8929 "ix86_split_copysign_var (operands); DONE;")
8931 ;; One complement instructions
8933 (define_expand "one_cmpl<mode>2"
8934 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8935 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8937 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8939 (define_insn "*one_cmpl<mode>2_1"
8940 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8941 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8942 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8944 not{<imodesuffix>}\t%0
8945 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8946 [(set_attr "isa" "*,avx512bw")
8947 (set_attr "type" "negnot,msklog")
8948 (set_attr "prefix" "*,vex")
8949 (set_attr "mode" "<MODE>")])
8951 (define_insn "*one_cmplhi2_1"
8952 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8953 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8954 "ix86_unary_operator_ok (NOT, HImode, operands)"
8957 knotw\t{%1, %0|%0, %1}"
8958 [(set_attr "isa" "*,avx512f")
8959 (set_attr "type" "negnot,msklog")
8960 (set_attr "prefix" "*,vex")
8961 (set_attr "mode" "HI")])
8963 ;; %%% Potential partial reg stall on alternative 1. What to do?
8964 (define_insn "*one_cmplqi2_1"
8965 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8966 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8967 "ix86_unary_operator_ok (NOT, QImode, operands)"
8969 switch (which_alternative)
8972 return "not{b}\t%0";
8974 return "not{l}\t%k0";
8976 if (TARGET_AVX512DQ)
8977 return "knotb\t{%1, %0|%0, %1}";
8978 return "knotw\t{%1, %0|%0, %1}";
8983 [(set_attr "isa" "*,*,avx512f")
8984 (set_attr "type" "negnot,negnot,msklog")
8985 (set_attr "prefix" "*,*,vex")
8986 (set_attr "mode" "QI,SI,QI")])
8988 ;; ??? Currently never generated - xor is used instead.
8989 (define_insn "*one_cmplsi2_1_zext"
8990 [(set (match_operand:DI 0 "register_operand" "=r")
8992 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8993 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8995 [(set_attr "type" "negnot")
8996 (set_attr "mode" "SI")])
8998 (define_insn "*one_cmpl<mode>2_2"
8999 [(set (reg FLAGS_REG)
9000 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9002 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9003 (not:SWI (match_dup 1)))]
9004 "ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9007 [(set_attr "type" "alu1")
9008 (set_attr "mode" "<MODE>")])
9011 [(set (match_operand 0 "flags_reg_operand")
9012 (match_operator 2 "compare_operator"
9013 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9015 (set (match_operand:SWI 1 "nonimmediate_operand")
9016 (not:SWI (match_dup 3)))]
9017 "ix86_match_ccmode (insn, CCNOmode)"
9018 [(parallel [(set (match_dup 0)
9019 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9022 (xor:SWI (match_dup 3) (const_int -1)))])])
9024 ;; ??? Currently never generated - xor is used instead.
9025 (define_insn "*one_cmplsi2_2_zext"
9026 [(set (reg FLAGS_REG)
9027 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9029 (set (match_operand:DI 0 "register_operand" "=r")
9030 (zero_extend:DI (not:SI (match_dup 1))))]
9031 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9032 && ix86_unary_operator_ok (NOT, SImode, operands)"
9034 [(set_attr "type" "alu1")
9035 (set_attr "mode" "SI")])
9038 [(set (match_operand 0 "flags_reg_operand")
9039 (match_operator 2 "compare_operator"
9040 [(not:SI (match_operand:SI 3 "register_operand"))
9042 (set (match_operand:DI 1 "register_operand")
9043 (zero_extend:DI (not:SI (match_dup 3))))]
9044 "ix86_match_ccmode (insn, CCNOmode)"
9045 [(parallel [(set (match_dup 0)
9046 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9049 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9051 ;; Shift instructions
9053 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9054 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9055 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9056 ;; from the assembler input.
9058 ;; This instruction shifts the target reg/mem as usual, but instead of
9059 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9060 ;; is a left shift double, bits are taken from the high order bits of
9061 ;; reg, else if the insn is a shift right double, bits are taken from the
9062 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9063 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9065 ;; Since sh[lr]d does not change the `reg' operand, that is done
9066 ;; separately, making all shifts emit pairs of shift double and normal
9067 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9068 ;; support a 63 bit shift, each shift where the count is in a reg expands
9069 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9071 ;; If the shift count is a constant, we need never emit more than one
9072 ;; shift pair, instead using moves and sign extension for counts greater
9075 (define_expand "ashl<mode>3"
9076 [(set (match_operand:SDWIM 0 "<shift_operand>")
9077 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9078 (match_operand:QI 2 "nonmemory_operand")))]
9080 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9082 (define_insn "*ashl<mode>3_doubleword"
9083 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9084 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9085 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9086 (clobber (reg:CC FLAGS_REG))]
9089 [(set_attr "type" "multi")])
9092 [(set (match_operand:DWI 0 "register_operand")
9093 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9094 (match_operand:QI 2 "nonmemory_operand")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9098 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9100 ;; By default we don't ask for a scratch register, because when DWImode
9101 ;; values are manipulated, registers are already at a premium. But if
9102 ;; we have one handy, we won't turn it away.
9105 [(match_scratch:DWIH 3 "r")
9106 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9108 (match_operand:<DWI> 1 "nonmemory_operand")
9109 (match_operand:QI 2 "nonmemory_operand")))
9110 (clobber (reg:CC FLAGS_REG))])
9114 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9116 (define_insn "x86_64_shld"
9117 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9118 (ior:DI (ashift:DI (match_dup 0)
9119 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9120 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9121 (minus:QI (const_int 64) (match_dup 2)))))
9122 (clobber (reg:CC FLAGS_REG))]
9124 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9125 [(set_attr "type" "ishift")
9126 (set_attr "prefix_0f" "1")
9127 (set_attr "mode" "DI")
9128 (set_attr "athlon_decode" "vector")
9129 (set_attr "amdfam10_decode" "vector")
9130 (set_attr "bdver1_decode" "vector")])
9132 (define_insn "x86_shld"
9133 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9134 (ior:SI (ashift:SI (match_dup 0)
9135 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9136 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9137 (minus:QI (const_int 32) (match_dup 2)))))
9138 (clobber (reg:CC FLAGS_REG))]
9140 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9141 [(set_attr "type" "ishift")
9142 (set_attr "prefix_0f" "1")
9143 (set_attr "mode" "SI")
9144 (set_attr "pent_pair" "np")
9145 (set_attr "athlon_decode" "vector")
9146 (set_attr "amdfam10_decode" "vector")
9147 (set_attr "bdver1_decode" "vector")])
9149 (define_expand "x86_shift<mode>_adj_1"
9150 [(set (reg:CCZ FLAGS_REG)
9151 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9154 (set (match_operand:SWI48 0 "register_operand")
9155 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9156 (match_operand:SWI48 1 "register_operand")
9159 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9160 (match_operand:SWI48 3 "register_operand")
9163 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9165 (define_expand "x86_shift<mode>_adj_2"
9166 [(use (match_operand:SWI48 0 "register_operand"))
9167 (use (match_operand:SWI48 1 "register_operand"))
9168 (use (match_operand:QI 2 "register_operand"))]
9171 rtx label = gen_label_rtx ();
9174 emit_insn (gen_testqi_ccz_1 (operands[2],
9175 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9177 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9178 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9179 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9180 gen_rtx_LABEL_REF (VOIDmode, label),
9182 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9183 JUMP_LABEL (tmp) = label;
9185 emit_move_insn (operands[0], operands[1]);
9186 ix86_expand_clear (operands[1]);
9189 LABEL_NUSES (label) = 1;
9194 ;; Avoid useless masking of count operand.
9195 (define_insn "*ashl<mode>3_mask"
9196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9198 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9201 (match_operand:SI 2 "register_operand" "c")
9202 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9203 (clobber (reg:CC FLAGS_REG))]
9204 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9205 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9206 == GET_MODE_BITSIZE (<MODE>mode)-1"
9208 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9210 [(set_attr "type" "ishift")
9211 (set_attr "mode" "<MODE>")])
9213 (define_insn "*bmi2_ashl<mode>3_1"
9214 [(set (match_operand:SWI48 0 "register_operand" "=r")
9215 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9216 (match_operand:SWI48 2 "register_operand" "r")))]
9218 "shlx\t{%2, %1, %0|%0, %1, %2}"
9219 [(set_attr "type" "ishiftx")
9220 (set_attr "mode" "<MODE>")])
9222 (define_insn "*ashl<mode>3_1"
9223 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9224 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9225 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9229 switch (get_attr_type (insn))
9236 gcc_assert (operands[2] == const1_rtx);
9237 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9238 return "add{<imodesuffix>}\t%0, %0";
9241 if (operands[2] == const1_rtx
9242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9243 return "sal{<imodesuffix>}\t%0";
9245 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9248 [(set_attr "isa" "*,*,bmi2")
9250 (cond [(eq_attr "alternative" "1")
9251 (const_string "lea")
9252 (eq_attr "alternative" "2")
9253 (const_string "ishiftx")
9254 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9255 (match_operand 0 "register_operand"))
9256 (match_operand 2 "const1_operand"))
9257 (const_string "alu")
9259 (const_string "ishift")))
9260 (set (attr "length_immediate")
9262 (ior (eq_attr "type" "alu")
9263 (and (eq_attr "type" "ishift")
9264 (and (match_operand 2 "const1_operand")
9265 (ior (match_test "TARGET_SHIFT1")
9266 (match_test "optimize_function_for_size_p (cfun)")))))
9268 (const_string "*")))
9269 (set_attr "mode" "<MODE>")])
9271 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9273 [(set (match_operand:SWI48 0 "register_operand")
9274 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9275 (match_operand:QI 2 "register_operand")))
9276 (clobber (reg:CC FLAGS_REG))]
9277 "TARGET_BMI2 && reload_completed"
9279 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9280 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9282 (define_insn "*bmi2_ashlsi3_1_zext"
9283 [(set (match_operand:DI 0 "register_operand" "=r")
9285 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9286 (match_operand:SI 2 "register_operand" "r"))))]
9287 "TARGET_64BIT && TARGET_BMI2"
9288 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9289 [(set_attr "type" "ishiftx")
9290 (set_attr "mode" "SI")])
9292 (define_insn "*ashlsi3_1_zext"
9293 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9295 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9296 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9297 (clobber (reg:CC FLAGS_REG))]
9298 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9300 switch (get_attr_type (insn))
9307 gcc_assert (operands[2] == const1_rtx);
9308 return "add{l}\t%k0, %k0";
9311 if (operands[2] == const1_rtx
9312 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313 return "sal{l}\t%k0";
9315 return "sal{l}\t{%2, %k0|%k0, %2}";
9318 [(set_attr "isa" "*,*,bmi2")
9320 (cond [(eq_attr "alternative" "1")
9321 (const_string "lea")
9322 (eq_attr "alternative" "2")
9323 (const_string "ishiftx")
9324 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9325 (match_operand 2 "const1_operand"))
9326 (const_string "alu")
9328 (const_string "ishift")))
9329 (set (attr "length_immediate")
9331 (ior (eq_attr "type" "alu")
9332 (and (eq_attr "type" "ishift")
9333 (and (match_operand 2 "const1_operand")
9334 (ior (match_test "TARGET_SHIFT1")
9335 (match_test "optimize_function_for_size_p (cfun)")))))
9337 (const_string "*")))
9338 (set_attr "mode" "SI")])
9340 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9342 [(set (match_operand:DI 0 "register_operand")
9344 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9345 (match_operand:QI 2 "register_operand"))))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9349 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9350 "operands[2] = gen_lowpart (SImode, operands[2]);")
9352 (define_insn "*ashlhi3_1"
9353 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9354 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9355 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9356 (clobber (reg:CC FLAGS_REG))]
9357 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9359 switch (get_attr_type (insn))
9365 gcc_assert (operands[2] == const1_rtx);
9366 return "add{w}\t%0, %0";
9369 if (operands[2] == const1_rtx
9370 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9371 return "sal{w}\t%0";
9373 return "sal{w}\t{%2, %0|%0, %2}";
9377 (cond [(eq_attr "alternative" "1")
9378 (const_string "lea")
9379 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9380 (match_operand 0 "register_operand"))
9381 (match_operand 2 "const1_operand"))
9382 (const_string "alu")
9384 (const_string "ishift")))
9385 (set (attr "length_immediate")
9387 (ior (eq_attr "type" "alu")
9388 (and (eq_attr "type" "ishift")
9389 (and (match_operand 2 "const1_operand")
9390 (ior (match_test "TARGET_SHIFT1")
9391 (match_test "optimize_function_for_size_p (cfun)")))))
9393 (const_string "*")))
9394 (set_attr "mode" "HI,SI")])
9396 ;; %%% Potential partial reg stall on alternative 1. What to do?
9397 (define_insn "*ashlqi3_1"
9398 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9399 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9400 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9401 (clobber (reg:CC FLAGS_REG))]
9402 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9404 switch (get_attr_type (insn))
9410 gcc_assert (operands[2] == const1_rtx);
9411 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9412 return "add{l}\t%k0, %k0";
9414 return "add{b}\t%0, %0";
9417 if (operands[2] == const1_rtx
9418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9420 if (get_attr_mode (insn) == MODE_SI)
9421 return "sal{l}\t%k0";
9423 return "sal{b}\t%0";
9427 if (get_attr_mode (insn) == MODE_SI)
9428 return "sal{l}\t{%2, %k0|%k0, %2}";
9430 return "sal{b}\t{%2, %0|%0, %2}";
9435 (cond [(eq_attr "alternative" "2")
9436 (const_string "lea")
9437 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9438 (match_operand 0 "register_operand"))
9439 (match_operand 2 "const1_operand"))
9440 (const_string "alu")
9442 (const_string "ishift")))
9443 (set (attr "length_immediate")
9445 (ior (eq_attr "type" "alu")
9446 (and (eq_attr "type" "ishift")
9447 (and (match_operand 2 "const1_operand")
9448 (ior (match_test "TARGET_SHIFT1")
9449 (match_test "optimize_function_for_size_p (cfun)")))))
9451 (const_string "*")))
9452 (set_attr "mode" "QI,SI,SI")])
9454 (define_insn "*ashlqi3_1_slp"
9455 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9456 (ashift:QI (match_dup 0)
9457 (match_operand:QI 1 "nonmemory_operand" "cI")))
9458 (clobber (reg:CC FLAGS_REG))]
9459 "(optimize_function_for_size_p (cfun)
9460 || !TARGET_PARTIAL_FLAG_REG_STALL
9461 || (operands[1] == const1_rtx
9463 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9465 switch (get_attr_type (insn))
9468 gcc_assert (operands[1] == const1_rtx);
9469 return "add{b}\t%0, %0";
9472 if (operands[1] == const1_rtx
9473 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9474 return "sal{b}\t%0";
9476 return "sal{b}\t{%1, %0|%0, %1}";
9480 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9481 (match_operand 0 "register_operand"))
9482 (match_operand 1 "const1_operand"))
9483 (const_string "alu")
9485 (const_string "ishift1")))
9486 (set (attr "length_immediate")
9488 (ior (eq_attr "type" "alu")
9489 (and (eq_attr "type" "ishift1")
9490 (and (match_operand 1 "const1_operand")
9491 (ior (match_test "TARGET_SHIFT1")
9492 (match_test "optimize_function_for_size_p (cfun)")))))
9494 (const_string "*")))
9495 (set_attr "mode" "QI")])
9497 ;; Convert ashift to the lea pattern to avoid flags dependency.
9499 [(set (match_operand 0 "register_operand")
9500 (ashift (match_operand 1 "index_register_operand")
9501 (match_operand:QI 2 "const_int_operand")))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9505 && true_regnum (operands[0]) != true_regnum (operands[1])"
9508 enum machine_mode mode = GET_MODE (operands[0]);
9511 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9514 operands[0] = gen_lowpart (mode, operands[0]);
9515 operands[1] = gen_lowpart (mode, operands[1]);
9518 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9520 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9522 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9526 ;; Convert ashift to the lea pattern to avoid flags dependency.
9528 [(set (match_operand:DI 0 "register_operand")
9530 (ashift:SI (match_operand:SI 1 "index_register_operand")
9531 (match_operand:QI 2 "const_int_operand"))))
9532 (clobber (reg:CC FLAGS_REG))]
9533 "TARGET_64BIT && reload_completed
9534 && true_regnum (operands[0]) != true_regnum (operands[1])"
9536 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9538 operands[1] = gen_lowpart (SImode, operands[1]);
9539 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9542 ;; This pattern can't accept a variable shift count, since shifts by
9543 ;; zero don't affect the flags. We assume that shifts by constant
9544 ;; zero are optimized away.
9545 (define_insn "*ashl<mode>3_cmp"
9546 [(set (reg FLAGS_REG)
9548 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9549 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9551 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9552 (ashift:SWI (match_dup 1) (match_dup 2)))]
9553 "(optimize_function_for_size_p (cfun)
9554 || !TARGET_PARTIAL_FLAG_REG_STALL
9555 || (operands[2] == const1_rtx
9557 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9558 && ix86_match_ccmode (insn, CCGOCmode)
9559 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9561 switch (get_attr_type (insn))
9564 gcc_assert (operands[2] == const1_rtx);
9565 return "add{<imodesuffix>}\t%0, %0";
9568 if (operands[2] == const1_rtx
9569 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9570 return "sal{<imodesuffix>}\t%0";
9572 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9576 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9577 (match_operand 0 "register_operand"))
9578 (match_operand 2 "const1_operand"))
9579 (const_string "alu")
9581 (const_string "ishift")))
9582 (set (attr "length_immediate")
9584 (ior (eq_attr "type" "alu")
9585 (and (eq_attr "type" "ishift")
9586 (and (match_operand 2 "const1_operand")
9587 (ior (match_test "TARGET_SHIFT1")
9588 (match_test "optimize_function_for_size_p (cfun)")))))
9590 (const_string "*")))
9591 (set_attr "mode" "<MODE>")])
9593 (define_insn "*ashlsi3_cmp_zext"
9594 [(set (reg FLAGS_REG)
9596 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9597 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9599 (set (match_operand:DI 0 "register_operand" "=r")
9600 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9602 && (optimize_function_for_size_p (cfun)
9603 || !TARGET_PARTIAL_FLAG_REG_STALL
9604 || (operands[2] == const1_rtx
9606 || TARGET_DOUBLE_WITH_ADD)))
9607 && ix86_match_ccmode (insn, CCGOCmode)
9608 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9610 switch (get_attr_type (insn))
9613 gcc_assert (operands[2] == const1_rtx);
9614 return "add{l}\t%k0, %k0";
9617 if (operands[2] == const1_rtx
9618 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9619 return "sal{l}\t%k0";
9621 return "sal{l}\t{%2, %k0|%k0, %2}";
9625 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9626 (match_operand 2 "const1_operand"))
9627 (const_string "alu")
9629 (const_string "ishift")))
9630 (set (attr "length_immediate")
9632 (ior (eq_attr "type" "alu")
9633 (and (eq_attr "type" "ishift")
9634 (and (match_operand 2 "const1_operand")
9635 (ior (match_test "TARGET_SHIFT1")
9636 (match_test "optimize_function_for_size_p (cfun)")))))
9638 (const_string "*")))
9639 (set_attr "mode" "SI")])
9641 (define_insn "*ashl<mode>3_cconly"
9642 [(set (reg FLAGS_REG)
9644 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9645 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9647 (clobber (match_scratch:SWI 0 "=<r>"))]
9648 "(optimize_function_for_size_p (cfun)
9649 || !TARGET_PARTIAL_FLAG_REG_STALL
9650 || (operands[2] == const1_rtx
9652 || TARGET_DOUBLE_WITH_ADD)))
9653 && ix86_match_ccmode (insn, CCGOCmode)"
9655 switch (get_attr_type (insn))
9658 gcc_assert (operands[2] == const1_rtx);
9659 return "add{<imodesuffix>}\t%0, %0";
9662 if (operands[2] == const1_rtx
9663 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9664 return "sal{<imodesuffix>}\t%0";
9666 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9670 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9671 (match_operand 0 "register_operand"))
9672 (match_operand 2 "const1_operand"))
9673 (const_string "alu")
9675 (const_string "ishift")))
9676 (set (attr "length_immediate")
9678 (ior (eq_attr "type" "alu")
9679 (and (eq_attr "type" "ishift")
9680 (and (match_operand 2 "const1_operand")
9681 (ior (match_test "TARGET_SHIFT1")
9682 (match_test "optimize_function_for_size_p (cfun)")))))
9684 (const_string "*")))
9685 (set_attr "mode" "<MODE>")])
9687 ;; See comment above `ashl<mode>3' about how this works.
9689 (define_expand "<shift_insn><mode>3"
9690 [(set (match_operand:SDWIM 0 "<shift_operand>")
9691 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9692 (match_operand:QI 2 "nonmemory_operand")))]
9694 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9696 ;; Avoid useless masking of count operand.
9697 (define_insn "*<shift_insn><mode>3_mask"
9698 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9700 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9703 (match_operand:SI 2 "register_operand" "c")
9704 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9707 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9708 == GET_MODE_BITSIZE (<MODE>mode)-1"
9710 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9712 [(set_attr "type" "ishift")
9713 (set_attr "mode" "<MODE>")])
9715 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9716 [(set (match_operand:DWI 0 "register_operand" "=r")
9717 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9718 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9719 (clobber (reg:CC FLAGS_REG))]
9722 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9724 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9725 [(set_attr "type" "multi")])
9727 ;; By default we don't ask for a scratch register, because when DWImode
9728 ;; values are manipulated, registers are already at a premium. But if
9729 ;; we have one handy, we won't turn it away.
9732 [(match_scratch:DWIH 3 "r")
9733 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9735 (match_operand:<DWI> 1 "register_operand")
9736 (match_operand:QI 2 "nonmemory_operand")))
9737 (clobber (reg:CC FLAGS_REG))])
9741 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9743 (define_insn "x86_64_shrd"
9744 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9745 (ior:DI (lshiftrt:DI (match_dup 0)
9746 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9747 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9748 (minus:QI (const_int 64) (match_dup 2)))))
9749 (clobber (reg:CC FLAGS_REG))]
9751 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9752 [(set_attr "type" "ishift")
9753 (set_attr "prefix_0f" "1")
9754 (set_attr "mode" "DI")
9755 (set_attr "athlon_decode" "vector")
9756 (set_attr "amdfam10_decode" "vector")
9757 (set_attr "bdver1_decode" "vector")])
9759 (define_insn "x86_shrd"
9760 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9761 (ior:SI (lshiftrt:SI (match_dup 0)
9762 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9763 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9764 (minus:QI (const_int 32) (match_dup 2)))))
9765 (clobber (reg:CC FLAGS_REG))]
9767 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9768 [(set_attr "type" "ishift")
9769 (set_attr "prefix_0f" "1")
9770 (set_attr "mode" "SI")
9771 (set_attr "pent_pair" "np")
9772 (set_attr "athlon_decode" "vector")
9773 (set_attr "amdfam10_decode" "vector")
9774 (set_attr "bdver1_decode" "vector")])
9776 (define_insn "ashrdi3_cvt"
9777 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9778 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9779 (match_operand:QI 2 "const_int_operand")))
9780 (clobber (reg:CC FLAGS_REG))]
9781 "TARGET_64BIT && INTVAL (operands[2]) == 63
9782 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9783 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9786 sar{q}\t{%2, %0|%0, %2}"
9787 [(set_attr "type" "imovx,ishift")
9788 (set_attr "prefix_0f" "0,*")
9789 (set_attr "length_immediate" "0,*")
9790 (set_attr "modrm" "0,1")
9791 (set_attr "mode" "DI")])
9793 (define_insn "ashrsi3_cvt"
9794 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9795 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9796 (match_operand:QI 2 "const_int_operand")))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "INTVAL (operands[2]) == 31
9799 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9800 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9803 sar{l}\t{%2, %0|%0, %2}"
9804 [(set_attr "type" "imovx,ishift")
9805 (set_attr "prefix_0f" "0,*")
9806 (set_attr "length_immediate" "0,*")
9807 (set_attr "modrm" "0,1")
9808 (set_attr "mode" "SI")])
9810 (define_insn "*ashrsi3_cvt_zext"
9811 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9813 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9814 (match_operand:QI 2 "const_int_operand"))))
9815 (clobber (reg:CC FLAGS_REG))]
9816 "TARGET_64BIT && INTVAL (operands[2]) == 31
9817 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9818 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9821 sar{l}\t{%2, %k0|%k0, %2}"
9822 [(set_attr "type" "imovx,ishift")
9823 (set_attr "prefix_0f" "0,*")
9824 (set_attr "length_immediate" "0,*")
9825 (set_attr "modrm" "0,1")
9826 (set_attr "mode" "SI")])
9828 (define_expand "x86_shift<mode>_adj_3"
9829 [(use (match_operand:SWI48 0 "register_operand"))
9830 (use (match_operand:SWI48 1 "register_operand"))
9831 (use (match_operand:QI 2 "register_operand"))]
9834 rtx label = gen_label_rtx ();
9837 emit_insn (gen_testqi_ccz_1 (operands[2],
9838 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9840 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9841 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9842 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9843 gen_rtx_LABEL_REF (VOIDmode, label),
9845 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9846 JUMP_LABEL (tmp) = label;
9848 emit_move_insn (operands[0], operands[1]);
9849 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9850 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9852 LABEL_NUSES (label) = 1;
9857 (define_insn "*bmi2_<shift_insn><mode>3_1"
9858 [(set (match_operand:SWI48 0 "register_operand" "=r")
9859 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9860 (match_operand:SWI48 2 "register_operand" "r")))]
9862 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9863 [(set_attr "type" "ishiftx")
9864 (set_attr "mode" "<MODE>")])
9866 (define_insn "*<shift_insn><mode>3_1"
9867 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9869 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9870 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9874 switch (get_attr_type (insn))
9880 if (operands[2] == const1_rtx
9881 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9882 return "<shift>{<imodesuffix>}\t%0";
9884 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9887 [(set_attr "isa" "*,bmi2")
9888 (set_attr "type" "ishift,ishiftx")
9889 (set (attr "length_immediate")
9891 (and (match_operand 2 "const1_operand")
9892 (ior (match_test "TARGET_SHIFT1")
9893 (match_test "optimize_function_for_size_p (cfun)")))
9895 (const_string "*")))
9896 (set_attr "mode" "<MODE>")])
9898 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9900 [(set (match_operand:SWI48 0 "register_operand")
9901 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9902 (match_operand:QI 2 "register_operand")))
9903 (clobber (reg:CC FLAGS_REG))]
9904 "TARGET_BMI2 && reload_completed"
9906 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9907 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9909 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9910 [(set (match_operand:DI 0 "register_operand" "=r")
9912 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9913 (match_operand:SI 2 "register_operand" "r"))))]
9914 "TARGET_64BIT && TARGET_BMI2"
9915 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9916 [(set_attr "type" "ishiftx")
9917 (set_attr "mode" "SI")])
9919 (define_insn "*<shift_insn>si3_1_zext"
9920 [(set (match_operand:DI 0 "register_operand" "=r,r")
9922 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9923 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9924 (clobber (reg:CC FLAGS_REG))]
9925 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9927 switch (get_attr_type (insn))
9933 if (operands[2] == const1_rtx
9934 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9935 return "<shift>{l}\t%k0";
9937 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9940 [(set_attr "isa" "*,bmi2")
9941 (set_attr "type" "ishift,ishiftx")
9942 (set (attr "length_immediate")
9944 (and (match_operand 2 "const1_operand")
9945 (ior (match_test "TARGET_SHIFT1")
9946 (match_test "optimize_function_for_size_p (cfun)")))
9948 (const_string "*")))
9949 (set_attr "mode" "SI")])
9951 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9953 [(set (match_operand:DI 0 "register_operand")
9955 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9956 (match_operand:QI 2 "register_operand"))))
9957 (clobber (reg:CC FLAGS_REG))]
9958 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9960 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9961 "operands[2] = gen_lowpart (SImode, operands[2]);")
9963 (define_insn "*<shift_insn><mode>3_1"
9964 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9966 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9967 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9968 (clobber (reg:CC FLAGS_REG))]
9969 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9971 if (operands[2] == const1_rtx
9972 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9973 return "<shift>{<imodesuffix>}\t%0";
9975 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9977 [(set_attr "type" "ishift")
9978 (set (attr "length_immediate")
9980 (and (match_operand 2 "const1_operand")
9981 (ior (match_test "TARGET_SHIFT1")
9982 (match_test "optimize_function_for_size_p (cfun)")))
9984 (const_string "*")))
9985 (set_attr "mode" "<MODE>")])
9987 (define_insn "*<shift_insn>qi3_1_slp"
9988 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9989 (any_shiftrt:QI (match_dup 0)
9990 (match_operand:QI 1 "nonmemory_operand" "cI")))
9991 (clobber (reg:CC FLAGS_REG))]
9992 "(optimize_function_for_size_p (cfun)
9993 || !TARGET_PARTIAL_REG_STALL
9994 || (operands[1] == const1_rtx
9997 if (operands[1] == const1_rtx
9998 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9999 return "<shift>{b}\t%0";
10001 return "<shift>{b}\t{%1, %0|%0, %1}";
10003 [(set_attr "type" "ishift1")
10004 (set (attr "length_immediate")
10006 (and (match_operand 1 "const1_operand")
10007 (ior (match_test "TARGET_SHIFT1")
10008 (match_test "optimize_function_for_size_p (cfun)")))
10010 (const_string "*")))
10011 (set_attr "mode" "QI")])
10013 ;; This pattern can't accept a variable shift count, since shifts by
10014 ;; zero don't affect the flags. We assume that shifts by constant
10015 ;; zero are optimized away.
10016 (define_insn "*<shift_insn><mode>3_cmp"
10017 [(set (reg FLAGS_REG)
10020 (match_operand:SWI 1 "nonimmediate_operand" "0")
10021 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10023 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10024 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10025 "(optimize_function_for_size_p (cfun)
10026 || !TARGET_PARTIAL_FLAG_REG_STALL
10027 || (operands[2] == const1_rtx
10029 && ix86_match_ccmode (insn, CCGOCmode)
10030 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10032 if (operands[2] == const1_rtx
10033 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10034 return "<shift>{<imodesuffix>}\t%0";
10036 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10038 [(set_attr "type" "ishift")
10039 (set (attr "length_immediate")
10041 (and (match_operand 2 "const1_operand")
10042 (ior (match_test "TARGET_SHIFT1")
10043 (match_test "optimize_function_for_size_p (cfun)")))
10045 (const_string "*")))
10046 (set_attr "mode" "<MODE>")])
10048 (define_insn "*<shift_insn>si3_cmp_zext"
10049 [(set (reg FLAGS_REG)
10051 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10052 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10054 (set (match_operand:DI 0 "register_operand" "=r")
10055 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10057 && (optimize_function_for_size_p (cfun)
10058 || !TARGET_PARTIAL_FLAG_REG_STALL
10059 || (operands[2] == const1_rtx
10061 && ix86_match_ccmode (insn, CCGOCmode)
10062 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10064 if (operands[2] == const1_rtx
10065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10066 return "<shift>{l}\t%k0";
10068 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10070 [(set_attr "type" "ishift")
10071 (set (attr "length_immediate")
10073 (and (match_operand 2 "const1_operand")
10074 (ior (match_test "TARGET_SHIFT1")
10075 (match_test "optimize_function_for_size_p (cfun)")))
10077 (const_string "*")))
10078 (set_attr "mode" "SI")])
10080 (define_insn "*<shift_insn><mode>3_cconly"
10081 [(set (reg FLAGS_REG)
10084 (match_operand:SWI 1 "register_operand" "0")
10085 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10087 (clobber (match_scratch:SWI 0 "=<r>"))]
10088 "(optimize_function_for_size_p (cfun)
10089 || !TARGET_PARTIAL_FLAG_REG_STALL
10090 || (operands[2] == const1_rtx
10092 && ix86_match_ccmode (insn, CCGOCmode)"
10094 if (operands[2] == const1_rtx
10095 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10096 return "<shift>{<imodesuffix>}\t%0";
10098 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10100 [(set_attr "type" "ishift")
10101 (set (attr "length_immediate")
10103 (and (match_operand 2 "const1_operand")
10104 (ior (match_test "TARGET_SHIFT1")
10105 (match_test "optimize_function_for_size_p (cfun)")))
10107 (const_string "*")))
10108 (set_attr "mode" "<MODE>")])
10110 ;; Rotate instructions
10112 (define_expand "<rotate_insn>ti3"
10113 [(set (match_operand:TI 0 "register_operand")
10114 (any_rotate:TI (match_operand:TI 1 "register_operand")
10115 (match_operand:QI 2 "nonmemory_operand")))]
10118 if (const_1_to_63_operand (operands[2], VOIDmode))
10119 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10120 (operands[0], operands[1], operands[2]));
10127 (define_expand "<rotate_insn>di3"
10128 [(set (match_operand:DI 0 "shiftdi_operand")
10129 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10130 (match_operand:QI 2 "nonmemory_operand")))]
10134 ix86_expand_binary_operator (<CODE>, DImode, operands);
10135 else if (const_1_to_31_operand (operands[2], VOIDmode))
10136 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10137 (operands[0], operands[1], operands[2]));
10144 (define_expand "<rotate_insn><mode>3"
10145 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10146 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10147 (match_operand:QI 2 "nonmemory_operand")))]
10149 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10151 ;; Avoid useless masking of count operand.
10152 (define_insn "*<rotate_insn><mode>3_mask"
10153 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10155 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10158 (match_operand:SI 2 "register_operand" "c")
10159 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10160 (clobber (reg:CC FLAGS_REG))]
10161 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10162 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10163 == GET_MODE_BITSIZE (<MODE>mode)-1"
10165 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10167 [(set_attr "type" "rotate")
10168 (set_attr "mode" "<MODE>")])
10170 ;; Implement rotation using two double-precision
10171 ;; shift instructions and a scratch register.
10173 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10174 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10175 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10176 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10177 (clobber (reg:CC FLAGS_REG))
10178 (clobber (match_scratch:DWIH 3 "=&r"))]
10182 [(set (match_dup 3) (match_dup 4))
10184 [(set (match_dup 4)
10185 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10186 (lshiftrt:DWIH (match_dup 5)
10187 (minus:QI (match_dup 6) (match_dup 2)))))
10188 (clobber (reg:CC FLAGS_REG))])
10190 [(set (match_dup 5)
10191 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10192 (lshiftrt:DWIH (match_dup 3)
10193 (minus:QI (match_dup 6) (match_dup 2)))))
10194 (clobber (reg:CC FLAGS_REG))])]
10196 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10198 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10201 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10202 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10203 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10204 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10205 (clobber (reg:CC FLAGS_REG))
10206 (clobber (match_scratch:DWIH 3 "=&r"))]
10210 [(set (match_dup 3) (match_dup 4))
10212 [(set (match_dup 4)
10213 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10214 (ashift:DWIH (match_dup 5)
10215 (minus:QI (match_dup 6) (match_dup 2)))))
10216 (clobber (reg:CC FLAGS_REG))])
10218 [(set (match_dup 5)
10219 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10220 (ashift:DWIH (match_dup 3)
10221 (minus:QI (match_dup 6) (match_dup 2)))))
10222 (clobber (reg:CC FLAGS_REG))])]
10224 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10226 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10229 (define_insn "*bmi2_rorx<mode>3_1"
10230 [(set (match_operand:SWI48 0 "register_operand" "=r")
10231 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10232 (match_operand:QI 2 "immediate_operand" "<S>")))]
10234 "rorx\t{%2, %1, %0|%0, %1, %2}"
10235 [(set_attr "type" "rotatex")
10236 (set_attr "mode" "<MODE>")])
10238 (define_insn "*<rotate_insn><mode>3_1"
10239 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10241 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10242 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10246 switch (get_attr_type (insn))
10252 if (operands[2] == const1_rtx
10253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10254 return "<rotate>{<imodesuffix>}\t%0";
10256 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10259 [(set_attr "isa" "*,bmi2")
10260 (set_attr "type" "rotate,rotatex")
10261 (set (attr "length_immediate")
10263 (and (eq_attr "type" "rotate")
10264 (and (match_operand 2 "const1_operand")
10265 (ior (match_test "TARGET_SHIFT1")
10266 (match_test "optimize_function_for_size_p (cfun)"))))
10268 (const_string "*")))
10269 (set_attr "mode" "<MODE>")])
10271 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10273 [(set (match_operand:SWI48 0 "register_operand")
10274 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10275 (match_operand:QI 2 "immediate_operand")))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "TARGET_BMI2 && reload_completed"
10278 [(set (match_dup 0)
10279 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10282 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10286 [(set (match_operand:SWI48 0 "register_operand")
10287 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10288 (match_operand:QI 2 "immediate_operand")))
10289 (clobber (reg:CC FLAGS_REG))]
10290 "TARGET_BMI2 && reload_completed"
10291 [(set (match_dup 0)
10292 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10294 (define_insn "*bmi2_rorxsi3_1_zext"
10295 [(set (match_operand:DI 0 "register_operand" "=r")
10297 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10298 (match_operand:QI 2 "immediate_operand" "I"))))]
10299 "TARGET_64BIT && TARGET_BMI2"
10300 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10301 [(set_attr "type" "rotatex")
10302 (set_attr "mode" "SI")])
10304 (define_insn "*<rotate_insn>si3_1_zext"
10305 [(set (match_operand:DI 0 "register_operand" "=r,r")
10307 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10308 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10309 (clobber (reg:CC FLAGS_REG))]
10310 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10312 switch (get_attr_type (insn))
10318 if (operands[2] == const1_rtx
10319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10320 return "<rotate>{l}\t%k0";
10322 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10325 [(set_attr "isa" "*,bmi2")
10326 (set_attr "type" "rotate,rotatex")
10327 (set (attr "length_immediate")
10329 (and (eq_attr "type" "rotate")
10330 (and (match_operand 2 "const1_operand")
10331 (ior (match_test "TARGET_SHIFT1")
10332 (match_test "optimize_function_for_size_p (cfun)"))))
10334 (const_string "*")))
10335 (set_attr "mode" "SI")])
10337 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10339 [(set (match_operand:DI 0 "register_operand")
10341 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10342 (match_operand:QI 2 "immediate_operand"))))
10343 (clobber (reg:CC FLAGS_REG))]
10344 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10345 [(set (match_dup 0)
10346 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10349 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10353 [(set (match_operand:DI 0 "register_operand")
10355 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10356 (match_operand:QI 2 "immediate_operand"))))
10357 (clobber (reg:CC FLAGS_REG))]
10358 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10359 [(set (match_dup 0)
10360 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10362 (define_insn "*<rotate_insn><mode>3_1"
10363 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10364 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10365 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10369 if (operands[2] == const1_rtx
10370 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10371 return "<rotate>{<imodesuffix>}\t%0";
10373 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10375 [(set_attr "type" "rotate")
10376 (set (attr "length_immediate")
10378 (and (match_operand 2 "const1_operand")
10379 (ior (match_test "TARGET_SHIFT1")
10380 (match_test "optimize_function_for_size_p (cfun)")))
10382 (const_string "*")))
10383 (set_attr "mode" "<MODE>")])
10385 (define_insn "*<rotate_insn>qi3_1_slp"
10386 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10387 (any_rotate:QI (match_dup 0)
10388 (match_operand:QI 1 "nonmemory_operand" "cI")))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "(optimize_function_for_size_p (cfun)
10391 || !TARGET_PARTIAL_REG_STALL
10392 || (operands[1] == const1_rtx
10393 && TARGET_SHIFT1))"
10395 if (operands[1] == const1_rtx
10396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10397 return "<rotate>{b}\t%0";
10399 return "<rotate>{b}\t{%1, %0|%0, %1}";
10401 [(set_attr "type" "rotate1")
10402 (set (attr "length_immediate")
10404 (and (match_operand 1 "const1_operand")
10405 (ior (match_test "TARGET_SHIFT1")
10406 (match_test "optimize_function_for_size_p (cfun)")))
10408 (const_string "*")))
10409 (set_attr "mode" "QI")])
10412 [(set (match_operand:HI 0 "register_operand")
10413 (any_rotate:HI (match_dup 0) (const_int 8)))
10414 (clobber (reg:CC FLAGS_REG))]
10416 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10417 [(parallel [(set (strict_low_part (match_dup 0))
10418 (bswap:HI (match_dup 0)))
10419 (clobber (reg:CC FLAGS_REG))])])
10421 ;; Bit set / bit test instructions
10423 (define_expand "extv"
10424 [(set (match_operand:SI 0 "register_operand")
10425 (sign_extract:SI (match_operand:SI 1 "register_operand")
10426 (match_operand:SI 2 "const8_operand")
10427 (match_operand:SI 3 "const8_operand")))]
10430 /* Handle extractions from %ah et al. */
10431 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10434 /* From mips.md: extract_bit_field doesn't verify that our source
10435 matches the predicate, so check it again here. */
10436 if (! ext_register_operand (operands[1], VOIDmode))
10440 (define_expand "extzv"
10441 [(set (match_operand:SI 0 "register_operand")
10442 (zero_extract:SI (match_operand 1 "ext_register_operand")
10443 (match_operand:SI 2 "const8_operand")
10444 (match_operand:SI 3 "const8_operand")))]
10447 /* Handle extractions from %ah et al. */
10448 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10451 /* From mips.md: extract_bit_field doesn't verify that our source
10452 matches the predicate, so check it again here. */
10453 if (! ext_register_operand (operands[1], VOIDmode))
10457 (define_expand "insv"
10458 [(set (zero_extract (match_operand 0 "register_operand")
10459 (match_operand 1 "const_int_operand")
10460 (match_operand 2 "const_int_operand"))
10461 (match_operand 3 "register_operand"))]
10464 rtx (*gen_mov_insv_1) (rtx, rtx);
10466 if (ix86_expand_pinsr (operands))
10469 /* Handle insertions to %ah et al. */
10470 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10473 /* From mips.md: insert_bit_field doesn't verify that our source
10474 matches the predicate, so check it again here. */
10475 if (! ext_register_operand (operands[0], VOIDmode))
10478 gen_mov_insv_1 = (TARGET_64BIT
10479 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10481 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10485 ;; %%% bts, btr, btc, bt.
10486 ;; In general these instructions are *slow* when applied to memory,
10487 ;; since they enforce atomic operation. When applied to registers,
10488 ;; it depends on the cpu implementation. They're never faster than
10489 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10490 ;; no point. But in 64-bit, we can't hold the relevant immediates
10491 ;; within the instruction itself, so operating on bits in the high
10492 ;; 32-bits of a register becomes easier.
10494 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10495 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10496 ;; negdf respectively, so they can never be disabled entirely.
10498 (define_insn "*btsq"
10499 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10501 (match_operand:DI 1 "const_0_to_63_operand"))
10503 (clobber (reg:CC FLAGS_REG))]
10504 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10505 "bts{q}\t{%1, %0|%0, %1}"
10506 [(set_attr "type" "alu1")
10507 (set_attr "prefix_0f" "1")
10508 (set_attr "mode" "DI")])
10510 (define_insn "*btrq"
10511 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10513 (match_operand:DI 1 "const_0_to_63_operand"))
10515 (clobber (reg:CC FLAGS_REG))]
10516 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10517 "btr{q}\t{%1, %0|%0, %1}"
10518 [(set_attr "type" "alu1")
10519 (set_attr "prefix_0f" "1")
10520 (set_attr "mode" "DI")])
10522 (define_insn "*btcq"
10523 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10525 (match_operand:DI 1 "const_0_to_63_operand"))
10526 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10529 "btc{q}\t{%1, %0|%0, %1}"
10530 [(set_attr "type" "alu1")
10531 (set_attr "prefix_0f" "1")
10532 (set_attr "mode" "DI")])
10534 ;; Allow Nocona to avoid these instructions if a register is available.
10537 [(match_scratch:DI 2 "r")
10538 (parallel [(set (zero_extract:DI
10539 (match_operand:DI 0 "register_operand")
10541 (match_operand:DI 1 "const_0_to_63_operand"))
10543 (clobber (reg:CC FLAGS_REG))])]
10544 "TARGET_64BIT && !TARGET_USE_BT"
10547 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10550 if (HOST_BITS_PER_WIDE_INT >= 64)
10551 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10552 else if (i < HOST_BITS_PER_WIDE_INT)
10553 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10555 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10557 op1 = immed_double_const (lo, hi, DImode);
10560 emit_move_insn (operands[2], op1);
10564 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10569 [(match_scratch:DI 2 "r")
10570 (parallel [(set (zero_extract:DI
10571 (match_operand:DI 0 "register_operand")
10573 (match_operand:DI 1 "const_0_to_63_operand"))
10575 (clobber (reg:CC FLAGS_REG))])]
10576 "TARGET_64BIT && !TARGET_USE_BT"
10579 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10582 if (HOST_BITS_PER_WIDE_INT >= 64)
10583 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10584 else if (i < HOST_BITS_PER_WIDE_INT)
10585 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10587 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10589 op1 = immed_double_const (~lo, ~hi, DImode);
10592 emit_move_insn (operands[2], op1);
10596 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10601 [(match_scratch:DI 2 "r")
10602 (parallel [(set (zero_extract:DI
10603 (match_operand:DI 0 "register_operand")
10605 (match_operand:DI 1 "const_0_to_63_operand"))
10606 (not:DI (zero_extract:DI
10607 (match_dup 0) (const_int 1) (match_dup 1))))
10608 (clobber (reg:CC FLAGS_REG))])]
10609 "TARGET_64BIT && !TARGET_USE_BT"
10612 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10615 if (HOST_BITS_PER_WIDE_INT >= 64)
10616 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10617 else if (i < HOST_BITS_PER_WIDE_INT)
10618 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10620 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10622 op1 = immed_double_const (lo, hi, DImode);
10625 emit_move_insn (operands[2], op1);
10629 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10633 (define_insn "*bt<mode>"
10634 [(set (reg:CCC FLAGS_REG)
10636 (zero_extract:SWI48
10637 (match_operand:SWI48 0 "register_operand" "r")
10639 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10641 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10642 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10643 [(set_attr "type" "alu1")
10644 (set_attr "prefix_0f" "1")
10645 (set_attr "mode" "<MODE>")])
10647 ;; Store-flag instructions.
10649 ;; For all sCOND expanders, also expand the compare or test insn that
10650 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10652 (define_insn_and_split "*setcc_di_1"
10653 [(set (match_operand:DI 0 "register_operand" "=q")
10654 (match_operator:DI 1 "ix86_comparison_operator"
10655 [(reg FLAGS_REG) (const_int 0)]))]
10656 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10658 "&& reload_completed"
10659 [(set (match_dup 2) (match_dup 1))
10660 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10662 PUT_MODE (operands[1], QImode);
10663 operands[2] = gen_lowpart (QImode, operands[0]);
10666 (define_insn_and_split "*setcc_si_1_and"
10667 [(set (match_operand:SI 0 "register_operand" "=q")
10668 (match_operator:SI 1 "ix86_comparison_operator"
10669 [(reg FLAGS_REG) (const_int 0)]))
10670 (clobber (reg:CC FLAGS_REG))]
10671 "!TARGET_PARTIAL_REG_STALL
10672 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10674 "&& reload_completed"
10675 [(set (match_dup 2) (match_dup 1))
10676 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10677 (clobber (reg:CC FLAGS_REG))])]
10679 PUT_MODE (operands[1], QImode);
10680 operands[2] = gen_lowpart (QImode, operands[0]);
10683 (define_insn_and_split "*setcc_si_1_movzbl"
10684 [(set (match_operand:SI 0 "register_operand" "=q")
10685 (match_operator:SI 1 "ix86_comparison_operator"
10686 [(reg FLAGS_REG) (const_int 0)]))]
10687 "!TARGET_PARTIAL_REG_STALL
10688 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10690 "&& reload_completed"
10691 [(set (match_dup 2) (match_dup 1))
10692 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10694 PUT_MODE (operands[1], QImode);
10695 operands[2] = gen_lowpart (QImode, operands[0]);
10698 (define_insn "*setcc_qi"
10699 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10700 (match_operator:QI 1 "ix86_comparison_operator"
10701 [(reg FLAGS_REG) (const_int 0)]))]
10704 [(set_attr "type" "setcc")
10705 (set_attr "mode" "QI")])
10707 (define_insn "*setcc_qi_slp"
10708 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10709 (match_operator:QI 1 "ix86_comparison_operator"
10710 [(reg FLAGS_REG) (const_int 0)]))]
10713 [(set_attr "type" "setcc")
10714 (set_attr "mode" "QI")])
10716 ;; In general it is not safe to assume too much about CCmode registers,
10717 ;; so simplify-rtx stops when it sees a second one. Under certain
10718 ;; conditions this is safe on x86, so help combine not create
10725 [(set (match_operand:QI 0 "nonimmediate_operand")
10726 (ne:QI (match_operator 1 "ix86_comparison_operator"
10727 [(reg FLAGS_REG) (const_int 0)])
10730 [(set (match_dup 0) (match_dup 1))]
10731 "PUT_MODE (operands[1], QImode);")
10734 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10735 (ne:QI (match_operator 1 "ix86_comparison_operator"
10736 [(reg FLAGS_REG) (const_int 0)])
10739 [(set (match_dup 0) (match_dup 1))]
10740 "PUT_MODE (operands[1], QImode);")
10743 [(set (match_operand:QI 0 "nonimmediate_operand")
10744 (eq:QI (match_operator 1 "ix86_comparison_operator"
10745 [(reg FLAGS_REG) (const_int 0)])
10748 [(set (match_dup 0) (match_dup 1))]
10750 rtx new_op1 = copy_rtx (operands[1]);
10751 operands[1] = new_op1;
10752 PUT_MODE (new_op1, QImode);
10753 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10754 GET_MODE (XEXP (new_op1, 0))));
10756 /* Make sure that (a) the CCmode we have for the flags is strong
10757 enough for the reversed compare or (b) we have a valid FP compare. */
10758 if (! ix86_comparison_operator (new_op1, VOIDmode))
10763 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10764 (eq:QI (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10768 [(set (match_dup 0) (match_dup 1))]
10770 rtx new_op1 = copy_rtx (operands[1]);
10771 operands[1] = new_op1;
10772 PUT_MODE (new_op1, QImode);
10773 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10774 GET_MODE (XEXP (new_op1, 0))));
10776 /* Make sure that (a) the CCmode we have for the flags is strong
10777 enough for the reversed compare or (b) we have a valid FP compare. */
10778 if (! ix86_comparison_operator (new_op1, VOIDmode))
10782 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10783 ;; subsequent logical operations are used to imitate conditional moves.
10784 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10787 (define_insn "setcc_<mode>_sse"
10788 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10789 (match_operator:MODEF 3 "sse_comparison_operator"
10790 [(match_operand:MODEF 1 "register_operand" "0,x")
10791 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10792 "SSE_FLOAT_MODE_P (<MODE>mode)"
10794 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10795 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10796 [(set_attr "isa" "noavx,avx")
10797 (set_attr "type" "ssecmp")
10798 (set_attr "length_immediate" "1")
10799 (set_attr "prefix" "orig,vex")
10800 (set_attr "mode" "<MODE>")])
10802 ;; Basic conditional jump instructions.
10803 ;; We ignore the overflow flag for signed branch instructions.
10805 (define_insn "*jcc_1"
10807 (if_then_else (match_operator 1 "ix86_comparison_operator"
10808 [(reg FLAGS_REG) (const_int 0)])
10809 (label_ref (match_operand 0))
10813 [(set_attr "type" "ibr")
10814 (set_attr "modrm" "0")
10815 (set (attr "length")
10816 (if_then_else (and (ge (minus (match_dup 0) (pc))
10818 (lt (minus (match_dup 0) (pc))
10823 (define_insn "*jcc_2"
10825 (if_then_else (match_operator 1 "ix86_comparison_operator"
10826 [(reg FLAGS_REG) (const_int 0)])
10828 (label_ref (match_operand 0))))]
10831 [(set_attr "type" "ibr")
10832 (set_attr "modrm" "0")
10833 (set (attr "length")
10834 (if_then_else (and (ge (minus (match_dup 0) (pc))
10836 (lt (minus (match_dup 0) (pc))
10841 ;; In general it is not safe to assume too much about CCmode registers,
10842 ;; so simplify-rtx stops when it sees a second one. Under certain
10843 ;; conditions this is safe on x86, so help combine not create
10851 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10852 [(reg FLAGS_REG) (const_int 0)])
10854 (label_ref (match_operand 1))
10858 (if_then_else (match_dup 0)
10859 (label_ref (match_dup 1))
10861 "PUT_MODE (operands[0], VOIDmode);")
10865 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10866 [(reg FLAGS_REG) (const_int 0)])
10868 (label_ref (match_operand 1))
10872 (if_then_else (match_dup 0)
10873 (label_ref (match_dup 1))
10876 rtx new_op0 = copy_rtx (operands[0]);
10877 operands[0] = new_op0;
10878 PUT_MODE (new_op0, VOIDmode);
10879 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10880 GET_MODE (XEXP (new_op0, 0))));
10882 /* Make sure that (a) the CCmode we have for the flags is strong
10883 enough for the reversed compare or (b) we have a valid FP compare. */
10884 if (! ix86_comparison_operator (new_op0, VOIDmode))
10888 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10889 ;; pass generates from shift insn with QImode operand. Actually, the mode
10890 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10891 ;; appropriate modulo of the bit offset value.
10893 (define_insn_and_split "*jcc_bt<mode>"
10895 (if_then_else (match_operator 0 "bt_comparison_operator"
10896 [(zero_extract:SWI48
10897 (match_operand:SWI48 1 "register_operand" "r")
10900 (match_operand:QI 2 "register_operand" "r")))
10902 (label_ref (match_operand 3))
10904 (clobber (reg:CC FLAGS_REG))]
10905 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10908 [(set (reg:CCC FLAGS_REG)
10910 (zero_extract:SWI48
10916 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10917 (label_ref (match_dup 3))
10920 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10922 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10925 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10926 ;; zero extended to SImode.
10927 (define_insn_and_split "*jcc_bt<mode>_1"
10929 (if_then_else (match_operator 0 "bt_comparison_operator"
10930 [(zero_extract:SWI48
10931 (match_operand:SWI48 1 "register_operand" "r")
10933 (match_operand:SI 2 "register_operand" "r"))
10935 (label_ref (match_operand 3))
10937 (clobber (reg:CC FLAGS_REG))]
10938 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10941 [(set (reg:CCC FLAGS_REG)
10943 (zero_extract:SWI48
10949 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10950 (label_ref (match_dup 3))
10953 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10955 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10958 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10959 ;; also for DImode, this is what combine produces.
10960 (define_insn_and_split "*jcc_bt<mode>_mask"
10962 (if_then_else (match_operator 0 "bt_comparison_operator"
10963 [(zero_extract:SWI48
10964 (match_operand:SWI48 1 "register_operand" "r")
10967 (match_operand:SI 2 "register_operand" "r")
10968 (match_operand:SI 3 "const_int_operand" "n")))])
10969 (label_ref (match_operand 4))
10971 (clobber (reg:CC FLAGS_REG))]
10972 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10973 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10974 == GET_MODE_BITSIZE (<MODE>mode)-1"
10977 [(set (reg:CCC FLAGS_REG)
10979 (zero_extract:SWI48
10985 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10986 (label_ref (match_dup 4))
10989 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10991 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10994 (define_insn_and_split "*jcc_btsi_1"
10996 (if_then_else (match_operator 0 "bt_comparison_operator"
10999 (match_operand:SI 1 "register_operand" "r")
11000 (match_operand:QI 2 "register_operand" "r"))
11003 (label_ref (match_operand 3))
11005 (clobber (reg:CC FLAGS_REG))]
11006 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11009 [(set (reg:CCC FLAGS_REG)
11017 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11018 (label_ref (match_dup 3))
11021 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11023 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11026 ;; avoid useless masking of bit offset operand
11027 (define_insn_and_split "*jcc_btsi_mask_1"
11030 (match_operator 0 "bt_comparison_operator"
11033 (match_operand:SI 1 "register_operand" "r")
11036 (match_operand:SI 2 "register_operand" "r")
11037 (match_operand:SI 3 "const_int_operand" "n")) 0))
11040 (label_ref (match_operand 4))
11042 (clobber (reg:CC FLAGS_REG))]
11043 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11044 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11047 [(set (reg:CCC FLAGS_REG)
11055 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11056 (label_ref (match_dup 4))
11058 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11060 ;; Define combination compare-and-branch fp compare instructions to help
11063 (define_insn "*jcc<mode>_0_i387"
11065 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11066 [(match_operand:X87MODEF 1 "register_operand" "f")
11067 (match_operand:X87MODEF 2 "const0_operand")])
11068 (label_ref (match_operand 3))
11070 (clobber (reg:CCFP FPSR_REG))
11071 (clobber (reg:CCFP FLAGS_REG))
11072 (clobber (match_scratch:HI 4 "=a"))]
11073 "TARGET_80387 && !TARGET_CMOVE"
11076 (define_insn "*jcc<mode>_0_r_i387"
11078 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11079 [(match_operand:X87MODEF 1 "register_operand" "f")
11080 (match_operand:X87MODEF 2 "const0_operand")])
11082 (label_ref (match_operand 3))))
11083 (clobber (reg:CCFP FPSR_REG))
11084 (clobber (reg:CCFP FLAGS_REG))
11085 (clobber (match_scratch:HI 4 "=a"))]
11086 "TARGET_80387 && !TARGET_CMOVE"
11089 (define_insn "*jccxf_i387"
11091 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11092 [(match_operand:XF 1 "register_operand" "f")
11093 (match_operand:XF 2 "register_operand" "f")])
11094 (label_ref (match_operand 3))
11096 (clobber (reg:CCFP FPSR_REG))
11097 (clobber (reg:CCFP FLAGS_REG))
11098 (clobber (match_scratch:HI 4 "=a"))]
11099 "TARGET_80387 && !TARGET_CMOVE"
11102 (define_insn "*jccxf_r_i387"
11104 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11105 [(match_operand:XF 1 "register_operand" "f")
11106 (match_operand:XF 2 "register_operand" "f")])
11108 (label_ref (match_operand 3))))
11109 (clobber (reg:CCFP FPSR_REG))
11110 (clobber (reg:CCFP FLAGS_REG))
11111 (clobber (match_scratch:HI 4 "=a"))]
11112 "TARGET_80387 && !TARGET_CMOVE"
11115 (define_insn "*jcc<mode>_i387"
11117 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11118 [(match_operand:MODEF 1 "register_operand" "f")
11119 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11120 (label_ref (match_operand 3))
11122 (clobber (reg:CCFP FPSR_REG))
11123 (clobber (reg:CCFP FLAGS_REG))
11124 (clobber (match_scratch:HI 4 "=a"))]
11125 "TARGET_80387 && !TARGET_CMOVE"
11128 (define_insn "*jcc<mode>_r_i387"
11130 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11131 [(match_operand:MODEF 1 "register_operand" "f")
11132 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11134 (label_ref (match_operand 3))))
11135 (clobber (reg:CCFP FPSR_REG))
11136 (clobber (reg:CCFP FLAGS_REG))
11137 (clobber (match_scratch:HI 4 "=a"))]
11138 "TARGET_80387 && !TARGET_CMOVE"
11141 (define_insn "*jccu<mode>_i387"
11143 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11144 [(match_operand:X87MODEF 1 "register_operand" "f")
11145 (match_operand:X87MODEF 2 "register_operand" "f")])
11146 (label_ref (match_operand 3))
11148 (clobber (reg:CCFP FPSR_REG))
11149 (clobber (reg:CCFP FLAGS_REG))
11150 (clobber (match_scratch:HI 4 "=a"))]
11151 "TARGET_80387 && !TARGET_CMOVE"
11154 (define_insn "*jccu<mode>_r_i387"
11156 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11157 [(match_operand:X87MODEF 1 "register_operand" "f")
11158 (match_operand:X87MODEF 2 "register_operand" "f")])
11160 (label_ref (match_operand 3))))
11161 (clobber (reg:CCFP FPSR_REG))
11162 (clobber (reg:CCFP FLAGS_REG))
11163 (clobber (match_scratch:HI 4 "=a"))]
11164 "TARGET_80387 && !TARGET_CMOVE"
11169 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11170 [(match_operand:X87MODEF 1 "register_operand")
11171 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11173 (match_operand 4)))
11174 (clobber (reg:CCFP FPSR_REG))
11175 (clobber (reg:CCFP FLAGS_REG))]
11176 "TARGET_80387 && !TARGET_CMOVE
11177 && reload_completed"
11180 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11181 operands[3], operands[4], NULL_RTX);
11187 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11188 [(match_operand:X87MODEF 1 "register_operand")
11189 (match_operand:X87MODEF 2 "general_operand")])
11191 (match_operand 4)))
11192 (clobber (reg:CCFP FPSR_REG))
11193 (clobber (reg:CCFP FLAGS_REG))
11194 (clobber (match_scratch:HI 5))]
11195 "TARGET_80387 && !TARGET_CMOVE
11196 && reload_completed"
11199 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11200 operands[3], operands[4], operands[5]);
11204 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11205 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11206 ;; with a precedence over other operators and is always put in the first
11207 ;; place. Swap condition and operands to match ficom instruction.
11209 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11212 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11213 [(match_operator:X87MODEF 1 "float_operator"
11214 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11215 (match_operand:X87MODEF 3 "register_operand" "f")])
11216 (label_ref (match_operand 4))
11218 (clobber (reg:CCFP FPSR_REG))
11219 (clobber (reg:CCFP FLAGS_REG))
11220 (clobber (match_scratch:HI 5 "=a"))]
11221 "TARGET_80387 && !TARGET_CMOVE
11222 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11223 || optimize_function_for_size_p (cfun))"
11226 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11229 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11230 [(match_operator:X87MODEF 1 "float_operator"
11231 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11232 (match_operand:X87MODEF 3 "register_operand" "f")])
11234 (label_ref (match_operand 4))))
11235 (clobber (reg:CCFP FPSR_REG))
11236 (clobber (reg:CCFP FLAGS_REG))
11237 (clobber (match_scratch:HI 5 "=a"))]
11238 "TARGET_80387 && !TARGET_CMOVE
11239 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11240 || optimize_function_for_size_p (cfun))"
11246 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11247 [(match_operator:X87MODEF 1 "float_operator"
11248 [(match_operand:SWI24 2 "memory_operand")])
11249 (match_operand:X87MODEF 3 "register_operand")])
11251 (match_operand 5)))
11252 (clobber (reg:CCFP FPSR_REG))
11253 (clobber (reg:CCFP FLAGS_REG))
11254 (clobber (match_scratch:HI 6))]
11255 "TARGET_80387 && !TARGET_CMOVE
11256 && reload_completed"
11259 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11260 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11261 operands[4], operands[5], operands[6]);
11265 ;; Unconditional and other jump instructions
11267 (define_insn "jump"
11269 (label_ref (match_operand 0)))]
11272 [(set_attr "type" "ibr")
11273 (set (attr "length")
11274 (if_then_else (and (ge (minus (match_dup 0) (pc))
11276 (lt (minus (match_dup 0) (pc))
11280 (set_attr "modrm" "0")])
11282 (define_expand "indirect_jump"
11283 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11287 operands[0] = convert_memory_address (word_mode, operands[0]);
11290 (define_insn "*indirect_jump"
11291 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11294 [(set_attr "type" "ibr")
11295 (set_attr "length_immediate" "0")])
11297 (define_expand "tablejump"
11298 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11299 (use (label_ref (match_operand 1)))])]
11302 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11303 relative. Convert the relative address to an absolute address. */
11307 enum rtx_code code;
11309 /* We can't use @GOTOFF for text labels on VxWorks;
11310 see gotoff_operand. */
11311 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11315 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11317 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11321 op1 = pic_offset_table_rtx;
11326 op0 = pic_offset_table_rtx;
11330 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11335 operands[0] = convert_memory_address (word_mode, operands[0]);
11338 (define_insn "*tablejump_1"
11339 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11340 (use (label_ref (match_operand 1)))]
11343 [(set_attr "type" "ibr")
11344 (set_attr "length_immediate" "0")])
11346 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11349 [(set (reg FLAGS_REG) (match_operand 0))
11350 (set (match_operand:QI 1 "register_operand")
11351 (match_operator:QI 2 "ix86_comparison_operator"
11352 [(reg FLAGS_REG) (const_int 0)]))
11353 (set (match_operand 3 "q_regs_operand")
11354 (zero_extend (match_dup 1)))]
11355 "(peep2_reg_dead_p (3, operands[1])
11356 || operands_match_p (operands[1], operands[3]))
11357 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11358 [(set (match_dup 4) (match_dup 0))
11359 (set (strict_low_part (match_dup 5))
11362 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11363 operands[5] = gen_lowpart (QImode, operands[3]);
11364 ix86_expand_clear (operands[3]);
11368 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11369 (match_operand 4)])
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (set (match_operand 3 "q_regs_operand")
11374 (zero_extend (match_dup 1)))]
11375 "(peep2_reg_dead_p (3, operands[1])
11376 || operands_match_p (operands[1], operands[3]))
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(parallel [(set (match_dup 5) (match_dup 0))
11380 (set (strict_low_part (match_dup 6))
11383 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11384 operands[6] = gen_lowpart (QImode, operands[3]);
11385 ix86_expand_clear (operands[3]);
11388 ;; Similar, but match zero extend with andsi3.
11391 [(set (reg FLAGS_REG) (match_operand 0))
11392 (set (match_operand:QI 1 "register_operand")
11393 (match_operator:QI 2 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)]))
11395 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11396 (and:SI (match_dup 3) (const_int 255)))
11397 (clobber (reg:CC FLAGS_REG))])]
11398 "REGNO (operands[1]) == REGNO (operands[3])
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(set (match_dup 4) (match_dup 0))
11401 (set (strict_low_part (match_dup 5))
11404 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11405 operands[5] = gen_lowpart (QImode, operands[3]);
11406 ix86_expand_clear (operands[3]);
11410 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11411 (match_operand 4)])
11412 (set (match_operand:QI 1 "register_operand")
11413 (match_operator:QI 2 "ix86_comparison_operator"
11414 [(reg FLAGS_REG) (const_int 0)]))
11415 (parallel [(set (match_operand 3 "q_regs_operand")
11416 (zero_extend (match_dup 1)))
11417 (clobber (reg:CC FLAGS_REG))])]
11418 "(peep2_reg_dead_p (3, operands[1])
11419 || operands_match_p (operands[1], operands[3]))
11420 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11421 [(parallel [(set (match_dup 5) (match_dup 0))
11423 (set (strict_low_part (match_dup 6))
11426 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427 operands[6] = gen_lowpart (QImode, operands[3]);
11428 ix86_expand_clear (operands[3]);
11431 ;; Call instructions.
11433 ;; The predicates normally associated with named expanders are not properly
11434 ;; checked for calls. This is a bug in the generic code, but it isn't that
11435 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11437 ;; P6 processors will jump to the address after the decrement when %esp
11438 ;; is used as a call operand, so they will execute return address as a code.
11439 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11441 ;; Register constraint for call instruction.
11442 (define_mode_attr c [(SI "l") (DI "r")])
11444 ;; Call subroutine returning no value.
11446 (define_expand "call"
11447 [(call (match_operand:QI 0)
11449 (use (match_operand 2))]
11452 ix86_expand_call (NULL, operands[0], operands[1],
11453 operands[2], NULL, false);
11457 (define_expand "sibcall"
11458 [(call (match_operand:QI 0)
11460 (use (match_operand 2))]
11463 ix86_expand_call (NULL, operands[0], operands[1],
11464 operands[2], NULL, true);
11468 (define_insn "*call"
11469 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11470 (match_operand 1))]
11471 "!SIBLING_CALL_P (insn)"
11472 "* return ix86_output_call_insn (insn, operands[0]);"
11473 [(set_attr "type" "call")])
11475 (define_insn "*call_rex64_ms_sysv"
11476 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11477 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rBwBz"))
11479 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11480 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11481 "* return ix86_output_call_insn (insn, operands[0]);"
11482 [(set_attr "type" "call")])
11484 (define_insn "*sibcall"
11485 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11486 (match_operand 1))]
11487 "SIBLING_CALL_P (insn)"
11488 "* return ix86_output_call_insn (insn, operands[0]);"
11489 [(set_attr "type" "call")])
11491 (define_insn "*sibcall_memory"
11492 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11494 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11496 "* return ix86_output_call_insn (insn, operands[0]);"
11497 [(set_attr "type" "call")])
11500 [(set (match_operand:W 0 "register_operand")
11501 (match_operand:W 1 "memory_operand"))
11502 (call (mem:QI (match_dup 0))
11503 (match_operand 3))]
11504 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11505 && peep2_reg_dead_p (2, operands[0])"
11506 [(parallel [(call (mem:QI (match_dup 1))
11508 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11511 [(set (match_operand:W 0 "register_operand")
11512 (match_operand:W 1 "memory_operand"))
11513 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11514 (call (mem:QI (match_dup 0))
11515 (match_operand 3))]
11516 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11517 && peep2_reg_dead_p (3, operands[0])"
11518 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11519 (parallel [(call (mem:QI (match_dup 1))
11521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11523 (define_expand "call_pop"
11524 [(parallel [(call (match_operand:QI 0)
11525 (match_operand:SI 1))
11526 (set (reg:SI SP_REG)
11527 (plus:SI (reg:SI SP_REG)
11528 (match_operand:SI 3)))])]
11531 ix86_expand_call (NULL, operands[0], operands[1],
11532 operands[2], operands[3], false);
11536 (define_insn "*call_pop"
11537 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 2 "immediate_operand" "i")))]
11542 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11543 "* return ix86_output_call_insn (insn, operands[0]);"
11544 [(set_attr "type" "call")])
11546 (define_insn "*sibcall_pop"
11547 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11549 (set (reg:SI SP_REG)
11550 (plus:SI (reg:SI SP_REG)
11551 (match_operand:SI 2 "immediate_operand" "i")))]
11552 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11553 "* return ix86_output_call_insn (insn, operands[0]);"
11554 [(set_attr "type" "call")])
11556 (define_insn "*sibcall_pop_memory"
11557 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 2 "immediate_operand" "i")))
11562 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11564 "* return ix86_output_call_insn (insn, operands[0]);"
11565 [(set_attr "type" "call")])
11568 [(set (match_operand:SI 0 "register_operand")
11569 (match_operand:SI 1 "memory_operand"))
11570 (parallel [(call (mem:QI (match_dup 0))
11572 (set (reg:SI SP_REG)
11573 (plus:SI (reg:SI SP_REG)
11574 (match_operand:SI 4 "immediate_operand")))])]
11575 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11576 && peep2_reg_dead_p (2, operands[0])"
11577 [(parallel [(call (mem:QI (match_dup 1))
11579 (set (reg:SI SP_REG)
11580 (plus:SI (reg:SI SP_REG)
11582 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11585 [(set (match_operand:SI 0 "register_operand")
11586 (match_operand:SI 1 "memory_operand"))
11587 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11588 (parallel [(call (mem:QI (match_dup 0))
11590 (set (reg:SI SP_REG)
11591 (plus:SI (reg:SI SP_REG)
11592 (match_operand:SI 4 "immediate_operand")))])]
11593 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11594 && peep2_reg_dead_p (3, operands[0])"
11595 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11596 (parallel [(call (mem:QI (match_dup 1))
11598 (set (reg:SI SP_REG)
11599 (plus:SI (reg:SI SP_REG)
11601 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11603 ;; Combining simple memory jump instruction
11606 [(set (match_operand:W 0 "register_operand")
11607 (match_operand:W 1 "memory_operand"))
11608 (set (pc) (match_dup 0))]
11609 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11610 [(set (pc) (match_dup 1))])
11612 ;; Call subroutine, returning value in operand 0
11614 (define_expand "call_value"
11615 [(set (match_operand 0)
11616 (call (match_operand:QI 1)
11617 (match_operand 2)))
11618 (use (match_operand 3))]
11621 ix86_expand_call (operands[0], operands[1], operands[2],
11622 operands[3], NULL, false);
11626 (define_expand "sibcall_value"
11627 [(set (match_operand 0)
11628 (call (match_operand:QI 1)
11629 (match_operand 2)))
11630 (use (match_operand 3))]
11633 ix86_expand_call (operands[0], operands[1], operands[2],
11634 operands[3], NULL, true);
11638 (define_insn "*call_value"
11639 [(set (match_operand 0)
11640 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11641 (match_operand 2)))]
11642 "!SIBLING_CALL_P (insn)"
11643 "* return ix86_output_call_insn (insn, operands[1]);"
11644 [(set_attr "type" "callv")])
11646 (define_insn "*sibcall_value"
11647 [(set (match_operand 0)
11648 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11649 (match_operand 2)))]
11650 "SIBLING_CALL_P (insn)"
11651 "* return ix86_output_call_insn (insn, operands[1]);"
11652 [(set_attr "type" "callv")])
11654 (define_insn "*sibcall_value_memory"
11655 [(set (match_operand 0)
11656 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11657 (match_operand 2)))
11658 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11660 "* return ix86_output_call_insn (insn, operands[1]);"
11661 [(set_attr "type" "callv")])
11664 [(set (match_operand:W 0 "register_operand")
11665 (match_operand:W 1 "memory_operand"))
11666 (set (match_operand 2)
11667 (call (mem:QI (match_dup 0))
11668 (match_operand 3)))]
11669 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11670 && peep2_reg_dead_p (2, operands[0])"
11671 [(parallel [(set (match_dup 2)
11672 (call (mem:QI (match_dup 1))
11674 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11677 [(set (match_operand:W 0 "register_operand")
11678 (match_operand:W 1 "memory_operand"))
11679 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
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 (2))
11684 && peep2_reg_dead_p (3, operands[0])"
11685 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11686 (parallel [(set (match_dup 2)
11687 (call (mem:QI (match_dup 1))
11689 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11691 (define_insn "*call_value_rex64_ms_sysv"
11692 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11693 [(set (match_operand 0)
11694 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rBwBz"))
11695 (match_operand 2)))
11696 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11697 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11698 "* return ix86_output_call_insn (insn, operands[1]);"
11699 [(set_attr "type" "callv")])
11701 (define_expand "call_value_pop"
11702 [(parallel [(set (match_operand 0)
11703 (call (match_operand:QI 1)
11704 (match_operand:SI 2)))
11705 (set (reg:SI SP_REG)
11706 (plus:SI (reg:SI SP_REG)
11707 (match_operand:SI 4)))])]
11710 ix86_expand_call (operands[0], operands[1], operands[2],
11711 operands[3], operands[4], false);
11715 (define_insn "*call_value_pop"
11716 [(set (match_operand 0)
11717 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11718 (match_operand 2)))
11719 (set (reg:SI SP_REG)
11720 (plus:SI (reg:SI SP_REG)
11721 (match_operand:SI 3 "immediate_operand" "i")))]
11722 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11723 "* return ix86_output_call_insn (insn, operands[1]);"
11724 [(set_attr "type" "callv")])
11726 (define_insn "*sibcall_value_pop"
11727 [(set (match_operand 0)
11728 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11729 (match_operand 2)))
11730 (set (reg:SI SP_REG)
11731 (plus:SI (reg:SI SP_REG)
11732 (match_operand:SI 3 "immediate_operand" "i")))]
11733 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11734 "* return ix86_output_call_insn (insn, operands[1]);"
11735 [(set_attr "type" "callv")])
11737 (define_insn "*sibcall_value_pop_memory"
11738 [(set (match_operand 0)
11739 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11740 (match_operand 2)))
11741 (set (reg:SI SP_REG)
11742 (plus:SI (reg:SI SP_REG)
11743 (match_operand:SI 3 "immediate_operand" "i")))
11744 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11746 "* return ix86_output_call_insn (insn, operands[1]);"
11747 [(set_attr "type" "callv")])
11750 [(set (match_operand:SI 0 "register_operand")
11751 (match_operand:SI 1 "memory_operand"))
11752 (parallel [(set (match_operand 2)
11753 (call (mem:QI (match_dup 0))
11754 (match_operand 3)))
11755 (set (reg:SI SP_REG)
11756 (plus:SI (reg:SI SP_REG)
11757 (match_operand:SI 4 "immediate_operand")))])]
11758 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11759 && peep2_reg_dead_p (2, operands[0])"
11760 [(parallel [(set (match_dup 2)
11761 (call (mem:QI (match_dup 1))
11763 (set (reg:SI SP_REG)
11764 (plus:SI (reg:SI SP_REG)
11766 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11769 [(set (match_operand:SI 0 "register_operand")
11770 (match_operand:SI 1 "memory_operand"))
11771 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11772 (parallel [(set (match_operand 2)
11773 (call (mem:QI (match_dup 0))
11774 (match_operand 3)))
11775 (set (reg:SI SP_REG)
11776 (plus:SI (reg:SI SP_REG)
11777 (match_operand:SI 4 "immediate_operand")))])]
11778 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11779 && peep2_reg_dead_p (3, operands[0])"
11780 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11781 (parallel [(set (match_dup 2)
11782 (call (mem:QI (match_dup 1))
11784 (set (reg:SI SP_REG)
11785 (plus:SI (reg:SI SP_REG)
11787 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11789 ;; Call subroutine returning any type.
11791 (define_expand "untyped_call"
11792 [(parallel [(call (match_operand 0)
11795 (match_operand 2)])]
11800 /* In order to give reg-stack an easier job in validating two
11801 coprocessor registers as containing a possible return value,
11802 simply pretend the untyped call returns a complex long double
11805 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11806 and should have the default ABI. */
11808 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11809 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11810 operands[0], const0_rtx,
11811 GEN_INT ((TARGET_64BIT
11812 ? (ix86_abi == SYSV_ABI
11813 ? X86_64_SSE_REGPARM_MAX
11814 : X86_64_MS_SSE_REGPARM_MAX)
11815 : X86_32_SSE_REGPARM_MAX)
11819 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11821 rtx set = XVECEXP (operands[2], 0, i);
11822 emit_move_insn (SET_DEST (set), SET_SRC (set));
11825 /* The optimizer does not know that the call sets the function value
11826 registers we stored in the result block. We avoid problems by
11827 claiming that all hard registers are used and clobbered at this
11829 emit_insn (gen_blockage ());
11834 ;; Prologue and epilogue instructions
11836 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11837 ;; all of memory. This blocks insns from being moved across this point.
11839 (define_insn "blockage"
11840 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11843 [(set_attr "length" "0")])
11845 ;; Do not schedule instructions accessing memory across this point.
11847 (define_expand "memory_blockage"
11848 [(set (match_dup 0)
11849 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11852 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11853 MEM_VOLATILE_P (operands[0]) = 1;
11856 (define_insn "*memory_blockage"
11857 [(set (match_operand:BLK 0)
11858 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11861 [(set_attr "length" "0")])
11863 ;; As USE insns aren't meaningful after reload, this is used instead
11864 ;; to prevent deleting instructions setting registers for PIC code
11865 (define_insn "prologue_use"
11866 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11869 [(set_attr "length" "0")])
11871 ;; Insn emitted into the body of a function to return from a function.
11872 ;; This is only done if the function's epilogue is known to be simple.
11873 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11875 (define_expand "return"
11877 "ix86_can_use_return_insn_p ()"
11879 if (crtl->args.pops_args)
11881 rtx popc = GEN_INT (crtl->args.pops_args);
11882 emit_jump_insn (gen_simple_return_pop_internal (popc));
11887 ;; We need to disable this for TARGET_SEH, as otherwise
11888 ;; shrink-wrapped prologue gets enabled too. This might exceed
11889 ;; the maximum size of prologue in unwind information.
11891 (define_expand "simple_return"
11895 if (crtl->args.pops_args)
11897 rtx popc = GEN_INT (crtl->args.pops_args);
11898 emit_jump_insn (gen_simple_return_pop_internal (popc));
11903 (define_insn "simple_return_internal"
11907 [(set_attr "length" "1")
11908 (set_attr "atom_unit" "jeu")
11909 (set_attr "length_immediate" "0")
11910 (set_attr "modrm" "0")])
11912 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11913 ;; instruction Athlon and K8 have.
11915 (define_insn "simple_return_internal_long"
11917 (unspec [(const_int 0)] UNSPEC_REP)]
11920 [(set_attr "length" "2")
11921 (set_attr "atom_unit" "jeu")
11922 (set_attr "length_immediate" "0")
11923 (set_attr "prefix_rep" "1")
11924 (set_attr "modrm" "0")])
11926 (define_insn "simple_return_pop_internal"
11928 (use (match_operand:SI 0 "const_int_operand"))]
11931 [(set_attr "length" "3")
11932 (set_attr "atom_unit" "jeu")
11933 (set_attr "length_immediate" "2")
11934 (set_attr "modrm" "0")])
11936 (define_insn "simple_return_indirect_internal"
11938 (use (match_operand:SI 0 "register_operand" "r"))]
11941 [(set_attr "type" "ibr")
11942 (set_attr "length_immediate" "0")])
11948 [(set_attr "length" "1")
11949 (set_attr "length_immediate" "0")
11950 (set_attr "modrm" "0")])
11952 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11953 (define_insn "nops"
11954 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11958 int num = INTVAL (operands[0]);
11960 gcc_assert (IN_RANGE (num, 1, 8));
11963 fputs ("\tnop\n", asm_out_file);
11967 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11968 (set_attr "length_immediate" "0")
11969 (set_attr "modrm" "0")])
11971 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11972 ;; branch prediction penalty for the third jump in a 16-byte
11976 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11979 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11980 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11982 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11983 The align insn is used to avoid 3 jump instructions in the row to improve
11984 branch prediction and the benefits hardly outweigh the cost of extra 8
11985 nops on the average inserted by full alignment pseudo operation. */
11989 [(set_attr "length" "16")])
11991 (define_expand "prologue"
11994 "ix86_expand_prologue (); DONE;")
11996 (define_insn "set_got"
11997 [(set (match_operand:SI 0 "register_operand" "=r")
11998 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11999 (clobber (reg:CC FLAGS_REG))]
12001 "* return output_set_got (operands[0], NULL_RTX);"
12002 [(set_attr "type" "multi")
12003 (set_attr "length" "12")])
12005 (define_insn "set_got_labelled"
12006 [(set (match_operand:SI 0 "register_operand" "=r")
12007 (unspec:SI [(label_ref (match_operand 1))]
12009 (clobber (reg:CC FLAGS_REG))]
12011 "* return output_set_got (operands[0], operands[1]);"
12012 [(set_attr "type" "multi")
12013 (set_attr "length" "12")])
12015 (define_insn "set_got_rex64"
12016 [(set (match_operand:DI 0 "register_operand" "=r")
12017 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12019 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12020 [(set_attr "type" "lea")
12021 (set_attr "length_address" "4")
12022 (set_attr "mode" "DI")])
12024 (define_insn "set_rip_rex64"
12025 [(set (match_operand:DI 0 "register_operand" "=r")
12026 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12028 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12029 [(set_attr "type" "lea")
12030 (set_attr "length_address" "4")
12031 (set_attr "mode" "DI")])
12033 (define_insn "set_got_offset_rex64"
12034 [(set (match_operand:DI 0 "register_operand" "=r")
12036 [(label_ref (match_operand 1))]
12037 UNSPEC_SET_GOT_OFFSET))]
12039 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12040 [(set_attr "type" "imov")
12041 (set_attr "length_immediate" "0")
12042 (set_attr "length_address" "8")
12043 (set_attr "mode" "DI")])
12045 (define_expand "epilogue"
12048 "ix86_expand_epilogue (1); DONE;")
12050 (define_expand "sibcall_epilogue"
12053 "ix86_expand_epilogue (0); DONE;")
12055 (define_expand "eh_return"
12056 [(use (match_operand 0 "register_operand"))]
12059 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12061 /* Tricky bit: we write the address of the handler to which we will
12062 be returning into someone else's stack frame, one word below the
12063 stack address we wish to restore. */
12064 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12065 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12066 tmp = gen_rtx_MEM (Pmode, tmp);
12067 emit_move_insn (tmp, ra);
12069 emit_jump_insn (gen_eh_return_internal ());
12074 (define_insn_and_split "eh_return_internal"
12078 "epilogue_completed"
12080 "ix86_expand_epilogue (2); DONE;")
12082 (define_insn "leave"
12083 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12084 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12085 (clobber (mem:BLK (scratch)))]
12088 [(set_attr "type" "leave")])
12090 (define_insn "leave_rex64"
12091 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12092 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12093 (clobber (mem:BLK (scratch)))]
12096 [(set_attr "type" "leave")])
12098 ;; Handle -fsplit-stack.
12100 (define_expand "split_stack_prologue"
12104 ix86_expand_split_stack_prologue ();
12108 ;; In order to support the call/return predictor, we use a return
12109 ;; instruction which the middle-end doesn't see.
12110 (define_insn "split_stack_return"
12111 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12112 UNSPECV_SPLIT_STACK_RETURN)]
12115 if (operands[0] == const0_rtx)
12120 [(set_attr "atom_unit" "jeu")
12121 (set_attr "modrm" "0")
12122 (set (attr "length")
12123 (if_then_else (match_operand:SI 0 "const0_operand")
12126 (set (attr "length_immediate")
12127 (if_then_else (match_operand:SI 0 "const0_operand")
12131 ;; If there are operand 0 bytes available on the stack, jump to
12134 (define_expand "split_stack_space_check"
12135 [(set (pc) (if_then_else
12136 (ltu (minus (reg SP_REG)
12137 (match_operand 0 "register_operand"))
12138 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12139 (label_ref (match_operand 1))
12143 rtx reg, size, limit;
12145 reg = gen_reg_rtx (Pmode);
12146 size = force_reg (Pmode, operands[0]);
12147 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12148 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12149 UNSPEC_STACK_CHECK);
12150 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12151 ix86_expand_branch (GEU, reg, limit, operands[1]);
12156 ;; Bit manipulation instructions.
12158 (define_expand "ffs<mode>2"
12159 [(set (match_dup 2) (const_int -1))
12160 (parallel [(set (match_dup 3) (match_dup 4))
12161 (set (match_operand:SWI48 0 "register_operand")
12163 (match_operand:SWI48 1 "nonimmediate_operand")))])
12164 (set (match_dup 0) (if_then_else:SWI48
12165 (eq (match_dup 3) (const_int 0))
12168 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12169 (clobber (reg:CC FLAGS_REG))])]
12172 enum machine_mode flags_mode;
12174 if (<MODE>mode == SImode && !TARGET_CMOVE)
12176 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12180 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12182 operands[2] = gen_reg_rtx (<MODE>mode);
12183 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12184 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12187 (define_insn_and_split "ffssi2_no_cmove"
12188 [(set (match_operand:SI 0 "register_operand" "=r")
12189 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12190 (clobber (match_scratch:SI 2 "=&q"))
12191 (clobber (reg:CC FLAGS_REG))]
12194 "&& reload_completed"
12195 [(parallel [(set (match_dup 4) (match_dup 5))
12196 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12197 (set (strict_low_part (match_dup 3))
12198 (eq:QI (match_dup 4) (const_int 0)))
12199 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12200 (clobber (reg:CC FLAGS_REG))])
12201 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12202 (clobber (reg:CC FLAGS_REG))])
12203 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12204 (clobber (reg:CC FLAGS_REG))])]
12206 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12208 operands[3] = gen_lowpart (QImode, operands[2]);
12209 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12210 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12212 ix86_expand_clear (operands[2]);
12215 (define_insn "*tzcnt<mode>_1"
12216 [(set (reg:CCC FLAGS_REG)
12217 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219 (set (match_operand:SWI48 0 "register_operand" "=r")
12220 (ctz:SWI48 (match_dup 1)))]
12222 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "alu1")
12224 (set_attr "prefix_0f" "1")
12225 (set_attr "prefix_rep" "1")
12226 (set_attr "btver2_decode" "double")
12227 (set_attr "mode" "<MODE>")])
12229 (define_insn "*bsf<mode>_1"
12230 [(set (reg:CCZ FLAGS_REG)
12231 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12233 (set (match_operand:SWI48 0 "register_operand" "=r")
12234 (ctz:SWI48 (match_dup 1)))]
12236 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12237 [(set_attr "type" "alu1")
12238 (set_attr "prefix_0f" "1")
12239 (set_attr "btver2_decode" "double")
12240 (set_attr "mode" "<MODE>")])
12242 (define_insn "ctz<mode>2"
12243 [(set (match_operand:SWI248 0 "register_operand" "=r")
12244 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12245 (clobber (reg:CC FLAGS_REG))]
12249 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12250 else if (optimize_function_for_size_p (cfun))
12252 else if (TARGET_GENERIC)
12253 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12254 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12256 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12258 [(set_attr "type" "alu1")
12259 (set_attr "prefix_0f" "1")
12260 (set (attr "prefix_rep")
12262 (ior (match_test "TARGET_BMI")
12263 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12264 (match_test "TARGET_GENERIC")))
12266 (const_string "0")))
12267 (set_attr "mode" "<MODE>")])
12269 (define_expand "clz<mode>2"
12271 [(set (match_operand:SWI248 0 "register_operand")
12274 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12275 (clobber (reg:CC FLAGS_REG))])
12277 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12278 (clobber (reg:CC FLAGS_REG))])]
12283 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12286 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12289 (define_insn "clz<mode>2_lzcnt"
12290 [(set (match_operand:SWI248 0 "register_operand" "=r")
12291 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12292 (clobber (reg:CC FLAGS_REG))]
12294 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12295 [(set_attr "prefix_rep" "1")
12296 (set_attr "type" "bitmanip")
12297 (set_attr "mode" "<MODE>")])
12299 ;; BMI instructions.
12300 (define_insn "*bmi_andn_<mode>"
12301 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12304 (match_operand:SWI48 1 "register_operand" "r,r"))
12305 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12306 (clobber (reg:CC FLAGS_REG))]
12308 "andn\t{%2, %1, %0|%0, %1, %2}"
12309 [(set_attr "type" "bitmanip")
12310 (set_attr "btver2_decode" "direct, double")
12311 (set_attr "mode" "<MODE>")])
12313 (define_insn "bmi_bextr_<mode>"
12314 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12315 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12316 (match_operand:SWI48 2 "register_operand" "r,r")]
12318 (clobber (reg:CC FLAGS_REG))]
12320 "bextr\t{%2, %1, %0|%0, %1, %2}"
12321 [(set_attr "type" "bitmanip")
12322 (set_attr "btver2_decode" "direct, double")
12323 (set_attr "mode" "<MODE>")])
12325 (define_insn "*bmi_blsi_<mode>"
12326 [(set (match_operand:SWI48 0 "register_operand" "=r")
12329 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12331 (clobber (reg:CC FLAGS_REG))]
12333 "blsi\t{%1, %0|%0, %1}"
12334 [(set_attr "type" "bitmanip")
12335 (set_attr "btver2_decode" "double")
12336 (set_attr "mode" "<MODE>")])
12338 (define_insn "*bmi_blsmsk_<mode>"
12339 [(set (match_operand:SWI48 0 "register_operand" "=r")
12342 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12345 (clobber (reg:CC FLAGS_REG))]
12347 "blsmsk\t{%1, %0|%0, %1}"
12348 [(set_attr "type" "bitmanip")
12349 (set_attr "btver2_decode" "double")
12350 (set_attr "mode" "<MODE>")])
12352 (define_insn "*bmi_blsr_<mode>"
12353 [(set (match_operand:SWI48 0 "register_operand" "=r")
12356 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12359 (clobber (reg:CC FLAGS_REG))]
12361 "blsr\t{%1, %0|%0, %1}"
12362 [(set_attr "type" "bitmanip")
12363 (set_attr "btver2_decode" "double")
12364 (set_attr "mode" "<MODE>")])
12366 ;; BMI2 instructions.
12367 (define_insn "bmi2_bzhi_<mode>3"
12368 [(set (match_operand:SWI48 0 "register_operand" "=r")
12369 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12370 (match_operand:SWI48 2 "register_operand" "r"))
12371 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12372 (clobber (reg:CC FLAGS_REG))]
12374 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12375 [(set_attr "type" "bitmanip")
12376 (set_attr "prefix" "vex")
12377 (set_attr "mode" "<MODE>")])
12379 (define_insn "bmi2_pdep_<mode>3"
12380 [(set (match_operand:SWI48 0 "register_operand" "=r")
12381 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12382 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12385 "pdep\t{%2, %1, %0|%0, %1, %2}"
12386 [(set_attr "type" "bitmanip")
12387 (set_attr "prefix" "vex")
12388 (set_attr "mode" "<MODE>")])
12390 (define_insn "bmi2_pext_<mode>3"
12391 [(set (match_operand:SWI48 0 "register_operand" "=r")
12392 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12393 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12396 "pext\t{%2, %1, %0|%0, %1, %2}"
12397 [(set_attr "type" "bitmanip")
12398 (set_attr "prefix" "vex")
12399 (set_attr "mode" "<MODE>")])
12401 ;; TBM instructions.
12402 (define_insn "tbm_bextri_<mode>"
12403 [(set (match_operand:SWI48 0 "register_operand" "=r")
12404 (zero_extract:SWI48
12405 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12406 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12407 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12408 (clobber (reg:CC FLAGS_REG))]
12411 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12412 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12414 [(set_attr "type" "bitmanip")
12415 (set_attr "mode" "<MODE>")])
12417 (define_insn "*tbm_blcfill_<mode>"
12418 [(set (match_operand:SWI48 0 "register_operand" "=r")
12421 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12424 (clobber (reg:CC FLAGS_REG))]
12426 "blcfill\t{%1, %0|%0, %1}"
12427 [(set_attr "type" "bitmanip")
12428 (set_attr "mode" "<MODE>")])
12430 (define_insn "*tbm_blci_<mode>"
12431 [(set (match_operand:SWI48 0 "register_operand" "=r")
12435 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12438 (clobber (reg:CC FLAGS_REG))]
12440 "blci\t{%1, %0|%0, %1}"
12441 [(set_attr "type" "bitmanip")
12442 (set_attr "mode" "<MODE>")])
12444 (define_insn "*tbm_blcic_<mode>"
12445 [(set (match_operand:SWI48 0 "register_operand" "=r")
12448 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12452 (clobber (reg:CC FLAGS_REG))]
12454 "blcic\t{%1, %0|%0, %1}"
12455 [(set_attr "type" "bitmanip")
12456 (set_attr "mode" "<MODE>")])
12458 (define_insn "*tbm_blcmsk_<mode>"
12459 [(set (match_operand:SWI48 0 "register_operand" "=r")
12462 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12465 (clobber (reg:CC FLAGS_REG))]
12467 "blcmsk\t{%1, %0|%0, %1}"
12468 [(set_attr "type" "bitmanip")
12469 (set_attr "mode" "<MODE>")])
12471 (define_insn "*tbm_blcs_<mode>"
12472 [(set (match_operand:SWI48 0 "register_operand" "=r")
12475 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12478 (clobber (reg:CC FLAGS_REG))]
12480 "blcs\t{%1, %0|%0, %1}"
12481 [(set_attr "type" "bitmanip")
12482 (set_attr "mode" "<MODE>")])
12484 (define_insn "*tbm_blsfill_<mode>"
12485 [(set (match_operand:SWI48 0 "register_operand" "=r")
12488 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12491 (clobber (reg:CC FLAGS_REG))]
12493 "blsfill\t{%1, %0|%0, %1}"
12494 [(set_attr "type" "bitmanip")
12495 (set_attr "mode" "<MODE>")])
12497 (define_insn "*tbm_blsic_<mode>"
12498 [(set (match_operand:SWI48 0 "register_operand" "=r")
12501 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12505 (clobber (reg:CC FLAGS_REG))]
12507 "blsic\t{%1, %0|%0, %1}"
12508 [(set_attr "type" "bitmanip")
12509 (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_t1mskc_<mode>"
12512 [(set (match_operand:SWI48 0 "register_operand" "=r")
12515 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12519 (clobber (reg:CC FLAGS_REG))]
12521 "t1mskc\t{%1, %0|%0, %1}"
12522 [(set_attr "type" "bitmanip")
12523 (set_attr "mode" "<MODE>")])
12525 (define_insn "*tbm_tzmsk_<mode>"
12526 [(set (match_operand:SWI48 0 "register_operand" "=r")
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12533 (clobber (reg:CC FLAGS_REG))]
12535 "tzmsk\t{%1, %0|%0, %1}"
12536 [(set_attr "type" "bitmanip")
12537 (set_attr "mode" "<MODE>")])
12539 (define_insn "bsr_rex64"
12540 [(set (match_operand:DI 0 "register_operand" "=r")
12541 (minus:DI (const_int 63)
12542 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12543 (clobber (reg:CC FLAGS_REG))]
12545 "bsr{q}\t{%1, %0|%0, %1}"
12546 [(set_attr "type" "alu1")
12547 (set_attr "prefix_0f" "1")
12548 (set_attr "mode" "DI")])
12551 [(set (match_operand:SI 0 "register_operand" "=r")
12552 (minus:SI (const_int 31)
12553 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12554 (clobber (reg:CC FLAGS_REG))]
12556 "bsr{l}\t{%1, %0|%0, %1}"
12557 [(set_attr "type" "alu1")
12558 (set_attr "prefix_0f" "1")
12559 (set_attr "mode" "SI")])
12561 (define_insn "*bsrhi"
12562 [(set (match_operand:HI 0 "register_operand" "=r")
12563 (minus:HI (const_int 15)
12564 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12565 (clobber (reg:CC FLAGS_REG))]
12567 "bsr{w}\t{%1, %0|%0, %1}"
12568 [(set_attr "type" "alu1")
12569 (set_attr "prefix_0f" "1")
12570 (set_attr "mode" "HI")])
12572 (define_insn "popcount<mode>2"
12573 [(set (match_operand:SWI248 0 "register_operand" "=r")
12575 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12576 (clobber (reg:CC FLAGS_REG))]
12580 return "popcnt\t{%1, %0|%0, %1}";
12582 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12585 [(set_attr "prefix_rep" "1")
12586 (set_attr "type" "bitmanip")
12587 (set_attr "mode" "<MODE>")])
12589 (define_insn "*popcount<mode>2_cmp"
12590 [(set (reg FLAGS_REG)
12593 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12595 (set (match_operand:SWI248 0 "register_operand" "=r")
12596 (popcount:SWI248 (match_dup 1)))]
12597 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12600 return "popcnt\t{%1, %0|%0, %1}";
12602 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12605 [(set_attr "prefix_rep" "1")
12606 (set_attr "type" "bitmanip")
12607 (set_attr "mode" "<MODE>")])
12609 (define_insn "*popcountsi2_cmp_zext"
12610 [(set (reg FLAGS_REG)
12612 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12614 (set (match_operand:DI 0 "register_operand" "=r")
12615 (zero_extend:DI(popcount:SI (match_dup 1))))]
12616 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12619 return "popcnt\t{%1, %0|%0, %1}";
12621 return "popcnt{l}\t{%1, %0|%0, %1}";
12624 [(set_attr "prefix_rep" "1")
12625 (set_attr "type" "bitmanip")
12626 (set_attr "mode" "SI")])
12628 (define_expand "bswapdi2"
12629 [(set (match_operand:DI 0 "register_operand")
12630 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12634 operands[1] = force_reg (DImode, operands[1]);
12637 (define_expand "bswapsi2"
12638 [(set (match_operand:SI 0 "register_operand")
12639 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12644 else if (TARGET_BSWAP)
12645 operands[1] = force_reg (SImode, operands[1]);
12648 rtx x = operands[0];
12650 emit_move_insn (x, operands[1]);
12651 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12652 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12653 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12658 (define_insn "*bswap<mode>2_movbe"
12659 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12660 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12662 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12665 movbe\t{%1, %0|%0, %1}
12666 movbe\t{%1, %0|%0, %1}"
12667 [(set_attr "type" "bitmanip,imov,imov")
12668 (set_attr "modrm" "0,1,1")
12669 (set_attr "prefix_0f" "*,1,1")
12670 (set_attr "prefix_extra" "*,1,1")
12671 (set_attr "mode" "<MODE>")])
12673 (define_insn "*bswap<mode>2"
12674 [(set (match_operand:SWI48 0 "register_operand" "=r")
12675 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12678 [(set_attr "type" "bitmanip")
12679 (set_attr "modrm" "0")
12680 (set_attr "mode" "<MODE>")])
12682 (define_insn "*bswaphi_lowpart_1"
12683 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12684 (bswap:HI (match_dup 0)))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12688 xchg{b}\t{%h0, %b0|%b0, %h0}
12689 rol{w}\t{$8, %0|%0, 8}"
12690 [(set_attr "length" "2,4")
12691 (set_attr "mode" "QI,HI")])
12693 (define_insn "bswaphi_lowpart"
12694 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12695 (bswap:HI (match_dup 0)))
12696 (clobber (reg:CC FLAGS_REG))]
12698 "rol{w}\t{$8, %0|%0, 8}"
12699 [(set_attr "length" "4")
12700 (set_attr "mode" "HI")])
12702 (define_expand "paritydi2"
12703 [(set (match_operand:DI 0 "register_operand")
12704 (parity:DI (match_operand:DI 1 "register_operand")))]
12707 rtx scratch = gen_reg_rtx (QImode);
12710 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12711 NULL_RTX, operands[1]));
12713 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12714 gen_rtx_REG (CCmode, FLAGS_REG),
12716 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12719 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12722 rtx tmp = gen_reg_rtx (SImode);
12724 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12725 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12730 (define_expand "paritysi2"
12731 [(set (match_operand:SI 0 "register_operand")
12732 (parity:SI (match_operand:SI 1 "register_operand")))]
12735 rtx scratch = gen_reg_rtx (QImode);
12738 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12740 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12741 gen_rtx_REG (CCmode, FLAGS_REG),
12743 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12745 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12749 (define_insn_and_split "paritydi2_cmp"
12750 [(set (reg:CC FLAGS_REG)
12751 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12753 (clobber (match_scratch:DI 0 "=r"))
12754 (clobber (match_scratch:SI 1 "=&r"))
12755 (clobber (match_scratch:HI 2 "=Q"))]
12758 "&& reload_completed"
12760 [(set (match_dup 1)
12761 (xor:SI (match_dup 1) (match_dup 4)))
12762 (clobber (reg:CC FLAGS_REG))])
12764 [(set (reg:CC FLAGS_REG)
12765 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12766 (clobber (match_dup 1))
12767 (clobber (match_dup 2))])]
12769 operands[4] = gen_lowpart (SImode, operands[3]);
12773 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12774 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12777 operands[1] = gen_highpart (SImode, operands[3]);
12780 (define_insn_and_split "paritysi2_cmp"
12781 [(set (reg:CC FLAGS_REG)
12782 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12784 (clobber (match_scratch:SI 0 "=r"))
12785 (clobber (match_scratch:HI 1 "=&Q"))]
12788 "&& reload_completed"
12790 [(set (match_dup 1)
12791 (xor:HI (match_dup 1) (match_dup 3)))
12792 (clobber (reg:CC FLAGS_REG))])
12794 [(set (reg:CC FLAGS_REG)
12795 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12796 (clobber (match_dup 1))])]
12798 operands[3] = gen_lowpart (HImode, operands[2]);
12800 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12801 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12804 (define_insn "*parityhi2_cmp"
12805 [(set (reg:CC FLAGS_REG)
12806 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12808 (clobber (match_scratch:HI 0 "=Q"))]
12810 "xor{b}\t{%h0, %b0|%b0, %h0}"
12811 [(set_attr "length" "2")
12812 (set_attr "mode" "HI")])
12815 ;; Thread-local storage patterns for ELF.
12817 ;; Note that these code sequences must appear exactly as shown
12818 ;; in order to allow linker relaxation.
12820 (define_insn "*tls_global_dynamic_32_gnu"
12821 [(set (match_operand:SI 0 "register_operand" "=a")
12823 [(match_operand:SI 1 "register_operand" "b")
12824 (match_operand 2 "tls_symbolic_operand")
12825 (match_operand 3 "constant_call_address_operand" "Bz")
12828 (clobber (match_scratch:SI 4 "=d"))
12829 (clobber (match_scratch:SI 5 "=c"))
12830 (clobber (reg:CC FLAGS_REG))]
12831 "!TARGET_64BIT && TARGET_GNU_TLS"
12834 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12835 if (TARGET_SUN_TLS)
12836 #ifdef HAVE_AS_IX86_TLSGDPLT
12837 return "call\t%a2@tlsgdplt";
12839 return "call\t%p3@plt";
12841 return "call\t%P3";
12843 [(set_attr "type" "multi")
12844 (set_attr "length" "12")])
12846 (define_expand "tls_global_dynamic_32"
12848 [(set (match_operand:SI 0 "register_operand")
12849 (unspec:SI [(match_operand:SI 2 "register_operand")
12850 (match_operand 1 "tls_symbolic_operand")
12851 (match_operand 3 "constant_call_address_operand")
12854 (clobber (match_scratch:SI 4))
12855 (clobber (match_scratch:SI 5))
12856 (clobber (reg:CC FLAGS_REG))])]
12858 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12860 (define_insn "*tls_global_dynamic_64_<mode>"
12861 [(set (match_operand:P 0 "register_operand" "=a")
12863 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12864 (match_operand 3)))
12865 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12870 fputs (ASM_BYTE "0x66\n", asm_out_file);
12872 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12873 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12874 fputs ("\trex64\n", asm_out_file);
12875 if (TARGET_SUN_TLS)
12876 return "call\t%p2@plt";
12877 return "call\t%P2";
12879 [(set_attr "type" "multi")
12880 (set (attr "length")
12881 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12883 (define_insn "*tls_global_dynamic_64_largepic"
12884 [(set (match_operand:DI 0 "register_operand" "=a")
12886 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12887 (match_operand:DI 3 "immediate_operand" "i")))
12888 (match_operand 4)))
12889 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12891 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12892 && GET_CODE (operands[3]) == CONST
12893 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12894 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12897 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12898 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12899 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12900 return "call\t{*%%rax|rax}";
12902 [(set_attr "type" "multi")
12903 (set_attr "length" "22")])
12905 (define_expand "tls_global_dynamic_64_<mode>"
12907 [(set (match_operand:P 0 "register_operand")
12909 (mem:QI (match_operand 2))
12911 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12914 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12916 (define_insn "*tls_local_dynamic_base_32_gnu"
12917 [(set (match_operand:SI 0 "register_operand" "=a")
12919 [(match_operand:SI 1 "register_operand" "b")
12920 (match_operand 2 "constant_call_address_operand" "Bz")
12922 UNSPEC_TLS_LD_BASE))
12923 (clobber (match_scratch:SI 3 "=d"))
12924 (clobber (match_scratch:SI 4 "=c"))
12925 (clobber (reg:CC FLAGS_REG))]
12926 "!TARGET_64BIT && TARGET_GNU_TLS"
12929 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12930 if (TARGET_SUN_TLS)
12932 if (HAVE_AS_IX86_TLSLDMPLT)
12933 return "call\t%&@tlsldmplt";
12935 return "call\t%p2@plt";
12937 return "call\t%P2";
12939 [(set_attr "type" "multi")
12940 (set_attr "length" "11")])
12942 (define_expand "tls_local_dynamic_base_32"
12944 [(set (match_operand:SI 0 "register_operand")
12946 [(match_operand:SI 1 "register_operand")
12947 (match_operand 2 "constant_call_address_operand")
12949 UNSPEC_TLS_LD_BASE))
12950 (clobber (match_scratch:SI 3))
12951 (clobber (match_scratch:SI 4))
12952 (clobber (reg:CC FLAGS_REG))])]
12954 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12956 (define_insn "*tls_local_dynamic_base_64_<mode>"
12957 [(set (match_operand:P 0 "register_operand" "=a")
12959 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
12960 (match_operand 2)))
12961 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12965 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12966 if (TARGET_SUN_TLS)
12967 return "call\t%p1@plt";
12968 return "call\t%P1";
12970 [(set_attr "type" "multi")
12971 (set_attr "length" "12")])
12973 (define_insn "*tls_local_dynamic_base_64_largepic"
12974 [(set (match_operand:DI 0 "register_operand" "=a")
12976 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12977 (match_operand:DI 2 "immediate_operand" "i")))
12978 (match_operand 3)))
12979 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12980 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12981 && GET_CODE (operands[2]) == CONST
12982 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12983 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12986 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12987 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12988 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12989 return "call\t{*%%rax|rax}";
12991 [(set_attr "type" "multi")
12992 (set_attr "length" "22")])
12994 (define_expand "tls_local_dynamic_base_64_<mode>"
12996 [(set (match_operand:P 0 "register_operand")
12998 (mem:QI (match_operand 1))
13000 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13002 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13004 ;; Local dynamic of a single variable is a lose. Show combine how
13005 ;; to convert that back to global dynamic.
13007 (define_insn_and_split "*tls_local_dynamic_32_once"
13008 [(set (match_operand:SI 0 "register_operand" "=a")
13010 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13011 (match_operand 2 "constant_call_address_operand" "Bz")
13013 UNSPEC_TLS_LD_BASE)
13014 (const:SI (unspec:SI
13015 [(match_operand 3 "tls_symbolic_operand")]
13017 (clobber (match_scratch:SI 4 "=d"))
13018 (clobber (match_scratch:SI 5 "=c"))
13019 (clobber (reg:CC FLAGS_REG))]
13024 [(set (match_dup 0)
13025 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13028 (clobber (match_dup 4))
13029 (clobber (match_dup 5))
13030 (clobber (reg:CC FLAGS_REG))])])
13032 ;; Segment register for the thread base ptr load
13033 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13035 ;; Load and add the thread base pointer from %<tp_seg>:0.
13036 (define_insn "*load_tp_x32"
13037 [(set (match_operand:SI 0 "register_operand" "=r")
13038 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13040 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13041 [(set_attr "type" "imov")
13042 (set_attr "modrm" "0")
13043 (set_attr "length" "7")
13044 (set_attr "memory" "load")
13045 (set_attr "imm_disp" "false")])
13047 (define_insn "*load_tp_x32_zext"
13048 [(set (match_operand:DI 0 "register_operand" "=r")
13049 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13051 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13052 [(set_attr "type" "imov")
13053 (set_attr "modrm" "0")
13054 (set_attr "length" "7")
13055 (set_attr "memory" "load")
13056 (set_attr "imm_disp" "false")])
13058 (define_insn "*load_tp_<mode>"
13059 [(set (match_operand:P 0 "register_operand" "=r")
13060 (unspec:P [(const_int 0)] UNSPEC_TP))]
13062 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13063 [(set_attr "type" "imov")
13064 (set_attr "modrm" "0")
13065 (set_attr "length" "7")
13066 (set_attr "memory" "load")
13067 (set_attr "imm_disp" "false")])
13069 (define_insn "*add_tp_x32"
13070 [(set (match_operand:SI 0 "register_operand" "=r")
13071 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13072 (match_operand:SI 1 "register_operand" "0")))
13073 (clobber (reg:CC FLAGS_REG))]
13075 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13076 [(set_attr "type" "alu")
13077 (set_attr "modrm" "0")
13078 (set_attr "length" "7")
13079 (set_attr "memory" "load")
13080 (set_attr "imm_disp" "false")])
13082 (define_insn "*add_tp_x32_zext"
13083 [(set (match_operand:DI 0 "register_operand" "=r")
13085 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13086 (match_operand:SI 1 "register_operand" "0"))))
13087 (clobber (reg:CC FLAGS_REG))]
13089 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13090 [(set_attr "type" "alu")
13091 (set_attr "modrm" "0")
13092 (set_attr "length" "7")
13093 (set_attr "memory" "load")
13094 (set_attr "imm_disp" "false")])
13096 (define_insn "*add_tp_<mode>"
13097 [(set (match_operand:P 0 "register_operand" "=r")
13098 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13099 (match_operand:P 1 "register_operand" "0")))
13100 (clobber (reg:CC FLAGS_REG))]
13102 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13103 [(set_attr "type" "alu")
13104 (set_attr "modrm" "0")
13105 (set_attr "length" "7")
13106 (set_attr "memory" "load")
13107 (set_attr "imm_disp" "false")])
13109 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13110 ;; %rax as destination of the initial executable code sequence.
13111 (define_insn "tls_initial_exec_64_sun"
13112 [(set (match_operand:DI 0 "register_operand" "=a")
13114 [(match_operand 1 "tls_symbolic_operand")]
13115 UNSPEC_TLS_IE_SUN))
13116 (clobber (reg:CC FLAGS_REG))]
13117 "TARGET_64BIT && TARGET_SUN_TLS"
13120 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13121 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13123 [(set_attr "type" "multi")])
13125 ;; GNU2 TLS patterns can be split.
13127 (define_expand "tls_dynamic_gnu2_32"
13128 [(set (match_dup 3)
13129 (plus:SI (match_operand:SI 2 "register_operand")
13131 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13134 [(set (match_operand:SI 0 "register_operand")
13135 (unspec:SI [(match_dup 1) (match_dup 3)
13136 (match_dup 2) (reg:SI SP_REG)]
13138 (clobber (reg:CC FLAGS_REG))])]
13139 "!TARGET_64BIT && TARGET_GNU2_TLS"
13141 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13142 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13145 (define_insn "*tls_dynamic_gnu2_lea_32"
13146 [(set (match_operand:SI 0 "register_operand" "=r")
13147 (plus:SI (match_operand:SI 1 "register_operand" "b")
13149 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13150 UNSPEC_TLSDESC))))]
13151 "!TARGET_64BIT && TARGET_GNU2_TLS"
13152 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13153 [(set_attr "type" "lea")
13154 (set_attr "mode" "SI")
13155 (set_attr "length" "6")
13156 (set_attr "length_address" "4")])
13158 (define_insn "*tls_dynamic_gnu2_call_32"
13159 [(set (match_operand:SI 0 "register_operand" "=a")
13160 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13161 (match_operand:SI 2 "register_operand" "0")
13162 ;; we have to make sure %ebx still points to the GOT
13163 (match_operand:SI 3 "register_operand" "b")
13166 (clobber (reg:CC FLAGS_REG))]
13167 "!TARGET_64BIT && TARGET_GNU2_TLS"
13168 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13169 [(set_attr "type" "call")
13170 (set_attr "length" "2")
13171 (set_attr "length_address" "0")])
13173 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13174 [(set (match_operand:SI 0 "register_operand" "=&a")
13176 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13177 (match_operand:SI 4)
13178 (match_operand:SI 2 "register_operand" "b")
13181 (const:SI (unspec:SI
13182 [(match_operand 1 "tls_symbolic_operand")]
13184 (clobber (reg:CC FLAGS_REG))]
13185 "!TARGET_64BIT && TARGET_GNU2_TLS"
13188 [(set (match_dup 0) (match_dup 5))]
13190 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13191 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13194 (define_expand "tls_dynamic_gnu2_64"
13195 [(set (match_dup 2)
13196 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13199 [(set (match_operand:DI 0 "register_operand")
13200 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13202 (clobber (reg:CC FLAGS_REG))])]
13203 "TARGET_64BIT && TARGET_GNU2_TLS"
13205 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13206 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13209 (define_insn "*tls_dynamic_gnu2_lea_64"
13210 [(set (match_operand:DI 0 "register_operand" "=r")
13211 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13213 "TARGET_64BIT && TARGET_GNU2_TLS"
13214 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13215 [(set_attr "type" "lea")
13216 (set_attr "mode" "DI")
13217 (set_attr "length" "7")
13218 (set_attr "length_address" "4")])
13220 (define_insn "*tls_dynamic_gnu2_call_64"
13221 [(set (match_operand:DI 0 "register_operand" "=a")
13222 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13223 (match_operand:DI 2 "register_operand" "0")
13226 (clobber (reg:CC FLAGS_REG))]
13227 "TARGET_64BIT && TARGET_GNU2_TLS"
13228 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13229 [(set_attr "type" "call")
13230 (set_attr "length" "2")
13231 (set_attr "length_address" "0")])
13233 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13234 [(set (match_operand:DI 0 "register_operand" "=&a")
13236 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13237 (match_operand:DI 3)
13240 (const:DI (unspec:DI
13241 [(match_operand 1 "tls_symbolic_operand")]
13243 (clobber (reg:CC FLAGS_REG))]
13244 "TARGET_64BIT && TARGET_GNU2_TLS"
13247 [(set (match_dup 0) (match_dup 4))]
13249 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13250 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13253 ;; These patterns match the binary 387 instructions for addM3, subM3,
13254 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13255 ;; SFmode. The first is the normal insn, the second the same insn but
13256 ;; with one operand a conversion, and the third the same insn but with
13257 ;; the other operand a conversion. The conversion may be SFmode or
13258 ;; SImode if the target mode DFmode, but only SImode if the target mode
13261 ;; Gcc is slightly more smart about handling normal two address instructions
13262 ;; so use special patterns for add and mull.
13264 (define_insn "*fop_<mode>_comm_mixed"
13265 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13266 (match_operator:MODEF 3 "binary_fp_operator"
13267 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13268 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13269 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13270 && COMMUTATIVE_ARITH_P (operands[3])
13271 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13272 "* return output_387_binary_op (insn, operands);"
13273 [(set (attr "type")
13274 (if_then_else (eq_attr "alternative" "1,2")
13275 (if_then_else (match_operand:MODEF 3 "mult_operator")
13276 (const_string "ssemul")
13277 (const_string "sseadd"))
13278 (if_then_else (match_operand:MODEF 3 "mult_operator")
13279 (const_string "fmul")
13280 (const_string "fop"))))
13281 (set_attr "isa" "*,noavx,avx")
13282 (set_attr "prefix" "orig,orig,vex")
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn "*fop_<mode>_comm_sse"
13286 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13287 (match_operator:MODEF 3 "binary_fp_operator"
13288 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13289 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13290 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13291 && COMMUTATIVE_ARITH_P (operands[3])
13292 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13293 "* return output_387_binary_op (insn, operands);"
13294 [(set (attr "type")
13295 (if_then_else (match_operand:MODEF 3 "mult_operator")
13296 (const_string "ssemul")
13297 (const_string "sseadd")))
13298 (set_attr "isa" "noavx,avx")
13299 (set_attr "prefix" "orig,vex")
13300 (set_attr "mode" "<MODE>")])
13302 (define_insn "*fop_<mode>_comm_i387"
13303 [(set (match_operand:MODEF 0 "register_operand" "=f")
13304 (match_operator:MODEF 3 "binary_fp_operator"
13305 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13306 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13307 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13308 && COMMUTATIVE_ARITH_P (operands[3])
13309 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13310 "* return output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (if_then_else (match_operand:MODEF 3 "mult_operator")
13313 (const_string "fmul")
13314 (const_string "fop")))
13315 (set_attr "mode" "<MODE>")])
13317 (define_insn "*fop_<mode>_1_mixed"
13318 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13319 (match_operator:MODEF 3 "binary_fp_operator"
13320 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13321 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13322 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13323 && !COMMUTATIVE_ARITH_P (operands[3])
13324 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13325 "* return output_387_binary_op (insn, operands);"
13326 [(set (attr "type")
13327 (cond [(and (eq_attr "alternative" "2,3")
13328 (match_operand:MODEF 3 "mult_operator"))
13329 (const_string "ssemul")
13330 (and (eq_attr "alternative" "2,3")
13331 (match_operand:MODEF 3 "div_operator"))
13332 (const_string "ssediv")
13333 (eq_attr "alternative" "2,3")
13334 (const_string "sseadd")
13335 (match_operand:MODEF 3 "mult_operator")
13336 (const_string "fmul")
13337 (match_operand:MODEF 3 "div_operator")
13338 (const_string "fdiv")
13340 (const_string "fop")))
13341 (set_attr "isa" "*,*,noavx,avx")
13342 (set_attr "prefix" "orig,orig,orig,vex")
13343 (set_attr "mode" "<MODE>")])
13345 (define_insn "*rcpsf2_sse"
13346 [(set (match_operand:SF 0 "register_operand" "=x")
13347 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13350 "%vrcpss\t{%1, %d0|%d0, %1}"
13351 [(set_attr "type" "sse")
13352 (set_attr "atom_sse_attr" "rcp")
13353 (set_attr "btver2_sse_attr" "rcp")
13354 (set_attr "prefix" "maybe_vex")
13355 (set_attr "mode" "SF")])
13357 (define_insn "*fop_<mode>_1_sse"
13358 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13359 (match_operator:MODEF 3 "binary_fp_operator"
13360 [(match_operand:MODEF 1 "register_operand" "0,x")
13361 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13362 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13363 && !COMMUTATIVE_ARITH_P (operands[3])"
13364 "* return output_387_binary_op (insn, operands);"
13365 [(set (attr "type")
13366 (cond [(match_operand:MODEF 3 "mult_operator")
13367 (const_string "ssemul")
13368 (match_operand:MODEF 3 "div_operator")
13369 (const_string "ssediv")
13371 (const_string "sseadd")))
13372 (set_attr "isa" "noavx,avx")
13373 (set_attr "prefix" "orig,vex")
13374 (set_attr "mode" "<MODE>")])
13376 ;; This pattern is not fully shadowed by the pattern above.
13377 (define_insn "*fop_<mode>_1_i387"
13378 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13379 (match_operator:MODEF 3 "binary_fp_operator"
13380 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13381 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13382 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13383 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13384 && !COMMUTATIVE_ARITH_P (operands[3])
13385 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13386 "* return output_387_binary_op (insn, operands);"
13387 [(set (attr "type")
13388 (cond [(match_operand:MODEF 3 "mult_operator")
13389 (const_string "fmul")
13390 (match_operand:MODEF 3 "div_operator")
13391 (const_string "fdiv")
13393 (const_string "fop")))
13394 (set_attr "mode" "<MODE>")])
13396 ;; ??? Add SSE splitters for these!
13397 (define_insn "*fop_<MODEF:mode>_2_i387"
13398 [(set (match_operand:MODEF 0 "register_operand" "=f")
13399 (match_operator:MODEF 3 "binary_fp_operator"
13401 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13402 (match_operand:MODEF 2 "register_operand" "0")]))]
13403 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13404 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13405 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13406 || optimize_function_for_size_p (cfun))"
13407 { return output_387_binary_op (insn, operands); }
13408 [(set (attr "type")
13409 (cond [(match_operand:MODEF 3 "mult_operator")
13410 (const_string "fmul")
13411 (match_operand:MODEF 3 "div_operator")
13412 (const_string "fdiv")
13414 (const_string "fop")))
13415 (set_attr "fp_int_src" "true")
13416 (set_attr "mode" "<SWI24:MODE>")])
13418 (define_insn "*fop_<MODEF:mode>_3_i387"
13419 [(set (match_operand:MODEF 0 "register_operand" "=f")
13420 (match_operator:MODEF 3 "binary_fp_operator"
13421 [(match_operand:MODEF 1 "register_operand" "0")
13423 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13424 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13425 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13426 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13427 || optimize_function_for_size_p (cfun))"
13428 { return output_387_binary_op (insn, operands); }
13429 [(set (attr "type")
13430 (cond [(match_operand:MODEF 3 "mult_operator")
13431 (const_string "fmul")
13432 (match_operand:MODEF 3 "div_operator")
13433 (const_string "fdiv")
13435 (const_string "fop")))
13436 (set_attr "fp_int_src" "true")
13437 (set_attr "mode" "<MODE>")])
13439 (define_insn "*fop_df_4_i387"
13440 [(set (match_operand:DF 0 "register_operand" "=f,f")
13441 (match_operator:DF 3 "binary_fp_operator"
13443 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13444 (match_operand:DF 2 "register_operand" "0,f")]))]
13445 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13446 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13447 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13448 "* return output_387_binary_op (insn, operands);"
13449 [(set (attr "type")
13450 (cond [(match_operand:DF 3 "mult_operator")
13451 (const_string "fmul")
13452 (match_operand:DF 3 "div_operator")
13453 (const_string "fdiv")
13455 (const_string "fop")))
13456 (set_attr "mode" "SF")])
13458 (define_insn "*fop_df_5_i387"
13459 [(set (match_operand:DF 0 "register_operand" "=f,f")
13460 (match_operator:DF 3 "binary_fp_operator"
13461 [(match_operand:DF 1 "register_operand" "0,f")
13463 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13464 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13465 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13466 "* return output_387_binary_op (insn, operands);"
13467 [(set (attr "type")
13468 (cond [(match_operand:DF 3 "mult_operator")
13469 (const_string "fmul")
13470 (match_operand:DF 3 "div_operator")
13471 (const_string "fdiv")
13473 (const_string "fop")))
13474 (set_attr "mode" "SF")])
13476 (define_insn "*fop_df_6_i387"
13477 [(set (match_operand:DF 0 "register_operand" "=f,f")
13478 (match_operator:DF 3 "binary_fp_operator"
13480 (match_operand:SF 1 "register_operand" "0,f"))
13482 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13483 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13484 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13485 "* return output_387_binary_op (insn, operands);"
13486 [(set (attr "type")
13487 (cond [(match_operand:DF 3 "mult_operator")
13488 (const_string "fmul")
13489 (match_operand:DF 3 "div_operator")
13490 (const_string "fdiv")
13492 (const_string "fop")))
13493 (set_attr "mode" "SF")])
13495 (define_insn "*fop_xf_comm_i387"
13496 [(set (match_operand:XF 0 "register_operand" "=f")
13497 (match_operator:XF 3 "binary_fp_operator"
13498 [(match_operand:XF 1 "register_operand" "%0")
13499 (match_operand:XF 2 "register_operand" "f")]))]
13501 && COMMUTATIVE_ARITH_P (operands[3])"
13502 "* return output_387_binary_op (insn, operands);"
13503 [(set (attr "type")
13504 (if_then_else (match_operand:XF 3 "mult_operator")
13505 (const_string "fmul")
13506 (const_string "fop")))
13507 (set_attr "mode" "XF")])
13509 (define_insn "*fop_xf_1_i387"
13510 [(set (match_operand:XF 0 "register_operand" "=f,f")
13511 (match_operator:XF 3 "binary_fp_operator"
13512 [(match_operand:XF 1 "register_operand" "0,f")
13513 (match_operand:XF 2 "register_operand" "f,0")]))]
13515 && !COMMUTATIVE_ARITH_P (operands[3])"
13516 "* return output_387_binary_op (insn, operands);"
13517 [(set (attr "type")
13518 (cond [(match_operand:XF 3 "mult_operator")
13519 (const_string "fmul")
13520 (match_operand:XF 3 "div_operator")
13521 (const_string "fdiv")
13523 (const_string "fop")))
13524 (set_attr "mode" "XF")])
13526 (define_insn "*fop_xf_2_i387"
13527 [(set (match_operand:XF 0 "register_operand" "=f")
13528 (match_operator:XF 3 "binary_fp_operator"
13530 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13531 (match_operand:XF 2 "register_operand" "0")]))]
13533 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13534 { return output_387_binary_op (insn, operands); }
13535 [(set (attr "type")
13536 (cond [(match_operand:XF 3 "mult_operator")
13537 (const_string "fmul")
13538 (match_operand:XF 3 "div_operator")
13539 (const_string "fdiv")
13541 (const_string "fop")))
13542 (set_attr "fp_int_src" "true")
13543 (set_attr "mode" "<MODE>")])
13545 (define_insn "*fop_xf_3_i387"
13546 [(set (match_operand:XF 0 "register_operand" "=f")
13547 (match_operator:XF 3 "binary_fp_operator"
13548 [(match_operand:XF 1 "register_operand" "0")
13550 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13552 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13553 { return output_387_binary_op (insn, operands); }
13554 [(set (attr "type")
13555 (cond [(match_operand:XF 3 "mult_operator")
13556 (const_string "fmul")
13557 (match_operand:XF 3 "div_operator")
13558 (const_string "fdiv")
13560 (const_string "fop")))
13561 (set_attr "fp_int_src" "true")
13562 (set_attr "mode" "<MODE>")])
13564 (define_insn "*fop_xf_4_i387"
13565 [(set (match_operand:XF 0 "register_operand" "=f,f")
13566 (match_operator:XF 3 "binary_fp_operator"
13568 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13569 (match_operand:XF 2 "register_operand" "0,f")]))]
13571 "* return output_387_binary_op (insn, operands);"
13572 [(set (attr "type")
13573 (cond [(match_operand:XF 3 "mult_operator")
13574 (const_string "fmul")
13575 (match_operand:XF 3 "div_operator")
13576 (const_string "fdiv")
13578 (const_string "fop")))
13579 (set_attr "mode" "<MODE>")])
13581 (define_insn "*fop_xf_5_i387"
13582 [(set (match_operand:XF 0 "register_operand" "=f,f")
13583 (match_operator:XF 3 "binary_fp_operator"
13584 [(match_operand:XF 1 "register_operand" "0,f")
13586 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13588 "* return output_387_binary_op (insn, operands);"
13589 [(set (attr "type")
13590 (cond [(match_operand:XF 3 "mult_operator")
13591 (const_string "fmul")
13592 (match_operand:XF 3 "div_operator")
13593 (const_string "fdiv")
13595 (const_string "fop")))
13596 (set_attr "mode" "<MODE>")])
13598 (define_insn "*fop_xf_6_i387"
13599 [(set (match_operand:XF 0 "register_operand" "=f,f")
13600 (match_operator:XF 3 "binary_fp_operator"
13602 (match_operand:MODEF 1 "register_operand" "0,f"))
13604 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13606 "* return output_387_binary_op (insn, operands);"
13607 [(set (attr "type")
13608 (cond [(match_operand:XF 3 "mult_operator")
13609 (const_string "fmul")
13610 (match_operand:XF 3 "div_operator")
13611 (const_string "fdiv")
13613 (const_string "fop")))
13614 (set_attr "mode" "<MODE>")])
13616 ;; FPU special functions.
13618 ;; This pattern implements a no-op XFmode truncation for
13619 ;; all fancy i386 XFmode math functions.
13621 (define_insn "truncxf<mode>2_i387_noop_unspec"
13622 [(set (match_operand:MODEF 0 "register_operand" "=f")
13623 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13624 UNSPEC_TRUNC_NOOP))]
13625 "TARGET_USE_FANCY_MATH_387"
13626 "* return output_387_reg_move (insn, operands);"
13627 [(set_attr "type" "fmov")
13628 (set_attr "mode" "<MODE>")])
13630 (define_insn "sqrtxf2"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13632 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13633 "TARGET_USE_FANCY_MATH_387"
13635 [(set_attr "type" "fpspc")
13636 (set_attr "mode" "XF")
13637 (set_attr "athlon_decode" "direct")
13638 (set_attr "amdfam10_decode" "direct")
13639 (set_attr "bdver1_decode" "direct")])
13641 (define_insn "sqrt_extend<mode>xf2_i387"
13642 [(set (match_operand:XF 0 "register_operand" "=f")
13645 (match_operand:MODEF 1 "register_operand" "0"))))]
13646 "TARGET_USE_FANCY_MATH_387"
13648 [(set_attr "type" "fpspc")
13649 (set_attr "mode" "XF")
13650 (set_attr "athlon_decode" "direct")
13651 (set_attr "amdfam10_decode" "direct")
13652 (set_attr "bdver1_decode" "direct")])
13654 (define_insn "*rsqrtsf2_sse"
13655 [(set (match_operand:SF 0 "register_operand" "=x")
13656 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13659 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13660 [(set_attr "type" "sse")
13661 (set_attr "atom_sse_attr" "rcp")
13662 (set_attr "btver2_sse_attr" "rcp")
13663 (set_attr "prefix" "maybe_vex")
13664 (set_attr "mode" "SF")])
13666 (define_expand "rsqrtsf2"
13667 [(set (match_operand:SF 0 "register_operand")
13668 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13672 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13676 (define_insn "*sqrt<mode>2_sse"
13677 [(set (match_operand:MODEF 0 "register_operand" "=x")
13679 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13680 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13681 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13682 [(set_attr "type" "sse")
13683 (set_attr "atom_sse_attr" "sqrt")
13684 (set_attr "btver2_sse_attr" "sqrt")
13685 (set_attr "prefix" "maybe_vex")
13686 (set_attr "mode" "<MODE>")
13687 (set_attr "athlon_decode" "*")
13688 (set_attr "amdfam10_decode" "*")
13689 (set_attr "bdver1_decode" "*")])
13691 (define_expand "sqrt<mode>2"
13692 [(set (match_operand:MODEF 0 "register_operand")
13694 (match_operand:MODEF 1 "nonimmediate_operand")))]
13695 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13696 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13698 if (<MODE>mode == SFmode
13700 && TARGET_RECIP_SQRT
13701 && !optimize_function_for_size_p (cfun)
13702 && flag_finite_math_only && !flag_trapping_math
13703 && flag_unsafe_math_optimizations)
13705 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13709 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13711 rtx op0 = gen_reg_rtx (XFmode);
13712 rtx op1 = force_reg (<MODE>mode, operands[1]);
13714 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13715 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13720 (define_insn "fpremxf4_i387"
13721 [(set (match_operand:XF 0 "register_operand" "=f")
13722 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13723 (match_operand:XF 3 "register_operand" "1")]
13725 (set (match_operand:XF 1 "register_operand" "=u")
13726 (unspec:XF [(match_dup 2) (match_dup 3)]
13728 (set (reg:CCFP FPSR_REG)
13729 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13731 "TARGET_USE_FANCY_MATH_387"
13733 [(set_attr "type" "fpspc")
13734 (set_attr "mode" "XF")])
13736 (define_expand "fmodxf3"
13737 [(use (match_operand:XF 0 "register_operand"))
13738 (use (match_operand:XF 1 "general_operand"))
13739 (use (match_operand:XF 2 "general_operand"))]
13740 "TARGET_USE_FANCY_MATH_387"
13742 rtx label = gen_label_rtx ();
13744 rtx op1 = gen_reg_rtx (XFmode);
13745 rtx op2 = gen_reg_rtx (XFmode);
13747 emit_move_insn (op2, operands[2]);
13748 emit_move_insn (op1, operands[1]);
13750 emit_label (label);
13751 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13752 ix86_emit_fp_unordered_jump (label);
13753 LABEL_NUSES (label) = 1;
13755 emit_move_insn (operands[0], op1);
13759 (define_expand "fmod<mode>3"
13760 [(use (match_operand:MODEF 0 "register_operand"))
13761 (use (match_operand:MODEF 1 "general_operand"))
13762 (use (match_operand:MODEF 2 "general_operand"))]
13763 "TARGET_USE_FANCY_MATH_387"
13765 rtx (*gen_truncxf) (rtx, rtx);
13767 rtx label = gen_label_rtx ();
13769 rtx op1 = gen_reg_rtx (XFmode);
13770 rtx op2 = gen_reg_rtx (XFmode);
13772 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13773 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13775 emit_label (label);
13776 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13777 ix86_emit_fp_unordered_jump (label);
13778 LABEL_NUSES (label) = 1;
13780 /* Truncate the result properly for strict SSE math. */
13781 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13782 && !TARGET_MIX_SSE_I387)
13783 gen_truncxf = gen_truncxf<mode>2;
13785 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13787 emit_insn (gen_truncxf (operands[0], op1));
13791 (define_insn "fprem1xf4_i387"
13792 [(set (match_operand:XF 0 "register_operand" "=f")
13793 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13794 (match_operand:XF 3 "register_operand" "1")]
13796 (set (match_operand:XF 1 "register_operand" "=u")
13797 (unspec:XF [(match_dup 2) (match_dup 3)]
13799 (set (reg:CCFP FPSR_REG)
13800 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13802 "TARGET_USE_FANCY_MATH_387"
13804 [(set_attr "type" "fpspc")
13805 (set_attr "mode" "XF")])
13807 (define_expand "remainderxf3"
13808 [(use (match_operand:XF 0 "register_operand"))
13809 (use (match_operand:XF 1 "general_operand"))
13810 (use (match_operand:XF 2 "general_operand"))]
13811 "TARGET_USE_FANCY_MATH_387"
13813 rtx label = gen_label_rtx ();
13815 rtx op1 = gen_reg_rtx (XFmode);
13816 rtx op2 = gen_reg_rtx (XFmode);
13818 emit_move_insn (op2, operands[2]);
13819 emit_move_insn (op1, operands[1]);
13821 emit_label (label);
13822 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13823 ix86_emit_fp_unordered_jump (label);
13824 LABEL_NUSES (label) = 1;
13826 emit_move_insn (operands[0], op1);
13830 (define_expand "remainder<mode>3"
13831 [(use (match_operand:MODEF 0 "register_operand"))
13832 (use (match_operand:MODEF 1 "general_operand"))
13833 (use (match_operand:MODEF 2 "general_operand"))]
13834 "TARGET_USE_FANCY_MATH_387"
13836 rtx (*gen_truncxf) (rtx, rtx);
13838 rtx label = gen_label_rtx ();
13840 rtx op1 = gen_reg_rtx (XFmode);
13841 rtx op2 = gen_reg_rtx (XFmode);
13843 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13844 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13846 emit_label (label);
13848 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13849 ix86_emit_fp_unordered_jump (label);
13850 LABEL_NUSES (label) = 1;
13852 /* Truncate the result properly for strict SSE math. */
13853 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13854 && !TARGET_MIX_SSE_I387)
13855 gen_truncxf = gen_truncxf<mode>2;
13857 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13859 emit_insn (gen_truncxf (operands[0], op1));
13863 (define_int_iterator SINCOS
13867 (define_int_attr sincos
13868 [(UNSPEC_SIN "sin")
13869 (UNSPEC_COS "cos")])
13871 (define_insn "*<sincos>xf2_i387"
13872 [(set (match_operand:XF 0 "register_operand" "=f")
13873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13875 "TARGET_USE_FANCY_MATH_387
13876 && flag_unsafe_math_optimizations"
13878 [(set_attr "type" "fpspc")
13879 (set_attr "mode" "XF")])
13881 (define_insn "*<sincos>_extend<mode>xf2_i387"
13882 [(set (match_operand:XF 0 "register_operand" "=f")
13883 (unspec:XF [(float_extend:XF
13884 (match_operand:MODEF 1 "register_operand" "0"))]
13886 "TARGET_USE_FANCY_MATH_387
13887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13888 || TARGET_MIX_SSE_I387)
13889 && flag_unsafe_math_optimizations"
13891 [(set_attr "type" "fpspc")
13892 (set_attr "mode" "XF")])
13894 ;; When sincos pattern is defined, sin and cos builtin functions will be
13895 ;; expanded to sincos pattern with one of its outputs left unused.
13896 ;; CSE pass will figure out if two sincos patterns can be combined,
13897 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13898 ;; depending on the unused output.
13900 (define_insn "sincosxf3"
13901 [(set (match_operand:XF 0 "register_operand" "=f")
13902 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13903 UNSPEC_SINCOS_COS))
13904 (set (match_operand:XF 1 "register_operand" "=u")
13905 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13909 [(set_attr "type" "fpspc")
13910 (set_attr "mode" "XF")])
13913 [(set (match_operand:XF 0 "register_operand")
13914 (unspec:XF [(match_operand:XF 2 "register_operand")]
13915 UNSPEC_SINCOS_COS))
13916 (set (match_operand:XF 1 "register_operand")
13917 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13918 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13919 && can_create_pseudo_p ()"
13920 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13923 [(set (match_operand:XF 0 "register_operand")
13924 (unspec:XF [(match_operand:XF 2 "register_operand")]
13925 UNSPEC_SINCOS_COS))
13926 (set (match_operand:XF 1 "register_operand")
13927 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13928 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13929 && can_create_pseudo_p ()"
13930 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13932 (define_insn "sincos_extend<mode>xf3_i387"
13933 [(set (match_operand:XF 0 "register_operand" "=f")
13934 (unspec:XF [(float_extend:XF
13935 (match_operand:MODEF 2 "register_operand" "0"))]
13936 UNSPEC_SINCOS_COS))
13937 (set (match_operand:XF 1 "register_operand" "=u")
13938 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13939 "TARGET_USE_FANCY_MATH_387
13940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941 || TARGET_MIX_SSE_I387)
13942 && flag_unsafe_math_optimizations"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13948 [(set (match_operand:XF 0 "register_operand")
13949 (unspec:XF [(float_extend:XF
13950 (match_operand:MODEF 2 "register_operand"))]
13951 UNSPEC_SINCOS_COS))
13952 (set (match_operand:XF 1 "register_operand")
13953 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13954 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13955 && can_create_pseudo_p ()"
13956 [(set (match_dup 1)
13957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13960 [(set (match_operand:XF 0 "register_operand")
13961 (unspec:XF [(float_extend:XF
13962 (match_operand:MODEF 2 "register_operand"))]
13963 UNSPEC_SINCOS_COS))
13964 (set (match_operand:XF 1 "register_operand")
13965 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13966 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13967 && can_create_pseudo_p ()"
13968 [(set (match_dup 0)
13969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13971 (define_expand "sincos<mode>3"
13972 [(use (match_operand:MODEF 0 "register_operand"))
13973 (use (match_operand:MODEF 1 "register_operand"))
13974 (use (match_operand:MODEF 2 "register_operand"))]
13975 "TARGET_USE_FANCY_MATH_387
13976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13977 || TARGET_MIX_SSE_I387)
13978 && flag_unsafe_math_optimizations"
13980 rtx op0 = gen_reg_rtx (XFmode);
13981 rtx op1 = gen_reg_rtx (XFmode);
13983 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13989 (define_insn "fptanxf4_i387"
13990 [(set (match_operand:XF 0 "register_operand" "=f")
13991 (match_operand:XF 3 "const_double_operand" "F"))
13992 (set (match_operand:XF 1 "register_operand" "=u")
13993 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13995 "TARGET_USE_FANCY_MATH_387
13996 && flag_unsafe_math_optimizations
13997 && standard_80387_constant_p (operands[3]) == 2"
13999 [(set_attr "type" "fpspc")
14000 (set_attr "mode" "XF")])
14002 (define_insn "fptan_extend<mode>xf4_i387"
14003 [(set (match_operand:MODEF 0 "register_operand" "=f")
14004 (match_operand:MODEF 3 "const_double_operand" "F"))
14005 (set (match_operand:XF 1 "register_operand" "=u")
14006 (unspec:XF [(float_extend:XF
14007 (match_operand:MODEF 2 "register_operand" "0"))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations
14013 && standard_80387_constant_p (operands[3]) == 2"
14015 [(set_attr "type" "fpspc")
14016 (set_attr "mode" "XF")])
14018 (define_expand "tanxf2"
14019 [(use (match_operand:XF 0 "register_operand"))
14020 (use (match_operand:XF 1 "register_operand"))]
14021 "TARGET_USE_FANCY_MATH_387
14022 && flag_unsafe_math_optimizations"
14024 rtx one = gen_reg_rtx (XFmode);
14025 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14027 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14031 (define_expand "tan<mode>2"
14032 [(use (match_operand:MODEF 0 "register_operand"))
14033 (use (match_operand:MODEF 1 "register_operand"))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036 || TARGET_MIX_SSE_I387)
14037 && flag_unsafe_math_optimizations"
14039 rtx op0 = gen_reg_rtx (XFmode);
14041 rtx one = gen_reg_rtx (<MODE>mode);
14042 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14044 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14045 operands[1], op2));
14046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 (define_insn "*fpatanxf3_i387"
14051 [(set (match_operand:XF 0 "register_operand" "=f")
14052 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14053 (match_operand:XF 2 "register_operand" "u")]
14055 (clobber (match_scratch:XF 3 "=2"))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && flag_unsafe_math_optimizations"
14059 [(set_attr "type" "fpspc")
14060 (set_attr "mode" "XF")])
14062 (define_insn "fpatan_extend<mode>xf3_i387"
14063 [(set (match_operand:XF 0 "register_operand" "=f")
14064 (unspec:XF [(float_extend:XF
14065 (match_operand:MODEF 1 "register_operand" "0"))
14067 (match_operand:MODEF 2 "register_operand" "u"))]
14069 (clobber (match_scratch:XF 3 "=2"))]
14070 "TARGET_USE_FANCY_MATH_387
14071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14072 || TARGET_MIX_SSE_I387)
14073 && flag_unsafe_math_optimizations"
14075 [(set_attr "type" "fpspc")
14076 (set_attr "mode" "XF")])
14078 (define_expand "atan2xf3"
14079 [(parallel [(set (match_operand:XF 0 "register_operand")
14080 (unspec:XF [(match_operand:XF 2 "register_operand")
14081 (match_operand:XF 1 "register_operand")]
14083 (clobber (match_scratch:XF 3))])]
14084 "TARGET_USE_FANCY_MATH_387
14085 && flag_unsafe_math_optimizations")
14087 (define_expand "atan2<mode>3"
14088 [(use (match_operand:MODEF 0 "register_operand"))
14089 (use (match_operand:MODEF 1 "register_operand"))
14090 (use (match_operand:MODEF 2 "register_operand"))]
14091 "TARGET_USE_FANCY_MATH_387
14092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14093 || TARGET_MIX_SSE_I387)
14094 && flag_unsafe_math_optimizations"
14096 rtx op0 = gen_reg_rtx (XFmode);
14098 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14103 (define_expand "atanxf2"
14104 [(parallel [(set (match_operand:XF 0 "register_operand")
14105 (unspec:XF [(match_dup 2)
14106 (match_operand:XF 1 "register_operand")]
14108 (clobber (match_scratch:XF 3))])]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations"
14112 operands[2] = gen_reg_rtx (XFmode);
14113 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14116 (define_expand "atan<mode>2"
14117 [(use (match_operand:MODEF 0 "register_operand"))
14118 (use (match_operand:MODEF 1 "register_operand"))]
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"
14124 rtx op0 = gen_reg_rtx (XFmode);
14126 rtx op2 = gen_reg_rtx (<MODE>mode);
14127 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14129 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14130 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14134 (define_expand "asinxf2"
14135 [(set (match_dup 2)
14136 (mult:XF (match_operand:XF 1 "register_operand")
14138 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14139 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14140 (parallel [(set (match_operand:XF 0 "register_operand")
14141 (unspec:XF [(match_dup 5) (match_dup 1)]
14143 (clobber (match_scratch:XF 6))])]
14144 "TARGET_USE_FANCY_MATH_387
14145 && flag_unsafe_math_optimizations"
14149 if (optimize_insn_for_size_p ())
14152 for (i = 2; i < 6; i++)
14153 operands[i] = gen_reg_rtx (XFmode);
14155 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14158 (define_expand "asin<mode>2"
14159 [(use (match_operand:MODEF 0 "register_operand"))
14160 (use (match_operand:MODEF 1 "general_operand"))]
14161 "TARGET_USE_FANCY_MATH_387
14162 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163 || TARGET_MIX_SSE_I387)
14164 && flag_unsafe_math_optimizations"
14166 rtx op0 = gen_reg_rtx (XFmode);
14167 rtx op1 = gen_reg_rtx (XFmode);
14169 if (optimize_insn_for_size_p ())
14172 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14173 emit_insn (gen_asinxf2 (op0, op1));
14174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14178 (define_expand "acosxf2"
14179 [(set (match_dup 2)
14180 (mult:XF (match_operand:XF 1 "register_operand")
14182 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14183 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14184 (parallel [(set (match_operand:XF 0 "register_operand")
14185 (unspec:XF [(match_dup 1) (match_dup 5)]
14187 (clobber (match_scratch:XF 6))])]
14188 "TARGET_USE_FANCY_MATH_387
14189 && flag_unsafe_math_optimizations"
14193 if (optimize_insn_for_size_p ())
14196 for (i = 2; i < 6; i++)
14197 operands[i] = gen_reg_rtx (XFmode);
14199 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14202 (define_expand "acos<mode>2"
14203 [(use (match_operand:MODEF 0 "register_operand"))
14204 (use (match_operand:MODEF 1 "general_operand"))]
14205 "TARGET_USE_FANCY_MATH_387
14206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14207 || TARGET_MIX_SSE_I387)
14208 && flag_unsafe_math_optimizations"
14210 rtx op0 = gen_reg_rtx (XFmode);
14211 rtx op1 = gen_reg_rtx (XFmode);
14213 if (optimize_insn_for_size_p ())
14216 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14217 emit_insn (gen_acosxf2 (op0, op1));
14218 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14222 (define_insn "fyl2xxf3_i387"
14223 [(set (match_operand:XF 0 "register_operand" "=f")
14224 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14225 (match_operand:XF 2 "register_operand" "u")]
14227 (clobber (match_scratch:XF 3 "=2"))]
14228 "TARGET_USE_FANCY_MATH_387
14229 && flag_unsafe_math_optimizations"
14231 [(set_attr "type" "fpspc")
14232 (set_attr "mode" "XF")])
14234 (define_insn "fyl2x_extend<mode>xf3_i387"
14235 [(set (match_operand:XF 0 "register_operand" "=f")
14236 (unspec:XF [(float_extend:XF
14237 (match_operand:MODEF 1 "register_operand" "0"))
14238 (match_operand:XF 2 "register_operand" "u")]
14240 (clobber (match_scratch:XF 3 "=2"))]
14241 "TARGET_USE_FANCY_MATH_387
14242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14243 || TARGET_MIX_SSE_I387)
14244 && flag_unsafe_math_optimizations"
14246 [(set_attr "type" "fpspc")
14247 (set_attr "mode" "XF")])
14249 (define_expand "logxf2"
14250 [(parallel [(set (match_operand:XF 0 "register_operand")
14251 (unspec:XF [(match_operand:XF 1 "register_operand")
14252 (match_dup 2)] UNSPEC_FYL2X))
14253 (clobber (match_scratch:XF 3))])]
14254 "TARGET_USE_FANCY_MATH_387
14255 && flag_unsafe_math_optimizations"
14257 operands[2] = gen_reg_rtx (XFmode);
14258 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14261 (define_expand "log<mode>2"
14262 [(use (match_operand:MODEF 0 "register_operand"))
14263 (use (match_operand:MODEF 1 "register_operand"))]
14264 "TARGET_USE_FANCY_MATH_387
14265 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14266 || TARGET_MIX_SSE_I387)
14267 && flag_unsafe_math_optimizations"
14269 rtx op0 = gen_reg_rtx (XFmode);
14271 rtx op2 = gen_reg_rtx (XFmode);
14272 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14274 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14275 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14279 (define_expand "log10xf2"
14280 [(parallel [(set (match_operand:XF 0 "register_operand")
14281 (unspec:XF [(match_operand:XF 1 "register_operand")
14282 (match_dup 2)] UNSPEC_FYL2X))
14283 (clobber (match_scratch:XF 3))])]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14287 operands[2] = gen_reg_rtx (XFmode);
14288 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14291 (define_expand "log10<mode>2"
14292 [(use (match_operand:MODEF 0 "register_operand"))
14293 (use (match_operand:MODEF 1 "register_operand"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14299 rtx op0 = gen_reg_rtx (XFmode);
14301 rtx op2 = gen_reg_rtx (XFmode);
14302 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14304 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14305 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14309 (define_expand "log2xf2"
14310 [(parallel [(set (match_operand:XF 0 "register_operand")
14311 (unspec:XF [(match_operand:XF 1 "register_operand")
14312 (match_dup 2)] UNSPEC_FYL2X))
14313 (clobber (match_scratch:XF 3))])]
14314 "TARGET_USE_FANCY_MATH_387
14315 && flag_unsafe_math_optimizations"
14317 operands[2] = gen_reg_rtx (XFmode);
14318 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14321 (define_expand "log2<mode>2"
14322 [(use (match_operand:MODEF 0 "register_operand"))
14323 (use (match_operand:MODEF 1 "register_operand"))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations"
14329 rtx op0 = gen_reg_rtx (XFmode);
14331 rtx op2 = gen_reg_rtx (XFmode);
14332 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14334 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14335 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14339 (define_insn "fyl2xp1xf3_i387"
14340 [(set (match_operand:XF 0 "register_operand" "=f")
14341 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14342 (match_operand:XF 2 "register_operand" "u")]
14344 (clobber (match_scratch:XF 3 "=2"))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14348 [(set_attr "type" "fpspc")
14349 (set_attr "mode" "XF")])
14351 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14352 [(set (match_operand:XF 0 "register_operand" "=f")
14353 (unspec:XF [(float_extend:XF
14354 (match_operand:MODEF 1 "register_operand" "0"))
14355 (match_operand:XF 2 "register_operand" "u")]
14357 (clobber (match_scratch:XF 3 "=2"))]
14358 "TARGET_USE_FANCY_MATH_387
14359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14360 || TARGET_MIX_SSE_I387)
14361 && flag_unsafe_math_optimizations"
14363 [(set_attr "type" "fpspc")
14364 (set_attr "mode" "XF")])
14366 (define_expand "log1pxf2"
14367 [(use (match_operand:XF 0 "register_operand"))
14368 (use (match_operand:XF 1 "register_operand"))]
14369 "TARGET_USE_FANCY_MATH_387
14370 && flag_unsafe_math_optimizations"
14372 if (optimize_insn_for_size_p ())
14375 ix86_emit_i387_log1p (operands[0], operands[1]);
14379 (define_expand "log1p<mode>2"
14380 [(use (match_operand:MODEF 0 "register_operand"))
14381 (use (match_operand:MODEF 1 "register_operand"))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384 || TARGET_MIX_SSE_I387)
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 op0 = gen_reg_rtx (XFmode);
14394 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14396 ix86_emit_i387_log1p (op0, operands[1]);
14397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 (define_insn "fxtractxf3_i387"
14402 [(set (match_operand:XF 0 "register_operand" "=f")
14403 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14404 UNSPEC_XTRACT_FRACT))
14405 (set (match_operand:XF 1 "register_operand" "=u")
14406 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations"
14410 [(set_attr "type" "fpspc")
14411 (set_attr "mode" "XF")])
14413 (define_insn "fxtract_extend<mode>xf3_i387"
14414 [(set (match_operand:XF 0 "register_operand" "=f")
14415 (unspec:XF [(float_extend:XF
14416 (match_operand:MODEF 2 "register_operand" "0"))]
14417 UNSPEC_XTRACT_FRACT))
14418 (set (match_operand:XF 1 "register_operand" "=u")
14419 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422 || TARGET_MIX_SSE_I387)
14423 && flag_unsafe_math_optimizations"
14425 [(set_attr "type" "fpspc")
14426 (set_attr "mode" "XF")])
14428 (define_expand "logbxf2"
14429 [(parallel [(set (match_dup 2)
14430 (unspec:XF [(match_operand:XF 1 "register_operand")]
14431 UNSPEC_XTRACT_FRACT))
14432 (set (match_operand:XF 0 "register_operand")
14433 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14436 "operands[2] = gen_reg_rtx (XFmode);")
14438 (define_expand "logb<mode>2"
14439 [(use (match_operand:MODEF 0 "register_operand"))
14440 (use (match_operand:MODEF 1 "register_operand"))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14443 || TARGET_MIX_SSE_I387)
14444 && flag_unsafe_math_optimizations"
14446 rtx op0 = gen_reg_rtx (XFmode);
14447 rtx op1 = gen_reg_rtx (XFmode);
14449 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14454 (define_expand "ilogbxf2"
14455 [(use (match_operand:SI 0 "register_operand"))
14456 (use (match_operand:XF 1 "register_operand"))]
14457 "TARGET_USE_FANCY_MATH_387
14458 && flag_unsafe_math_optimizations"
14462 if (optimize_insn_for_size_p ())
14465 op0 = gen_reg_rtx (XFmode);
14466 op1 = gen_reg_rtx (XFmode);
14468 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14469 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14473 (define_expand "ilogb<mode>2"
14474 [(use (match_operand:SI 0 "register_operand"))
14475 (use (match_operand:MODEF 1 "register_operand"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478 || TARGET_MIX_SSE_I387)
14479 && flag_unsafe_math_optimizations"
14483 if (optimize_insn_for_size_p ())
14486 op0 = gen_reg_rtx (XFmode);
14487 op1 = gen_reg_rtx (XFmode);
14489 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14490 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14494 (define_insn "*f2xm1xf2_i387"
14495 [(set (match_operand:XF 0 "register_operand" "=f")
14496 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14498 "TARGET_USE_FANCY_MATH_387
14499 && flag_unsafe_math_optimizations"
14501 [(set_attr "type" "fpspc")
14502 (set_attr "mode" "XF")])
14504 (define_insn "fscalexf4_i387"
14505 [(set (match_operand:XF 0 "register_operand" "=f")
14506 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14507 (match_operand:XF 3 "register_operand" "1")]
14508 UNSPEC_FSCALE_FRACT))
14509 (set (match_operand:XF 1 "register_operand" "=u")
14510 (unspec:XF [(match_dup 2) (match_dup 3)]
14511 UNSPEC_FSCALE_EXP))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14515 [(set_attr "type" "fpspc")
14516 (set_attr "mode" "XF")])
14518 (define_expand "expNcorexf3"
14519 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14520 (match_operand:XF 2 "register_operand")))
14521 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14522 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14523 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14524 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14525 (parallel [(set (match_operand:XF 0 "register_operand")
14526 (unspec:XF [(match_dup 8) (match_dup 4)]
14527 UNSPEC_FSCALE_FRACT))
14529 (unspec:XF [(match_dup 8) (match_dup 4)]
14530 UNSPEC_FSCALE_EXP))])]
14531 "TARGET_USE_FANCY_MATH_387
14532 && flag_unsafe_math_optimizations"
14536 if (optimize_insn_for_size_p ())
14539 for (i = 3; i < 10; i++)
14540 operands[i] = gen_reg_rtx (XFmode);
14542 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14545 (define_expand "expxf2"
14546 [(use (match_operand:XF 0 "register_operand"))
14547 (use (match_operand:XF 1 "register_operand"))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && flag_unsafe_math_optimizations"
14553 if (optimize_insn_for_size_p ())
14556 op2 = gen_reg_rtx (XFmode);
14557 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14559 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14563 (define_expand "exp<mode>2"
14564 [(use (match_operand:MODEF 0 "register_operand"))
14565 (use (match_operand:MODEF 1 "general_operand"))]
14566 "TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations"
14573 if (optimize_insn_for_size_p ())
14576 op0 = gen_reg_rtx (XFmode);
14577 op1 = gen_reg_rtx (XFmode);
14579 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14580 emit_insn (gen_expxf2 (op0, op1));
14581 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14585 (define_expand "exp10xf2"
14586 [(use (match_operand:XF 0 "register_operand"))
14587 (use (match_operand:XF 1 "register_operand"))]
14588 "TARGET_USE_FANCY_MATH_387
14589 && flag_unsafe_math_optimizations"
14593 if (optimize_insn_for_size_p ())
14596 op2 = gen_reg_rtx (XFmode);
14597 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14599 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14603 (define_expand "exp10<mode>2"
14604 [(use (match_operand:MODEF 0 "register_operand"))
14605 (use (match_operand:MODEF 1 "general_operand"))]
14606 "TARGET_USE_FANCY_MATH_387
14607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14608 || TARGET_MIX_SSE_I387)
14609 && flag_unsafe_math_optimizations"
14613 if (optimize_insn_for_size_p ())
14616 op0 = gen_reg_rtx (XFmode);
14617 op1 = gen_reg_rtx (XFmode);
14619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620 emit_insn (gen_exp10xf2 (op0, op1));
14621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14625 (define_expand "exp2xf2"
14626 [(use (match_operand:XF 0 "register_operand"))
14627 (use (match_operand:XF 1 "register_operand"))]
14628 "TARGET_USE_FANCY_MATH_387
14629 && flag_unsafe_math_optimizations"
14633 if (optimize_insn_for_size_p ())
14636 op2 = gen_reg_rtx (XFmode);
14637 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14639 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14643 (define_expand "exp2<mode>2"
14644 [(use (match_operand:MODEF 0 "register_operand"))
14645 (use (match_operand:MODEF 1 "general_operand"))]
14646 "TARGET_USE_FANCY_MATH_387
14647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14648 || TARGET_MIX_SSE_I387)
14649 && flag_unsafe_math_optimizations"
14653 if (optimize_insn_for_size_p ())
14656 op0 = gen_reg_rtx (XFmode);
14657 op1 = gen_reg_rtx (XFmode);
14659 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660 emit_insn (gen_exp2xf2 (op0, op1));
14661 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14665 (define_expand "expm1xf2"
14666 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14668 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14669 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14670 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14671 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14672 (parallel [(set (match_dup 7)
14673 (unspec:XF [(match_dup 6) (match_dup 4)]
14674 UNSPEC_FSCALE_FRACT))
14676 (unspec:XF [(match_dup 6) (match_dup 4)]
14677 UNSPEC_FSCALE_EXP))])
14678 (parallel [(set (match_dup 10)
14679 (unspec:XF [(match_dup 9) (match_dup 8)]
14680 UNSPEC_FSCALE_FRACT))
14681 (set (match_dup 11)
14682 (unspec:XF [(match_dup 9) (match_dup 8)]
14683 UNSPEC_FSCALE_EXP))])
14684 (set (match_dup 12) (minus:XF (match_dup 10)
14685 (float_extend:XF (match_dup 13))))
14686 (set (match_operand:XF 0 "register_operand")
14687 (plus:XF (match_dup 12) (match_dup 7)))]
14688 "TARGET_USE_FANCY_MATH_387
14689 && flag_unsafe_math_optimizations"
14693 if (optimize_insn_for_size_p ())
14696 for (i = 2; i < 13; i++)
14697 operands[i] = gen_reg_rtx (XFmode);
14700 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14702 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14705 (define_expand "expm1<mode>2"
14706 [(use (match_operand:MODEF 0 "register_operand"))
14707 (use (match_operand:MODEF 1 "general_operand"))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14710 || TARGET_MIX_SSE_I387)
14711 && flag_unsafe_math_optimizations"
14715 if (optimize_insn_for_size_p ())
14718 op0 = gen_reg_rtx (XFmode);
14719 op1 = gen_reg_rtx (XFmode);
14721 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14722 emit_insn (gen_expm1xf2 (op0, op1));
14723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14727 (define_expand "ldexpxf3"
14728 [(match_operand:XF 0 "register_operand")
14729 (match_operand:XF 1 "register_operand")
14730 (match_operand:SI 2 "register_operand")]
14731 "TARGET_USE_FANCY_MATH_387
14732 && flag_unsafe_math_optimizations"
14735 if (optimize_insn_for_size_p ())
14738 tmp1 = gen_reg_rtx (XFmode);
14739 tmp2 = gen_reg_rtx (XFmode);
14741 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14742 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14743 operands[1], tmp1));
14747 (define_expand "ldexp<mode>3"
14748 [(use (match_operand:MODEF 0 "register_operand"))
14749 (use (match_operand:MODEF 1 "general_operand"))
14750 (use (match_operand:SI 2 "register_operand"))]
14751 "TARGET_USE_FANCY_MATH_387
14752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14753 || TARGET_MIX_SSE_I387)
14754 && flag_unsafe_math_optimizations"
14758 if (optimize_insn_for_size_p ())
14761 op0 = gen_reg_rtx (XFmode);
14762 op1 = gen_reg_rtx (XFmode);
14764 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14765 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14766 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14770 (define_expand "scalbxf3"
14771 [(parallel [(set (match_operand:XF 0 " register_operand")
14772 (unspec:XF [(match_operand:XF 1 "register_operand")
14773 (match_operand:XF 2 "register_operand")]
14774 UNSPEC_FSCALE_FRACT))
14776 (unspec:XF [(match_dup 1) (match_dup 2)]
14777 UNSPEC_FSCALE_EXP))])]
14778 "TARGET_USE_FANCY_MATH_387
14779 && flag_unsafe_math_optimizations"
14781 if (optimize_insn_for_size_p ())
14784 operands[3] = gen_reg_rtx (XFmode);
14787 (define_expand "scalb<mode>3"
14788 [(use (match_operand:MODEF 0 "register_operand"))
14789 (use (match_operand:MODEF 1 "general_operand"))
14790 (use (match_operand:MODEF 2 "general_operand"))]
14791 "TARGET_USE_FANCY_MATH_387
14792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14793 || TARGET_MIX_SSE_I387)
14794 && flag_unsafe_math_optimizations"
14798 if (optimize_insn_for_size_p ())
14801 op0 = gen_reg_rtx (XFmode);
14802 op1 = gen_reg_rtx (XFmode);
14803 op2 = gen_reg_rtx (XFmode);
14805 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14806 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14807 emit_insn (gen_scalbxf3 (op0, op1, op2));
14808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14812 (define_expand "significandxf2"
14813 [(parallel [(set (match_operand:XF 0 "register_operand")
14814 (unspec:XF [(match_operand:XF 1 "register_operand")]
14815 UNSPEC_XTRACT_FRACT))
14817 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14818 "TARGET_USE_FANCY_MATH_387
14819 && flag_unsafe_math_optimizations"
14820 "operands[2] = gen_reg_rtx (XFmode);")
14822 (define_expand "significand<mode>2"
14823 [(use (match_operand:MODEF 0 "register_operand"))
14824 (use (match_operand:MODEF 1 "register_operand"))]
14825 "TARGET_USE_FANCY_MATH_387
14826 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14827 || TARGET_MIX_SSE_I387)
14828 && flag_unsafe_math_optimizations"
14830 rtx op0 = gen_reg_rtx (XFmode);
14831 rtx op1 = gen_reg_rtx (XFmode);
14833 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14839 (define_insn "sse4_1_round<mode>2"
14840 [(set (match_operand:MODEF 0 "register_operand" "=x")
14841 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14842 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14845 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14846 [(set_attr "type" "ssecvt")
14847 (set_attr "prefix_extra" "1")
14848 (set_attr "prefix" "maybe_vex")
14849 (set_attr "mode" "<MODE>")])
14851 (define_insn "rintxf2"
14852 [(set (match_operand:XF 0 "register_operand" "=f")
14853 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14855 "TARGET_USE_FANCY_MATH_387
14856 && flag_unsafe_math_optimizations"
14858 [(set_attr "type" "fpspc")
14859 (set_attr "mode" "XF")])
14861 (define_expand "rint<mode>2"
14862 [(use (match_operand:MODEF 0 "register_operand"))
14863 (use (match_operand:MODEF 1 "register_operand"))]
14864 "(TARGET_USE_FANCY_MATH_387
14865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14866 || TARGET_MIX_SSE_I387)
14867 && flag_unsafe_math_optimizations)
14868 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14869 && !flag_trapping_math)"
14871 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14872 && !flag_trapping_math)
14875 emit_insn (gen_sse4_1_round<mode>2
14876 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14877 else if (optimize_insn_for_size_p ())
14880 ix86_expand_rint (operands[0], operands[1]);
14884 rtx op0 = gen_reg_rtx (XFmode);
14885 rtx op1 = gen_reg_rtx (XFmode);
14887 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14888 emit_insn (gen_rintxf2 (op0, op1));
14890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14895 (define_expand "round<mode>2"
14896 [(match_operand:X87MODEF 0 "register_operand")
14897 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14898 "(TARGET_USE_FANCY_MATH_387
14899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14900 || TARGET_MIX_SSE_I387)
14901 && flag_unsafe_math_optimizations)
14902 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14903 && !flag_trapping_math && !flag_rounding_math)"
14905 if (optimize_insn_for_size_p ())
14908 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909 && !flag_trapping_math && !flag_rounding_math)
14913 operands[1] = force_reg (<MODE>mode, operands[1]);
14914 ix86_expand_round_sse4 (operands[0], operands[1]);
14916 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14917 ix86_expand_round (operands[0], operands[1]);
14919 ix86_expand_rounddf_32 (operands[0], operands[1]);
14923 operands[1] = force_reg (<MODE>mode, operands[1]);
14924 ix86_emit_i387_round (operands[0], operands[1]);
14929 (define_insn_and_split "*fistdi2_1"
14930 [(set (match_operand:DI 0 "nonimmediate_operand")
14931 (unspec:DI [(match_operand:XF 1 "register_operand")]
14933 "TARGET_USE_FANCY_MATH_387
14934 && can_create_pseudo_p ()"
14939 if (memory_operand (operands[0], VOIDmode))
14940 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14943 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14944 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14949 [(set_attr "type" "fpspc")
14950 (set_attr "mode" "DI")])
14952 (define_insn "fistdi2"
14953 [(set (match_operand:DI 0 "memory_operand" "=m")
14954 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14956 (clobber (match_scratch:XF 2 "=&1f"))]
14957 "TARGET_USE_FANCY_MATH_387"
14958 "* return output_fix_trunc (insn, operands, false);"
14959 [(set_attr "type" "fpspc")
14960 (set_attr "mode" "DI")])
14962 (define_insn "fistdi2_with_temp"
14963 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14964 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14966 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14967 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14968 "TARGET_USE_FANCY_MATH_387"
14970 [(set_attr "type" "fpspc")
14971 (set_attr "mode" "DI")])
14974 [(set (match_operand:DI 0 "register_operand")
14975 (unspec:DI [(match_operand:XF 1 "register_operand")]
14977 (clobber (match_operand:DI 2 "memory_operand"))
14978 (clobber (match_scratch 3))]
14980 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14981 (clobber (match_dup 3))])
14982 (set (match_dup 0) (match_dup 2))])
14985 [(set (match_operand:DI 0 "memory_operand")
14986 (unspec:DI [(match_operand:XF 1 "register_operand")]
14988 (clobber (match_operand:DI 2 "memory_operand"))
14989 (clobber (match_scratch 3))]
14991 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14992 (clobber (match_dup 3))])])
14994 (define_insn_and_split "*fist<mode>2_1"
14995 [(set (match_operand:SWI24 0 "register_operand")
14996 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14998 "TARGET_USE_FANCY_MATH_387
14999 && can_create_pseudo_p ()"
15004 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15005 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15009 [(set_attr "type" "fpspc")
15010 (set_attr "mode" "<MODE>")])
15012 (define_insn "fist<mode>2"
15013 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15014 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15016 "TARGET_USE_FANCY_MATH_387"
15017 "* return output_fix_trunc (insn, operands, false);"
15018 [(set_attr "type" "fpspc")
15019 (set_attr "mode" "<MODE>")])
15021 (define_insn "fist<mode>2_with_temp"
15022 [(set (match_operand:SWI24 0 "register_operand" "=r")
15023 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15025 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15026 "TARGET_USE_FANCY_MATH_387"
15028 [(set_attr "type" "fpspc")
15029 (set_attr "mode" "<MODE>")])
15032 [(set (match_operand:SWI24 0 "register_operand")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15035 (clobber (match_operand:SWI24 2 "memory_operand"))]
15037 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15038 (set (match_dup 0) (match_dup 2))])
15041 [(set (match_operand:SWI24 0 "memory_operand")
15042 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15044 (clobber (match_operand:SWI24 2 "memory_operand"))]
15046 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15048 (define_expand "lrintxf<mode>2"
15049 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15050 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15052 "TARGET_USE_FANCY_MATH_387")
15054 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15055 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15056 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15057 UNSPEC_FIX_NOTRUNC))]
15058 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15060 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15061 [(match_operand:SWI248x 0 "nonimmediate_operand")
15062 (match_operand:X87MODEF 1 "register_operand")]
15063 "(TARGET_USE_FANCY_MATH_387
15064 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15065 || TARGET_MIX_SSE_I387)
15066 && flag_unsafe_math_optimizations)
15067 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15068 && <SWI248x:MODE>mode != HImode
15069 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15070 && !flag_trapping_math && !flag_rounding_math)"
15072 if (optimize_insn_for_size_p ())
15075 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15076 && <SWI248x:MODE>mode != HImode
15077 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15078 && !flag_trapping_math && !flag_rounding_math)
15079 ix86_expand_lround (operands[0], operands[1]);
15081 ix86_emit_i387_round (operands[0], operands[1]);
15085 (define_int_iterator FRNDINT_ROUNDING
15086 [UNSPEC_FRNDINT_FLOOR
15087 UNSPEC_FRNDINT_CEIL
15088 UNSPEC_FRNDINT_TRUNC])
15090 (define_int_iterator FIST_ROUNDING
15094 ;; Base name for define_insn
15095 (define_int_attr rounding_insn
15096 [(UNSPEC_FRNDINT_FLOOR "floor")
15097 (UNSPEC_FRNDINT_CEIL "ceil")
15098 (UNSPEC_FRNDINT_TRUNC "btrunc")
15099 (UNSPEC_FIST_FLOOR "floor")
15100 (UNSPEC_FIST_CEIL "ceil")])
15102 (define_int_attr rounding
15103 [(UNSPEC_FRNDINT_FLOOR "floor")
15104 (UNSPEC_FRNDINT_CEIL "ceil")
15105 (UNSPEC_FRNDINT_TRUNC "trunc")
15106 (UNSPEC_FIST_FLOOR "floor")
15107 (UNSPEC_FIST_CEIL "ceil")])
15109 (define_int_attr ROUNDING
15110 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15111 (UNSPEC_FRNDINT_CEIL "CEIL")
15112 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15113 (UNSPEC_FIST_FLOOR "FLOOR")
15114 (UNSPEC_FIST_CEIL "CEIL")])
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_<rounding>"
15118 [(set (match_operand:XF 0 "register_operand")
15119 (unspec:XF [(match_operand:XF 1 "register_operand")]
15121 (clobber (reg:CC FLAGS_REG))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations
15124 && can_create_pseudo_p ()"
15129 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15131 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15134 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15135 operands[2], operands[3]));
15138 [(set_attr "type" "frndint")
15139 (set_attr "i387_cw" "<rounding>")
15140 (set_attr "mode" "XF")])
15142 (define_insn "frndintxf2_<rounding>_i387"
15143 [(set (match_operand:XF 0 "register_operand" "=f")
15144 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15146 (use (match_operand:HI 2 "memory_operand" "m"))
15147 (use (match_operand:HI 3 "memory_operand" "m"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15150 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15151 [(set_attr "type" "frndint")
15152 (set_attr "i387_cw" "<rounding>")
15153 (set_attr "mode" "XF")])
15155 (define_expand "<rounding_insn>xf2"
15156 [(parallel [(set (match_operand:XF 0 "register_operand")
15157 (unspec:XF [(match_operand:XF 1 "register_operand")]
15159 (clobber (reg:CC FLAGS_REG))])]
15160 "TARGET_USE_FANCY_MATH_387
15161 && flag_unsafe_math_optimizations
15162 && !optimize_insn_for_size_p ()")
15164 (define_expand "<rounding_insn><mode>2"
15165 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15166 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15168 (clobber (reg:CC FLAGS_REG))])]
15169 "(TARGET_USE_FANCY_MATH_387
15170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15171 || TARGET_MIX_SSE_I387)
15172 && flag_unsafe_math_optimizations)
15173 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15174 && !flag_trapping_math)"
15176 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15177 && !flag_trapping_math)
15180 emit_insn (gen_sse4_1_round<mode>2
15181 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15182 else if (optimize_insn_for_size_p ())
15184 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15186 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15187 ix86_expand_floorceil (operands[0], operands[1], true);
15188 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15189 ix86_expand_floorceil (operands[0], operands[1], false);
15190 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15191 ix86_expand_trunc (operands[0], operands[1]);
15193 gcc_unreachable ();
15197 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15198 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15199 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15200 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15201 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15202 ix86_expand_truncdf_32 (operands[0], operands[1]);
15204 gcc_unreachable ();
15211 if (optimize_insn_for_size_p ())
15214 op0 = gen_reg_rtx (XFmode);
15215 op1 = gen_reg_rtx (XFmode);
15216 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15217 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15219 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15224 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15225 (define_insn_and_split "frndintxf2_mask_pm"
15226 [(set (match_operand:XF 0 "register_operand")
15227 (unspec:XF [(match_operand:XF 1 "register_operand")]
15228 UNSPEC_FRNDINT_MASK_PM))
15229 (clobber (reg:CC FLAGS_REG))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations
15232 && can_create_pseudo_p ()"
15237 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15239 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15240 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15242 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15243 operands[2], operands[3]));
15246 [(set_attr "type" "frndint")
15247 (set_attr "i387_cw" "mask_pm")
15248 (set_attr "mode" "XF")])
15250 (define_insn "frndintxf2_mask_pm_i387"
15251 [(set (match_operand:XF 0 "register_operand" "=f")
15252 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15253 UNSPEC_FRNDINT_MASK_PM))
15254 (use (match_operand:HI 2 "memory_operand" "m"))
15255 (use (match_operand:HI 3 "memory_operand" "m"))]
15256 "TARGET_USE_FANCY_MATH_387
15257 && flag_unsafe_math_optimizations"
15258 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15259 [(set_attr "type" "frndint")
15260 (set_attr "i387_cw" "mask_pm")
15261 (set_attr "mode" "XF")])
15263 (define_expand "nearbyintxf2"
15264 [(parallel [(set (match_operand:XF 0 "register_operand")
15265 (unspec:XF [(match_operand:XF 1 "register_operand")]
15266 UNSPEC_FRNDINT_MASK_PM))
15267 (clobber (reg:CC FLAGS_REG))])]
15268 "TARGET_USE_FANCY_MATH_387
15269 && flag_unsafe_math_optimizations")
15271 (define_expand "nearbyint<mode>2"
15272 [(use (match_operand:MODEF 0 "register_operand"))
15273 (use (match_operand:MODEF 1 "register_operand"))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15276 || TARGET_MIX_SSE_I387)
15277 && flag_unsafe_math_optimizations"
15279 rtx op0 = gen_reg_rtx (XFmode);
15280 rtx op1 = gen_reg_rtx (XFmode);
15282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15283 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15285 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15289 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15290 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15291 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15292 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15294 (clobber (reg:CC FLAGS_REG))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && flag_unsafe_math_optimizations
15297 && can_create_pseudo_p ()"
15302 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15304 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15305 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15306 if (memory_operand (operands[0], VOIDmode))
15307 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15308 operands[2], operands[3]));
15311 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15312 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15313 (operands[0], operands[1], operands[2],
15314 operands[3], operands[4]));
15318 [(set_attr "type" "fistp")
15319 (set_attr "i387_cw" "<rounding>")
15320 (set_attr "mode" "<MODE>")])
15322 (define_insn "fistdi2_<rounding>"
15323 [(set (match_operand:DI 0 "memory_operand" "=m")
15324 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15326 (use (match_operand:HI 2 "memory_operand" "m"))
15327 (use (match_operand:HI 3 "memory_operand" "m"))
15328 (clobber (match_scratch:XF 4 "=&1f"))]
15329 "TARGET_USE_FANCY_MATH_387
15330 && flag_unsafe_math_optimizations"
15331 "* return output_fix_trunc (insn, operands, false);"
15332 [(set_attr "type" "fistp")
15333 (set_attr "i387_cw" "<rounding>")
15334 (set_attr "mode" "DI")])
15336 (define_insn "fistdi2_<rounding>_with_temp"
15337 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15338 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15340 (use (match_operand:HI 2 "memory_operand" "m,m"))
15341 (use (match_operand:HI 3 "memory_operand" "m,m"))
15342 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15343 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15344 "TARGET_USE_FANCY_MATH_387
15345 && flag_unsafe_math_optimizations"
15347 [(set_attr "type" "fistp")
15348 (set_attr "i387_cw" "<rounding>")
15349 (set_attr "mode" "DI")])
15352 [(set (match_operand:DI 0 "register_operand")
15353 (unspec:DI [(match_operand:XF 1 "register_operand")]
15355 (use (match_operand:HI 2 "memory_operand"))
15356 (use (match_operand:HI 3 "memory_operand"))
15357 (clobber (match_operand:DI 4 "memory_operand"))
15358 (clobber (match_scratch 5))]
15360 [(parallel [(set (match_dup 4)
15361 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15362 (use (match_dup 2))
15363 (use (match_dup 3))
15364 (clobber (match_dup 5))])
15365 (set (match_dup 0) (match_dup 4))])
15368 [(set (match_operand:DI 0 "memory_operand")
15369 (unspec:DI [(match_operand:XF 1 "register_operand")]
15371 (use (match_operand:HI 2 "memory_operand"))
15372 (use (match_operand:HI 3 "memory_operand"))
15373 (clobber (match_operand:DI 4 "memory_operand"))
15374 (clobber (match_scratch 5))]
15376 [(parallel [(set (match_dup 0)
15377 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15378 (use (match_dup 2))
15379 (use (match_dup 3))
15380 (clobber (match_dup 5))])])
15382 (define_insn "fist<mode>2_<rounding>"
15383 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15384 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15386 (use (match_operand:HI 2 "memory_operand" "m"))
15387 (use (match_operand:HI 3 "memory_operand" "m"))]
15388 "TARGET_USE_FANCY_MATH_387
15389 && flag_unsafe_math_optimizations"
15390 "* return output_fix_trunc (insn, operands, false);"
15391 [(set_attr "type" "fistp")
15392 (set_attr "i387_cw" "<rounding>")
15393 (set_attr "mode" "<MODE>")])
15395 (define_insn "fist<mode>2_<rounding>_with_temp"
15396 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15397 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15399 (use (match_operand:HI 2 "memory_operand" "m,m"))
15400 (use (match_operand:HI 3 "memory_operand" "m,m"))
15401 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15402 "TARGET_USE_FANCY_MATH_387
15403 && flag_unsafe_math_optimizations"
15405 [(set_attr "type" "fistp")
15406 (set_attr "i387_cw" "<rounding>")
15407 (set_attr "mode" "<MODE>")])
15410 [(set (match_operand:SWI24 0 "register_operand")
15411 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15413 (use (match_operand:HI 2 "memory_operand"))
15414 (use (match_operand:HI 3 "memory_operand"))
15415 (clobber (match_operand:SWI24 4 "memory_operand"))]
15417 [(parallel [(set (match_dup 4)
15418 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15419 (use (match_dup 2))
15420 (use (match_dup 3))])
15421 (set (match_dup 0) (match_dup 4))])
15424 [(set (match_operand:SWI24 0 "memory_operand")
15425 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15427 (use (match_operand:HI 2 "memory_operand"))
15428 (use (match_operand:HI 3 "memory_operand"))
15429 (clobber (match_operand:SWI24 4 "memory_operand"))]
15431 [(parallel [(set (match_dup 0)
15432 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15433 (use (match_dup 2))
15434 (use (match_dup 3))])])
15436 (define_expand "l<rounding_insn>xf<mode>2"
15437 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15438 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15440 (clobber (reg:CC FLAGS_REG))])]
15441 "TARGET_USE_FANCY_MATH_387
15442 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15443 && flag_unsafe_math_optimizations")
15445 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15446 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15447 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15449 (clobber (reg:CC FLAGS_REG))])]
15450 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15451 && !flag_trapping_math"
15453 if (TARGET_64BIT && optimize_insn_for_size_p ())
15456 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15457 ix86_expand_lfloorceil (operands[0], operands[1], true);
15458 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15459 ix86_expand_lfloorceil (operands[0], operands[1], false);
15461 gcc_unreachable ();
15466 (define_insn "fxam<mode>2_i387"
15467 [(set (match_operand:HI 0 "register_operand" "=a")
15469 [(match_operand:X87MODEF 1 "register_operand" "f")]
15471 "TARGET_USE_FANCY_MATH_387"
15472 "fxam\n\tfnstsw\t%0"
15473 [(set_attr "type" "multi")
15474 (set_attr "length" "4")
15475 (set_attr "unit" "i387")
15476 (set_attr "mode" "<MODE>")])
15478 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15479 [(set (match_operand:HI 0 "register_operand")
15481 [(match_operand:MODEF 1 "memory_operand")]
15483 "TARGET_USE_FANCY_MATH_387
15484 && can_create_pseudo_p ()"
15487 [(set (match_dup 2)(match_dup 1))
15489 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15491 operands[2] = gen_reg_rtx (<MODE>mode);
15493 MEM_VOLATILE_P (operands[1]) = 1;
15495 [(set_attr "type" "multi")
15496 (set_attr "unit" "i387")
15497 (set_attr "mode" "<MODE>")])
15499 (define_expand "isinfxf2"
15500 [(use (match_operand:SI 0 "register_operand"))
15501 (use (match_operand:XF 1 "register_operand"))]
15502 "TARGET_USE_FANCY_MATH_387
15503 && ix86_libc_has_function (function_c99_misc)"
15505 rtx mask = GEN_INT (0x45);
15506 rtx val = GEN_INT (0x05);
15510 rtx scratch = gen_reg_rtx (HImode);
15511 rtx res = gen_reg_rtx (QImode);
15513 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15515 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15516 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15517 cond = gen_rtx_fmt_ee (EQ, QImode,
15518 gen_rtx_REG (CCmode, FLAGS_REG),
15520 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15521 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15525 (define_expand "isinf<mode>2"
15526 [(use (match_operand:SI 0 "register_operand"))
15527 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15528 "TARGET_USE_FANCY_MATH_387
15529 && ix86_libc_has_function (function_c99_misc)
15530 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15532 rtx mask = GEN_INT (0x45);
15533 rtx val = GEN_INT (0x05);
15537 rtx scratch = gen_reg_rtx (HImode);
15538 rtx res = gen_reg_rtx (QImode);
15540 /* Remove excess precision by forcing value through memory. */
15541 if (memory_operand (operands[1], VOIDmode))
15542 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15545 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15547 emit_move_insn (temp, operands[1]);
15548 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15551 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15552 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15553 cond = gen_rtx_fmt_ee (EQ, QImode,
15554 gen_rtx_REG (CCmode, FLAGS_REG),
15556 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15557 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15561 (define_expand "signbitxf2"
15562 [(use (match_operand:SI 0 "register_operand"))
15563 (use (match_operand:XF 1 "register_operand"))]
15564 "TARGET_USE_FANCY_MATH_387"
15566 rtx scratch = gen_reg_rtx (HImode);
15568 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15569 emit_insn (gen_andsi3 (operands[0],
15570 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15574 (define_insn "movmsk_df"
15575 [(set (match_operand:SI 0 "register_operand" "=r")
15577 [(match_operand:DF 1 "register_operand" "x")]
15579 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15580 "%vmovmskpd\t{%1, %0|%0, %1}"
15581 [(set_attr "type" "ssemov")
15582 (set_attr "prefix" "maybe_vex")
15583 (set_attr "mode" "DF")])
15585 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15586 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15587 (define_expand "signbitdf2"
15588 [(use (match_operand:SI 0 "register_operand"))
15589 (use (match_operand:DF 1 "register_operand"))]
15590 "TARGET_USE_FANCY_MATH_387
15591 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15593 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15595 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15596 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15600 rtx scratch = gen_reg_rtx (HImode);
15602 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15603 emit_insn (gen_andsi3 (operands[0],
15604 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15609 (define_expand "signbitsf2"
15610 [(use (match_operand:SI 0 "register_operand"))
15611 (use (match_operand:SF 1 "register_operand"))]
15612 "TARGET_USE_FANCY_MATH_387
15613 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15615 rtx scratch = gen_reg_rtx (HImode);
15617 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15618 emit_insn (gen_andsi3 (operands[0],
15619 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15623 ;; Block operation instructions
15626 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15629 [(set_attr "length" "1")
15630 (set_attr "length_immediate" "0")
15631 (set_attr "modrm" "0")])
15633 (define_expand "movmem<mode>"
15634 [(use (match_operand:BLK 0 "memory_operand"))
15635 (use (match_operand:BLK 1 "memory_operand"))
15636 (use (match_operand:SWI48 2 "nonmemory_operand"))
15637 (use (match_operand:SWI48 3 "const_int_operand"))
15638 (use (match_operand:SI 4 "const_int_operand"))
15639 (use (match_operand:SI 5 "const_int_operand"))
15640 (use (match_operand:SI 6 ""))
15641 (use (match_operand:SI 7 ""))
15642 (use (match_operand:SI 8 ""))]
15645 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15646 operands[2], NULL, operands[3],
15647 operands[4], operands[5],
15648 operands[6], operands[7],
15649 operands[8], false))
15655 ;; Most CPUs don't like single string operations
15656 ;; Handle this case here to simplify previous expander.
15658 (define_expand "strmov"
15659 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15660 (set (match_operand 1 "memory_operand") (match_dup 4))
15661 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15662 (clobber (reg:CC FLAGS_REG))])
15663 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15664 (clobber (reg:CC FLAGS_REG))])]
15667 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15669 /* If .md ever supports :P for Pmode, these can be directly
15670 in the pattern above. */
15671 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15672 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15674 /* Can't use this if the user has appropriated esi or edi. */
15675 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15676 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15678 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15679 operands[2], operands[3],
15680 operands[5], operands[6]));
15684 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15687 (define_expand "strmov_singleop"
15688 [(parallel [(set (match_operand 1 "memory_operand")
15689 (match_operand 3 "memory_operand"))
15690 (set (match_operand 0 "register_operand")
15692 (set (match_operand 2 "register_operand")
15693 (match_operand 5))])]
15695 "ix86_current_function_needs_cld = 1;")
15697 (define_insn "*strmovdi_rex_1"
15698 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15699 (mem:DI (match_operand:P 3 "register_operand" "1")))
15700 (set (match_operand:P 0 "register_operand" "=D")
15701 (plus:P (match_dup 2)
15703 (set (match_operand:P 1 "register_operand" "=S")
15704 (plus:P (match_dup 3)
15707 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15709 [(set_attr "type" "str")
15710 (set_attr "memory" "both")
15711 (set_attr "mode" "DI")])
15713 (define_insn "*strmovsi_1"
15714 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15715 (mem:SI (match_operand:P 3 "register_operand" "1")))
15716 (set (match_operand:P 0 "register_operand" "=D")
15717 (plus:P (match_dup 2)
15719 (set (match_operand:P 1 "register_operand" "=S")
15720 (plus:P (match_dup 3)
15722 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15724 [(set_attr "type" "str")
15725 (set_attr "memory" "both")
15726 (set_attr "mode" "SI")])
15728 (define_insn "*strmovhi_1"
15729 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15730 (mem:HI (match_operand:P 3 "register_operand" "1")))
15731 (set (match_operand:P 0 "register_operand" "=D")
15732 (plus:P (match_dup 2)
15734 (set (match_operand:P 1 "register_operand" "=S")
15735 (plus:P (match_dup 3)
15737 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15739 [(set_attr "type" "str")
15740 (set_attr "memory" "both")
15741 (set_attr "mode" "HI")])
15743 (define_insn "*strmovqi_1"
15744 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15745 (mem:QI (match_operand:P 3 "register_operand" "1")))
15746 (set (match_operand:P 0 "register_operand" "=D")
15747 (plus:P (match_dup 2)
15749 (set (match_operand:P 1 "register_operand" "=S")
15750 (plus:P (match_dup 3)
15752 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15754 [(set_attr "type" "str")
15755 (set_attr "memory" "both")
15756 (set (attr "prefix_rex")
15758 (match_test "<P:MODE>mode == DImode")
15760 (const_string "*")))
15761 (set_attr "mode" "QI")])
15763 (define_expand "rep_mov"
15764 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15765 (set (match_operand 0 "register_operand")
15767 (set (match_operand 2 "register_operand")
15769 (set (match_operand 1 "memory_operand")
15770 (match_operand 3 "memory_operand"))
15771 (use (match_dup 4))])]
15773 "ix86_current_function_needs_cld = 1;")
15775 (define_insn "*rep_movdi_rex64"
15776 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15777 (set (match_operand:P 0 "register_operand" "=D")
15778 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15780 (match_operand:P 3 "register_operand" "0")))
15781 (set (match_operand:P 1 "register_operand" "=S")
15782 (plus:P (ashift:P (match_dup 5) (const_int 3))
15783 (match_operand:P 4 "register_operand" "1")))
15784 (set (mem:BLK (match_dup 3))
15785 (mem:BLK (match_dup 4)))
15786 (use (match_dup 5))]
15788 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15790 [(set_attr "type" "str")
15791 (set_attr "prefix_rep" "1")
15792 (set_attr "memory" "both")
15793 (set_attr "mode" "DI")])
15795 (define_insn "*rep_movsi"
15796 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15800 (match_operand:P 3 "register_operand" "0")))
15801 (set (match_operand:P 1 "register_operand" "=S")
15802 (plus:P (ashift:P (match_dup 5) (const_int 2))
15803 (match_operand:P 4 "register_operand" "1")))
15804 (set (mem:BLK (match_dup 3))
15805 (mem:BLK (match_dup 4)))
15806 (use (match_dup 5))]
15807 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15808 "%^rep{%;} movs{l|d}"
15809 [(set_attr "type" "str")
15810 (set_attr "prefix_rep" "1")
15811 (set_attr "memory" "both")
15812 (set_attr "mode" "SI")])
15814 (define_insn "*rep_movqi"
15815 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15816 (set (match_operand:P 0 "register_operand" "=D")
15817 (plus:P (match_operand:P 3 "register_operand" "0")
15818 (match_operand:P 5 "register_operand" "2")))
15819 (set (match_operand:P 1 "register_operand" "=S")
15820 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15821 (set (mem:BLK (match_dup 3))
15822 (mem:BLK (match_dup 4)))
15823 (use (match_dup 5))]
15824 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15826 [(set_attr "type" "str")
15827 (set_attr "prefix_rep" "1")
15828 (set_attr "memory" "both")
15829 (set_attr "mode" "QI")])
15831 (define_expand "setmem<mode>"
15832 [(use (match_operand:BLK 0 "memory_operand"))
15833 (use (match_operand:SWI48 1 "nonmemory_operand"))
15834 (use (match_operand:QI 2 "nonmemory_operand"))
15835 (use (match_operand 3 "const_int_operand"))
15836 (use (match_operand:SI 4 "const_int_operand"))
15837 (use (match_operand:SI 5 "const_int_operand"))
15838 (use (match_operand:SI 6 ""))
15839 (use (match_operand:SI 7 ""))
15840 (use (match_operand:SI 8 ""))]
15843 if (ix86_expand_set_or_movmem (operands[0], NULL,
15844 operands[1], operands[2],
15845 operands[3], operands[4],
15846 operands[5], operands[6],
15847 operands[7], operands[8], true))
15853 ;; Most CPUs don't like single string operations
15854 ;; Handle this case here to simplify previous expander.
15856 (define_expand "strset"
15857 [(set (match_operand 1 "memory_operand")
15858 (match_operand 2 "register_operand"))
15859 (parallel [(set (match_operand 0 "register_operand")
15861 (clobber (reg:CC FLAGS_REG))])]
15864 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15865 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15867 /* If .md ever supports :P for Pmode, this can be directly
15868 in the pattern above. */
15869 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15870 GEN_INT (GET_MODE_SIZE (GET_MODE
15872 /* Can't use this if the user has appropriated eax or edi. */
15873 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15874 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15876 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15882 (define_expand "strset_singleop"
15883 [(parallel [(set (match_operand 1 "memory_operand")
15884 (match_operand 2 "register_operand"))
15885 (set (match_operand 0 "register_operand")
15887 (unspec [(const_int 0)] UNSPEC_STOS)])]
15889 "ix86_current_function_needs_cld = 1;")
15891 (define_insn "*strsetdi_rex_1"
15892 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15893 (match_operand:DI 2 "register_operand" "a"))
15894 (set (match_operand:P 0 "register_operand" "=D")
15895 (plus:P (match_dup 1)
15897 (unspec [(const_int 0)] UNSPEC_STOS)]
15899 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15901 [(set_attr "type" "str")
15902 (set_attr "memory" "store")
15903 (set_attr "mode" "DI")])
15905 (define_insn "*strsetsi_1"
15906 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15907 (match_operand:SI 2 "register_operand" "a"))
15908 (set (match_operand:P 0 "register_operand" "=D")
15909 (plus:P (match_dup 1)
15911 (unspec [(const_int 0)] UNSPEC_STOS)]
15912 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15914 [(set_attr "type" "str")
15915 (set_attr "memory" "store")
15916 (set_attr "mode" "SI")])
15918 (define_insn "*strsethi_1"
15919 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15920 (match_operand:HI 2 "register_operand" "a"))
15921 (set (match_operand:P 0 "register_operand" "=D")
15922 (plus:P (match_dup 1)
15924 (unspec [(const_int 0)] UNSPEC_STOS)]
15925 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15927 [(set_attr "type" "str")
15928 (set_attr "memory" "store")
15929 (set_attr "mode" "HI")])
15931 (define_insn "*strsetqi_1"
15932 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15933 (match_operand:QI 2 "register_operand" "a"))
15934 (set (match_operand:P 0 "register_operand" "=D")
15935 (plus:P (match_dup 1)
15937 (unspec [(const_int 0)] UNSPEC_STOS)]
15938 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15940 [(set_attr "type" "str")
15941 (set_attr "memory" "store")
15942 (set (attr "prefix_rex")
15944 (match_test "<P:MODE>mode == DImode")
15946 (const_string "*")))
15947 (set_attr "mode" "QI")])
15949 (define_expand "rep_stos"
15950 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15951 (set (match_operand 0 "register_operand")
15953 (set (match_operand 2 "memory_operand") (const_int 0))
15954 (use (match_operand 3 "register_operand"))
15955 (use (match_dup 1))])]
15957 "ix86_current_function_needs_cld = 1;")
15959 (define_insn "*rep_stosdi_rex64"
15960 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15961 (set (match_operand:P 0 "register_operand" "=D")
15962 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15964 (match_operand:P 3 "register_operand" "0")))
15965 (set (mem:BLK (match_dup 3))
15967 (use (match_operand:DI 2 "register_operand" "a"))
15968 (use (match_dup 4))]
15970 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15972 [(set_attr "type" "str")
15973 (set_attr "prefix_rep" "1")
15974 (set_attr "memory" "store")
15975 (set_attr "mode" "DI")])
15977 (define_insn "*rep_stossi"
15978 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15979 (set (match_operand:P 0 "register_operand" "=D")
15980 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15982 (match_operand:P 3 "register_operand" "0")))
15983 (set (mem:BLK (match_dup 3))
15985 (use (match_operand:SI 2 "register_operand" "a"))
15986 (use (match_dup 4))]
15987 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15988 "%^rep{%;} stos{l|d}"
15989 [(set_attr "type" "str")
15990 (set_attr "prefix_rep" "1")
15991 (set_attr "memory" "store")
15992 (set_attr "mode" "SI")])
15994 (define_insn "*rep_stosqi"
15995 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15996 (set (match_operand:P 0 "register_operand" "=D")
15997 (plus:P (match_operand:P 3 "register_operand" "0")
15998 (match_operand:P 4 "register_operand" "1")))
15999 (set (mem:BLK (match_dup 3))
16001 (use (match_operand:QI 2 "register_operand" "a"))
16002 (use (match_dup 4))]
16003 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16005 [(set_attr "type" "str")
16006 (set_attr "prefix_rep" "1")
16007 (set_attr "memory" "store")
16008 (set (attr "prefix_rex")
16010 (match_test "<P:MODE>mode == DImode")
16012 (const_string "*")))
16013 (set_attr "mode" "QI")])
16015 (define_expand "cmpstrnsi"
16016 [(set (match_operand:SI 0 "register_operand")
16017 (compare:SI (match_operand:BLK 1 "general_operand")
16018 (match_operand:BLK 2 "general_operand")))
16019 (use (match_operand 3 "general_operand"))
16020 (use (match_operand 4 "immediate_operand"))]
16023 rtx addr1, addr2, out, outlow, count, countreg, align;
16025 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16028 /* Can't use this if the user has appropriated ecx, esi or edi. */
16029 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16034 out = gen_reg_rtx (SImode);
16036 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16037 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16038 if (addr1 != XEXP (operands[1], 0))
16039 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16040 if (addr2 != XEXP (operands[2], 0))
16041 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16043 count = operands[3];
16044 countreg = ix86_zero_extend_to_Pmode (count);
16046 /* %%% Iff we are testing strict equality, we can use known alignment
16047 to good advantage. This may be possible with combine, particularly
16048 once cc0 is dead. */
16049 align = operands[4];
16051 if (CONST_INT_P (count))
16053 if (INTVAL (count) == 0)
16055 emit_move_insn (operands[0], const0_rtx);
16058 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16059 operands[1], operands[2]));
16063 rtx (*gen_cmp) (rtx, rtx);
16065 gen_cmp = (TARGET_64BIT
16066 ? gen_cmpdi_1 : gen_cmpsi_1);
16068 emit_insn (gen_cmp (countreg, countreg));
16069 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16070 operands[1], operands[2]));
16073 outlow = gen_lowpart (QImode, out);
16074 emit_insn (gen_cmpintqi (outlow));
16075 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16077 if (operands[0] != out)
16078 emit_move_insn (operands[0], out);
16083 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16085 (define_expand "cmpintqi"
16086 [(set (match_dup 1)
16087 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16089 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16090 (parallel [(set (match_operand:QI 0 "register_operand")
16091 (minus:QI (match_dup 1)
16093 (clobber (reg:CC FLAGS_REG))])]
16096 operands[1] = gen_reg_rtx (QImode);
16097 operands[2] = gen_reg_rtx (QImode);
16100 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16101 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16103 (define_expand "cmpstrnqi_nz_1"
16104 [(parallel [(set (reg:CC FLAGS_REG)
16105 (compare:CC (match_operand 4 "memory_operand")
16106 (match_operand 5 "memory_operand")))
16107 (use (match_operand 2 "register_operand"))
16108 (use (match_operand:SI 3 "immediate_operand"))
16109 (clobber (match_operand 0 "register_operand"))
16110 (clobber (match_operand 1 "register_operand"))
16111 (clobber (match_dup 2))])]
16113 "ix86_current_function_needs_cld = 1;")
16115 (define_insn "*cmpstrnqi_nz_1"
16116 [(set (reg:CC FLAGS_REG)
16117 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16118 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16119 (use (match_operand:P 6 "register_operand" "2"))
16120 (use (match_operand:SI 3 "immediate_operand" "i"))
16121 (clobber (match_operand:P 0 "register_operand" "=S"))
16122 (clobber (match_operand:P 1 "register_operand" "=D"))
16123 (clobber (match_operand:P 2 "register_operand" "=c"))]
16124 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16126 [(set_attr "type" "str")
16127 (set_attr "mode" "QI")
16128 (set (attr "prefix_rex")
16130 (match_test "<P:MODE>mode == DImode")
16132 (const_string "*")))
16133 (set_attr "prefix_rep" "1")])
16135 ;; The same, but the count is not known to not be zero.
16137 (define_expand "cmpstrnqi_1"
16138 [(parallel [(set (reg:CC FLAGS_REG)
16139 (if_then_else:CC (ne (match_operand 2 "register_operand")
16141 (compare:CC (match_operand 4 "memory_operand")
16142 (match_operand 5 "memory_operand"))
16144 (use (match_operand:SI 3 "immediate_operand"))
16145 (use (reg:CC FLAGS_REG))
16146 (clobber (match_operand 0 "register_operand"))
16147 (clobber (match_operand 1 "register_operand"))
16148 (clobber (match_dup 2))])]
16150 "ix86_current_function_needs_cld = 1;")
16152 (define_insn "*cmpstrnqi_1"
16153 [(set (reg:CC FLAGS_REG)
16154 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16156 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16157 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16159 (use (match_operand:SI 3 "immediate_operand" "i"))
16160 (use (reg:CC FLAGS_REG))
16161 (clobber (match_operand:P 0 "register_operand" "=S"))
16162 (clobber (match_operand:P 1 "register_operand" "=D"))
16163 (clobber (match_operand:P 2 "register_operand" "=c"))]
16164 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16166 [(set_attr "type" "str")
16167 (set_attr "mode" "QI")
16168 (set (attr "prefix_rex")
16170 (match_test "<P:MODE>mode == DImode")
16172 (const_string "*")))
16173 (set_attr "prefix_rep" "1")])
16175 (define_expand "strlen<mode>"
16176 [(set (match_operand:P 0 "register_operand")
16177 (unspec:P [(match_operand:BLK 1 "general_operand")
16178 (match_operand:QI 2 "immediate_operand")
16179 (match_operand 3 "immediate_operand")]
16183 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16189 (define_expand "strlenqi_1"
16190 [(parallel [(set (match_operand 0 "register_operand")
16192 (clobber (match_operand 1 "register_operand"))
16193 (clobber (reg:CC FLAGS_REG))])]
16195 "ix86_current_function_needs_cld = 1;")
16197 (define_insn "*strlenqi_1"
16198 [(set (match_operand:P 0 "register_operand" "=&c")
16199 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16200 (match_operand:QI 2 "register_operand" "a")
16201 (match_operand:P 3 "immediate_operand" "i")
16202 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16203 (clobber (match_operand:P 1 "register_operand" "=D"))
16204 (clobber (reg:CC FLAGS_REG))]
16205 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16206 "%^repnz{%;} scasb"
16207 [(set_attr "type" "str")
16208 (set_attr "mode" "QI")
16209 (set (attr "prefix_rex")
16211 (match_test "<P:MODE>mode == DImode")
16213 (const_string "*")))
16214 (set_attr "prefix_rep" "1")])
16216 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16217 ;; handled in combine, but it is not currently up to the task.
16218 ;; When used for their truth value, the cmpstrn* expanders generate
16227 ;; The intermediate three instructions are unnecessary.
16229 ;; This one handles cmpstrn*_nz_1...
16232 (set (reg:CC FLAGS_REG)
16233 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16234 (mem:BLK (match_operand 5 "register_operand"))))
16235 (use (match_operand 6 "register_operand"))
16236 (use (match_operand:SI 3 "immediate_operand"))
16237 (clobber (match_operand 0 "register_operand"))
16238 (clobber (match_operand 1 "register_operand"))
16239 (clobber (match_operand 2 "register_operand"))])
16240 (set (match_operand:QI 7 "register_operand")
16241 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16242 (set (match_operand:QI 8 "register_operand")
16243 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16244 (set (reg FLAGS_REG)
16245 (compare (match_dup 7) (match_dup 8)))
16247 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16249 (set (reg:CC FLAGS_REG)
16250 (compare:CC (mem:BLK (match_dup 4))
16251 (mem:BLK (match_dup 5))))
16252 (use (match_dup 6))
16253 (use (match_dup 3))
16254 (clobber (match_dup 0))
16255 (clobber (match_dup 1))
16256 (clobber (match_dup 2))])])
16258 ;; ...and this one handles cmpstrn*_1.
16261 (set (reg:CC FLAGS_REG)
16262 (if_then_else:CC (ne (match_operand 6 "register_operand")
16264 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16265 (mem:BLK (match_operand 5 "register_operand")))
16267 (use (match_operand:SI 3 "immediate_operand"))
16268 (use (reg:CC FLAGS_REG))
16269 (clobber (match_operand 0 "register_operand"))
16270 (clobber (match_operand 1 "register_operand"))
16271 (clobber (match_operand 2 "register_operand"))])
16272 (set (match_operand:QI 7 "register_operand")
16273 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16274 (set (match_operand:QI 8 "register_operand")
16275 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16276 (set (reg FLAGS_REG)
16277 (compare (match_dup 7) (match_dup 8)))
16279 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16281 (set (reg:CC FLAGS_REG)
16282 (if_then_else:CC (ne (match_dup 6)
16284 (compare:CC (mem:BLK (match_dup 4))
16285 (mem:BLK (match_dup 5)))
16287 (use (match_dup 3))
16288 (use (reg:CC FLAGS_REG))
16289 (clobber (match_dup 0))
16290 (clobber (match_dup 1))
16291 (clobber (match_dup 2))])])
16293 ;; Conditional move instructions.
16295 (define_expand "mov<mode>cc"
16296 [(set (match_operand:SWIM 0 "register_operand")
16297 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16298 (match_operand:SWIM 2 "<general_operand>")
16299 (match_operand:SWIM 3 "<general_operand>")))]
16301 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16303 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16304 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16305 ;; So just document what we're doing explicitly.
16307 (define_expand "x86_mov<mode>cc_0_m1"
16309 [(set (match_operand:SWI48 0 "register_operand")
16310 (if_then_else:SWI48
16311 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16312 [(match_operand 1 "flags_reg_operand")
16316 (clobber (reg:CC FLAGS_REG))])])
16318 (define_insn "*x86_mov<mode>cc_0_m1"
16319 [(set (match_operand:SWI48 0 "register_operand" "=r")
16320 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16321 [(reg FLAGS_REG) (const_int 0)])
16324 (clobber (reg:CC FLAGS_REG))]
16326 "sbb{<imodesuffix>}\t%0, %0"
16327 ; Since we don't have the proper number of operands for an alu insn,
16328 ; fill in all the blanks.
16329 [(set_attr "type" "alu")
16330 (set_attr "use_carry" "1")
16331 (set_attr "pent_pair" "pu")
16332 (set_attr "memory" "none")
16333 (set_attr "imm_disp" "false")
16334 (set_attr "mode" "<MODE>")
16335 (set_attr "length_immediate" "0")])
16337 (define_insn "*x86_mov<mode>cc_0_m1_se"
16338 [(set (match_operand:SWI48 0 "register_operand" "=r")
16339 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16340 [(reg FLAGS_REG) (const_int 0)])
16343 (clobber (reg:CC FLAGS_REG))]
16345 "sbb{<imodesuffix>}\t%0, %0"
16346 [(set_attr "type" "alu")
16347 (set_attr "use_carry" "1")
16348 (set_attr "pent_pair" "pu")
16349 (set_attr "memory" "none")
16350 (set_attr "imm_disp" "false")
16351 (set_attr "mode" "<MODE>")
16352 (set_attr "length_immediate" "0")])
16354 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16355 [(set (match_operand:SWI48 0 "register_operand" "=r")
16356 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16357 [(reg FLAGS_REG) (const_int 0)])))
16358 (clobber (reg:CC FLAGS_REG))]
16360 "sbb{<imodesuffix>}\t%0, %0"
16361 [(set_attr "type" "alu")
16362 (set_attr "use_carry" "1")
16363 (set_attr "pent_pair" "pu")
16364 (set_attr "memory" "none")
16365 (set_attr "imm_disp" "false")
16366 (set_attr "mode" "<MODE>")
16367 (set_attr "length_immediate" "0")])
16369 (define_insn "*mov<mode>cc_noc"
16370 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16371 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16372 [(reg FLAGS_REG) (const_int 0)])
16373 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16374 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16375 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16377 cmov%O2%C1\t{%2, %0|%0, %2}
16378 cmov%O2%c1\t{%3, %0|%0, %3}"
16379 [(set_attr "type" "icmov")
16380 (set_attr "mode" "<MODE>")])
16382 ;; Don't do conditional moves with memory inputs. This splitter helps
16383 ;; register starved x86_32 by forcing inputs into registers before reload.
16385 [(set (match_operand:SWI248 0 "register_operand")
16386 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16387 [(reg FLAGS_REG) (const_int 0)])
16388 (match_operand:SWI248 2 "nonimmediate_operand")
16389 (match_operand:SWI248 3 "nonimmediate_operand")))]
16390 "!TARGET_64BIT && TARGET_CMOVE
16391 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16392 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16393 && can_create_pseudo_p ()
16394 && optimize_insn_for_speed_p ()"
16395 [(set (match_dup 0)
16396 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16398 if (MEM_P (operands[2]))
16399 operands[2] = force_reg (<MODE>mode, operands[2]);
16400 if (MEM_P (operands[3]))
16401 operands[3] = force_reg (<MODE>mode, operands[3]);
16404 (define_insn "*movqicc_noc"
16405 [(set (match_operand:QI 0 "register_operand" "=r,r")
16406 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:QI 2 "register_operand" "r,0")
16409 (match_operand:QI 3 "register_operand" "0,r")))]
16410 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16412 [(set_attr "type" "icmov")
16413 (set_attr "mode" "QI")])
16416 [(set (match_operand:SWI12 0 "register_operand")
16417 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16419 (match_operand:SWI12 2 "register_operand")
16420 (match_operand:SWI12 3 "register_operand")))]
16421 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16422 && reload_completed"
16423 [(set (match_dup 0)
16424 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16426 operands[0] = gen_lowpart (SImode, operands[0]);
16427 operands[2] = gen_lowpart (SImode, operands[2]);
16428 operands[3] = gen_lowpart (SImode, operands[3]);
16431 ;; Don't do conditional moves with memory inputs
16433 [(match_scratch:SWI248 2 "r")
16434 (set (match_operand:SWI248 0 "register_operand")
16435 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16436 [(reg FLAGS_REG) (const_int 0)])
16438 (match_operand:SWI248 3 "memory_operand")))]
16439 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16440 && optimize_insn_for_speed_p ()"
16441 [(set (match_dup 2) (match_dup 3))
16443 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16446 [(match_scratch:SWI248 2 "r")
16447 (set (match_operand:SWI248 0 "register_operand")
16448 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16449 [(reg FLAGS_REG) (const_int 0)])
16450 (match_operand:SWI248 3 "memory_operand")
16452 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16453 && optimize_insn_for_speed_p ()"
16454 [(set (match_dup 2) (match_dup 3))
16456 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16458 (define_expand "mov<mode>cc"
16459 [(set (match_operand:X87MODEF 0 "register_operand")
16460 (if_then_else:X87MODEF
16461 (match_operand 1 "comparison_operator")
16462 (match_operand:X87MODEF 2 "register_operand")
16463 (match_operand:X87MODEF 3 "register_operand")))]
16464 "(TARGET_80387 && TARGET_CMOVE)
16465 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16466 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16468 (define_insn "*movxfcc_1"
16469 [(set (match_operand:XF 0 "register_operand" "=f,f")
16470 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16471 [(reg FLAGS_REG) (const_int 0)])
16472 (match_operand:XF 2 "register_operand" "f,0")
16473 (match_operand:XF 3 "register_operand" "0,f")))]
16474 "TARGET_80387 && TARGET_CMOVE"
16476 fcmov%F1\t{%2, %0|%0, %2}
16477 fcmov%f1\t{%3, %0|%0, %3}"
16478 [(set_attr "type" "fcmov")
16479 (set_attr "mode" "XF")])
16481 (define_insn "*movdfcc_1"
16482 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16483 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16484 [(reg FLAGS_REG) (const_int 0)])
16485 (match_operand:DF 2 "nonimmediate_operand"
16487 (match_operand:DF 3 "nonimmediate_operand"
16488 "0 ,f,0 ,rm,0, rm")))]
16489 "TARGET_80387 && TARGET_CMOVE
16490 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16492 fcmov%F1\t{%2, %0|%0, %2}
16493 fcmov%f1\t{%3, %0|%0, %3}
16496 cmov%O2%C1\t{%2, %0|%0, %2}
16497 cmov%O2%c1\t{%3, %0|%0, %3}"
16498 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16499 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16500 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16503 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16504 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16505 [(reg FLAGS_REG) (const_int 0)])
16506 (match_operand:DF 2 "nonimmediate_operand")
16507 (match_operand:DF 3 "nonimmediate_operand")))]
16508 "!TARGET_64BIT && reload_completed"
16509 [(set (match_dup 2)
16510 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16512 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16514 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16515 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16518 (define_insn "*movsfcc_1_387"
16519 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16520 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16523 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524 "TARGET_80387 && TARGET_CMOVE
16525 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16527 fcmov%F1\t{%2, %0|%0, %2}
16528 fcmov%f1\t{%3, %0|%0, %3}
16529 cmov%O2%C1\t{%2, %0|%0, %2}
16530 cmov%O2%c1\t{%3, %0|%0, %3}"
16531 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16532 (set_attr "mode" "SF,SF,SI,SI")])
16534 ;; Don't do conditional moves with memory inputs. This splitter helps
16535 ;; register starved x86_32 by forcing inputs into registers before reload.
16537 [(set (match_operand:MODEF 0 "register_operand")
16538 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16539 [(reg FLAGS_REG) (const_int 0)])
16540 (match_operand:MODEF 2 "nonimmediate_operand")
16541 (match_operand:MODEF 3 "nonimmediate_operand")))]
16542 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16543 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16544 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16545 && can_create_pseudo_p ()
16546 && optimize_insn_for_speed_p ()"
16547 [(set (match_dup 0)
16548 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16550 if (MEM_P (operands[2]))
16551 operands[2] = force_reg (<MODE>mode, operands[2]);
16552 if (MEM_P (operands[3]))
16553 operands[3] = force_reg (<MODE>mode, operands[3]);
16556 ;; Don't do conditional moves with memory inputs
16558 [(match_scratch:MODEF 2 "r")
16559 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16560 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16561 [(reg FLAGS_REG) (const_int 0)])
16563 (match_operand:MODEF 3 "memory_operand")))]
16564 "(<MODE>mode != DFmode || TARGET_64BIT)
16565 && TARGET_80387 && TARGET_CMOVE
16566 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16567 && optimize_insn_for_speed_p ()"
16568 [(set (match_dup 2) (match_dup 3))
16570 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16573 [(match_scratch:MODEF 2 "r")
16574 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16575 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16576 [(reg FLAGS_REG) (const_int 0)])
16577 (match_operand:MODEF 3 "memory_operand")
16579 "(<MODE>mode != DFmode || TARGET_64BIT)
16580 && TARGET_80387 && TARGET_CMOVE
16581 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16582 && optimize_insn_for_speed_p ()"
16583 [(set (match_dup 2) (match_dup 3))
16585 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16587 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16588 ;; the scalar versions to have only XMM registers as operands.
16590 ;; XOP conditional move
16591 (define_insn "*xop_pcmov_<mode>"
16592 [(set (match_operand:MODEF 0 "register_operand" "=x")
16593 (if_then_else:MODEF
16594 (match_operand:MODEF 1 "register_operand" "x")
16595 (match_operand:MODEF 2 "register_operand" "x")
16596 (match_operand:MODEF 3 "register_operand" "x")))]
16598 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16599 [(set_attr "type" "sse4arg")])
16601 ;; These versions of the min/max patterns are intentionally ignorant of
16602 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16603 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16604 ;; are undefined in this condition, we're certain this is correct.
16606 (define_insn "<code><mode>3"
16607 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16609 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16610 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16611 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16613 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16614 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16615 [(set_attr "isa" "noavx,avx")
16616 (set_attr "prefix" "orig,vex")
16617 (set_attr "type" "sseadd")
16618 (set_attr "mode" "<MODE>")])
16620 ;; These versions of the min/max patterns implement exactly the operations
16621 ;; min = (op1 < op2 ? op1 : op2)
16622 ;; max = (!(op1 < op2) ? op1 : op2)
16623 ;; Their operands are not commutative, and thus they may be used in the
16624 ;; presence of -0.0 and NaN.
16626 (define_int_iterator IEEE_MAXMIN
16630 (define_int_attr ieee_maxmin
16631 [(UNSPEC_IEEE_MAX "max")
16632 (UNSPEC_IEEE_MIN "min")])
16634 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16635 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16637 [(match_operand:MODEF 1 "register_operand" "0,x")
16638 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16640 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16642 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16643 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16644 [(set_attr "isa" "noavx,avx")
16645 (set_attr "prefix" "orig,vex")
16646 (set_attr "type" "sseadd")
16647 (set_attr "mode" "<MODE>")])
16649 ;; Make two stack loads independent:
16651 ;; fld %st(0) -> fld bb
16652 ;; fmul bb fmul %st(1), %st
16654 ;; Actually we only match the last two instructions for simplicity.
16656 [(set (match_operand 0 "fp_register_operand")
16657 (match_operand 1 "fp_register_operand"))
16659 (match_operator 2 "binary_fp_operator"
16661 (match_operand 3 "memory_operand")]))]
16662 "REGNO (operands[0]) != REGNO (operands[1])"
16663 [(set (match_dup 0) (match_dup 3))
16664 (set (match_dup 0) (match_dup 4))]
16666 ;; The % modifier is not operational anymore in peephole2's, so we have to
16667 ;; swap the operands manually in the case of addition and multiplication.
16671 if (COMMUTATIVE_ARITH_P (operands[2]))
16672 op0 = operands[0], op1 = operands[1];
16674 op0 = operands[1], op1 = operands[0];
16676 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16677 GET_MODE (operands[2]),
16681 ;; Conditional addition patterns
16682 (define_expand "add<mode>cc"
16683 [(match_operand:SWI 0 "register_operand")
16684 (match_operand 1 "ordered_comparison_operator")
16685 (match_operand:SWI 2 "register_operand")
16686 (match_operand:SWI 3 "const_int_operand")]
16688 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16690 ;; Misc patterns (?)
16692 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16693 ;; Otherwise there will be nothing to keep
16695 ;; [(set (reg ebp) (reg esp))]
16696 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16697 ;; (clobber (eflags)]
16698 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16700 ;; in proper program order.
16702 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16703 [(set (match_operand:P 0 "register_operand" "=r,r")
16704 (plus:P (match_operand:P 1 "register_operand" "0,r")
16705 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16706 (clobber (reg:CC FLAGS_REG))
16707 (clobber (mem:BLK (scratch)))]
16710 switch (get_attr_type (insn))
16713 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16716 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16717 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16718 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16720 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16723 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16724 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16727 [(set (attr "type")
16728 (cond [(and (eq_attr "alternative" "0")
16729 (not (match_test "TARGET_OPT_AGU")))
16730 (const_string "alu")
16731 (match_operand:<MODE> 2 "const0_operand")
16732 (const_string "imov")
16734 (const_string "lea")))
16735 (set (attr "length_immediate")
16736 (cond [(eq_attr "type" "imov")
16738 (and (eq_attr "type" "alu")
16739 (match_operand 2 "const128_operand"))
16742 (const_string "*")))
16743 (set_attr "mode" "<MODE>")])
16745 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16746 [(set (match_operand:P 0 "register_operand" "=r")
16747 (minus:P (match_operand:P 1 "register_operand" "0")
16748 (match_operand:P 2 "register_operand" "r")))
16749 (clobber (reg:CC FLAGS_REG))
16750 (clobber (mem:BLK (scratch)))]
16752 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16753 [(set_attr "type" "alu")
16754 (set_attr "mode" "<MODE>")])
16756 (define_insn "allocate_stack_worker_probe_<mode>"
16757 [(set (match_operand:P 0 "register_operand" "=a")
16758 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16759 UNSPECV_STACK_PROBE))
16760 (clobber (reg:CC FLAGS_REG))]
16761 "ix86_target_stack_probe ()"
16762 "call\t___chkstk_ms"
16763 [(set_attr "type" "multi")
16764 (set_attr "length" "5")])
16766 (define_expand "allocate_stack"
16767 [(match_operand 0 "register_operand")
16768 (match_operand 1 "general_operand")]
16769 "ix86_target_stack_probe ()"
16773 #ifndef CHECK_STACK_LIMIT
16774 #define CHECK_STACK_LIMIT 0
16777 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16778 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16782 rtx (*insn) (rtx, rtx);
16784 x = copy_to_mode_reg (Pmode, operands[1]);
16786 insn = (TARGET_64BIT
16787 ? gen_allocate_stack_worker_probe_di
16788 : gen_allocate_stack_worker_probe_si);
16790 emit_insn (insn (x, x));
16793 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16794 stack_pointer_rtx, 0, OPTAB_DIRECT);
16796 if (x != stack_pointer_rtx)
16797 emit_move_insn (stack_pointer_rtx, x);
16799 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16803 ;; Use IOR for stack probes, this is shorter.
16804 (define_expand "probe_stack"
16805 [(match_operand 0 "memory_operand")]
16808 rtx (*gen_ior3) (rtx, rtx, rtx);
16810 gen_ior3 = (GET_MODE (operands[0]) == DImode
16811 ? gen_iordi3 : gen_iorsi3);
16813 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16817 (define_insn "adjust_stack_and_probe<mode>"
16818 [(set (match_operand:P 0 "register_operand" "=r")
16819 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16820 UNSPECV_PROBE_STACK_RANGE))
16821 (set (reg:P SP_REG)
16822 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16823 (clobber (reg:CC FLAGS_REG))
16824 (clobber (mem:BLK (scratch)))]
16826 "* return output_adjust_stack_and_probe (operands[0]);"
16827 [(set_attr "type" "multi")])
16829 (define_insn "probe_stack_range<mode>"
16830 [(set (match_operand:P 0 "register_operand" "=r")
16831 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16832 (match_operand:P 2 "const_int_operand" "n")]
16833 UNSPECV_PROBE_STACK_RANGE))
16834 (clobber (reg:CC FLAGS_REG))]
16836 "* return output_probe_stack_range (operands[0], operands[2]);"
16837 [(set_attr "type" "multi")])
16839 (define_expand "builtin_setjmp_receiver"
16840 [(label_ref (match_operand 0))]
16841 "!TARGET_64BIT && flag_pic"
16847 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16848 rtx label_rtx = gen_label_rtx ();
16849 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16850 xops[0] = xops[1] = picreg;
16851 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16852 ix86_expand_binary_operator (MINUS, SImode, xops);
16856 emit_insn (gen_set_got (pic_offset_table_rtx));
16860 (define_insn_and_split "nonlocal_goto_receiver"
16861 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16862 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16864 "&& reload_completed"
16867 if (crtl->uses_pic_offset_table)
16870 rtx label_rtx = gen_label_rtx ();
16873 /* Get a new pic base. */
16874 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16875 /* Correct this with the offset from the new to the old. */
16876 xops[0] = xops[1] = pic_offset_table_rtx;
16877 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16878 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16879 UNSPEC_MACHOPIC_OFFSET);
16880 xops[2] = gen_rtx_CONST (Pmode, tmp);
16881 ix86_expand_binary_operator (MINUS, SImode, xops);
16884 /* No pic reg restore needed. */
16885 emit_note (NOTE_INSN_DELETED);
16890 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16891 ;; Do not split instructions with mask registers.
16893 [(set (match_operand 0 "general_reg_operand")
16894 (match_operator 3 "promotable_binary_operator"
16895 [(match_operand 1 "general_reg_operand")
16896 (match_operand 2 "aligned_operand")]))
16897 (clobber (reg:CC FLAGS_REG))]
16898 "! TARGET_PARTIAL_REG_STALL && reload_completed
16899 && ((GET_MODE (operands[0]) == HImode
16900 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16901 /* ??? next two lines just !satisfies_constraint_K (...) */
16902 || !CONST_INT_P (operands[2])
16903 || satisfies_constraint_K (operands[2])))
16904 || (GET_MODE (operands[0]) == QImode
16905 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16906 [(parallel [(set (match_dup 0)
16907 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16908 (clobber (reg:CC FLAGS_REG))])]
16910 operands[0] = gen_lowpart (SImode, operands[0]);
16911 operands[1] = gen_lowpart (SImode, operands[1]);
16912 if (GET_CODE (operands[3]) != ASHIFT)
16913 operands[2] = gen_lowpart (SImode, operands[2]);
16914 PUT_MODE (operands[3], SImode);
16917 ; Promote the QImode tests, as i386 has encoding of the AND
16918 ; instruction with 32-bit sign-extended immediate and thus the
16919 ; instruction size is unchanged, except in the %eax case for
16920 ; which it is increased by one byte, hence the ! optimize_size.
16922 [(set (match_operand 0 "flags_reg_operand")
16923 (match_operator 2 "compare_operator"
16924 [(and (match_operand 3 "aligned_operand")
16925 (match_operand 4 "const_int_operand"))
16927 (set (match_operand 1 "register_operand")
16928 (and (match_dup 3) (match_dup 4)))]
16929 "! TARGET_PARTIAL_REG_STALL && reload_completed
16930 && optimize_insn_for_speed_p ()
16931 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16932 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16933 /* Ensure that the operand will remain sign-extended immediate. */
16934 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16935 [(parallel [(set (match_dup 0)
16936 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16939 (and:SI (match_dup 3) (match_dup 4)))])]
16942 = gen_int_mode (INTVAL (operands[4])
16943 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16944 operands[1] = gen_lowpart (SImode, operands[1]);
16945 operands[3] = gen_lowpart (SImode, operands[3]);
16948 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16949 ; the TEST instruction with 32-bit sign-extended immediate and thus
16950 ; the instruction size would at least double, which is not what we
16951 ; want even with ! optimize_size.
16953 [(set (match_operand 0 "flags_reg_operand")
16954 (match_operator 1 "compare_operator"
16955 [(and (match_operand:HI 2 "aligned_operand")
16956 (match_operand:HI 3 "const_int_operand"))
16958 "! TARGET_PARTIAL_REG_STALL && reload_completed
16959 && ! TARGET_FAST_PREFIX
16960 && optimize_insn_for_speed_p ()
16961 /* Ensure that the operand will remain sign-extended immediate. */
16962 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16963 [(set (match_dup 0)
16964 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16968 = gen_int_mode (INTVAL (operands[3])
16969 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16970 operands[2] = gen_lowpart (SImode, operands[2]);
16974 [(set (match_operand 0 "register_operand")
16975 (neg (match_operand 1 "register_operand")))
16976 (clobber (reg:CC FLAGS_REG))]
16977 "! TARGET_PARTIAL_REG_STALL && reload_completed
16978 && (GET_MODE (operands[0]) == HImode
16979 || (GET_MODE (operands[0]) == QImode
16980 && (TARGET_PROMOTE_QImode
16981 || optimize_insn_for_size_p ())))"
16982 [(parallel [(set (match_dup 0)
16983 (neg:SI (match_dup 1)))
16984 (clobber (reg:CC FLAGS_REG))])]
16986 operands[0] = gen_lowpart (SImode, operands[0]);
16987 operands[1] = gen_lowpart (SImode, operands[1]);
16990 ;; Do not split instructions with mask regs.
16992 [(set (match_operand 0 "general_reg_operand")
16993 (not (match_operand 1 "general_reg_operand")))]
16994 "! TARGET_PARTIAL_REG_STALL && reload_completed
16995 && (GET_MODE (operands[0]) == HImode
16996 || (GET_MODE (operands[0]) == QImode
16997 && (TARGET_PROMOTE_QImode
16998 || optimize_insn_for_size_p ())))"
16999 [(set (match_dup 0)
17000 (not:SI (match_dup 1)))]
17002 operands[0] = gen_lowpart (SImode, operands[0]);
17003 operands[1] = gen_lowpart (SImode, operands[1]);
17006 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17007 ;; transform a complex memory operation into two memory to register operations.
17009 ;; Don't push memory operands
17011 [(set (match_operand:SWI 0 "push_operand")
17012 (match_operand:SWI 1 "memory_operand"))
17013 (match_scratch:SWI 2 "<r>")]
17014 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17015 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17016 [(set (match_dup 2) (match_dup 1))
17017 (set (match_dup 0) (match_dup 2))])
17019 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17022 [(set (match_operand:SF 0 "push_operand")
17023 (match_operand:SF 1 "memory_operand"))
17024 (match_scratch:SF 2 "r")]
17025 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17026 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17027 [(set (match_dup 2) (match_dup 1))
17028 (set (match_dup 0) (match_dup 2))])
17030 ;; Don't move an immediate directly to memory when the instruction
17031 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17033 [(match_scratch:SWI124 1 "<r>")
17034 (set (match_operand:SWI124 0 "memory_operand")
17036 "optimize_insn_for_speed_p ()
17037 && ((<MODE>mode == HImode
17038 && TARGET_LCP_STALL)
17039 || (!TARGET_USE_MOV0
17040 && TARGET_SPLIT_LONG_MOVES
17041 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17042 && peep2_regno_dead_p (0, FLAGS_REG)"
17043 [(parallel [(set (match_dup 2) (const_int 0))
17044 (clobber (reg:CC FLAGS_REG))])
17045 (set (match_dup 0) (match_dup 1))]
17046 "operands[2] = gen_lowpart (SImode, operands[1]);")
17049 [(match_scratch:SWI124 2 "<r>")
17050 (set (match_operand:SWI124 0 "memory_operand")
17051 (match_operand:SWI124 1 "immediate_operand"))]
17052 "optimize_insn_for_speed_p ()
17053 && ((<MODE>mode == HImode
17054 && TARGET_LCP_STALL)
17055 || (TARGET_SPLIT_LONG_MOVES
17056 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17057 [(set (match_dup 2) (match_dup 1))
17058 (set (match_dup 0) (match_dup 2))])
17060 ;; Don't compare memory with zero, load and use a test instead.
17062 [(set (match_operand 0 "flags_reg_operand")
17063 (match_operator 1 "compare_operator"
17064 [(match_operand:SI 2 "memory_operand")
17066 (match_scratch:SI 3 "r")]
17067 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17068 [(set (match_dup 3) (match_dup 2))
17069 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17071 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17072 ;; Don't split NOTs with a displacement operand, because resulting XOR
17073 ;; will not be pairable anyway.
17075 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17076 ;; represented using a modRM byte. The XOR replacement is long decoded,
17077 ;; so this split helps here as well.
17079 ;; Note: Can't do this as a regular split because we can't get proper
17080 ;; lifetime information then.
17083 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17084 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17085 "optimize_insn_for_speed_p ()
17086 && ((TARGET_NOT_UNPAIRABLE
17087 && (!MEM_P (operands[0])
17088 || !memory_displacement_operand (operands[0], <MODE>mode)))
17089 || (TARGET_NOT_VECTORMODE
17090 && long_memory_operand (operands[0], <MODE>mode)))
17091 && peep2_regno_dead_p (0, FLAGS_REG)"
17092 [(parallel [(set (match_dup 0)
17093 (xor:SWI124 (match_dup 1) (const_int -1)))
17094 (clobber (reg:CC FLAGS_REG))])])
17096 ;; Non pairable "test imm, reg" instructions can be translated to
17097 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17098 ;; byte opcode instead of two, have a short form for byte operands),
17099 ;; so do it for other CPUs as well. Given that the value was dead,
17100 ;; this should not create any new dependencies. Pass on the sub-word
17101 ;; versions if we're concerned about partial register stalls.
17104 [(set (match_operand 0 "flags_reg_operand")
17105 (match_operator 1 "compare_operator"
17106 [(and:SI (match_operand:SI 2 "register_operand")
17107 (match_operand:SI 3 "immediate_operand"))
17109 "ix86_match_ccmode (insn, CCNOmode)
17110 && (true_regnum (operands[2]) != AX_REG
17111 || satisfies_constraint_K (operands[3]))
17112 && peep2_reg_dead_p (1, operands[2])"
17114 [(set (match_dup 0)
17115 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17118 (and:SI (match_dup 2) (match_dup 3)))])])
17120 ;; We don't need to handle HImode case, because it will be promoted to SImode
17121 ;; on ! TARGET_PARTIAL_REG_STALL
17124 [(set (match_operand 0 "flags_reg_operand")
17125 (match_operator 1 "compare_operator"
17126 [(and:QI (match_operand:QI 2 "register_operand")
17127 (match_operand:QI 3 "immediate_operand"))
17129 "! TARGET_PARTIAL_REG_STALL
17130 && ix86_match_ccmode (insn, CCNOmode)
17131 && true_regnum (operands[2]) != AX_REG
17132 && peep2_reg_dead_p (1, operands[2])"
17134 [(set (match_dup 0)
17135 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17138 (and:QI (match_dup 2) (match_dup 3)))])])
17141 [(set (match_operand 0 "flags_reg_operand")
17142 (match_operator 1 "compare_operator"
17145 (match_operand 2 "ext_register_operand")
17148 (match_operand 3 "const_int_operand"))
17150 "! TARGET_PARTIAL_REG_STALL
17151 && ix86_match_ccmode (insn, CCNOmode)
17152 && true_regnum (operands[2]) != AX_REG
17153 && peep2_reg_dead_p (1, operands[2])"
17154 [(parallel [(set (match_dup 0)
17163 (set (zero_extract:SI (match_dup 2)
17171 (match_dup 3)))])])
17173 ;; Don't do logical operations with memory inputs.
17175 [(match_scratch:SI 2 "r")
17176 (parallel [(set (match_operand:SI 0 "register_operand")
17177 (match_operator:SI 3 "arith_or_logical_operator"
17179 (match_operand:SI 1 "memory_operand")]))
17180 (clobber (reg:CC FLAGS_REG))])]
17181 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17182 [(set (match_dup 2) (match_dup 1))
17183 (parallel [(set (match_dup 0)
17184 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17185 (clobber (reg:CC FLAGS_REG))])])
17188 [(match_scratch:SI 2 "r")
17189 (parallel [(set (match_operand:SI 0 "register_operand")
17190 (match_operator:SI 3 "arith_or_logical_operator"
17191 [(match_operand:SI 1 "memory_operand")
17193 (clobber (reg:CC FLAGS_REG))])]
17194 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17195 [(set (match_dup 2) (match_dup 1))
17196 (parallel [(set (match_dup 0)
17197 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17198 (clobber (reg:CC FLAGS_REG))])])
17200 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17201 ;; refers to the destination of the load!
17204 [(set (match_operand:SI 0 "register_operand")
17205 (match_operand:SI 1 "register_operand"))
17206 (parallel [(set (match_dup 0)
17207 (match_operator:SI 3 "commutative_operator"
17209 (match_operand:SI 2 "memory_operand")]))
17210 (clobber (reg:CC FLAGS_REG))])]
17211 "REGNO (operands[0]) != REGNO (operands[1])
17212 && GENERAL_REGNO_P (REGNO (operands[0]))
17213 && GENERAL_REGNO_P (REGNO (operands[1]))"
17214 [(set (match_dup 0) (match_dup 4))
17215 (parallel [(set (match_dup 0)
17216 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17217 (clobber (reg:CC FLAGS_REG))])]
17218 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17221 [(set (match_operand 0 "register_operand")
17222 (match_operand 1 "register_operand"))
17224 (match_operator 3 "commutative_operator"
17226 (match_operand 2 "memory_operand")]))]
17227 "REGNO (operands[0]) != REGNO (operands[1])
17228 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17229 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17230 [(set (match_dup 0) (match_dup 2))
17232 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17234 ; Don't do logical operations with memory outputs
17236 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17237 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17238 ; the same decoder scheduling characteristics as the original.
17241 [(match_scratch:SI 2 "r")
17242 (parallel [(set (match_operand:SI 0 "memory_operand")
17243 (match_operator:SI 3 "arith_or_logical_operator"
17245 (match_operand:SI 1 "nonmemory_operand")]))
17246 (clobber (reg:CC FLAGS_REG))])]
17247 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248 /* Do not split stack checking probes. */
17249 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17250 [(set (match_dup 2) (match_dup 0))
17251 (parallel [(set (match_dup 2)
17252 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17253 (clobber (reg:CC FLAGS_REG))])
17254 (set (match_dup 0) (match_dup 2))])
17257 [(match_scratch:SI 2 "r")
17258 (parallel [(set (match_operand:SI 0 "memory_operand")
17259 (match_operator:SI 3 "arith_or_logical_operator"
17260 [(match_operand:SI 1 "nonmemory_operand")
17262 (clobber (reg:CC FLAGS_REG))])]
17263 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17264 /* Do not split stack checking probes. */
17265 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17266 [(set (match_dup 2) (match_dup 0))
17267 (parallel [(set (match_dup 2)
17268 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17269 (clobber (reg:CC FLAGS_REG))])
17270 (set (match_dup 0) (match_dup 2))])
17272 ;; Attempt to use arith or logical operations with memory outputs with
17273 ;; setting of flags.
17275 [(set (match_operand:SWI 0 "register_operand")
17276 (match_operand:SWI 1 "memory_operand"))
17277 (parallel [(set (match_dup 0)
17278 (match_operator:SWI 3 "plusminuslogic_operator"
17280 (match_operand:SWI 2 "<nonmemory_operand>")]))
17281 (clobber (reg:CC FLAGS_REG))])
17282 (set (match_dup 1) (match_dup 0))
17283 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17284 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17285 && peep2_reg_dead_p (4, operands[0])
17286 && !reg_overlap_mentioned_p (operands[0], operands[1])
17287 && !reg_overlap_mentioned_p (operands[0], operands[2])
17288 && (<MODE>mode != QImode
17289 || immediate_operand (operands[2], QImode)
17290 || q_regs_operand (operands[2], QImode))
17291 && ix86_match_ccmode (peep2_next_insn (3),
17292 (GET_CODE (operands[3]) == PLUS
17293 || GET_CODE (operands[3]) == MINUS)
17294 ? CCGOCmode : CCNOmode)"
17295 [(parallel [(set (match_dup 4) (match_dup 5))
17296 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17297 (match_dup 2)]))])]
17299 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17300 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17301 copy_rtx (operands[1]),
17302 copy_rtx (operands[2]));
17303 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17304 operands[5], const0_rtx);
17308 [(parallel [(set (match_operand:SWI 0 "register_operand")
17309 (match_operator:SWI 2 "plusminuslogic_operator"
17311 (match_operand:SWI 1 "memory_operand")]))
17312 (clobber (reg:CC FLAGS_REG))])
17313 (set (match_dup 1) (match_dup 0))
17314 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17315 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17316 && GET_CODE (operands[2]) != MINUS
17317 && peep2_reg_dead_p (3, operands[0])
17318 && !reg_overlap_mentioned_p (operands[0], operands[1])
17319 && ix86_match_ccmode (peep2_next_insn (2),
17320 GET_CODE (operands[2]) == PLUS
17321 ? CCGOCmode : CCNOmode)"
17322 [(parallel [(set (match_dup 3) (match_dup 4))
17323 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17324 (match_dup 0)]))])]
17326 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17327 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17328 copy_rtx (operands[1]),
17329 copy_rtx (operands[0]));
17330 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17331 operands[4], const0_rtx);
17335 [(set (match_operand:SWI12 0 "register_operand")
17336 (match_operand:SWI12 1 "memory_operand"))
17337 (parallel [(set (match_operand:SI 4 "register_operand")
17338 (match_operator:SI 3 "plusminuslogic_operator"
17340 (match_operand:SI 2 "nonmemory_operand")]))
17341 (clobber (reg:CC FLAGS_REG))])
17342 (set (match_dup 1) (match_dup 0))
17343 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17344 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17345 && REG_P (operands[0]) && REG_P (operands[4])
17346 && REGNO (operands[0]) == REGNO (operands[4])
17347 && peep2_reg_dead_p (4, operands[0])
17348 && (<MODE>mode != QImode
17349 || immediate_operand (operands[2], SImode)
17350 || q_regs_operand (operands[2], SImode))
17351 && !reg_overlap_mentioned_p (operands[0], operands[1])
17352 && !reg_overlap_mentioned_p (operands[0], operands[2])
17353 && ix86_match_ccmode (peep2_next_insn (3),
17354 (GET_CODE (operands[3]) == PLUS
17355 || GET_CODE (operands[3]) == MINUS)
17356 ? CCGOCmode : CCNOmode)"
17357 [(parallel [(set (match_dup 4) (match_dup 5))
17358 (set (match_dup 1) (match_dup 6))])]
17360 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17361 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17362 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17363 copy_rtx (operands[1]), operands[2]);
17364 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17365 operands[5], const0_rtx);
17366 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17367 copy_rtx (operands[1]),
17368 copy_rtx (operands[2]));
17371 ;; Attempt to always use XOR for zeroing registers.
17373 [(set (match_operand 0 "register_operand")
17374 (match_operand 1 "const0_operand"))]
17375 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17376 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17377 && GENERAL_REG_P (operands[0])
17378 && peep2_regno_dead_p (0, FLAGS_REG)"
17379 [(parallel [(set (match_dup 0) (const_int 0))
17380 (clobber (reg:CC FLAGS_REG))])]
17381 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17384 [(set (strict_low_part (match_operand 0 "register_operand"))
17386 "(GET_MODE (operands[0]) == QImode
17387 || GET_MODE (operands[0]) == HImode)
17388 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17389 && peep2_regno_dead_p (0, FLAGS_REG)"
17390 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17391 (clobber (reg:CC FLAGS_REG))])])
17393 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17395 [(set (match_operand:SWI248 0 "register_operand")
17397 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17398 && peep2_regno_dead_p (0, FLAGS_REG)"
17399 [(parallel [(set (match_dup 0) (const_int -1))
17400 (clobber (reg:CC FLAGS_REG))])]
17402 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17403 operands[0] = gen_lowpart (SImode, operands[0]);
17406 ;; Attempt to convert simple lea to add/shift.
17407 ;; These can be created by move expanders.
17408 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17409 ;; relevant lea instructions were already split.
17412 [(set (match_operand:SWI48 0 "register_operand")
17413 (plus:SWI48 (match_dup 0)
17414 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17416 && peep2_regno_dead_p (0, FLAGS_REG)"
17417 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17418 (clobber (reg:CC FLAGS_REG))])])
17421 [(set (match_operand:SWI48 0 "register_operand")
17422 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17425 && peep2_regno_dead_p (0, FLAGS_REG)"
17426 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17427 (clobber (reg:CC FLAGS_REG))])])
17430 [(set (match_operand:DI 0 "register_operand")
17432 (plus:SI (match_operand:SI 1 "register_operand")
17433 (match_operand:SI 2 "nonmemory_operand"))))]
17434 "TARGET_64BIT && !TARGET_OPT_AGU
17435 && REGNO (operands[0]) == REGNO (operands[1])
17436 && peep2_regno_dead_p (0, FLAGS_REG)"
17437 [(parallel [(set (match_dup 0)
17438 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17439 (clobber (reg:CC FLAGS_REG))])])
17442 [(set (match_operand:DI 0 "register_operand")
17444 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17445 (match_operand:SI 2 "register_operand"))))]
17446 "TARGET_64BIT && !TARGET_OPT_AGU
17447 && REGNO (operands[0]) == REGNO (operands[2])
17448 && peep2_regno_dead_p (0, FLAGS_REG)"
17449 [(parallel [(set (match_dup 0)
17450 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17451 (clobber (reg:CC FLAGS_REG))])])
17454 [(set (match_operand:SWI48 0 "register_operand")
17455 (mult:SWI48 (match_dup 0)
17456 (match_operand:SWI48 1 "const_int_operand")))]
17457 "exact_log2 (INTVAL (operands[1])) >= 0
17458 && peep2_regno_dead_p (0, FLAGS_REG)"
17459 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17460 (clobber (reg:CC FLAGS_REG))])]
17461 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17464 [(set (match_operand:DI 0 "register_operand")
17466 (mult:SI (match_operand:SI 1 "register_operand")
17467 (match_operand:SI 2 "const_int_operand"))))]
17469 && exact_log2 (INTVAL (operands[2])) >= 0
17470 && REGNO (operands[0]) == REGNO (operands[1])
17471 && peep2_regno_dead_p (0, FLAGS_REG)"
17472 [(parallel [(set (match_dup 0)
17473 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17477 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17478 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17479 ;; On many CPUs it is also faster, since special hardware to avoid esp
17480 ;; dependencies is present.
17482 ;; While some of these conversions may be done using splitters, we use
17483 ;; peepholes in order to allow combine_stack_adjustments pass to see
17484 ;; nonobfuscated RTL.
17486 ;; Convert prologue esp subtractions to push.
17487 ;; We need register to push. In order to keep verify_flow_info happy we have
17489 ;; - use scratch and clobber it in order to avoid dependencies
17490 ;; - use already live register
17491 ;; We can't use the second way right now, since there is no reliable way how to
17492 ;; verify that given register is live. First choice will also most likely in
17493 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17494 ;; call clobbered registers are dead. We may want to use base pointer as an
17495 ;; alternative when no register is available later.
17498 [(match_scratch:W 1 "r")
17499 (parallel [(set (reg:P SP_REG)
17500 (plus:P (reg:P SP_REG)
17501 (match_operand:P 0 "const_int_operand")))
17502 (clobber (reg:CC FLAGS_REG))
17503 (clobber (mem:BLK (scratch)))])]
17504 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17505 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17506 [(clobber (match_dup 1))
17507 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17508 (clobber (mem:BLK (scratch)))])])
17511 [(match_scratch:W 1 "r")
17512 (parallel [(set (reg:P SP_REG)
17513 (plus:P (reg:P SP_REG)
17514 (match_operand:P 0 "const_int_operand")))
17515 (clobber (reg:CC FLAGS_REG))
17516 (clobber (mem:BLK (scratch)))])]
17517 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17518 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17519 [(clobber (match_dup 1))
17520 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17521 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17522 (clobber (mem:BLK (scratch)))])])
17524 ;; Convert esp subtractions to push.
17526 [(match_scratch:W 1 "r")
17527 (parallel [(set (reg:P SP_REG)
17528 (plus:P (reg:P SP_REG)
17529 (match_operand:P 0 "const_int_operand")))
17530 (clobber (reg:CC FLAGS_REG))])]
17531 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17532 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17533 [(clobber (match_dup 1))
17534 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17537 [(match_scratch:W 1 "r")
17538 (parallel [(set (reg:P SP_REG)
17539 (plus:P (reg:P SP_REG)
17540 (match_operand:P 0 "const_int_operand")))
17541 (clobber (reg:CC FLAGS_REG))])]
17542 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17543 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17544 [(clobber (match_dup 1))
17545 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17546 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17548 ;; Convert epilogue deallocator to pop.
17550 [(match_scratch:W 1 "r")
17551 (parallel [(set (reg:P SP_REG)
17552 (plus:P (reg:P SP_REG)
17553 (match_operand:P 0 "const_int_operand")))
17554 (clobber (reg:CC FLAGS_REG))
17555 (clobber (mem:BLK (scratch)))])]
17556 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17557 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17558 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17559 (clobber (mem:BLK (scratch)))])])
17561 ;; Two pops case is tricky, since pop causes dependency
17562 ;; on destination register. We use two registers if available.
17564 [(match_scratch:W 1 "r")
17565 (match_scratch:W 2 "r")
17566 (parallel [(set (reg:P SP_REG)
17567 (plus:P (reg:P SP_REG)
17568 (match_operand:P 0 "const_int_operand")))
17569 (clobber (reg:CC FLAGS_REG))
17570 (clobber (mem:BLK (scratch)))])]
17571 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17572 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17573 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17574 (clobber (mem:BLK (scratch)))])
17575 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17578 [(match_scratch:W 1 "r")
17579 (parallel [(set (reg:P SP_REG)
17580 (plus:P (reg:P SP_REG)
17581 (match_operand:P 0 "const_int_operand")))
17582 (clobber (reg:CC FLAGS_REG))
17583 (clobber (mem:BLK (scratch)))])]
17584 "optimize_insn_for_size_p ()
17585 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17586 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17587 (clobber (mem:BLK (scratch)))])
17588 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17590 ;; Convert esp additions to pop.
17592 [(match_scratch:W 1 "r")
17593 (parallel [(set (reg:P SP_REG)
17594 (plus:P (reg:P SP_REG)
17595 (match_operand:P 0 "const_int_operand")))
17596 (clobber (reg:CC FLAGS_REG))])]
17597 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17598 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17600 ;; Two pops case is tricky, since pop causes dependency
17601 ;; on destination register. We use two registers if available.
17603 [(match_scratch:W 1 "r")
17604 (match_scratch:W 2 "r")
17605 (parallel [(set (reg:P SP_REG)
17606 (plus:P (reg:P SP_REG)
17607 (match_operand:P 0 "const_int_operand")))
17608 (clobber (reg:CC FLAGS_REG))])]
17609 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17610 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17611 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17614 [(match_scratch:W 1 "r")
17615 (parallel [(set (reg:P SP_REG)
17616 (plus:P (reg:P SP_REG)
17617 (match_operand:P 0 "const_int_operand")))
17618 (clobber (reg:CC FLAGS_REG))])]
17619 "optimize_insn_for_size_p ()
17620 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17621 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17622 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17624 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17625 ;; required and register dies. Similarly for 128 to -128.
17627 [(set (match_operand 0 "flags_reg_operand")
17628 (match_operator 1 "compare_operator"
17629 [(match_operand 2 "register_operand")
17630 (match_operand 3 "const_int_operand")]))]
17631 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17632 && incdec_operand (operands[3], GET_MODE (operands[3])))
17633 || (!TARGET_FUSE_CMP_AND_BRANCH
17634 && INTVAL (operands[3]) == 128))
17635 && ix86_match_ccmode (insn, CCGCmode)
17636 && peep2_reg_dead_p (1, operands[2])"
17637 [(parallel [(set (match_dup 0)
17638 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17639 (clobber (match_dup 2))])])
17641 ;; Convert imul by three, five and nine into lea
17644 [(set (match_operand:SWI48 0 "register_operand")
17645 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17646 (match_operand:SWI48 2 "const359_operand")))
17647 (clobber (reg:CC FLAGS_REG))])]
17648 "!TARGET_PARTIAL_REG_STALL
17649 || <MODE>mode == SImode
17650 || optimize_function_for_size_p (cfun)"
17651 [(set (match_dup 0)
17652 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17654 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17658 [(set (match_operand:SWI48 0 "register_operand")
17659 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17660 (match_operand:SWI48 2 "const359_operand")))
17661 (clobber (reg:CC FLAGS_REG))])]
17662 "optimize_insn_for_speed_p ()
17663 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17664 [(set (match_dup 0) (match_dup 1))
17666 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17668 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17670 ;; imul $32bit_imm, mem, reg is vector decoded, while
17671 ;; imul $32bit_imm, reg, reg is direct decoded.
17673 [(match_scratch:SWI48 3 "r")
17674 (parallel [(set (match_operand:SWI48 0 "register_operand")
17675 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17676 (match_operand:SWI48 2 "immediate_operand")))
17677 (clobber (reg:CC FLAGS_REG))])]
17678 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17679 && !satisfies_constraint_K (operands[2])"
17680 [(set (match_dup 3) (match_dup 1))
17681 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17682 (clobber (reg:CC FLAGS_REG))])])
17685 [(match_scratch:SI 3 "r")
17686 (parallel [(set (match_operand:DI 0 "register_operand")
17688 (mult:SI (match_operand:SI 1 "memory_operand")
17689 (match_operand:SI 2 "immediate_operand"))))
17690 (clobber (reg:CC FLAGS_REG))])]
17692 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17693 && !satisfies_constraint_K (operands[2])"
17694 [(set (match_dup 3) (match_dup 1))
17695 (parallel [(set (match_dup 0)
17696 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17697 (clobber (reg:CC FLAGS_REG))])])
17699 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17700 ;; Convert it into imul reg, reg
17701 ;; It would be better to force assembler to encode instruction using long
17702 ;; immediate, but there is apparently no way to do so.
17704 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17706 (match_operand:SWI248 1 "nonimmediate_operand")
17707 (match_operand:SWI248 2 "const_int_operand")))
17708 (clobber (reg:CC FLAGS_REG))])
17709 (match_scratch:SWI248 3 "r")]
17710 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17711 && satisfies_constraint_K (operands[2])"
17712 [(set (match_dup 3) (match_dup 2))
17713 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17714 (clobber (reg:CC FLAGS_REG))])]
17716 if (!rtx_equal_p (operands[0], operands[1]))
17717 emit_move_insn (operands[0], operands[1]);
17720 ;; After splitting up read-modify operations, array accesses with memory
17721 ;; operands might end up in form:
17723 ;; movl 4(%esp), %edx
17725 ;; instead of pre-splitting:
17727 ;; addl 4(%esp), %eax
17729 ;; movl 4(%esp), %edx
17730 ;; leal (%edx,%eax,4), %eax
17733 [(match_scratch:W 5 "r")
17734 (parallel [(set (match_operand 0 "register_operand")
17735 (ashift (match_operand 1 "register_operand")
17736 (match_operand 2 "const_int_operand")))
17737 (clobber (reg:CC FLAGS_REG))])
17738 (parallel [(set (match_operand 3 "register_operand")
17739 (plus (match_dup 0)
17740 (match_operand 4 "x86_64_general_operand")))
17741 (clobber (reg:CC FLAGS_REG))])]
17742 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17743 /* Validate MODE for lea. */
17744 && ((!TARGET_PARTIAL_REG_STALL
17745 && (GET_MODE (operands[0]) == QImode
17746 || GET_MODE (operands[0]) == HImode))
17747 || GET_MODE (operands[0]) == SImode
17748 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17749 && (rtx_equal_p (operands[0], operands[3])
17750 || peep2_reg_dead_p (2, operands[0]))
17751 /* We reorder load and the shift. */
17752 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17753 [(set (match_dup 5) (match_dup 4))
17754 (set (match_dup 0) (match_dup 1))]
17756 enum machine_mode op1mode = GET_MODE (operands[1]);
17757 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17758 int scale = 1 << INTVAL (operands[2]);
17759 rtx index = gen_lowpart (word_mode, operands[1]);
17760 rtx base = gen_lowpart (word_mode, operands[5]);
17761 rtx dest = gen_lowpart (mode, operands[3]);
17763 operands[1] = gen_rtx_PLUS (word_mode, base,
17764 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17765 operands[5] = base;
17766 if (mode != word_mode)
17767 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17768 if (op1mode != word_mode)
17769 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17770 operands[0] = dest;
17773 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17774 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17775 ;; caught for use by garbage collectors and the like. Using an insn that
17776 ;; maps to SIGILL makes it more likely the program will rightfully die.
17777 ;; Keeping with tradition, "6" is in honor of #UD.
17778 (define_insn "trap"
17779 [(trap_if (const_int 1) (const_int 6))]
17782 #ifdef HAVE_AS_IX86_UD2
17785 return ASM_SHORT "0x0b0f";
17788 [(set_attr "length" "2")])
17790 (define_expand "prefetch"
17791 [(prefetch (match_operand 0 "address_operand")
17792 (match_operand:SI 1 "const_int_operand")
17793 (match_operand:SI 2 "const_int_operand"))]
17794 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17796 bool write = INTVAL (operands[1]) != 0;
17797 int locality = INTVAL (operands[2]);
17799 gcc_assert (IN_RANGE (locality, 0, 3));
17801 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17802 supported by SSE counterpart or the SSE prefetch is not available
17803 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17805 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17806 operands[2] = const2_rtx;
17807 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17808 operands[2] = GEN_INT (3);
17810 operands[1] = const0_rtx;
17813 (define_insn "*prefetch_sse"
17814 [(prefetch (match_operand 0 "address_operand" "p")
17816 (match_operand:SI 1 "const_int_operand"))]
17817 "TARGET_PREFETCH_SSE"
17819 static const char * const patterns[4] = {
17820 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17823 int locality = INTVAL (operands[1]);
17824 gcc_assert (IN_RANGE (locality, 0, 3));
17826 return patterns[locality];
17828 [(set_attr "type" "sse")
17829 (set_attr "atom_sse_attr" "prefetch")
17830 (set (attr "length_address")
17831 (symbol_ref "memory_address_length (operands[0], false)"))
17832 (set_attr "memory" "none")])
17834 (define_insn "*prefetch_3dnow"
17835 [(prefetch (match_operand 0 "address_operand" "p")
17836 (match_operand:SI 1 "const_int_operand" "n")
17840 if (INTVAL (operands[1]) == 0)
17841 return "prefetch\t%a0";
17843 return "prefetchw\t%a0";
17845 [(set_attr "type" "mmx")
17846 (set (attr "length_address")
17847 (symbol_ref "memory_address_length (operands[0], false)"))
17848 (set_attr "memory" "none")])
17850 (define_insn "*prefetch_prefetchwt1_<mode>"
17851 [(prefetch (match_operand:P 0 "address_operand" "p")
17854 "TARGET_PREFETCHWT1"
17855 "prefetchwt1\t%a0";
17856 [(set_attr "type" "sse")
17857 (set (attr "length_address")
17858 (symbol_ref "memory_address_length (operands[0], false)"))
17859 (set_attr "memory" "none")])
17861 (define_expand "stack_protect_set"
17862 [(match_operand 0 "memory_operand")
17863 (match_operand 1 "memory_operand")]
17864 "TARGET_SSP_TLS_GUARD"
17866 rtx (*insn)(rtx, rtx);
17868 #ifdef TARGET_THREAD_SSP_OFFSET
17869 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17870 insn = (TARGET_LP64
17871 ? gen_stack_tls_protect_set_di
17872 : gen_stack_tls_protect_set_si);
17874 insn = (TARGET_LP64
17875 ? gen_stack_protect_set_di
17876 : gen_stack_protect_set_si);
17879 emit_insn (insn (operands[0], operands[1]));
17883 (define_insn "stack_protect_set_<mode>"
17884 [(set (match_operand:PTR 0 "memory_operand" "=m")
17885 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17887 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17888 (clobber (reg:CC FLAGS_REG))]
17889 "TARGET_SSP_TLS_GUARD"
17890 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17891 [(set_attr "type" "multi")])
17893 (define_insn "stack_tls_protect_set_<mode>"
17894 [(set (match_operand:PTR 0 "memory_operand" "=m")
17895 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17896 UNSPEC_SP_TLS_SET))
17897 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17898 (clobber (reg:CC FLAGS_REG))]
17900 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17901 [(set_attr "type" "multi")])
17903 (define_expand "stack_protect_test"
17904 [(match_operand 0 "memory_operand")
17905 (match_operand 1 "memory_operand")
17907 "TARGET_SSP_TLS_GUARD"
17909 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17911 rtx (*insn)(rtx, rtx, rtx);
17913 #ifdef TARGET_THREAD_SSP_OFFSET
17914 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17915 insn = (TARGET_LP64
17916 ? gen_stack_tls_protect_test_di
17917 : gen_stack_tls_protect_test_si);
17919 insn = (TARGET_LP64
17920 ? gen_stack_protect_test_di
17921 : gen_stack_protect_test_si);
17924 emit_insn (insn (flags, operands[0], operands[1]));
17926 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17927 flags, const0_rtx, operands[2]));
17931 (define_insn "stack_protect_test_<mode>"
17932 [(set (match_operand:CCZ 0 "flags_reg_operand")
17933 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17934 (match_operand:PTR 2 "memory_operand" "m")]
17936 (clobber (match_scratch:PTR 3 "=&r"))]
17937 "TARGET_SSP_TLS_GUARD"
17938 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17939 [(set_attr "type" "multi")])
17941 (define_insn "stack_tls_protect_test_<mode>"
17942 [(set (match_operand:CCZ 0 "flags_reg_operand")
17943 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17944 (match_operand:PTR 2 "const_int_operand" "i")]
17945 UNSPEC_SP_TLS_TEST))
17946 (clobber (match_scratch:PTR 3 "=r"))]
17948 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17949 [(set_attr "type" "multi")])
17951 (define_insn "sse4_2_crc32<mode>"
17952 [(set (match_operand:SI 0 "register_operand" "=r")
17954 [(match_operand:SI 1 "register_operand" "0")
17955 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17957 "TARGET_SSE4_2 || TARGET_CRC32"
17958 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17959 [(set_attr "type" "sselog1")
17960 (set_attr "prefix_rep" "1")
17961 (set_attr "prefix_extra" "1")
17962 (set (attr "prefix_data16")
17963 (if_then_else (match_operand:HI 2)
17965 (const_string "*")))
17966 (set (attr "prefix_rex")
17967 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17969 (const_string "*")))
17970 (set_attr "mode" "SI")])
17972 (define_insn "sse4_2_crc32di"
17973 [(set (match_operand:DI 0 "register_operand" "=r")
17975 [(match_operand:DI 1 "register_operand" "0")
17976 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17978 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17979 "crc32{q}\t{%2, %0|%0, %2}"
17980 [(set_attr "type" "sselog1")
17981 (set_attr "prefix_rep" "1")
17982 (set_attr "prefix_extra" "1")
17983 (set_attr "mode" "DI")])
17985 (define_insn "rdpmc"
17986 [(set (match_operand:DI 0 "register_operand" "=A")
17987 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17991 [(set_attr "type" "other")
17992 (set_attr "length" "2")])
17994 (define_insn "rdpmc_rex64"
17995 [(set (match_operand:DI 0 "register_operand" "=a")
17996 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17998 (set (match_operand:DI 1 "register_operand" "=d")
17999 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18002 [(set_attr "type" "other")
18003 (set_attr "length" "2")])
18005 (define_insn "rdtsc"
18006 [(set (match_operand:DI 0 "register_operand" "=A")
18007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18010 [(set_attr "type" "other")
18011 (set_attr "length" "2")])
18013 (define_insn "rdtsc_rex64"
18014 [(set (match_operand:DI 0 "register_operand" "=a")
18015 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18016 (set (match_operand:DI 1 "register_operand" "=d")
18017 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18020 [(set_attr "type" "other")
18021 (set_attr "length" "2")])
18023 (define_insn "rdtscp"
18024 [(set (match_operand:DI 0 "register_operand" "=A")
18025 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18026 (set (match_operand:SI 1 "register_operand" "=c")
18027 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18030 [(set_attr "type" "other")
18031 (set_attr "length" "3")])
18033 (define_insn "rdtscp_rex64"
18034 [(set (match_operand:DI 0 "register_operand" "=a")
18035 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18036 (set (match_operand:DI 1 "register_operand" "=d")
18037 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18038 (set (match_operand:SI 2 "register_operand" "=c")
18039 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18042 [(set_attr "type" "other")
18043 (set_attr "length" "3")])
18045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18047 ;; FXSR, XSAVE and XSAVEOPT instructions
18049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18051 (define_insn "fxsave"
18052 [(set (match_operand:BLK 0 "memory_operand" "=m")
18053 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18056 [(set_attr "type" "other")
18057 (set_attr "memory" "store")
18058 (set (attr "length")
18059 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18061 (define_insn "fxsave64"
18062 [(set (match_operand:BLK 0 "memory_operand" "=m")
18063 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18064 "TARGET_64BIT && TARGET_FXSR"
18066 [(set_attr "type" "other")
18067 (set_attr "memory" "store")
18068 (set (attr "length")
18069 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18071 (define_insn "fxrstor"
18072 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18076 [(set_attr "type" "other")
18077 (set_attr "memory" "load")
18078 (set (attr "length")
18079 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18081 (define_insn "fxrstor64"
18082 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18083 UNSPECV_FXRSTOR64)]
18084 "TARGET_64BIT && TARGET_FXSR"
18086 [(set_attr "type" "other")
18087 (set_attr "memory" "load")
18088 (set (attr "length")
18089 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18091 (define_int_iterator ANY_XSAVE
18093 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18094 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18095 (UNSPECV_XSAVES "TARGET_XSAVES")])
18097 (define_int_iterator ANY_XSAVE64
18099 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18100 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18101 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18103 (define_int_attr xsave
18104 [(UNSPECV_XSAVE "xsave")
18105 (UNSPECV_XSAVE64 "xsave64")
18106 (UNSPECV_XSAVEOPT "xsaveopt")
18107 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18108 (UNSPECV_XSAVEC "xsavec")
18109 (UNSPECV_XSAVEC64 "xsavec64")
18110 (UNSPECV_XSAVES "xsaves")
18111 (UNSPECV_XSAVES64 "xsaves64")])
18113 (define_int_iterator ANY_XRSTOR
18115 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18117 (define_int_iterator ANY_XRSTOR64
18119 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18121 (define_int_attr xrstor
18122 [(UNSPECV_XRSTOR "xrstor")
18123 (UNSPECV_XRSTOR64 "xrstor")
18124 (UNSPECV_XRSTORS "xrstors")
18125 (UNSPECV_XRSTORS64 "xrstors")])
18127 (define_insn "<xsave>"
18128 [(set (match_operand:BLK 0 "memory_operand" "=m")
18129 (unspec_volatile:BLK
18130 [(match_operand:DI 1 "register_operand" "A")]
18132 "!TARGET_64BIT && TARGET_XSAVE"
18134 [(set_attr "type" "other")
18135 (set_attr "memory" "store")
18136 (set (attr "length")
18137 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18139 (define_insn "<xsave>_rex64"
18140 [(set (match_operand:BLK 0 "memory_operand" "=m")
18141 (unspec_volatile:BLK
18142 [(match_operand:SI 1 "register_operand" "a")
18143 (match_operand:SI 2 "register_operand" "d")]
18145 "TARGET_64BIT && TARGET_XSAVE"
18147 [(set_attr "type" "other")
18148 (set_attr "memory" "store")
18149 (set (attr "length")
18150 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18152 (define_insn "<xsave>"
18153 [(set (match_operand:BLK 0 "memory_operand" "=m")
18154 (unspec_volatile:BLK
18155 [(match_operand:SI 1 "register_operand" "a")
18156 (match_operand:SI 2 "register_operand" "d")]
18158 "TARGET_64BIT && TARGET_XSAVE"
18160 [(set_attr "type" "other")
18161 (set_attr "memory" "store")
18162 (set (attr "length")
18163 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18165 (define_insn "<xrstor>"
18166 [(unspec_volatile:BLK
18167 [(match_operand:BLK 0 "memory_operand" "m")
18168 (match_operand:DI 1 "register_operand" "A")]
18170 "!TARGET_64BIT && TARGET_XSAVE"
18172 [(set_attr "type" "other")
18173 (set_attr "memory" "load")
18174 (set (attr "length")
18175 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18177 (define_insn "<xrstor>_rex64"
18178 [(unspec_volatile:BLK
18179 [(match_operand:BLK 0 "memory_operand" "m")
18180 (match_operand:SI 1 "register_operand" "a")
18181 (match_operand:SI 2 "register_operand" "d")]
18183 "TARGET_64BIT && TARGET_XSAVE"
18185 [(set_attr "type" "other")
18186 (set_attr "memory" "load")
18187 (set (attr "length")
18188 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18190 (define_insn "<xrstor>64"
18191 [(unspec_volatile:BLK
18192 [(match_operand:BLK 0 "memory_operand" "m")
18193 (match_operand:SI 1 "register_operand" "a")
18194 (match_operand:SI 2 "register_operand" "d")]
18196 "TARGET_64BIT && TARGET_XSAVE"
18198 [(set_attr "type" "other")
18199 (set_attr "memory" "load")
18200 (set (attr "length")
18201 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18203 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18205 ;; Floating-point instructions for atomic compound assignments
18207 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18209 ; Clobber all floating-point registers on environment save and restore
18210 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18211 (define_insn "fnstenv"
18212 [(set (match_operand:BLK 0 "memory_operand" "=m")
18213 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18214 (clobber (reg:HI FPCR_REG))
18215 (clobber (reg:XF ST0_REG))
18216 (clobber (reg:XF ST1_REG))
18217 (clobber (reg:XF ST2_REG))
18218 (clobber (reg:XF ST3_REG))
18219 (clobber (reg:XF ST4_REG))
18220 (clobber (reg:XF ST5_REG))
18221 (clobber (reg:XF ST6_REG))
18222 (clobber (reg:XF ST7_REG))]
18225 [(set_attr "type" "other")
18226 (set_attr "memory" "store")
18227 (set (attr "length")
18228 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18230 (define_insn "fldenv"
18231 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18233 (clobber (reg:CCFP FPSR_REG))
18234 (clobber (reg:HI FPCR_REG))
18235 (clobber (reg:XF ST0_REG))
18236 (clobber (reg:XF ST1_REG))
18237 (clobber (reg:XF ST2_REG))
18238 (clobber (reg:XF ST3_REG))
18239 (clobber (reg:XF ST4_REG))
18240 (clobber (reg:XF ST5_REG))
18241 (clobber (reg:XF ST6_REG))
18242 (clobber (reg:XF ST7_REG))]
18245 [(set_attr "type" "other")
18246 (set_attr "memory" "load")
18247 (set (attr "length")
18248 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18250 (define_insn "fnstsw"
18251 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18252 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18255 [(set_attr "type" "other,other")
18256 (set_attr "memory" "none,store")
18257 (set (attr "length")
18258 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18260 (define_insn "fnclex"
18261 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18264 [(set_attr "type" "other")
18265 (set_attr "memory" "none")
18266 (set_attr "length" "2")])
18268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18270 ;; LWP instructions
18272 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18274 (define_expand "lwp_llwpcb"
18275 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18276 UNSPECV_LLWP_INTRINSIC)]
18279 (define_insn "*lwp_llwpcb<mode>1"
18280 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18281 UNSPECV_LLWP_INTRINSIC)]
18284 [(set_attr "type" "lwp")
18285 (set_attr "mode" "<MODE>")
18286 (set_attr "length" "5")])
18288 (define_expand "lwp_slwpcb"
18289 [(set (match_operand 0 "register_operand" "=r")
18290 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18295 insn = (Pmode == DImode
18297 : gen_lwp_slwpcbsi);
18299 emit_insn (insn (operands[0]));
18303 (define_insn "lwp_slwpcb<mode>"
18304 [(set (match_operand:P 0 "register_operand" "=r")
18305 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18308 [(set_attr "type" "lwp")
18309 (set_attr "mode" "<MODE>")
18310 (set_attr "length" "5")])
18312 (define_expand "lwp_lwpval<mode>3"
18313 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18314 (match_operand:SI 2 "nonimmediate_operand" "rm")
18315 (match_operand:SI 3 "const_int_operand" "i")]
18316 UNSPECV_LWPVAL_INTRINSIC)]
18318 ;; Avoid unused variable warning.
18319 "(void) operands[0];")
18321 (define_insn "*lwp_lwpval<mode>3_1"
18322 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18323 (match_operand:SI 1 "nonimmediate_operand" "rm")
18324 (match_operand:SI 2 "const_int_operand" "i")]
18325 UNSPECV_LWPVAL_INTRINSIC)]
18327 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18328 [(set_attr "type" "lwp")
18329 (set_attr "mode" "<MODE>")
18330 (set (attr "length")
18331 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18333 (define_expand "lwp_lwpins<mode>3"
18334 [(set (reg:CCC FLAGS_REG)
18335 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18336 (match_operand:SI 2 "nonimmediate_operand" "rm")
18337 (match_operand:SI 3 "const_int_operand" "i")]
18338 UNSPECV_LWPINS_INTRINSIC))
18339 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18340 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18343 (define_insn "*lwp_lwpins<mode>3_1"
18344 [(set (reg:CCC FLAGS_REG)
18345 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18346 (match_operand:SI 1 "nonimmediate_operand" "rm")
18347 (match_operand:SI 2 "const_int_operand" "i")]
18348 UNSPECV_LWPINS_INTRINSIC))]
18350 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18351 [(set_attr "type" "lwp")
18352 (set_attr "mode" "<MODE>")
18353 (set (attr "length")
18354 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18356 (define_int_iterator RDFSGSBASE
18360 (define_int_iterator WRFSGSBASE
18364 (define_int_attr fsgs
18365 [(UNSPECV_RDFSBASE "fs")
18366 (UNSPECV_RDGSBASE "gs")
18367 (UNSPECV_WRFSBASE "fs")
18368 (UNSPECV_WRGSBASE "gs")])
18370 (define_insn "rd<fsgs>base<mode>"
18371 [(set (match_operand:SWI48 0 "register_operand" "=r")
18372 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18373 "TARGET_64BIT && TARGET_FSGSBASE"
18375 [(set_attr "type" "other")
18376 (set_attr "prefix_extra" "2")])
18378 (define_insn "wr<fsgs>base<mode>"
18379 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18381 "TARGET_64BIT && TARGET_FSGSBASE"
18383 [(set_attr "type" "other")
18384 (set_attr "prefix_extra" "2")])
18386 (define_insn "rdrand<mode>_1"
18387 [(set (match_operand:SWI248 0 "register_operand" "=r")
18388 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18389 (set (reg:CCC FLAGS_REG)
18390 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18393 [(set_attr "type" "other")
18394 (set_attr "prefix_extra" "1")])
18396 (define_insn "rdseed<mode>_1"
18397 [(set (match_operand:SWI248 0 "register_operand" "=r")
18398 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18399 (set (reg:CCC FLAGS_REG)
18400 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18403 [(set_attr "type" "other")
18404 (set_attr "prefix_extra" "1")])
18406 (define_expand "pause"
18407 [(set (match_dup 0)
18408 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18411 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18412 MEM_VOLATILE_P (operands[0]) = 1;
18415 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18416 ;; They have the same encoding.
18417 (define_insn "*pause"
18418 [(set (match_operand:BLK 0)
18419 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18422 [(set_attr "length" "2")
18423 (set_attr "memory" "unknown")])
18425 (define_expand "xbegin"
18426 [(set (match_operand:SI 0 "register_operand")
18427 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18430 rtx label = gen_label_rtx ();
18432 /* xbegin is emitted as jump_insn, so reload won't be able
18433 to reload its operand. Force the value into AX hard register. */
18434 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18435 emit_move_insn (ax_reg, constm1_rtx);
18437 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18439 emit_label (label);
18440 LABEL_NUSES (label) = 1;
18442 emit_move_insn (operands[0], ax_reg);
18447 (define_insn "xbegin_1"
18449 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18451 (label_ref (match_operand 1))
18453 (set (match_operand:SI 0 "register_operand" "+a")
18454 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18457 [(set_attr "type" "other")
18458 (set_attr "length" "6")])
18460 (define_insn "xend"
18461 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18464 [(set_attr "type" "other")
18465 (set_attr "length" "3")])
18467 (define_insn "xabort"
18468 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18472 [(set_attr "type" "other")
18473 (set_attr "length" "3")])
18475 (define_expand "xtest"
18476 [(set (match_operand:QI 0 "register_operand")
18477 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18480 emit_insn (gen_xtest_1 ());
18482 ix86_expand_setcc (operands[0], NE,
18483 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18487 (define_insn "xtest_1"
18488 [(set (reg:CCZ FLAGS_REG)
18489 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18492 [(set_attr "type" "other")
18493 (set_attr "length" "3")])
18495 (define_insn "clflushopt"
18496 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18497 UNSPECV_CLFLUSHOPT)]
18498 "TARGET_CLFLUSHOPT"
18500 [(set_attr "type" "sse")
18501 (set_attr "atom_sse_attr" "fence")
18502 (set_attr "memory" "unknown")])
18506 (include "sync.md")