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
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
183 (define_c_enum "unspecv" [
186 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_SPLIT_STACK_RETURN
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
214 ;; For atomic compound assignments.
220 ;; For RDRAND support
223 ;; For RDSEED support
235 ;; Constants to represent rounding modes in the ROUND instruction
244 ;; Constants to represent AVX512F embeded rounding
246 [(ROUND_NEAREST_INT 0)
254 ;; Constants to represent pcomtrue/pcomfalse variants
264 ;; Constants used in the XOP pperm instruction
266 [(PPERM_SRC 0x00) /* copy source */
267 (PPERM_INVERT 0x20) /* invert source */
268 (PPERM_REVERSE 0x40) /* bit reverse source */
269 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
270 (PPERM_ZERO 0x80) /* all 0's */
271 (PPERM_ONES 0xa0) /* all 1's */
272 (PPERM_SIGN 0xc0) /* propagate sign bit */
273 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
274 (PPERM_SRC1 0x00) /* use first source byte */
275 (PPERM_SRC2 0x10) /* use second source byte */
278 ;; Registers by name.
357 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
360 ;; In C guard expressions, put expressions which may be compile-time
361 ;; constants first. This allows for better optimization. For
362 ;; example, write "TARGET_64BIT && reload_completed", not
363 ;; "reload_completed && TARGET_64BIT".
367 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
368 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
370 (const (symbol_ref "ix86_schedule")))
372 ;; A basic instruction type. Refinements due to arguments to be
373 ;; provided in other attributes.
376 alu,alu1,negnot,imov,imovx,lea,
377 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
378 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
379 push,pop,call,callv,leave,
381 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
382 fxch,fistp,fisttp,frndint,
383 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
384 ssemul,sseimul,ssediv,sselog,sselog1,
385 sseishft,sseishft1,ssecmp,ssecomi,
386 ssecvt,ssecvt1,sseicvt,sseins,
387 sseshuf,sseshuf1,ssemuladd,sse4arg,
389 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
390 (const_string "other"))
392 ;; Main data type used by the insn
394 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
396 (const_string "unknown"))
398 ;; The CPU unit operations uses.
399 (define_attr "unit" "integer,i387,sse,mmx,unknown"
400 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
401 fxch,fistp,fisttp,frndint")
402 (const_string "i387")
403 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
404 ssemul,sseimul,ssediv,sselog,sselog1,
405 sseishft,sseishft1,ssecmp,ssecomi,
406 ssecvt,ssecvt1,sseicvt,sseins,
407 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
409 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
411 (eq_attr "type" "other")
412 (const_string "unknown")]
413 (const_string "integer")))
415 ;; The minimum required alignment of vector mode memory operands of the SSE
416 ;; (non-VEX/EVEX) instruction in bits, if it is different from
417 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
418 ;; multiple alternatives, this should be conservative maximum of those minimum
419 ;; required alignments.
420 (define_attr "ssememalign" "" (const_int 0))
422 ;; The (bounding maximum) length of an instruction immediate.
423 (define_attr "length_immediate" ""
424 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
425 bitmanip,imulx,msklog,mskmov")
427 (eq_attr "unit" "i387,sse,mmx")
429 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
430 rotate,rotatex,rotate1,imul,icmp,push,pop")
431 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
432 (eq_attr "type" "imov,test")
433 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
434 (eq_attr "type" "call")
435 (if_then_else (match_operand 0 "constant_call_address_operand")
438 (eq_attr "type" "callv")
439 (if_then_else (match_operand 1 "constant_call_address_operand")
442 ;; We don't know the size before shorten_branches. Expect
443 ;; the instruction to fit for better scheduling.
444 (eq_attr "type" "ibr")
447 (symbol_ref "/* Update immediate_length and other attributes! */
448 gcc_unreachable (),1")))
450 ;; The (bounding maximum) length of an instruction address.
451 (define_attr "length_address" ""
452 (cond [(eq_attr "type" "str,other,multi,fxch")
454 (and (eq_attr "type" "call")
455 (match_operand 0 "constant_call_address_operand"))
457 (and (eq_attr "type" "callv")
458 (match_operand 1 "constant_call_address_operand"))
461 (symbol_ref "ix86_attr_length_address_default (insn)")))
463 ;; Set when length prefix is used.
464 (define_attr "prefix_data16" ""
465 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
467 (eq_attr "mode" "HI")
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
474 ;; Set when string REP prefix is used.
475 (define_attr "prefix_rep" ""
476 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
478 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
483 ;; Set when 0f opcode prefix is used.
484 (define_attr "prefix_0f" ""
486 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
487 (eq_attr "unit" "sse,mmx"))
491 ;; Set when REX opcode prefix is used.
492 (define_attr "prefix_rex" ""
493 (cond [(not (match_test "TARGET_64BIT"))
495 (and (eq_attr "mode" "DI")
496 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
497 (eq_attr "unit" "!mmx")))
499 (and (eq_attr "mode" "QI")
500 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
502 (match_test "x86_extended_reg_mentioned_p (insn)")
504 (and (eq_attr "type" "imovx")
505 (match_operand:QI 1 "ext_QIreg_operand"))
510 ;; There are also additional prefixes in 3DNOW, SSSE3.
511 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
512 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
513 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
514 (define_attr "prefix_extra" ""
515 (cond [(eq_attr "type" "ssemuladd,sse4arg")
517 (eq_attr "type" "sseiadd1,ssecvt1")
522 ;; Prefix used: original, VEX or maybe VEX.
523 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
524 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
526 (eq_attr "mode" "XI,V16SF,V8DF")
527 (const_string "evex")
529 (const_string "orig")))
531 ;; VEX W bit is used.
532 (define_attr "prefix_vex_w" "" (const_int 0))
534 ;; The length of VEX prefix
535 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
536 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
537 ;; still prefix_0f 1, with prefix_extra 1.
538 (define_attr "length_vex" ""
539 (if_then_else (and (eq_attr "prefix_0f" "1")
540 (eq_attr "prefix_extra" "0"))
541 (if_then_else (eq_attr "prefix_vex_w" "1")
542 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
543 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
544 (if_then_else (eq_attr "prefix_vex_w" "1")
545 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
546 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
548 ;; 4-bytes evex prefix and 1 byte opcode.
549 (define_attr "length_evex" "" (const_int 5))
551 ;; Set when modrm byte is used.
552 (define_attr "modrm" ""
553 (cond [(eq_attr "type" "str,leave")
555 (eq_attr "unit" "i387")
557 (and (eq_attr "type" "incdec")
558 (and (not (match_test "TARGET_64BIT"))
559 (ior (match_operand:SI 1 "register_operand")
560 (match_operand:HI 1 "register_operand"))))
562 (and (eq_attr "type" "push")
563 (not (match_operand 1 "memory_operand")))
565 (and (eq_attr "type" "pop")
566 (not (match_operand 0 "memory_operand")))
568 (and (eq_attr "type" "imov")
569 (and (not (eq_attr "mode" "DI"))
570 (ior (and (match_operand 0 "register_operand")
571 (match_operand 1 "immediate_operand"))
572 (ior (and (match_operand 0 "ax_reg_operand")
573 (match_operand 1 "memory_displacement_only_operand"))
574 (and (match_operand 0 "memory_displacement_only_operand")
575 (match_operand 1 "ax_reg_operand"))))))
577 (and (eq_attr "type" "call")
578 (match_operand 0 "constant_call_address_operand"))
580 (and (eq_attr "type" "callv")
581 (match_operand 1 "constant_call_address_operand"))
583 (and (eq_attr "type" "alu,alu1,icmp,test")
584 (match_operand 0 "ax_reg_operand"))
585 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
589 ;; The (bounding maximum) length of an instruction in bytes.
590 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
591 ;; Later we may want to split them and compute proper length as for
593 (define_attr "length" ""
594 (cond [(eq_attr "type" "other,multi,fistp,frndint")
596 (eq_attr "type" "fcmp")
598 (eq_attr "unit" "i387")
600 (plus (attr "prefix_data16")
601 (attr "length_address")))
602 (ior (eq_attr "prefix" "evex")
603 (and (ior (eq_attr "prefix" "maybe_evex")
604 (eq_attr "prefix" "maybe_vex"))
605 (match_test "TARGET_AVX512F")))
606 (plus (attr "length_evex")
607 (plus (attr "length_immediate")
609 (attr "length_address"))))
610 (ior (eq_attr "prefix" "vex")
611 (and (ior (eq_attr "prefix" "maybe_vex")
612 (eq_attr "prefix" "maybe_evex"))
613 (match_test "TARGET_AVX")))
614 (plus (attr "length_vex")
615 (plus (attr "length_immediate")
617 (attr "length_address"))))]
618 (plus (plus (attr "modrm")
619 (plus (attr "prefix_0f")
620 (plus (attr "prefix_rex")
621 (plus (attr "prefix_extra")
623 (plus (attr "prefix_rep")
624 (plus (attr "prefix_data16")
625 (plus (attr "length_immediate")
626 (attr "length_address")))))))
628 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
629 ;; `store' if there is a simple memory reference therein, or `unknown'
630 ;; if the instruction is complex.
632 (define_attr "memory" "none,load,store,both,unknown"
633 (cond [(eq_attr "type" "other,multi,str,lwp")
634 (const_string "unknown")
635 (eq_attr "type" "lea,fcmov,fpspc")
636 (const_string "none")
637 (eq_attr "type" "fistp,leave")
638 (const_string "both")
639 (eq_attr "type" "frndint")
640 (const_string "load")
641 (eq_attr "type" "push")
642 (if_then_else (match_operand 1 "memory_operand")
643 (const_string "both")
644 (const_string "store"))
645 (eq_attr "type" "pop")
646 (if_then_else (match_operand 0 "memory_operand")
647 (const_string "both")
648 (const_string "load"))
649 (eq_attr "type" "setcc")
650 (if_then_else (match_operand 0 "memory_operand")
651 (const_string "store")
652 (const_string "none"))
653 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
654 (if_then_else (ior (match_operand 0 "memory_operand")
655 (match_operand 1 "memory_operand"))
656 (const_string "load")
657 (const_string "none"))
658 (eq_attr "type" "ibr")
659 (if_then_else (match_operand 0 "memory_operand")
660 (const_string "load")
661 (const_string "none"))
662 (eq_attr "type" "call")
663 (if_then_else (match_operand 0 "constant_call_address_operand")
664 (const_string "none")
665 (const_string "load"))
666 (eq_attr "type" "callv")
667 (if_then_else (match_operand 1 "constant_call_address_operand")
668 (const_string "none")
669 (const_string "load"))
670 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
671 (match_operand 1 "memory_operand"))
672 (const_string "both")
673 (and (match_operand 0 "memory_operand")
674 (match_operand 1 "memory_operand"))
675 (const_string "both")
676 (match_operand 0 "memory_operand")
677 (const_string "store")
678 (match_operand 1 "memory_operand")
679 (const_string "load")
681 "!alu1,negnot,ishift1,
682 imov,imovx,icmp,test,bitmanip,
684 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
685 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
686 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
687 (match_operand 2 "memory_operand"))
688 (const_string "load")
689 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
690 (match_operand 3 "memory_operand"))
691 (const_string "load")
693 (const_string "none")))
695 ;; Indicates if an instruction has both an immediate and a displacement.
697 (define_attr "imm_disp" "false,true,unknown"
698 (cond [(eq_attr "type" "other,multi")
699 (const_string "unknown")
700 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
701 (and (match_operand 0 "memory_displacement_operand")
702 (match_operand 1 "immediate_operand")))
703 (const_string "true")
704 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
705 (and (match_operand 0 "memory_displacement_operand")
706 (match_operand 2 "immediate_operand")))
707 (const_string "true")
709 (const_string "false")))
711 ;; Indicates if an FP operation has an integer source.
713 (define_attr "fp_int_src" "false,true"
714 (const_string "false"))
716 ;; Defines rounding mode of an FP operation.
718 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
719 (const_string "any"))
721 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
722 (define_attr "use_carry" "0,1" (const_string "0"))
724 ;; Define attribute to indicate unaligned ssemov insns
725 (define_attr "movu" "0,1" (const_string "0"))
727 ;; Used to control the "enabled" attribute on a per-instruction basis.
728 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
729 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
730 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
731 (const_string "base"))
733 (define_attr "enabled" ""
734 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
735 (eq_attr "isa" "x64_sse4")
736 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
737 (eq_attr "isa" "x64_sse4_noavx")
738 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
739 (eq_attr "isa" "x64_avx")
740 (symbol_ref "TARGET_64BIT && TARGET_AVX")
741 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
742 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
743 (eq_attr "isa" "sse2_noavx")
744 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
745 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
746 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
747 (eq_attr "isa" "sse4_noavx")
748 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
749 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
750 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
751 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
752 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
753 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
754 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
755 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
756 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
757 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
758 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
759 (eq_attr "isa" "fma_avx512f")
760 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
764 ;; Describe a user's asm statement.
765 (define_asm_attributes
766 [(set_attr "length" "128")
767 (set_attr "type" "multi")])
769 (define_code_iterator plusminus [plus minus])
771 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
773 (define_code_iterator multdiv [mult div])
775 ;; Base name for define_insn
776 (define_code_attr plusminus_insn
777 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
778 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
780 ;; Base name for insn mnemonic.
781 (define_code_attr plusminus_mnemonic
782 [(plus "add") (ss_plus "adds") (us_plus "addus")
783 (minus "sub") (ss_minus "subs") (us_minus "subus")])
784 (define_code_attr plusminus_carry_mnemonic
785 [(plus "adc") (minus "sbb")])
786 (define_code_attr multdiv_mnemonic
787 [(mult "mul") (div "div")])
789 ;; Mark commutative operators as such in constraints.
790 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
791 (minus "") (ss_minus "") (us_minus "")])
793 ;; Mapping of max and min
794 (define_code_iterator maxmin [smax smin umax umin])
796 ;; Mapping of signed max and min
797 (define_code_iterator smaxmin [smax smin])
799 ;; Mapping of unsigned max and min
800 (define_code_iterator umaxmin [umax umin])
802 ;; Base name for integer and FP insn mnemonic
803 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
804 (umax "maxu") (umin "minu")])
805 (define_code_attr maxmin_float [(smax "max") (smin "min")])
807 ;; Mapping of logic operators
808 (define_code_iterator any_logic [and ior xor])
809 (define_code_iterator any_or [ior xor])
810 (define_code_iterator fpint_logic [and xor])
812 ;; Base name for insn mnemonic.
813 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
815 ;; Mapping of logic-shift operators
816 (define_code_iterator any_lshift [ashift lshiftrt])
818 ;; Mapping of shift-right operators
819 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
821 ;; Mapping of all shift operators
822 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
824 ;; Base name for define_insn
825 (define_code_attr shift_insn
826 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
828 ;; Base name for insn mnemonic.
829 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
830 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
832 ;; Mapping of rotate operators
833 (define_code_iterator any_rotate [rotate rotatert])
835 ;; Base name for define_insn
836 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
838 ;; Base name for insn mnemonic.
839 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
841 ;; Mapping of abs neg operators
842 (define_code_iterator absneg [abs neg])
844 ;; Base name for x87 insn mnemonic.
845 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
847 ;; Used in signed and unsigned widening multiplications.
848 (define_code_iterator any_extend [sign_extend zero_extend])
850 ;; Prefix for insn menmonic.
851 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
853 ;; Prefix for define_insn
854 (define_code_attr u [(sign_extend "") (zero_extend "u")])
855 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
856 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
858 ;; Used in signed and unsigned truncations.
859 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
860 ;; Instruction suffix for truncations.
861 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
863 ;; Used in signed and unsigned fix.
864 (define_code_iterator any_fix [fix unsigned_fix])
865 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
867 ;; All integer modes.
868 (define_mode_iterator SWI1248x [QI HI SI DI])
870 ;; All integer modes without QImode.
871 (define_mode_iterator SWI248x [HI SI DI])
873 ;; All integer modes without QImode and HImode.
874 (define_mode_iterator SWI48x [SI DI])
876 ;; All integer modes without SImode and DImode.
877 (define_mode_iterator SWI12 [QI HI])
879 ;; All integer modes without DImode.
880 (define_mode_iterator SWI124 [QI HI SI])
882 ;; All integer modes without QImode and DImode.
883 (define_mode_iterator SWI24 [HI SI])
885 ;; Single word integer modes.
886 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
888 ;; Single word integer modes without QImode.
889 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
891 ;; Single word integer modes without QImode and HImode.
892 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
894 ;; All math-dependant single and double word integer modes.
895 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
896 (HI "TARGET_HIMODE_MATH")
897 SI DI (TI "TARGET_64BIT")])
899 ;; Math-dependant single word integer modes.
900 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
901 (HI "TARGET_HIMODE_MATH")
902 SI (DI "TARGET_64BIT")])
904 ;; Math-dependant integer modes without DImode.
905 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
906 (HI "TARGET_HIMODE_MATH")
909 ;; Math-dependant single word integer modes without QImode.
910 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
911 SI (DI "TARGET_64BIT")])
913 ;; Double word integer modes.
914 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
915 (TI "TARGET_64BIT")])
917 ;; Double word integer modes as mode attribute.
918 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
919 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
921 ;; Half mode for double word integer modes.
922 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
923 (DI "TARGET_64BIT")])
925 ;; Instruction suffix for integer modes.
926 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
928 ;; Pointer size prefix for integer modes (Intel asm dialect)
929 (define_mode_attr iptrsize [(QI "BYTE")
934 ;; Register class for integer modes.
935 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
937 ;; Immediate operand constraint for integer modes.
938 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
940 ;; General operand constraint for word modes.
941 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
943 ;; Immediate operand constraint for double integer modes.
944 (define_mode_attr di [(SI "nF") (DI "e")])
946 ;; Immediate operand constraint for shifts.
947 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
949 ;; General operand predicate for integer modes.
950 (define_mode_attr general_operand
951 [(QI "general_operand")
952 (HI "general_operand")
953 (SI "x86_64_general_operand")
954 (DI "x86_64_general_operand")
955 (TI "x86_64_general_operand")])
957 ;; General sign/zero extend operand predicate for integer modes.
958 (define_mode_attr general_szext_operand
959 [(QI "general_operand")
960 (HI "general_operand")
961 (SI "x86_64_szext_general_operand")
962 (DI "x86_64_szext_general_operand")])
964 ;; Immediate operand predicate for integer modes.
965 (define_mode_attr immediate_operand
966 [(QI "immediate_operand")
967 (HI "immediate_operand")
968 (SI "x86_64_immediate_operand")
969 (DI "x86_64_immediate_operand")])
971 ;; Nonmemory operand predicate for integer modes.
972 (define_mode_attr nonmemory_operand
973 [(QI "nonmemory_operand")
974 (HI "nonmemory_operand")
975 (SI "x86_64_nonmemory_operand")
976 (DI "x86_64_nonmemory_operand")])
978 ;; Operand predicate for shifts.
979 (define_mode_attr shift_operand
980 [(QI "nonimmediate_operand")
981 (HI "nonimmediate_operand")
982 (SI "nonimmediate_operand")
983 (DI "shiftdi_operand")
984 (TI "register_operand")])
986 ;; Operand predicate for shift argument.
987 (define_mode_attr shift_immediate_operand
988 [(QI "const_1_to_31_operand")
989 (HI "const_1_to_31_operand")
990 (SI "const_1_to_31_operand")
991 (DI "const_1_to_63_operand")])
993 ;; Input operand predicate for arithmetic left shifts.
994 (define_mode_attr ashl_input_operand
995 [(QI "nonimmediate_operand")
996 (HI "nonimmediate_operand")
997 (SI "nonimmediate_operand")
998 (DI "ashldi_input_operand")
999 (TI "reg_or_pm1_operand")])
1001 ;; SSE and x87 SFmode and DFmode floating point modes
1002 (define_mode_iterator MODEF [SF DF])
1004 ;; All x87 floating point modes
1005 (define_mode_iterator X87MODEF [SF DF XF])
1007 ;; SSE instruction suffix for various modes
1008 (define_mode_attr ssemodesuffix
1009 [(SF "ss") (DF "sd")
1010 (V16SF "ps") (V8DF "pd")
1011 (V8SF "ps") (V4DF "pd")
1012 (V4SF "ps") (V2DF "pd")
1013 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1014 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1015 (V64QI "b") (V16SI "d") (V8DI "q")])
1017 ;; SSE vector suffix for floating point modes
1018 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1020 ;; SSE vector mode corresponding to a scalar mode
1021 (define_mode_attr ssevecmode
1022 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1023 (define_mode_attr ssevecmodelower
1024 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1026 ;; Instruction suffix for REX 64bit operators.
1027 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1029 ;; This mode iterator allows :P to be used for patterns that operate on
1030 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1031 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1033 ;; This mode iterator allows :W to be used for patterns that operate on
1034 ;; word_mode sized quantities.
1035 (define_mode_iterator W
1036 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1038 ;; This mode iterator allows :PTR to be used for patterns that operate on
1039 ;; ptr_mode sized quantities.
1040 (define_mode_iterator PTR
1041 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1043 ;; Scheduling descriptions
1045 (include "pentium.md")
1048 (include "athlon.md")
1049 (include "bdver1.md")
1050 (include "bdver3.md")
1051 (include "btver2.md")
1052 (include "geode.md")
1055 (include "core2.md")
1058 ;; Operand and operator predicates and constraints
1060 (include "predicates.md")
1061 (include "constraints.md")
1064 ;; Compare and branch/compare and store instructions.
1066 (define_expand "cbranch<mode>4"
1067 [(set (reg:CC FLAGS_REG)
1068 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1069 (match_operand:SDWIM 2 "<general_operand>")))
1070 (set (pc) (if_then_else
1071 (match_operator 0 "ordered_comparison_operator"
1072 [(reg:CC FLAGS_REG) (const_int 0)])
1073 (label_ref (match_operand 3))
1077 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1078 operands[1] = force_reg (<MODE>mode, operands[1]);
1079 ix86_expand_branch (GET_CODE (operands[0]),
1080 operands[1], operands[2], operands[3]);
1084 (define_expand "cstore<mode>4"
1085 [(set (reg:CC FLAGS_REG)
1086 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1087 (match_operand:SWIM 3 "<general_operand>")))
1088 (set (match_operand:QI 0 "register_operand")
1089 (match_operator 1 "ordered_comparison_operator"
1090 [(reg:CC FLAGS_REG) (const_int 0)]))]
1093 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1094 operands[2] = force_reg (<MODE>mode, operands[2]);
1095 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1096 operands[2], operands[3]);
1100 (define_expand "cmp<mode>_1"
1101 [(set (reg:CC FLAGS_REG)
1102 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1103 (match_operand:SWI48 1 "<general_operand>")))])
1105 (define_insn "*cmp<mode>_ccno_1"
1106 [(set (reg FLAGS_REG)
1107 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1108 (match_operand:SWI 1 "const0_operand")))]
1109 "ix86_match_ccmode (insn, CCNOmode)"
1111 test{<imodesuffix>}\t%0, %0
1112 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1113 [(set_attr "type" "test,icmp")
1114 (set_attr "length_immediate" "0,1")
1115 (set_attr "mode" "<MODE>")])
1117 (define_insn "*cmp<mode>_1"
1118 [(set (reg FLAGS_REG)
1119 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1120 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1121 "ix86_match_ccmode (insn, CCmode)"
1122 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1123 [(set_attr "type" "icmp")
1124 (set_attr "mode" "<MODE>")])
1126 (define_insn "*cmp<mode>_minus_1"
1127 [(set (reg FLAGS_REG)
1129 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1130 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1132 "ix86_match_ccmode (insn, CCGOCmode)"
1133 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1134 [(set_attr "type" "icmp")
1135 (set_attr "mode" "<MODE>")])
1137 (define_insn "*cmpqi_ext_1"
1138 [(set (reg FLAGS_REG)
1140 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1143 (match_operand 1 "ext_register_operand" "Q,Q")
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %0|%0, %h1}"
1148 [(set_attr "isa" "*,nox64")
1149 (set_attr "type" "icmp")
1150 (set_attr "mode" "QI")])
1152 (define_insn "*cmpqi_ext_2"
1153 [(set (reg FLAGS_REG)
1157 (match_operand 0 "ext_register_operand" "Q")
1160 (match_operand:QI 1 "const0_operand")))]
1161 "ix86_match_ccmode (insn, CCNOmode)"
1163 [(set_attr "type" "test")
1164 (set_attr "length_immediate" "0")
1165 (set_attr "mode" "QI")])
1167 (define_expand "cmpqi_ext_3"
1168 [(set (reg:CC FLAGS_REG)
1172 (match_operand 0 "ext_register_operand")
1175 (match_operand:QI 1 "const_int_operand")))])
1177 (define_insn "*cmpqi_ext_3"
1178 [(set (reg FLAGS_REG)
1182 (match_operand 0 "ext_register_operand" "Q,Q")
1185 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1186 "ix86_match_ccmode (insn, CCmode)"
1187 "cmp{b}\t{%1, %h0|%h0, %1}"
1188 [(set_attr "isa" "*,nox64")
1189 (set_attr "type" "icmp")
1190 (set_attr "modrm" "1")
1191 (set_attr "mode" "QI")])
1193 (define_insn "*cmpqi_ext_4"
1194 [(set (reg FLAGS_REG)
1198 (match_operand 0 "ext_register_operand" "Q")
1203 (match_operand 1 "ext_register_operand" "Q")
1205 (const_int 8)) 0)))]
1206 "ix86_match_ccmode (insn, CCmode)"
1207 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1208 [(set_attr "type" "icmp")
1209 (set_attr "mode" "QI")])
1211 ;; These implement float point compares.
1212 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1213 ;; which would allow mix and match FP modes on the compares. Which is what
1214 ;; the old patterns did, but with many more of them.
1216 (define_expand "cbranchxf4"
1217 [(set (reg:CC FLAGS_REG)
1218 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1219 (match_operand:XF 2 "nonmemory_operand")))
1220 (set (pc) (if_then_else
1221 (match_operator 0 "ix86_fp_comparison_operator"
1224 (label_ref (match_operand 3))
1228 ix86_expand_branch (GET_CODE (operands[0]),
1229 operands[1], operands[2], operands[3]);
1233 (define_expand "cstorexf4"
1234 [(set (reg:CC FLAGS_REG)
1235 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1236 (match_operand:XF 3 "nonmemory_operand")))
1237 (set (match_operand:QI 0 "register_operand")
1238 (match_operator 1 "ix86_fp_comparison_operator"
1243 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1244 operands[2], operands[3]);
1248 (define_expand "cbranch<mode>4"
1249 [(set (reg:CC FLAGS_REG)
1250 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1251 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1252 (set (pc) (if_then_else
1253 (match_operator 0 "ix86_fp_comparison_operator"
1256 (label_ref (match_operand 3))
1258 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1260 ix86_expand_branch (GET_CODE (operands[0]),
1261 operands[1], operands[2], operands[3]);
1265 (define_expand "cstore<mode>4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1268 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1269 (set (match_operand:QI 0 "register_operand")
1270 (match_operator 1 "ix86_fp_comparison_operator"
1273 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1275 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1276 operands[2], operands[3]);
1280 (define_expand "cbranchcc4"
1281 [(set (pc) (if_then_else
1282 (match_operator 0 "comparison_operator"
1283 [(match_operand 1 "flags_reg_operand")
1284 (match_operand 2 "const0_operand")])
1285 (label_ref (match_operand 3))
1289 ix86_expand_branch (GET_CODE (operands[0]),
1290 operands[1], operands[2], operands[3]);
1294 (define_expand "cstorecc4"
1295 [(set (match_operand:QI 0 "register_operand")
1296 (match_operator 1 "comparison_operator"
1297 [(match_operand 2 "flags_reg_operand")
1298 (match_operand 3 "const0_operand")]))]
1301 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1302 operands[2], operands[3]);
1307 ;; FP compares, step 1:
1308 ;; Set the FP condition codes.
1310 ;; CCFPmode compare with exceptions
1311 ;; CCFPUmode compare with no exceptions
1313 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1314 ;; used to manage the reg stack popping would not be preserved.
1316 (define_insn "*cmp<mode>_0_i387"
1317 [(set (match_operand:HI 0 "register_operand" "=a")
1320 (match_operand:X87MODEF 1 "register_operand" "f")
1321 (match_operand:X87MODEF 2 "const0_operand"))]
1324 "* return output_fp_compare (insn, operands, false, false);"
1325 [(set_attr "type" "multi")
1326 (set_attr "unit" "i387")
1327 (set_attr "mode" "<MODE>")])
1329 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1330 [(set (reg:CCFP FLAGS_REG)
1332 (match_operand:X87MODEF 1 "register_operand" "f")
1333 (match_operand:X87MODEF 2 "const0_operand")))
1334 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1335 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1337 "&& reload_completed"
1340 [(compare:CCFP (match_dup 1)(match_dup 2))]
1342 (set (reg:CC FLAGS_REG)
1343 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1345 [(set_attr "type" "multi")
1346 (set_attr "unit" "i387")
1347 (set_attr "mode" "<MODE>")])
1349 (define_insn "*cmpxf_i387"
1350 [(set (match_operand:HI 0 "register_operand" "=a")
1353 (match_operand:XF 1 "register_operand" "f")
1354 (match_operand:XF 2 "register_operand" "f"))]
1357 "* return output_fp_compare (insn, operands, false, false);"
1358 [(set_attr "type" "multi")
1359 (set_attr "unit" "i387")
1360 (set_attr "mode" "XF")])
1362 (define_insn_and_split "*cmpxf_cc_i387"
1363 [(set (reg:CCFP FLAGS_REG)
1365 (match_operand:XF 1 "register_operand" "f")
1366 (match_operand:XF 2 "register_operand" "f")))
1367 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1368 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1370 "&& reload_completed"
1373 [(compare:CCFP (match_dup 1)(match_dup 2))]
1375 (set (reg:CC FLAGS_REG)
1376 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1380 (set_attr "mode" "XF")])
1382 (define_insn "*cmp<mode>_i387"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1386 (match_operand:MODEF 1 "register_operand" "f")
1387 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1390 "* return output_fp_compare (insn, operands, false, false);"
1391 [(set_attr "type" "multi")
1392 (set_attr "unit" "i387")
1393 (set_attr "mode" "<MODE>")])
1395 (define_insn_and_split "*cmp<mode>_cc_i387"
1396 [(set (reg:CCFP FLAGS_REG)
1398 (match_operand:MODEF 1 "register_operand" "f")
1399 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1400 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1401 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1403 "&& reload_completed"
1406 [(compare:CCFP (match_dup 1)(match_dup 2))]
1408 (set (reg:CC FLAGS_REG)
1409 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1411 [(set_attr "type" "multi")
1412 (set_attr "unit" "i387")
1413 (set_attr "mode" "<MODE>")])
1415 (define_insn "*cmpu<mode>_i387"
1416 [(set (match_operand:HI 0 "register_operand" "=a")
1419 (match_operand:X87MODEF 1 "register_operand" "f")
1420 (match_operand:X87MODEF 2 "register_operand" "f"))]
1423 "* return output_fp_compare (insn, operands, false, true);"
1424 [(set_attr "type" "multi")
1425 (set_attr "unit" "i387")
1426 (set_attr "mode" "<MODE>")])
1428 (define_insn_and_split "*cmpu<mode>_cc_i387"
1429 [(set (reg:CCFPU FLAGS_REG)
1431 (match_operand:X87MODEF 1 "register_operand" "f")
1432 (match_operand:X87MODEF 2 "register_operand" "f")))
1433 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1434 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1436 "&& reload_completed"
1439 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1441 (set (reg:CC FLAGS_REG)
1442 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1444 [(set_attr "type" "multi")
1445 (set_attr "unit" "i387")
1446 (set_attr "mode" "<MODE>")])
1448 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1449 [(set (match_operand:HI 0 "register_operand" "=a")
1452 (match_operand:X87MODEF 1 "register_operand" "f")
1453 (match_operator:X87MODEF 3 "float_operator"
1454 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1457 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1458 || optimize_function_for_size_p (cfun))"
1459 "* return output_fp_compare (insn, operands, false, false);"
1460 [(set_attr "type" "multi")
1461 (set_attr "unit" "i387")
1462 (set_attr "fp_int_src" "true")
1463 (set_attr "mode" "<SWI24:MODE>")])
1465 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1466 [(set (reg:CCFP FLAGS_REG)
1468 (match_operand:X87MODEF 1 "register_operand" "f")
1469 (match_operator:X87MODEF 3 "float_operator"
1470 [(match_operand:SWI24 2 "memory_operand" "m")])))
1471 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1472 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1473 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1474 || optimize_function_for_size_p (cfun))"
1476 "&& reload_completed"
1481 (match_op_dup 3 [(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 "fp_int_src" "true")
1489 (set_attr "mode" "<SWI24:MODE>")])
1491 ;; FP compares, step 2
1492 ;; Move the fpsw to ax.
1494 (define_insn "x86_fnstsw_1"
1495 [(set (match_operand:HI 0 "register_operand" "=a")
1496 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1499 [(set (attr "length")
1500 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1501 (set_attr "mode" "SI")
1502 (set_attr "unit" "i387")])
1504 ;; FP compares, step 3
1505 ;; Get ax into flags, general case.
1507 (define_insn "x86_sahf_1"
1508 [(set (reg:CC FLAGS_REG)
1509 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1513 #ifndef HAVE_AS_IX86_SAHF
1515 return ASM_BYTE "0x9e";
1520 [(set_attr "length" "1")
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "direct")
1524 (set_attr "mode" "SI")])
1526 ;; Pentium Pro can do steps 1 through 3 in one go.
1527 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1528 ;; (these i387 instructions set flags directly)
1530 (define_mode_iterator FPCMP [CCFP CCFPU])
1531 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1533 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1534 [(set (reg:FPCMP FLAGS_REG)
1536 (match_operand:MODEF 0 "register_operand" "f,x")
1537 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1538 "TARGET_MIX_SSE_I387
1539 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1540 "* return output_fp_compare (insn, operands, true,
1541 <FPCMP:MODE>mode == CCFPUmode);"
1542 [(set_attr "type" "fcmp,ssecomi")
1543 (set_attr "prefix" "orig,maybe_vex")
1544 (set_attr "mode" "<MODEF:MODE>")
1545 (set (attr "prefix_rep")
1546 (if_then_else (eq_attr "type" "ssecomi")
1548 (const_string "*")))
1549 (set (attr "prefix_data16")
1550 (cond [(eq_attr "type" "fcmp")
1552 (eq_attr "mode" "DF")
1555 (const_string "0")))
1556 (set_attr "athlon_decode" "vector")
1557 (set_attr "amdfam10_decode" "direct")
1558 (set_attr "bdver1_decode" "double")])
1560 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1561 [(set (reg:FPCMP FLAGS_REG)
1563 (match_operand:MODEF 0 "register_operand" "x")
1564 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1566 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1567 "* return output_fp_compare (insn, operands, true,
1568 <FPCMP:MODE>mode == CCFPUmode);"
1569 [(set_attr "type" "ssecomi")
1570 (set_attr "prefix" "maybe_vex")
1571 (set_attr "mode" "<MODEF:MODE>")
1572 (set_attr "prefix_rep" "0")
1573 (set (attr "prefix_data16")
1574 (if_then_else (eq_attr "mode" "DF")
1576 (const_string "0")))
1577 (set_attr "athlon_decode" "vector")
1578 (set_attr "amdfam10_decode" "direct")
1579 (set_attr "bdver1_decode" "double")])
1581 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1582 [(set (reg:FPCMP FLAGS_REG)
1584 (match_operand:X87MODEF 0 "register_operand" "f")
1585 (match_operand:X87MODEF 1 "register_operand" "f")))]
1586 "TARGET_80387 && TARGET_CMOVE
1587 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1588 "* return output_fp_compare (insn, operands, true,
1589 <FPCMP:MODE>mode == CCFPUmode);"
1590 [(set_attr "type" "fcmp")
1591 (set_attr "mode" "<X87MODEF:MODE>")
1592 (set_attr "athlon_decode" "vector")
1593 (set_attr "amdfam10_decode" "direct")
1594 (set_attr "bdver1_decode" "double")])
1596 ;; Push/pop instructions.
1598 (define_insn "*push<mode>2"
1599 [(set (match_operand:DWI 0 "push_operand" "=<")
1600 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1603 [(set_attr "type" "multi")
1604 (set_attr "mode" "<MODE>")])
1607 [(set (match_operand:TI 0 "push_operand")
1608 (match_operand:TI 1 "general_operand"))]
1609 "TARGET_64BIT && reload_completed
1610 && !SSE_REG_P (operands[1])"
1612 "ix86_split_long_move (operands); DONE;")
1614 (define_insn "*pushdi2_rex64"
1615 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1621 [(set_attr "type" "push,multi")
1622 (set_attr "mode" "DI")])
1624 ;; Convert impossible pushes of immediate to existing instructions.
1625 ;; First try to get scratch register and go through it. In case this
1626 ;; fails, push sign extended lower part first and then overwrite
1627 ;; upper part by 32bit move.
1629 [(match_scratch:DI 2 "r")
1630 (set (match_operand:DI 0 "push_operand")
1631 (match_operand:DI 1 "immediate_operand"))]
1632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633 && !x86_64_immediate_operand (operands[1], DImode)"
1634 [(set (match_dup 2) (match_dup 1))
1635 (set (match_dup 0) (match_dup 2))])
1637 ;; We need to define this as both peepholer and splitter for case
1638 ;; peephole2 pass is not run.
1639 ;; "&& 1" is needed to keep it from matching the previous pattern.
1641 [(set (match_operand:DI 0 "push_operand")
1642 (match_operand:DI 1 "immediate_operand"))]
1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645 [(set (match_dup 0) (match_dup 1))
1646 (set (match_dup 2) (match_dup 3))]
1648 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1650 operands[1] = gen_lowpart (DImode, operands[2]);
1651 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1656 [(set (match_operand:DI 0 "push_operand")
1657 (match_operand:DI 1 "immediate_operand"))]
1658 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659 ? epilogue_completed : reload_completed)
1660 && !symbolic_operand (operands[1], DImode)
1661 && !x86_64_immediate_operand (operands[1], DImode)"
1662 [(set (match_dup 0) (match_dup 1))
1663 (set (match_dup 2) (match_dup 3))]
1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1667 operands[1] = gen_lowpart (DImode, operands[2]);
1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1673 [(set (match_operand:DI 0 "push_operand")
1674 (match_operand:DI 1 "general_operand"))]
1675 "!TARGET_64BIT && reload_completed
1676 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1678 "ix86_split_long_move (operands); DONE;")
1680 (define_insn "*pushsi2"
1681 [(set (match_operand:SI 0 "push_operand" "=<")
1682 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1685 [(set_attr "type" "push")
1686 (set_attr "mode" "SI")])
1688 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1689 ;; "push a byte/word". But actually we use pushl, which has the effect
1690 ;; of rounding the amount pushed up to a word.
1692 ;; For TARGET_64BIT we always round up to 8 bytes.
1693 (define_insn "*push<mode>2_rex64"
1694 [(set (match_operand:SWI124 0 "push_operand" "=X")
1695 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "DI")])
1701 (define_insn "*push<mode>2"
1702 [(set (match_operand:SWI12 0 "push_operand" "=X")
1703 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1709 (define_insn "*push<mode>2_prologue"
1710 [(set (match_operand:W 0 "push_operand" "=<")
1711 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1712 (clobber (mem:BLK (scratch)))]
1714 "push{<imodesuffix>}\t%1"
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "<MODE>")])
1718 (define_insn "*pop<mode>1"
1719 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1720 (match_operand:W 1 "pop_operand" ">"))]
1722 "pop{<imodesuffix>}\t%0"
1723 [(set_attr "type" "pop")
1724 (set_attr "mode" "<MODE>")])
1726 (define_insn "*pop<mode>1_epilogue"
1727 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1728 (match_operand:W 1 "pop_operand" ">"))
1729 (clobber (mem:BLK (scratch)))]
1731 "pop{<imodesuffix>}\t%0"
1732 [(set_attr "type" "pop")
1733 (set_attr "mode" "<MODE>")])
1735 (define_insn "*pushfl<mode>2"
1736 [(set (match_operand:W 0 "push_operand" "=<")
1737 (match_operand:W 1 "flags_reg_operand"))]
1739 "pushf{<imodesuffix>}"
1740 [(set_attr "type" "push")
1741 (set_attr "mode" "<MODE>")])
1743 (define_insn "*popfl<mode>1"
1744 [(set (match_operand:W 0 "flags_reg_operand")
1745 (match_operand:W 1 "pop_operand" ">"))]
1747 "popf{<imodesuffix>}"
1748 [(set_attr "type" "pop")
1749 (set_attr "mode" "<MODE>")])
1752 ;; Move instructions.
1754 (define_expand "movxi"
1755 [(set (match_operand:XI 0 "nonimmediate_operand")
1756 (match_operand:XI 1 "general_operand"))]
1758 "ix86_expand_move (XImode, operands); DONE;")
1760 ;; Reload patterns to support multi-word load/store
1761 ;; with non-offsetable address.
1762 (define_expand "reload_noff_store"
1763 [(parallel [(match_operand 0 "memory_operand" "=m")
1764 (match_operand 1 "register_operand" "r")
1765 (match_operand:DI 2 "register_operand" "=&r")])]
1768 rtx mem = operands[0];
1769 rtx addr = XEXP (mem, 0);
1771 emit_move_insn (operands[2], addr);
1772 mem = replace_equiv_address_nv (mem, operands[2]);
1774 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1778 (define_expand "reload_noff_load"
1779 [(parallel [(match_operand 0 "register_operand" "=r")
1780 (match_operand 1 "memory_operand" "m")
1781 (match_operand:DI 2 "register_operand" "=r")])]
1784 rtx mem = operands[1];
1785 rtx addr = XEXP (mem, 0);
1787 emit_move_insn (operands[2], addr);
1788 mem = replace_equiv_address_nv (mem, operands[2]);
1790 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1794 (define_expand "movoi"
1795 [(set (match_operand:OI 0 "nonimmediate_operand")
1796 (match_operand:OI 1 "general_operand"))]
1798 "ix86_expand_move (OImode, operands); DONE;")
1800 (define_expand "movti"
1801 [(set (match_operand:TI 0 "nonimmediate_operand")
1802 (match_operand:TI 1 "nonimmediate_operand"))]
1803 "TARGET_64BIT || TARGET_SSE"
1806 ix86_expand_move (TImode, operands);
1807 else if (push_operand (operands[0], TImode))
1808 ix86_expand_push (TImode, operands[1]);
1810 ix86_expand_vector_move (TImode, operands);
1814 ;; This expands to what emit_move_complex would generate if we didn't
1815 ;; have a movti pattern. Having this avoids problems with reload on
1816 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1817 ;; to have around all the time.
1818 (define_expand "movcdi"
1819 [(set (match_operand:CDI 0 "nonimmediate_operand")
1820 (match_operand:CDI 1 "general_operand"))]
1823 if (push_operand (operands[0], CDImode))
1824 emit_move_complex_push (CDImode, operands[0], operands[1]);
1826 emit_move_complex_parts (operands[0], operands[1]);
1830 (define_expand "mov<mode>"
1831 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1832 (match_operand:SWI1248x 1 "general_operand"))]
1834 "ix86_expand_move (<MODE>mode, operands); DONE;")
1836 (define_insn "*mov<mode>_xor"
1837 [(set (match_operand:SWI48 0 "register_operand" "=r")
1838 (match_operand:SWI48 1 "const0_operand"))
1839 (clobber (reg:CC FLAGS_REG))]
1842 [(set_attr "type" "alu1")
1843 (set_attr "mode" "SI")
1844 (set_attr "length_immediate" "0")])
1846 (define_insn "*mov<mode>_or"
1847 [(set (match_operand:SWI48 0 "register_operand" "=r")
1848 (match_operand:SWI48 1 "const_int_operand"))
1849 (clobber (reg:CC FLAGS_REG))]
1851 && operands[1] == constm1_rtx"
1852 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1853 [(set_attr "type" "alu1")
1854 (set_attr "mode" "<MODE>")
1855 (set_attr "length_immediate" "1")])
1857 (define_insn "*movxi_internal_avx512f"
1858 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1859 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1860 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1862 switch (which_alternative)
1865 return standard_sse_constant_opcode (insn, operands[1]);
1868 if (misaligned_operand (operands[0], XImode)
1869 || misaligned_operand (operands[1], XImode))
1870 return "vmovdqu32\t{%1, %0|%0, %1}";
1872 return "vmovdqa32\t{%1, %0|%0, %1}";
1877 [(set_attr "type" "sselog1,ssemov,ssemov")
1878 (set_attr "prefix" "evex")
1879 (set_attr "mode" "XI")])
1881 (define_insn "*movoi_internal_avx"
1882 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1883 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1884 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1886 switch (get_attr_type (insn))
1889 return standard_sse_constant_opcode (insn, operands[1]);
1892 if (misaligned_operand (operands[0], OImode)
1893 || misaligned_operand (operands[1], OImode))
1895 if (get_attr_mode (insn) == MODE_V8SF)
1896 return "vmovups\t{%1, %0|%0, %1}";
1898 return "vmovdqu\t{%1, %0|%0, %1}";
1902 if (get_attr_mode (insn) == MODE_V8SF)
1903 return "vmovaps\t{%1, %0|%0, %1}";
1905 return "vmovdqa\t{%1, %0|%0, %1}";
1912 [(set_attr "type" "sselog1,ssemov,ssemov")
1913 (set_attr "prefix" "vex")
1915 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1916 (const_string "V8SF")
1917 (and (eq_attr "alternative" "2")
1918 (match_test "TARGET_SSE_TYPELESS_STORES"))
1919 (const_string "V8SF")
1921 (const_string "OI")))])
1923 (define_insn "*movti_internal"
1924 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1925 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1926 "(TARGET_64BIT || TARGET_SSE)
1927 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1929 switch (get_attr_type (insn))
1935 return standard_sse_constant_opcode (insn, operands[1]);
1938 /* TDmode values are passed as TImode on the stack. Moving them
1939 to stack may result in unaligned memory access. */
1940 if (misaligned_operand (operands[0], TImode)
1941 || misaligned_operand (operands[1], TImode))
1943 if (get_attr_mode (insn) == MODE_V4SF)
1944 return "%vmovups\t{%1, %0|%0, %1}";
1946 return "%vmovdqu\t{%1, %0|%0, %1}";
1950 if (get_attr_mode (insn) == MODE_V4SF)
1951 return "%vmovaps\t{%1, %0|%0, %1}";
1953 return "%vmovdqa\t{%1, %0|%0, %1}";
1960 [(set_attr "isa" "x64,x64,*,*,*")
1961 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1962 (set (attr "prefix")
1963 (if_then_else (eq_attr "type" "sselog1,ssemov")
1964 (const_string "maybe_vex")
1965 (const_string "orig")))
1967 (cond [(eq_attr "alternative" "0,1")
1969 (ior (not (match_test "TARGET_SSE2"))
1970 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1971 (const_string "V4SF")
1972 (and (eq_attr "alternative" "4")
1973 (match_test "TARGET_SSE_TYPELESS_STORES"))
1974 (const_string "V4SF")
1975 (match_test "TARGET_AVX")
1977 (match_test "optimize_function_for_size_p (cfun)")
1978 (const_string "V4SF")
1980 (const_string "TI")))])
1983 [(set (match_operand:TI 0 "nonimmediate_operand")
1984 (match_operand:TI 1 "general_operand"))]
1986 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1988 "ix86_split_long_move (operands); DONE;")
1990 (define_insn "*movdi_internal"
1991 [(set (match_operand:DI 0 "nonimmediate_operand"
1992 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1993 (match_operand:DI 1 "general_operand"
1994 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1995 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1997 switch (get_attr_type (insn))
2003 return "pxor\t%0, %0";
2006 /* Handle broken assemblers that require movd instead of movq. */
2007 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2008 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2009 return "movd\t{%1, %0|%0, %1}";
2010 return "movq\t{%1, %0|%0, %1}";
2013 if (GENERAL_REG_P (operands[0]))
2014 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2016 return standard_sse_constant_opcode (insn, operands[1]);
2019 switch (get_attr_mode (insn))
2022 /* Handle broken assemblers that require movd instead of movq. */
2023 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2024 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2025 return "%vmovd\t{%1, %0|%0, %1}";
2026 return "%vmovq\t{%1, %0|%0, %1}";
2028 return "%vmovdqa\t{%1, %0|%0, %1}";
2030 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2033 gcc_assert (!TARGET_AVX);
2034 return "movlps\t{%1, %0|%0, %1}";
2036 return "%vmovaps\t{%1, %0|%0, %1}";
2043 if (SSE_REG_P (operands[0]))
2044 return "movq2dq\t{%1, %0|%0, %1}";
2046 return "movdq2q\t{%1, %0|%0, %1}";
2049 return "lea{q}\t{%E1, %0|%0, %E1}";
2052 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2053 if (get_attr_mode (insn) == MODE_SI)
2054 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2055 else if (which_alternative == 4)
2056 return "movabs{q}\t{%1, %0|%0, %1}";
2057 else if (ix86_use_lea_for_mov (insn, operands))
2058 return "lea{q}\t{%E1, %0|%0, %E1}";
2060 return "mov{q}\t{%1, %0|%0, %1}";
2067 (cond [(eq_attr "alternative" "0,1")
2068 (const_string "nox64")
2069 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2070 (const_string "x64")
2071 (eq_attr "alternative" "17")
2072 (const_string "x64_sse4")
2074 (const_string "*")))
2076 (cond [(eq_attr "alternative" "0,1")
2077 (const_string "multi")
2078 (eq_attr "alternative" "6")
2079 (const_string "mmx")
2080 (eq_attr "alternative" "7,8,9,10,11")
2081 (const_string "mmxmov")
2082 (eq_attr "alternative" "12,17")
2083 (const_string "sselog1")
2084 (eq_attr "alternative" "13,14,15,16,18")
2085 (const_string "ssemov")
2086 (eq_attr "alternative" "19,20")
2087 (const_string "ssecvt")
2088 (match_operand 1 "pic_32bit_operand")
2089 (const_string "lea")
2091 (const_string "imov")))
2094 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2096 (const_string "*")))
2097 (set (attr "length_immediate")
2098 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2100 (eq_attr "alternative" "17")
2103 (const_string "*")))
2104 (set (attr "prefix_rex")
2105 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2107 (const_string "*")))
2108 (set (attr "prefix_extra")
2109 (if_then_else (eq_attr "alternative" "17")
2111 (const_string "*")))
2112 (set (attr "prefix")
2113 (if_then_else (eq_attr "type" "sselog1,ssemov")
2114 (const_string "maybe_vex")
2115 (const_string "orig")))
2116 (set (attr "prefix_data16")
2117 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2119 (const_string "*")))
2121 (cond [(eq_attr "alternative" "2")
2123 (eq_attr "alternative" "12,13")
2124 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2125 (match_operand 1 "ext_sse_reg_operand"))
2127 (ior (not (match_test "TARGET_SSE2"))
2128 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2129 (const_string "V4SF")
2130 (match_test "TARGET_AVX")
2132 (match_test "optimize_function_for_size_p (cfun)")
2133 (const_string "V4SF")
2135 (const_string "TI"))
2137 (and (eq_attr "alternative" "14,15")
2138 (not (match_test "TARGET_SSE2")))
2139 (const_string "V2SF")
2140 (eq_attr "alternative" "17")
2143 (const_string "DI")))])
2146 [(set (match_operand:DI 0 "nonimmediate_operand")
2147 (match_operand:DI 1 "general_operand"))]
2148 "!TARGET_64BIT && reload_completed
2149 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2150 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2152 "ix86_split_long_move (operands); DONE;")
2154 (define_insn "*movsi_internal"
2155 [(set (match_operand:SI 0 "nonimmediate_operand"
2156 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2157 (match_operand:SI 1 "general_operand"
2158 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2159 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2161 switch (get_attr_type (insn))
2164 if (GENERAL_REG_P (operands[0]))
2165 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2167 return standard_sse_constant_opcode (insn, operands[1]);
2170 switch (get_attr_mode (insn))
2173 return "%vmovd\t{%1, %0|%0, %1}";
2175 return "%vmovdqa\t{%1, %0|%0, %1}";
2177 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2180 return "%vmovaps\t{%1, %0|%0, %1}";
2183 gcc_assert (!TARGET_AVX);
2184 return "movss\t{%1, %0|%0, %1}";
2191 return "pxor\t%0, %0";
2194 switch (get_attr_mode (insn))
2197 return "movq\t{%1, %0|%0, %1}";
2199 return "movd\t{%1, %0|%0, %1}";
2206 return "lea{l}\t{%E1, %0|%0, %E1}";
2209 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2210 if (ix86_use_lea_for_mov (insn, operands))
2211 return "lea{l}\t{%E1, %0|%0, %E1}";
2213 return "mov{l}\t{%1, %0|%0, %1}";
2220 (if_then_else (eq_attr "alternative" "11")
2221 (const_string "sse4")
2222 (const_string "*")))
2224 (cond [(eq_attr "alternative" "2")
2225 (const_string "mmx")
2226 (eq_attr "alternative" "3,4,5")
2227 (const_string "mmxmov")
2228 (eq_attr "alternative" "6,11")
2229 (const_string "sselog1")
2230 (eq_attr "alternative" "7,8,9,10,12")
2231 (const_string "ssemov")
2232 (match_operand 1 "pic_32bit_operand")
2233 (const_string "lea")
2235 (const_string "imov")))
2236 (set (attr "length_immediate")
2237 (if_then_else (eq_attr "alternative" "11")
2239 (const_string "*")))
2240 (set (attr "prefix_extra")
2241 (if_then_else (eq_attr "alternative" "11")
2243 (const_string "*")))
2244 (set (attr "prefix")
2245 (if_then_else (eq_attr "type" "sselog1,ssemov")
2246 (const_string "maybe_vex")
2247 (const_string "orig")))
2248 (set (attr "prefix_data16")
2249 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2251 (const_string "*")))
2253 (cond [(eq_attr "alternative" "2,3")
2255 (eq_attr "alternative" "6,7")
2256 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2257 (match_operand 1 "ext_sse_reg_operand"))
2259 (ior (not (match_test "TARGET_SSE2"))
2260 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2261 (const_string "V4SF")
2262 (match_test "TARGET_AVX")
2264 (match_test "optimize_function_for_size_p (cfun)")
2265 (const_string "V4SF")
2267 (const_string "TI"))
2269 (and (eq_attr "alternative" "8,9")
2270 (not (match_test "TARGET_SSE2")))
2272 (eq_attr "alternative" "11")
2275 (const_string "SI")))])
2277 (define_insn "*movhi_internal"
2278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2279 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2282 switch (get_attr_type (insn))
2285 /* movzwl is faster than movw on p2 due to partial word stalls,
2286 though not as fast as an aligned movl. */
2287 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2290 switch (which_alternative)
2292 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2293 case 5: return "kmovw\t{%1, %0|%0, %1}";
2294 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2295 default: gcc_unreachable ();
2299 if (get_attr_mode (insn) == MODE_SI)
2300 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2302 return "mov{w}\t{%1, %0|%0, %1}";
2306 (cond [(match_test "optimize_function_for_size_p (cfun)")
2307 (const_string "imov")
2308 (and (eq_attr "alternative" "0")
2309 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2310 (not (match_test "TARGET_HIMODE_MATH"))))
2311 (const_string "imov")
2312 (and (eq_attr "alternative" "1,2")
2313 (match_operand:HI 1 "aligned_operand"))
2314 (const_string "imov")
2315 (eq_attr "alternative" "4,5,6")
2316 (const_string "mskmov")
2317 (and (match_test "TARGET_MOVX")
2318 (eq_attr "alternative" "0,2"))
2319 (const_string "imovx")
2321 (const_string "imov")))
2322 (set (attr "prefix")
2323 (if_then_else (eq_attr "alternative" "4,5,6")
2324 (const_string "vex")
2325 (const_string "orig")))
2327 (cond [(eq_attr "type" "imovx")
2329 (and (eq_attr "alternative" "1,2")
2330 (match_operand:HI 1 "aligned_operand"))
2332 (and (eq_attr "alternative" "0")
2333 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2334 (not (match_test "TARGET_HIMODE_MATH"))))
2337 (const_string "HI")))])
2339 ;; Situation is quite tricky about when to choose full sized (SImode) move
2340 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2341 ;; partial register dependency machines (such as AMD Athlon), where QImode
2342 ;; moves issue extra dependency and for partial register stalls machines
2343 ;; that don't use QImode patterns (and QImode move cause stall on the next
2346 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2347 ;; register stall machines with, where we use QImode instructions, since
2348 ;; partial register stall can be caused there. Then we use movzx.
2350 (define_insn "*movqi_internal"
2351 [(set (match_operand:QI 0 "nonimmediate_operand"
2352 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2353 (match_operand:QI 1 "general_operand"
2354 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2355 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2357 switch (get_attr_type (insn))
2360 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2361 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2364 switch (which_alternative)
2366 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2367 case 8: return "kmovw\t{%1, %0|%0, %1}";
2368 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2369 default: gcc_unreachable ();
2373 if (get_attr_mode (insn) == MODE_SI)
2374 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2376 return "mov{b}\t{%1, %0|%0, %1}";
2380 (cond [(and (eq_attr "alternative" "5")
2381 (not (match_operand:QI 1 "aligned_operand")))
2382 (const_string "imovx")
2383 (match_test "optimize_function_for_size_p (cfun)")
2384 (const_string "imov")
2385 (and (eq_attr "alternative" "3")
2386 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2387 (not (match_test "TARGET_QIMODE_MATH"))))
2388 (const_string "imov")
2389 (eq_attr "alternative" "3,5")
2390 (const_string "imovx")
2391 (eq_attr "alternative" "7,8,9")
2392 (const_string "mskmov")
2393 (and (match_test "TARGET_MOVX")
2394 (eq_attr "alternative" "2"))
2395 (const_string "imovx")
2397 (const_string "imov")))
2398 (set (attr "prefix")
2399 (if_then_else (eq_attr "alternative" "7,8,9")
2400 (const_string "vex")
2401 (const_string "orig")))
2403 (cond [(eq_attr "alternative" "3,4,5")
2405 (eq_attr "alternative" "6")
2407 (eq_attr "type" "imovx")
2409 (and (eq_attr "type" "imov")
2410 (and (eq_attr "alternative" "0,1")
2411 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2412 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2413 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2415 ;; Avoid partial register stalls when not using QImode arithmetic
2416 (and (eq_attr "type" "imov")
2417 (and (eq_attr "alternative" "0,1")
2418 (and (match_test "TARGET_PARTIAL_REG_STALL")
2419 (not (match_test "TARGET_QIMODE_MATH")))))
2422 (const_string "QI")))])
2424 ;; Stores and loads of ax to arbitrary constant address.
2425 ;; We fake an second form of instruction to force reload to load address
2426 ;; into register when rax is not available
2427 (define_insn "*movabs<mode>_1"
2428 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2429 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2430 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2432 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2433 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2434 [(set_attr "type" "imov")
2435 (set_attr "modrm" "0,*")
2436 (set_attr "length_address" "8,0")
2437 (set_attr "length_immediate" "0,*")
2438 (set_attr "memory" "store")
2439 (set_attr "mode" "<MODE>")])
2441 (define_insn "*movabs<mode>_2"
2442 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2443 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2444 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2446 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2447 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2448 [(set_attr "type" "imov")
2449 (set_attr "modrm" "0,*")
2450 (set_attr "length_address" "8,0")
2451 (set_attr "length_immediate" "0")
2452 (set_attr "memory" "load")
2453 (set_attr "mode" "<MODE>")])
2455 (define_insn "swap<mode>"
2456 [(set (match_operand:SWI48 0 "register_operand" "+r")
2457 (match_operand:SWI48 1 "register_operand" "+r"))
2461 "xchg{<imodesuffix>}\t%1, %0"
2462 [(set_attr "type" "imov")
2463 (set_attr "mode" "<MODE>")
2464 (set_attr "pent_pair" "np")
2465 (set_attr "athlon_decode" "vector")
2466 (set_attr "amdfam10_decode" "double")
2467 (set_attr "bdver1_decode" "double")])
2469 (define_insn "*swap<mode>_1"
2470 [(set (match_operand:SWI12 0 "register_operand" "+r")
2471 (match_operand:SWI12 1 "register_operand" "+r"))
2474 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2476 [(set_attr "type" "imov")
2477 (set_attr "mode" "SI")
2478 (set_attr "pent_pair" "np")
2479 (set_attr "athlon_decode" "vector")
2480 (set_attr "amdfam10_decode" "double")
2481 (set_attr "bdver1_decode" "double")])
2483 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2484 ;; is disabled for AMDFAM10
2485 (define_insn "*swap<mode>_2"
2486 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2487 (match_operand:SWI12 1 "register_operand" "+<r>"))
2490 "TARGET_PARTIAL_REG_STALL"
2491 "xchg{<imodesuffix>}\t%1, %0"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "pent_pair" "np")
2495 (set_attr "athlon_decode" "vector")])
2497 (define_expand "movstrict<mode>"
2498 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2499 (match_operand:SWI12 1 "general_operand"))]
2502 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2504 if (GET_CODE (operands[0]) == SUBREG
2505 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2507 /* Don't generate memory->memory moves, go through a register */
2508 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2509 operands[1] = force_reg (<MODE>mode, operands[1]);
2512 (define_insn "*movstrict<mode>_1"
2513 [(set (strict_low_part
2514 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2515 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2516 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2517 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2518 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2519 [(set_attr "type" "imov")
2520 (set_attr "mode" "<MODE>")])
2522 (define_insn "*movstrict<mode>_xor"
2523 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2524 (match_operand:SWI12 1 "const0_operand"))
2525 (clobber (reg:CC FLAGS_REG))]
2527 "xor{<imodesuffix>}\t%0, %0"
2528 [(set_attr "type" "alu1")
2529 (set_attr "mode" "<MODE>")
2530 (set_attr "length_immediate" "0")])
2532 (define_insn "*mov<mode>_extv_1"
2533 [(set (match_operand:SWI24 0 "register_operand" "=R")
2534 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2538 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2539 [(set_attr "type" "imovx")
2540 (set_attr "mode" "SI")])
2542 (define_insn "*movqi_extv_1"
2543 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2544 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2549 switch (get_attr_type (insn))
2552 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2554 return "mov{b}\t{%h1, %0|%0, %h1}";
2557 [(set_attr "isa" "*,*,nox64")
2559 (if_then_else (and (match_operand:QI 0 "register_operand")
2560 (ior (not (match_operand:QI 0 "QIreg_operand"))
2561 (match_test "TARGET_MOVX")))
2562 (const_string "imovx")
2563 (const_string "imov")))
2565 (if_then_else (eq_attr "type" "imovx")
2567 (const_string "QI")))])
2569 (define_insn "*mov<mode>_extzv_1"
2570 [(set (match_operand:SWI48 0 "register_operand" "=R")
2571 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2575 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2576 [(set_attr "type" "imovx")
2577 (set_attr "mode" "SI")])
2579 (define_insn "*movqi_extzv_2"
2580 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2582 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2587 switch (get_attr_type (insn))
2590 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2592 return "mov{b}\t{%h1, %0|%0, %h1}";
2595 [(set_attr "isa" "*,*,nox64")
2597 (if_then_else (and (match_operand:QI 0 "register_operand")
2598 (ior (not (match_operand:QI 0 "QIreg_operand"))
2599 (match_test "TARGET_MOVX")))
2600 (const_string "imovx")
2601 (const_string "imov")))
2603 (if_then_else (eq_attr "type" "imovx")
2605 (const_string "QI")))])
2607 (define_insn "mov<mode>_insv_1"
2608 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2611 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2614 if (CONST_INT_P (operands[1]))
2615 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2616 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2618 [(set_attr "isa" "*,nox64")
2619 (set_attr "type" "imov")
2620 (set_attr "mode" "QI")])
2622 (define_insn "*movqi_insv_2"
2623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2626 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2629 "mov{b}\t{%h1, %h0|%h0, %h1}"
2630 [(set_attr "type" "imov")
2631 (set_attr "mode" "QI")])
2633 ;; Floating point push instructions.
2635 (define_insn "*pushtf"
2636 [(set (match_operand:TF 0 "push_operand" "=<,<")
2637 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2638 "TARGET_64BIT || TARGET_SSE"
2640 /* This insn should be already split before reg-stack. */
2643 [(set_attr "isa" "*,x64")
2644 (set_attr "type" "multi")
2645 (set_attr "unit" "sse,*")
2646 (set_attr "mode" "TF,DI")])
2648 ;; %%% Kill this when call knows how to work this out.
2650 [(set (match_operand:TF 0 "push_operand")
2651 (match_operand:TF 1 "sse_reg_operand"))]
2652 "TARGET_SSE && reload_completed"
2653 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2654 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2656 (define_insn "*pushxf"
2657 [(set (match_operand:XF 0 "push_operand" "=<,<")
2658 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2661 /* This insn should be already split before reg-stack. */
2664 [(set_attr "type" "multi")
2665 (set_attr "unit" "i387,*")
2667 (cond [(eq_attr "alternative" "1")
2668 (if_then_else (match_test "TARGET_64BIT")
2670 (const_string "SI"))
2672 (const_string "XF")))])
2674 ;; %%% Kill this when call knows how to work this out.
2676 [(set (match_operand:XF 0 "push_operand")
2677 (match_operand:XF 1 "fp_register_operand"))]
2679 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2680 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2681 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2683 (define_insn "*pushdf"
2684 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2685 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2688 /* This insn should be already split before reg-stack. */
2691 [(set_attr "isa" "*,nox64,x64,sse2")
2692 (set_attr "type" "multi")
2693 (set_attr "unit" "i387,*,*,sse")
2694 (set_attr "mode" "DF,SI,DI,DF")])
2696 ;; %%% Kill this when call knows how to work this out.
2698 [(set (match_operand:DF 0 "push_operand")
2699 (match_operand:DF 1 "any_fp_register_operand"))]
2701 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2702 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2704 (define_insn "*pushsf_rex64"
2705 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2706 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2709 /* Anything else should be already split before reg-stack. */
2710 gcc_assert (which_alternative == 1);
2711 return "push{q}\t%q1";
2713 [(set_attr "type" "multi,push,multi")
2714 (set_attr "unit" "i387,*,*")
2715 (set_attr "mode" "SF,DI,SF")])
2717 (define_insn "*pushsf"
2718 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2719 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2722 /* Anything else should be already split before reg-stack. */
2723 gcc_assert (which_alternative == 1);
2724 return "push{l}\t%1";
2726 [(set_attr "type" "multi,push,multi")
2727 (set_attr "unit" "i387,*,*")
2728 (set_attr "mode" "SF,SI,SF")])
2730 ;; %%% Kill this when call knows how to work this out.
2732 [(set (match_operand:SF 0 "push_operand")
2733 (match_operand:SF 1 "any_fp_register_operand"))]
2735 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2736 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2737 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2740 [(set (match_operand:SF 0 "push_operand")
2741 (match_operand:SF 1 "memory_operand"))]
2743 && (operands[2] = find_constant_src (insn))"
2744 [(set (match_dup 0) (match_dup 2))])
2747 [(set (match_operand 0 "push_operand")
2748 (match_operand 1 "general_operand"))]
2750 && (GET_MODE (operands[0]) == TFmode
2751 || GET_MODE (operands[0]) == XFmode
2752 || GET_MODE (operands[0]) == DFmode)
2753 && !ANY_FP_REG_P (operands[1])"
2755 "ix86_split_long_move (operands); DONE;")
2757 ;; Floating point move instructions.
2759 (define_expand "movtf"
2760 [(set (match_operand:TF 0 "nonimmediate_operand")
2761 (match_operand:TF 1 "nonimmediate_operand"))]
2762 "TARGET_64BIT || TARGET_SSE"
2763 "ix86_expand_move (TFmode, operands); DONE;")
2765 (define_expand "mov<mode>"
2766 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2767 (match_operand:X87MODEF 1 "general_operand"))]
2769 "ix86_expand_move (<MODE>mode, operands); DONE;")
2771 (define_insn "*movtf_internal"
2772 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2773 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2774 "(TARGET_64BIT || TARGET_SSE)
2775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2776 && (!can_create_pseudo_p ()
2777 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2778 || GET_CODE (operands[1]) != CONST_DOUBLE
2779 || (optimize_function_for_size_p (cfun)
2780 && standard_sse_constant_p (operands[1])
2781 && !memory_operand (operands[0], TFmode))
2782 || (!TARGET_MEMORY_MISMATCH_STALL
2783 && memory_operand (operands[0], TFmode)))"
2785 switch (get_attr_type (insn))
2788 return standard_sse_constant_opcode (insn, operands[1]);
2791 /* Handle misaligned load/store since we
2792 don't have movmisaligntf pattern. */
2793 if (misaligned_operand (operands[0], TFmode)
2794 || misaligned_operand (operands[1], TFmode))
2796 if (get_attr_mode (insn) == MODE_V4SF)
2797 return "%vmovups\t{%1, %0|%0, %1}";
2799 return "%vmovdqu\t{%1, %0|%0, %1}";
2803 if (get_attr_mode (insn) == MODE_V4SF)
2804 return "%vmovaps\t{%1, %0|%0, %1}";
2806 return "%vmovdqa\t{%1, %0|%0, %1}";
2816 [(set_attr "isa" "*,*,*,x64,x64")
2817 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2818 (set (attr "prefix")
2819 (if_then_else (eq_attr "type" "sselog1,ssemov")
2820 (const_string "maybe_vex")
2821 (const_string "orig")))
2823 (cond [(eq_attr "alternative" "3,4")
2825 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2826 (const_string "V4SF")
2827 (and (eq_attr "alternative" "2")
2828 (match_test "TARGET_SSE_TYPELESS_STORES"))
2829 (const_string "V4SF")
2830 (match_test "TARGET_AVX")
2832 (ior (not (match_test "TARGET_SSE2"))
2833 (match_test "optimize_function_for_size_p (cfun)"))
2834 (const_string "V4SF")
2836 (const_string "TI")))])
2838 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2839 (define_insn "*movxf_internal"
2840 [(set (match_operand:XF 0 "nonimmediate_operand"
2841 "=f,m,f,?Yx*r ,!o ,!o")
2842 (match_operand:XF 1 "general_operand"
2843 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2844 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2845 && (!can_create_pseudo_p ()
2846 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2847 || GET_CODE (operands[1]) != CONST_DOUBLE
2848 || (optimize_function_for_size_p (cfun)
2849 && standard_80387_constant_p (operands[1]) > 0
2850 && !memory_operand (operands[0], XFmode))
2851 || (!TARGET_MEMORY_MISMATCH_STALL
2852 && memory_operand (operands[0], XFmode)))"
2854 switch (get_attr_type (insn))
2857 if (which_alternative == 2)
2858 return standard_80387_constant_opcode (operands[1]);
2859 return output_387_reg_move (insn, operands);
2868 [(set_attr "isa" "*,*,*,*,nox64,x64")
2869 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2871 (cond [(eq_attr "alternative" "3,4,5")
2872 (if_then_else (match_test "TARGET_64BIT")
2874 (const_string "SI"))
2876 (const_string "XF")))])
2878 ;; Possible store forwarding (partial memory) stall in alternative 4.
2879 (define_insn "*movdf_internal"
2880 [(set (match_operand:DF 0 "nonimmediate_operand"
2881 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2882 (match_operand:DF 1 "general_operand"
2883 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2884 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && (!can_create_pseudo_p ()
2886 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2887 || GET_CODE (operands[1]) != CONST_DOUBLE
2888 || (optimize_function_for_size_p (cfun)
2889 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2890 && standard_80387_constant_p (operands[1]) > 0)
2891 || (TARGET_SSE2 && TARGET_SSE_MATH
2892 && standard_sse_constant_p (operands[1])))
2893 && !memory_operand (operands[0], DFmode))
2894 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2895 && memory_operand (operands[0], DFmode)))"
2897 switch (get_attr_type (insn))
2900 if (which_alternative == 2)
2901 return standard_80387_constant_opcode (operands[1]);
2902 return output_387_reg_move (insn, operands);
2908 if (get_attr_mode (insn) == MODE_SI)
2909 return "mov{l}\t{%1, %k0|%k0, %1}";
2910 else if (which_alternative == 8)
2911 return "movabs{q}\t{%1, %0|%0, %1}";
2913 return "mov{q}\t{%1, %0|%0, %1}";
2916 return standard_sse_constant_opcode (insn, operands[1]);
2919 switch (get_attr_mode (insn))
2922 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2923 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2924 return "%vmovsd\t{%1, %0|%0, %1}";
2927 return "%vmovaps\t{%1, %0|%0, %1}";
2929 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2931 return "%vmovapd\t{%1, %0|%0, %1}";
2934 gcc_assert (!TARGET_AVX);
2935 return "movlps\t{%1, %0|%0, %1}";
2937 gcc_assert (!TARGET_AVX);
2938 return "movlpd\t{%1, %0|%0, %1}";
2941 /* Handle broken assemblers that require movd instead of movq. */
2942 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2943 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2944 return "%vmovd\t{%1, %0|%0, %1}";
2945 return "%vmovq\t{%1, %0|%0, %1}";
2956 (cond [(eq_attr "alternative" "3,4")
2957 (const_string "nox64")
2958 (eq_attr "alternative" "5,6,7,8,17,18")
2959 (const_string "x64")
2960 (eq_attr "alternative" "9,10,11,12")
2961 (const_string "sse2")
2963 (const_string "*")))
2965 (cond [(eq_attr "alternative" "0,1,2")
2966 (const_string "fmov")
2967 (eq_attr "alternative" "3,4")
2968 (const_string "multi")
2969 (eq_attr "alternative" "5,6,7,8")
2970 (const_string "imov")
2971 (eq_attr "alternative" "9,13")
2972 (const_string "sselog1")
2974 (const_string "ssemov")))
2976 (if_then_else (eq_attr "alternative" "8")
2978 (const_string "*")))
2979 (set (attr "length_immediate")
2980 (if_then_else (eq_attr "alternative" "8")
2982 (const_string "*")))
2983 (set (attr "prefix")
2984 (if_then_else (eq_attr "type" "sselog1,ssemov")
2985 (const_string "maybe_vex")
2986 (const_string "orig")))
2987 (set (attr "prefix_data16")
2989 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2990 (eq_attr "mode" "V1DF"))
2992 (const_string "*")))
2994 (cond [(eq_attr "alternative" "3,4,7")
2996 (eq_attr "alternative" "5,6,8,17,18")
2999 /* xorps is one byte shorter for non-AVX targets. */
3000 (eq_attr "alternative" "9,13")
3001 (cond [(not (match_test "TARGET_SSE2"))
3002 (const_string "V4SF")
3003 (match_test "TARGET_AVX512F")
3005 (match_test "TARGET_AVX")
3006 (const_string "V2DF")
3007 (match_test "optimize_function_for_size_p (cfun)")
3008 (const_string "V4SF")
3009 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3012 (const_string "V2DF"))
3014 /* For architectures resolving dependencies on
3015 whole SSE registers use movapd to break dependency
3016 chains, otherwise use short move to avoid extra work. */
3018 /* movaps is one byte shorter for non-AVX targets. */
3019 (eq_attr "alternative" "10,14")
3020 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3021 (match_operand 1 "ext_sse_reg_operand"))
3022 (const_string "V8DF")
3023 (ior (not (match_test "TARGET_SSE2"))
3024 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3025 (const_string "V4SF")
3026 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3027 (const_string "V2DF")
3028 (match_test "TARGET_AVX")
3030 (match_test "optimize_function_for_size_p (cfun)")
3031 (const_string "V4SF")
3033 (const_string "DF"))
3035 /* For architectures resolving dependencies on register
3036 parts we may avoid extra work to zero out upper part
3038 (eq_attr "alternative" "11,15")
3039 (cond [(not (match_test "TARGET_SSE2"))
3040 (const_string "V2SF")
3041 (match_test "TARGET_AVX")
3043 (match_test "TARGET_SSE_SPLIT_REGS")
3044 (const_string "V1DF")
3046 (const_string "DF"))
3048 (and (eq_attr "alternative" "12,16")
3049 (not (match_test "TARGET_SSE2")))
3050 (const_string "V2SF")
3052 (const_string "DF")))])
3054 (define_insn "*movsf_internal"
3055 [(set (match_operand:SF 0 "nonimmediate_operand"
3056 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3057 (match_operand:SF 1 "general_operand"
3058 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3059 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3060 && (!can_create_pseudo_p ()
3061 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3062 || GET_CODE (operands[1]) != CONST_DOUBLE
3063 || (optimize_function_for_size_p (cfun)
3064 && ((!TARGET_SSE_MATH
3065 && standard_80387_constant_p (operands[1]) > 0)
3067 && standard_sse_constant_p (operands[1]))))
3068 || memory_operand (operands[0], SFmode))"
3070 switch (get_attr_type (insn))
3073 if (which_alternative == 2)
3074 return standard_80387_constant_opcode (operands[1]);
3075 return output_387_reg_move (insn, operands);
3078 return "mov{l}\t{%1, %0|%0, %1}";
3081 return standard_sse_constant_opcode (insn, operands[1]);
3084 switch (get_attr_mode (insn))
3087 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3088 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3089 return "%vmovss\t{%1, %0|%0, %1}";
3092 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3094 return "%vmovaps\t{%1, %0|%0, %1}";
3097 return "%vmovd\t{%1, %0|%0, %1}";
3104 switch (get_attr_mode (insn))
3107 return "movq\t{%1, %0|%0, %1}";
3109 return "movd\t{%1, %0|%0, %1}";
3120 (cond [(eq_attr "alternative" "0,1,2")
3121 (const_string "fmov")
3122 (eq_attr "alternative" "3,4")
3123 (const_string "imov")
3124 (eq_attr "alternative" "5")
3125 (const_string "sselog1")
3126 (eq_attr "alternative" "11,12,13,14,15")
3127 (const_string "mmxmov")
3129 (const_string "ssemov")))
3130 (set (attr "prefix")
3131 (if_then_else (eq_attr "type" "sselog1,ssemov")
3132 (const_string "maybe_vex")
3133 (const_string "orig")))
3134 (set (attr "prefix_data16")
3135 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3137 (const_string "*")))
3139 (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
3141 (eq_attr "alternative" "11")
3143 (eq_attr "alternative" "5")
3144 (cond [(not (match_test "TARGET_SSE2"))
3145 (const_string "V4SF")
3146 (match_test "TARGET_AVX512F")
3147 (const_string "V16SF")
3148 (match_test "TARGET_AVX")
3149 (const_string "V4SF")
3150 (match_test "optimize_function_for_size_p (cfun)")
3151 (const_string "V4SF")
3152 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3155 (const_string "V4SF"))
3157 /* For architectures resolving dependencies on
3158 whole SSE registers use APS move to break dependency
3159 chains, otherwise use short move to avoid extra work.
3161 Do the same for architectures resolving dependencies on
3162 the parts. While in DF mode it is better to always handle
3163 just register parts, the SF mode is different due to lack
3164 of instructions to load just part of the register. It is
3165 better to maintain the whole registers in single format
3166 to avoid problems on using packed logical operations. */
3167 (eq_attr "alternative" "6")
3168 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3169 (match_operand 1 "ext_sse_reg_operand"))
3170 (const_string "V16SF")
3171 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3172 (match_test "TARGET_SSE_SPLIT_REGS"))
3173 (const_string "V4SF")
3175 (const_string "SF"))
3177 (const_string "SF")))])
3180 [(set (match_operand 0 "any_fp_register_operand")
3181 (match_operand 1 "memory_operand"))]
3183 && (GET_MODE (operands[0]) == TFmode
3184 || GET_MODE (operands[0]) == XFmode
3185 || GET_MODE (operands[0]) == DFmode
3186 || GET_MODE (operands[0]) == SFmode)
3187 && (operands[2] = find_constant_src (insn))"
3188 [(set (match_dup 0) (match_dup 2))]
3190 rtx c = operands[2];
3191 int r = REGNO (operands[0]);
3193 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3194 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3199 [(set (match_operand 0 "any_fp_register_operand")
3200 (float_extend (match_operand 1 "memory_operand")))]
3202 && (GET_MODE (operands[0]) == TFmode
3203 || GET_MODE (operands[0]) == XFmode
3204 || GET_MODE (operands[0]) == DFmode)
3205 && (operands[2] = find_constant_src (insn))"
3206 [(set (match_dup 0) (match_dup 2))]
3208 rtx c = operands[2];
3209 int r = REGNO (operands[0]);
3211 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3212 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3216 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3218 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3219 (match_operand:X87MODEF 1 "immediate_operand"))]
3221 && (standard_80387_constant_p (operands[1]) == 8
3222 || standard_80387_constant_p (operands[1]) == 9)"
3223 [(set (match_dup 0)(match_dup 1))
3225 (neg:X87MODEF (match_dup 0)))]
3229 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3230 if (real_isnegzero (&r))
3231 operands[1] = CONST0_RTX (<MODE>mode);
3233 operands[1] = CONST1_RTX (<MODE>mode);
3237 [(set (match_operand 0 "nonimmediate_operand")
3238 (match_operand 1 "general_operand"))]
3240 && (GET_MODE (operands[0]) == TFmode
3241 || GET_MODE (operands[0]) == XFmode
3242 || GET_MODE (operands[0]) == DFmode)
3243 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3245 "ix86_split_long_move (operands); DONE;")
3247 (define_insn "swapxf"
3248 [(set (match_operand:XF 0 "register_operand" "+f")
3249 (match_operand:XF 1 "register_operand" "+f"))
3254 if (STACK_TOP_P (operands[0]))
3259 [(set_attr "type" "fxch")
3260 (set_attr "mode" "XF")])
3262 (define_insn "*swap<mode>"
3263 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3264 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3267 "TARGET_80387 || reload_completed"
3269 if (STACK_TOP_P (operands[0]))
3274 [(set_attr "type" "fxch")
3275 (set_attr "mode" "<MODE>")])
3277 ;; Zero extension instructions
3279 (define_expand "zero_extendsidi2"
3280 [(set (match_operand:DI 0 "nonimmediate_operand")
3281 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3283 (define_insn "*zero_extendsidi2"
3284 [(set (match_operand:DI 0 "nonimmediate_operand"
3285 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3287 (match_operand:SI 1 "x86_64_zext_operand"
3288 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3291 switch (get_attr_type (insn))
3294 if (ix86_use_lea_for_mov (insn, operands))
3295 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3297 return "mov{l}\t{%1, %k0|%k0, %1}";
3303 return "movd\t{%1, %0|%0, %1}";
3306 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3309 if (GENERAL_REG_P (operands[0]))
3310 return "%vmovd\t{%1, %k0|%k0, %1}";
3312 return "%vmovd\t{%1, %0|%0, %1}";
3319 (cond [(eq_attr "alternative" "0,1,2")
3320 (const_string "nox64")
3321 (eq_attr "alternative" "3,7")
3322 (const_string "x64")
3323 (eq_attr "alternative" "8")
3324 (const_string "x64_sse4")
3325 (eq_attr "alternative" "10")
3326 (const_string "sse2")
3328 (const_string "*")))
3330 (cond [(eq_attr "alternative" "0,1,2,4")
3331 (const_string "multi")
3332 (eq_attr "alternative" "5,6")
3333 (const_string "mmxmov")
3334 (eq_attr "alternative" "7,9,10")
3335 (const_string "ssemov")
3336 (eq_attr "alternative" "8")
3337 (const_string "sselog1")
3339 (const_string "imovx")))
3340 (set (attr "prefix_extra")
3341 (if_then_else (eq_attr "alternative" "8")
3343 (const_string "*")))
3344 (set (attr "length_immediate")
3345 (if_then_else (eq_attr "alternative" "8")
3347 (const_string "*")))
3348 (set (attr "prefix")
3349 (if_then_else (eq_attr "type" "ssemov,sselog1")
3350 (const_string "maybe_vex")
3351 (const_string "orig")))
3352 (set (attr "prefix_0f")
3353 (if_then_else (eq_attr "type" "imovx")
3355 (const_string "*")))
3357 (cond [(eq_attr "alternative" "5,6")
3359 (eq_attr "alternative" "7,8,9")
3362 (const_string "SI")))])
3365 [(set (match_operand:DI 0 "memory_operand")
3366 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3368 [(set (match_dup 4) (const_int 0))]
3369 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3372 [(set (match_operand:DI 0 "register_operand")
3373 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3374 "!TARGET_64BIT && reload_completed
3375 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3376 && true_regnum (operands[0]) == true_regnum (operands[1])"
3377 [(set (match_dup 4) (const_int 0))]
3378 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3381 [(set (match_operand:DI 0 "nonimmediate_operand")
3382 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3383 "!TARGET_64BIT && reload_completed
3384 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3385 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3386 [(set (match_dup 3) (match_dup 1))
3387 (set (match_dup 4) (const_int 0))]
3388 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3390 (define_insn "zero_extend<mode>di2"
3391 [(set (match_operand:DI 0 "register_operand" "=r")
3393 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3395 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "SI")])
3399 (define_expand "zero_extend<mode>si2"
3400 [(set (match_operand:SI 0 "register_operand")
3401 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3404 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3406 operands[1] = force_reg (<MODE>mode, operands[1]);
3407 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3412 (define_insn_and_split "zero_extend<mode>si2_and"
3413 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3415 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3416 (clobber (reg:CC FLAGS_REG))]
3417 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3419 "&& reload_completed"
3420 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3421 (clobber (reg:CC FLAGS_REG))])]
3423 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3425 ix86_expand_clear (operands[0]);
3427 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3428 emit_insn (gen_movstrict<mode>
3429 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3433 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3435 [(set_attr "type" "alu1")
3436 (set_attr "mode" "SI")])
3438 (define_insn "*zero_extend<mode>si2"
3439 [(set (match_operand:SI 0 "register_operand" "=r")
3441 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3442 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3443 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3444 [(set_attr "type" "imovx")
3445 (set_attr "mode" "SI")])
3447 (define_expand "zero_extendqihi2"
3448 [(set (match_operand:HI 0 "register_operand")
3449 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3452 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3454 operands[1] = force_reg (QImode, operands[1]);
3455 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3460 (define_insn_and_split "zero_extendqihi2_and"
3461 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3462 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3463 (clobber (reg:CC FLAGS_REG))]
3464 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3466 "&& reload_completed"
3467 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3468 (clobber (reg:CC FLAGS_REG))])]
3470 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3472 ix86_expand_clear (operands[0]);
3474 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3475 emit_insn (gen_movstrictqi
3476 (gen_lowpart (QImode, operands[0]), operands[1]));
3480 operands[0] = gen_lowpart (SImode, operands[0]);
3482 [(set_attr "type" "alu1")
3483 (set_attr "mode" "SI")])
3485 ; zero extend to SImode to avoid partial register stalls
3486 (define_insn "*zero_extendqihi2"
3487 [(set (match_operand:HI 0 "register_operand" "=r")
3488 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3489 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3490 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3491 [(set_attr "type" "imovx")
3492 (set_attr "mode" "SI")])
3494 ;; Sign extension instructions
3496 (define_expand "extendsidi2"
3497 [(set (match_operand:DI 0 "register_operand")
3498 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3503 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3508 (define_insn "*extendsidi2_rex64"
3509 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3510 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3514 movs{lq|x}\t{%1, %0|%0, %1}"
3515 [(set_attr "type" "imovx")
3516 (set_attr "mode" "DI")
3517 (set_attr "prefix_0f" "0")
3518 (set_attr "modrm" "0,1")])
3520 (define_insn "extendsidi2_1"
3521 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3522 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3523 (clobber (reg:CC FLAGS_REG))
3524 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3528 ;; Split the memory case. If the source register doesn't die, it will stay
3529 ;; this way, if it does die, following peephole2s take care of it.
3531 [(set (match_operand:DI 0 "memory_operand")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand"))]
3538 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3540 emit_move_insn (operands[3], operands[1]);
3542 /* Generate a cltd if possible and doing so it profitable. */
3543 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3544 && true_regnum (operands[1]) == AX_REG
3545 && true_regnum (operands[2]) == DX_REG)
3547 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3551 emit_move_insn (operands[2], operands[1]);
3552 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3554 emit_move_insn (operands[4], operands[2]);
3558 ;; Peepholes for the case where the source register does die, after
3559 ;; being split with the above splitter.
3561 [(set (match_operand:SI 0 "memory_operand")
3562 (match_operand:SI 1 "register_operand"))
3563 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3564 (parallel [(set (match_dup 2)
3565 (ashiftrt:SI (match_dup 2) (const_int 31)))
3566 (clobber (reg:CC FLAGS_REG))])
3567 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3568 "REGNO (operands[1]) != REGNO (operands[2])
3569 && peep2_reg_dead_p (2, operands[1])
3570 && peep2_reg_dead_p (4, operands[2])
3571 && !reg_mentioned_p (operands[2], operands[3])"
3572 [(set (match_dup 0) (match_dup 1))
3573 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3574 (clobber (reg:CC FLAGS_REG))])
3575 (set (match_dup 3) (match_dup 1))])
3578 [(set (match_operand:SI 0 "memory_operand")
3579 (match_operand:SI 1 "register_operand"))
3580 (parallel [(set (match_operand:SI 2 "register_operand")
3581 (ashiftrt:SI (match_dup 1) (const_int 31)))
3582 (clobber (reg:CC FLAGS_REG))])
3583 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3584 "/* cltd is shorter than sarl $31, %eax */
3585 !optimize_function_for_size_p (cfun)
3586 && true_regnum (operands[1]) == AX_REG
3587 && true_regnum (operands[2]) == DX_REG
3588 && peep2_reg_dead_p (2, operands[1])
3589 && peep2_reg_dead_p (3, operands[2])
3590 && !reg_mentioned_p (operands[2], operands[3])"
3591 [(set (match_dup 0) (match_dup 1))
3592 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3593 (clobber (reg:CC FLAGS_REG))])
3594 (set (match_dup 3) (match_dup 1))])
3596 ;; Extend to register case. Optimize case where source and destination
3597 ;; registers match and cases where we can use cltd.
3599 [(set (match_operand:DI 0 "register_operand")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_scratch:SI 2))]
3606 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3608 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3609 emit_move_insn (operands[3], operands[1]);
3611 /* Generate a cltd if possible and doing so it profitable. */
3612 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3613 && true_regnum (operands[3]) == AX_REG
3614 && true_regnum (operands[4]) == DX_REG)
3616 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3620 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3621 emit_move_insn (operands[4], operands[1]);
3623 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3627 (define_insn "extend<mode>di2"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3630 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3632 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "DI")])
3636 (define_insn "extendhisi2"
3637 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3638 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3641 switch (get_attr_prefix_0f (insn))
3644 return "{cwtl|cwde}";
3646 return "movs{wl|x}\t{%1, %0|%0, %1}";
3649 [(set_attr "type" "imovx")
3650 (set_attr "mode" "SI")
3651 (set (attr "prefix_0f")
3652 ;; movsx is short decodable while cwtl is vector decoded.
3653 (if_then_else (and (eq_attr "cpu" "!k6")
3654 (eq_attr "alternative" "0"))
3656 (const_string "1")))
3658 (if_then_else (eq_attr "prefix_0f" "0")
3660 (const_string "1")))])
3662 (define_insn "*extendhisi2_zext"
3663 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3669 switch (get_attr_prefix_0f (insn))
3672 return "{cwtl|cwde}";
3674 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3677 [(set_attr "type" "imovx")
3678 (set_attr "mode" "SI")
3679 (set (attr "prefix_0f")
3680 ;; movsx is short decodable while cwtl is vector decoded.
3681 (if_then_else (and (eq_attr "cpu" "!k6")
3682 (eq_attr "alternative" "0"))
3684 (const_string "1")))
3686 (if_then_else (eq_attr "prefix_0f" "0")
3688 (const_string "1")))])
3690 (define_insn "extendqisi2"
3691 [(set (match_operand:SI 0 "register_operand" "=r")
3692 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3694 "movs{bl|x}\t{%1, %0|%0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")])
3698 (define_insn "*extendqisi2_zext"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3701 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3703 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3704 [(set_attr "type" "imovx")
3705 (set_attr "mode" "SI")])
3707 (define_insn "extendqihi2"
3708 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3709 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3712 switch (get_attr_prefix_0f (insn))
3715 return "{cbtw|cbw}";
3717 return "movs{bw|x}\t{%1, %0|%0, %1}";
3720 [(set_attr "type" "imovx")
3721 (set_attr "mode" "HI")
3722 (set (attr "prefix_0f")
3723 ;; movsx is short decodable while cwtl is vector decoded.
3724 (if_then_else (and (eq_attr "cpu" "!k6")
3725 (eq_attr "alternative" "0"))
3727 (const_string "1")))
3729 (if_then_else (eq_attr "prefix_0f" "0")
3731 (const_string "1")))])
3733 ;; Conversions between float and double.
3735 ;; These are all no-ops in the model used for the 80387.
3736 ;; So just emit moves.
3738 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3740 [(set (match_operand:DF 0 "push_operand")
3741 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3744 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3747 [(set (match_operand:XF 0 "push_operand")
3748 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3750 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3751 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3752 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3754 (define_expand "extendsfdf2"
3755 [(set (match_operand:DF 0 "nonimmediate_operand")
3756 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3759 /* ??? Needed for compress_float_constant since all fp constants
3760 are TARGET_LEGITIMATE_CONSTANT_P. */
3761 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3763 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3764 && standard_80387_constant_p (operands[1]) > 0)
3766 operands[1] = simplify_const_unary_operation
3767 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3768 emit_move_insn_1 (operands[0], operands[1]);
3771 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3775 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3777 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3779 We do the conversion post reload to avoid producing of 128bit spills
3780 that might lead to ICE on 32bit target. The sequence unlikely combine
3783 [(set (match_operand:DF 0 "register_operand")
3785 (match_operand:SF 1 "nonimmediate_operand")))]
3786 "TARGET_USE_VECTOR_FP_CONVERTS
3787 && optimize_insn_for_speed_p ()
3788 && reload_completed && SSE_REG_P (operands[0])"
3793 (parallel [(const_int 0) (const_int 1)]))))]
3795 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3796 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3797 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3798 Try to avoid move when unpacking can be done in source. */
3799 if (REG_P (operands[1]))
3801 /* If it is unsafe to overwrite upper half of source, we need
3802 to move to destination and unpack there. */
3803 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3804 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3805 && true_regnum (operands[0]) != true_regnum (operands[1]))
3807 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3808 emit_move_insn (tmp, operands[1]);
3811 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3812 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3816 emit_insn (gen_vec_setv4sf_0 (operands[3],
3817 CONST0_RTX (V4SFmode), operands[1]));
3820 ;; It's more profitable to split and then extend in the same register.
3822 [(set (match_operand:DF 0 "register_operand")
3824 (match_operand:SF 1 "memory_operand")))]
3825 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3826 && optimize_insn_for_speed_p ()
3827 && SSE_REG_P (operands[0])"
3828 [(set (match_dup 2) (match_dup 1))
3829 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3830 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3832 (define_insn "*extendsfdf2_mixed"
3833 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3835 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3836 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3838 switch (which_alternative)
3842 return output_387_reg_move (insn, operands);
3845 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3851 [(set_attr "type" "fmov,fmov,ssecvt")
3852 (set_attr "prefix" "orig,orig,maybe_vex")
3853 (set_attr "mode" "SF,XF,DF")])
3855 (define_insn "*extendsfdf2_sse"
3856 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3857 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3858 "TARGET_SSE2 && TARGET_SSE_MATH"
3859 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3860 [(set_attr "type" "ssecvt")
3861 (set_attr "prefix" "maybe_vex")
3862 (set_attr "mode" "DF")])
3864 (define_insn "*extendsfdf2_i387"
3865 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3866 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3868 "* return output_387_reg_move (insn, operands);"
3869 [(set_attr "type" "fmov")
3870 (set_attr "mode" "SF,XF")])
3872 (define_expand "extend<mode>xf2"
3873 [(set (match_operand:XF 0 "nonimmediate_operand")
3874 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3877 /* ??? Needed for compress_float_constant since all fp constants
3878 are TARGET_LEGITIMATE_CONSTANT_P. */
3879 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3881 if (standard_80387_constant_p (operands[1]) > 0)
3883 operands[1] = simplify_const_unary_operation
3884 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3885 emit_move_insn_1 (operands[0], operands[1]);
3888 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3892 (define_insn "*extend<mode>xf2_i387"
3893 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3895 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3897 "* return output_387_reg_move (insn, operands);"
3898 [(set_attr "type" "fmov")
3899 (set_attr "mode" "<MODE>,XF")])
3901 ;; %%% This seems bad bad news.
3902 ;; This cannot output into an f-reg because there is no way to be sure
3903 ;; of truncating in that case. Otherwise this is just like a simple move
3904 ;; insn. So we pretend we can output to a reg in order to get better
3905 ;; register preferencing, but we really use a stack slot.
3907 ;; Conversion from DFmode to SFmode.
3909 (define_expand "truncdfsf2"
3910 [(set (match_operand:SF 0 "nonimmediate_operand")
3912 (match_operand:DF 1 "nonimmediate_operand")))]
3913 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3915 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3917 else if (flag_unsafe_math_optimizations)
3921 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3922 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3927 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3929 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3931 We do the conversion post reload to avoid producing of 128bit spills
3932 that might lead to ICE on 32bit target. The sequence unlikely combine
3935 [(set (match_operand:SF 0 "register_operand")
3937 (match_operand:DF 1 "nonimmediate_operand")))]
3938 "TARGET_USE_VECTOR_FP_CONVERTS
3939 && optimize_insn_for_speed_p ()
3940 && reload_completed && SSE_REG_P (operands[0])"
3943 (float_truncate:V2SF
3947 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3948 operands[3] = CONST0_RTX (V2SFmode);
3949 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3950 /* Use movsd for loading from memory, unpcklpd for registers.
3951 Try to avoid move when unpacking can be done in source, or SSE3
3952 movddup is available. */
3953 if (REG_P (operands[1]))
3956 && true_regnum (operands[0]) != true_regnum (operands[1])
3957 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3958 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3960 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3961 emit_move_insn (tmp, operands[1]);
3964 else if (!TARGET_SSE3)
3965 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3966 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3969 emit_insn (gen_sse2_loadlpd (operands[4],
3970 CONST0_RTX (V2DFmode), operands[1]));
3973 ;; It's more profitable to split and then extend in the same register.
3975 [(set (match_operand:SF 0 "register_operand")
3977 (match_operand:DF 1 "memory_operand")))]
3978 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3979 && optimize_insn_for_speed_p ()
3980 && SSE_REG_P (operands[0])"
3981 [(set (match_dup 2) (match_dup 1))
3982 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3983 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3985 (define_expand "truncdfsf2_with_temp"
3986 [(parallel [(set (match_operand:SF 0)
3987 (float_truncate:SF (match_operand:DF 1)))
3988 (clobber (match_operand:SF 2))])])
3990 (define_insn "*truncdfsf_fast_mixed"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3993 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3994 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3996 switch (which_alternative)
3999 return output_387_reg_move (insn, operands);
4001 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4006 [(set_attr "type" "fmov,ssecvt")
4007 (set_attr "prefix" "orig,maybe_vex")
4008 (set_attr "mode" "SF")])
4010 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4011 ;; because nothing we do here is unsafe.
4012 (define_insn "*truncdfsf_fast_sse"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4015 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4016 "TARGET_SSE2 && TARGET_SSE_MATH"
4017 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4018 [(set_attr "type" "ssecvt")
4019 (set_attr "prefix" "maybe_vex")
4020 (set_attr "mode" "SF")])
4022 (define_insn "*truncdfsf_fast_i387"
4023 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4025 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4026 "TARGET_80387 && flag_unsafe_math_optimizations"
4027 "* return output_387_reg_move (insn, operands);"
4028 [(set_attr "type" "fmov")
4029 (set_attr "mode" "SF")])
4031 (define_insn "*truncdfsf_mixed"
4032 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4034 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4035 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4036 "TARGET_MIX_SSE_I387"
4038 switch (which_alternative)
4041 return output_387_reg_move (insn, operands);
4043 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4049 [(set_attr "isa" "*,sse2,*,*,*")
4050 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4051 (set_attr "unit" "*,*,i387,i387,i387")
4052 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4053 (set_attr "mode" "SF")])
4055 (define_insn "*truncdfsf_i387"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4062 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4071 [(set_attr "type" "fmov,multi,multi,multi")
4072 (set_attr "unit" "*,i387,i387,i387")
4073 (set_attr "mode" "SF")])
4075 (define_insn "*truncdfsf2_i387_1"
4076 [(set (match_operand:SF 0 "memory_operand" "=m")
4078 (match_operand:DF 1 "register_operand" "f")))]
4080 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4081 && !TARGET_MIX_SSE_I387"
4082 "* return output_387_reg_move (insn, operands);"
4083 [(set_attr "type" "fmov")
4084 (set_attr "mode" "SF")])
4087 [(set (match_operand:SF 0 "register_operand")
4089 (match_operand:DF 1 "fp_register_operand")))
4090 (clobber (match_operand 2))]
4092 [(set (match_dup 2) (match_dup 1))
4093 (set (match_dup 0) (match_dup 2))]
4094 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4096 ;; Conversion from XFmode to {SF,DF}mode
4098 (define_expand "truncxf<mode>2"
4099 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4100 (float_truncate:MODEF
4101 (match_operand:XF 1 "register_operand")))
4102 (clobber (match_dup 2))])]
4105 if (flag_unsafe_math_optimizations)
4107 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4108 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4109 if (reg != operands[0])
4110 emit_move_insn (operands[0], reg);
4114 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4117 (define_insn "*truncxfsf2_mixed"
4118 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4120 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4121 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4124 gcc_assert (!which_alternative);
4125 return output_387_reg_move (insn, operands);
4127 [(set_attr "type" "fmov,multi,multi,multi")
4128 (set_attr "unit" "*,i387,i387,i387")
4129 (set_attr "mode" "SF")])
4131 (define_insn "*truncxfdf2_mixed"
4132 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4134 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4135 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4138 gcc_assert (!which_alternative);
4139 return output_387_reg_move (insn, operands);
4141 [(set_attr "isa" "*,*,sse2,*")
4142 (set_attr "type" "fmov,multi,multi,multi")
4143 (set_attr "unit" "*,i387,i387,i387")
4144 (set_attr "mode" "DF")])
4146 (define_insn "truncxf<mode>2_i387_noop"
4147 [(set (match_operand:MODEF 0 "register_operand" "=f")
4148 (float_truncate:MODEF
4149 (match_operand:XF 1 "register_operand" "f")))]
4150 "TARGET_80387 && flag_unsafe_math_optimizations"
4151 "* return output_387_reg_move (insn, operands);"
4152 [(set_attr "type" "fmov")
4153 (set_attr "mode" "<MODE>")])
4155 (define_insn "*truncxf<mode>2_i387"
4156 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4157 (float_truncate:MODEF
4158 (match_operand:XF 1 "register_operand" "f")))]
4160 "* return output_387_reg_move (insn, operands);"
4161 [(set_attr "type" "fmov")
4162 (set_attr "mode" "<MODE>")])
4165 [(set (match_operand:MODEF 0 "register_operand")
4166 (float_truncate:MODEF
4167 (match_operand:XF 1 "register_operand")))
4168 (clobber (match_operand:MODEF 2 "memory_operand"))]
4169 "TARGET_80387 && reload_completed"
4170 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4171 (set (match_dup 0) (match_dup 2))])
4174 [(set (match_operand:MODEF 0 "memory_operand")
4175 (float_truncate:MODEF
4176 (match_operand:XF 1 "register_operand")))
4177 (clobber (match_operand:MODEF 2 "memory_operand"))]
4179 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4181 ;; Signed conversion to DImode.
4183 (define_expand "fix_truncxfdi2"
4184 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4185 (fix:DI (match_operand:XF 1 "register_operand")))
4186 (clobber (reg:CC FLAGS_REG))])]
4191 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4196 (define_expand "fix_trunc<mode>di2"
4197 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4198 (fix:DI (match_operand:MODEF 1 "register_operand")))
4199 (clobber (reg:CC FLAGS_REG))])]
4200 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4203 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4205 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4208 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4210 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4211 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4212 if (out != operands[0])
4213 emit_move_insn (operands[0], out);
4218 ;; Signed conversion to SImode.
4220 (define_expand "fix_truncxfsi2"
4221 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4222 (fix:SI (match_operand:XF 1 "register_operand")))
4223 (clobber (reg:CC FLAGS_REG))])]
4228 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4233 (define_expand "fix_trunc<mode>si2"
4234 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4235 (fix:SI (match_operand:MODEF 1 "register_operand")))
4236 (clobber (reg:CC FLAGS_REG))])]
4237 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4240 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4242 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4245 if (SSE_FLOAT_MODE_P (<MODE>mode))
4247 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4248 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4249 if (out != operands[0])
4250 emit_move_insn (operands[0], out);
4255 ;; Signed conversion to HImode.
4257 (define_expand "fix_trunc<mode>hi2"
4258 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4259 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4260 (clobber (reg:CC FLAGS_REG))])]
4262 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4266 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4271 ;; Unsigned conversion to SImode.
4273 (define_expand "fixuns_trunc<mode>si2"
4275 [(set (match_operand:SI 0 "register_operand")
4277 (match_operand:MODEF 1 "nonimmediate_operand")))
4279 (clobber (match_scratch:<ssevecmode> 3))
4280 (clobber (match_scratch:<ssevecmode> 4))])]
4281 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4283 enum machine_mode mode = <MODE>mode;
4284 enum machine_mode vecmode = <ssevecmode>mode;
4285 REAL_VALUE_TYPE TWO31r;
4288 if (optimize_insn_for_size_p ())
4291 real_ldexp (&TWO31r, &dconst1, 31);
4292 two31 = const_double_from_real_value (TWO31r, mode);
4293 two31 = ix86_build_const_vector (vecmode, true, two31);
4294 operands[2] = force_reg (vecmode, two31);
4297 (define_insn_and_split "*fixuns_trunc<mode>_1"
4298 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4300 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4301 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4302 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4303 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4304 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4305 && optimize_function_for_speed_p (cfun)"
4307 "&& reload_completed"
4310 ix86_split_convert_uns_si_sse (operands);
4314 ;; Unsigned conversion to HImode.
4315 ;; Without these patterns, we'll try the unsigned SI conversion which
4316 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4318 (define_expand "fixuns_trunc<mode>hi2"
4320 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4321 (set (match_operand:HI 0 "nonimmediate_operand")
4322 (subreg:HI (match_dup 2) 0))]
4323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4324 "operands[2] = gen_reg_rtx (SImode);")
4326 ;; When SSE is available, it is always faster to use it!
4327 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4328 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4329 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4330 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4331 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4332 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4333 [(set_attr "type" "sseicvt")
4334 (set_attr "prefix" "maybe_vex")
4335 (set (attr "prefix_rex")
4337 (match_test "<SWI48:MODE>mode == DImode")
4339 (const_string "*")))
4340 (set_attr "mode" "<MODEF:MODE>")
4341 (set_attr "athlon_decode" "double,vector")
4342 (set_attr "amdfam10_decode" "double,double")
4343 (set_attr "bdver1_decode" "double,double")])
4345 ;; Avoid vector decoded forms of the instruction.
4347 [(match_scratch:MODEF 2 "x")
4348 (set (match_operand:SWI48 0 "register_operand")
4349 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4350 "TARGET_AVOID_VECTOR_DECODE
4351 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4352 && optimize_insn_for_speed_p ()"
4353 [(set (match_dup 2) (match_dup 1))
4354 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4356 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4357 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4358 (fix:SWI248x (match_operand 1 "register_operand")))]
4359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4361 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && (TARGET_64BIT || <MODE>mode != DImode))
4364 && can_create_pseudo_p ()"
4369 if (memory_operand (operands[0], VOIDmode))
4370 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4373 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4374 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4380 [(set_attr "type" "fisttp")
4381 (set_attr "mode" "<MODE>")])
4383 (define_insn "fix_trunc<mode>_i387_fisttp"
4384 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4385 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4386 (clobber (match_scratch:XF 2 "=&1f"))]
4387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4389 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4390 && (TARGET_64BIT || <MODE>mode != DImode))
4391 && TARGET_SSE_MATH)"
4392 "* return output_fix_trunc (insn, operands, true);"
4393 [(set_attr "type" "fisttp")
4394 (set_attr "mode" "<MODE>")])
4396 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4397 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4398 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4399 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4400 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4401 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4403 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4404 && (TARGET_64BIT || <MODE>mode != DImode))
4405 && TARGET_SSE_MATH)"
4407 [(set_attr "type" "fisttp")
4408 (set_attr "mode" "<MODE>")])
4411 [(set (match_operand:SWI248x 0 "register_operand")
4412 (fix:SWI248x (match_operand 1 "register_operand")))
4413 (clobber (match_operand:SWI248x 2 "memory_operand"))
4414 (clobber (match_scratch 3))]
4416 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4417 (clobber (match_dup 3))])
4418 (set (match_dup 0) (match_dup 2))])
4421 [(set (match_operand:SWI248x 0 "memory_operand")
4422 (fix:SWI248x (match_operand 1 "register_operand")))
4423 (clobber (match_operand:SWI248x 2 "memory_operand"))
4424 (clobber (match_scratch 3))]
4426 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4427 (clobber (match_dup 3))])])
4429 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4430 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4431 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4432 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4433 ;; function in i386.c.
4434 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4435 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4436 (fix:SWI248x (match_operand 1 "register_operand")))
4437 (clobber (reg:CC FLAGS_REG))]
4438 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4440 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4441 && (TARGET_64BIT || <MODE>mode != DImode))
4442 && can_create_pseudo_p ()"
4447 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4449 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4450 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4451 if (memory_operand (operands[0], VOIDmode))
4452 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4453 operands[2], operands[3]));
4456 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4457 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4458 operands[2], operands[3],
4463 [(set_attr "type" "fistp")
4464 (set_attr "i387_cw" "trunc")
4465 (set_attr "mode" "<MODE>")])
4467 (define_insn "fix_truncdi_i387"
4468 [(set (match_operand:DI 0 "memory_operand" "=m")
4469 (fix:DI (match_operand 1 "register_operand" "f")))
4470 (use (match_operand:HI 2 "memory_operand" "m"))
4471 (use (match_operand:HI 3 "memory_operand" "m"))
4472 (clobber (match_scratch:XF 4 "=&1f"))]
4473 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4475 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4476 "* return output_fix_trunc (insn, operands, false);"
4477 [(set_attr "type" "fistp")
4478 (set_attr "i387_cw" "trunc")
4479 (set_attr "mode" "DI")])
4481 (define_insn "fix_truncdi_i387_with_temp"
4482 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4483 (fix:DI (match_operand 1 "register_operand" "f,f")))
4484 (use (match_operand:HI 2 "memory_operand" "m,m"))
4485 (use (match_operand:HI 3 "memory_operand" "m,m"))
4486 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4487 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4488 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4490 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4492 [(set_attr "type" "fistp")
4493 (set_attr "i387_cw" "trunc")
4494 (set_attr "mode" "DI")])
4497 [(set (match_operand:DI 0 "register_operand")
4498 (fix:DI (match_operand 1 "register_operand")))
4499 (use (match_operand:HI 2 "memory_operand"))
4500 (use (match_operand:HI 3 "memory_operand"))
4501 (clobber (match_operand:DI 4 "memory_operand"))
4502 (clobber (match_scratch 5))]
4504 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4507 (clobber (match_dup 5))])
4508 (set (match_dup 0) (match_dup 4))])
4511 [(set (match_operand:DI 0 "memory_operand")
4512 (fix:DI (match_operand 1 "register_operand")))
4513 (use (match_operand:HI 2 "memory_operand"))
4514 (use (match_operand:HI 3 "memory_operand"))
4515 (clobber (match_operand:DI 4 "memory_operand"))
4516 (clobber (match_scratch 5))]
4518 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4521 (clobber (match_dup 5))])])
4523 (define_insn "fix_trunc<mode>_i387"
4524 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4525 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4526 (use (match_operand:HI 2 "memory_operand" "m"))
4527 (use (match_operand:HI 3 "memory_operand" "m"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "<MODE>")])
4536 (define_insn "fix_trunc<mode>_i387_with_temp"
4537 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4538 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "<MODE>")])
4551 [(set (match_operand:SWI24 0 "register_operand")
4552 (fix:SWI24 (match_operand 1 "register_operand")))
4553 (use (match_operand:HI 2 "memory_operand"))
4554 (use (match_operand:HI 3 "memory_operand"))
4555 (clobber (match_operand:SWI24 4 "memory_operand"))]
4557 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4559 (use (match_dup 3))])
4560 (set (match_dup 0) (match_dup 4))])
4563 [(set (match_operand:SWI24 0 "memory_operand")
4564 (fix:SWI24 (match_operand 1 "register_operand")))
4565 (use (match_operand:HI 2 "memory_operand"))
4566 (use (match_operand:HI 3 "memory_operand"))
4567 (clobber (match_operand:SWI24 4 "memory_operand"))]
4569 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4571 (use (match_dup 3))])])
4573 (define_insn "x86_fnstcw_1"
4574 [(set (match_operand:HI 0 "memory_operand" "=m")
4575 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4578 [(set (attr "length")
4579 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4580 (set_attr "mode" "HI")
4581 (set_attr "unit" "i387")
4582 (set_attr "bdver1_decode" "vector")])
4584 (define_insn "x86_fldcw_1"
4585 [(set (reg:HI FPCR_REG)
4586 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4589 [(set (attr "length")
4590 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4591 (set_attr "mode" "HI")
4592 (set_attr "unit" "i387")
4593 (set_attr "athlon_decode" "vector")
4594 (set_attr "amdfam10_decode" "vector")
4595 (set_attr "bdver1_decode" "vector")])
4597 ;; Conversion between fixed point and floating point.
4599 ;; Even though we only accept memory inputs, the backend _really_
4600 ;; wants to be able to do this between registers.
4602 (define_expand "floathi<mode>2"
4603 [(set (match_operand:X87MODEF 0 "register_operand")
4604 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4607 || TARGET_MIX_SSE_I387)")
4609 ;; Pre-reload splitter to add memory clobber to the pattern.
4610 (define_insn_and_split "*floathi<mode>2_1"
4611 [(set (match_operand:X87MODEF 0 "register_operand")
4612 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4615 || TARGET_MIX_SSE_I387)
4616 && can_create_pseudo_p ()"
4619 [(parallel [(set (match_dup 0)
4620 (float:X87MODEF (match_dup 1)))
4621 (clobber (match_dup 2))])]
4622 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4624 (define_insn "*floathi<mode>2_i387_with_temp"
4625 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4626 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4627 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4629 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4630 || TARGET_MIX_SSE_I387)"
4632 [(set_attr "type" "fmov,multi")
4633 (set_attr "mode" "<MODE>")
4634 (set_attr "unit" "*,i387")
4635 (set_attr "fp_int_src" "true")])
4637 (define_insn "*floathi<mode>2_i387"
4638 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4639 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4642 || TARGET_MIX_SSE_I387)"
4644 [(set_attr "type" "fmov")
4645 (set_attr "mode" "<MODE>")
4646 (set_attr "fp_int_src" "true")])
4649 [(set (match_operand:X87MODEF 0 "register_operand")
4650 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4651 (clobber (match_operand:HI 2 "memory_operand"))]
4653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4654 || TARGET_MIX_SSE_I387)
4655 && reload_completed"
4656 [(set (match_dup 2) (match_dup 1))
4657 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4660 [(set (match_operand:X87MODEF 0 "register_operand")
4661 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4662 (clobber (match_operand:HI 2 "memory_operand"))]
4664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4665 || TARGET_MIX_SSE_I387)
4666 && reload_completed"
4667 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4669 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4670 [(set (match_operand:X87MODEF 0 "register_operand")
4672 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4674 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4675 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4677 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4678 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4679 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4681 rtx reg = gen_reg_rtx (XFmode);
4682 rtx (*insn)(rtx, rtx);
4684 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4686 if (<X87MODEF:MODE>mode == SFmode)
4687 insn = gen_truncxfsf2;
4688 else if (<X87MODEF:MODE>mode == DFmode)
4689 insn = gen_truncxfdf2;
4693 emit_insn (insn (operands[0], reg));
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4700 [(set (match_operand:X87MODEF 0 "register_operand")
4701 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4703 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4704 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4705 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4706 || TARGET_MIX_SSE_I387))
4707 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4708 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4709 && ((<SWI48x:MODE>mode == SImode
4710 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4711 && optimize_function_for_speed_p (cfun)
4712 && flag_trapping_math)
4713 || !(TARGET_INTER_UNIT_CONVERSIONS
4714 || optimize_function_for_size_p (cfun)))))
4715 && can_create_pseudo_p ()"
4718 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4719 (clobber (match_dup 2))])]
4721 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4723 /* Avoid store forwarding (partial memory) stall penalty
4724 by passing DImode value through XMM registers. */
4725 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4726 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4727 && optimize_function_for_speed_p (cfun))
4729 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4736 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4737 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4739 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4740 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4741 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4742 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4744 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4745 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4746 (set_attr "unit" "*,i387,*,*,*")
4747 (set_attr "athlon_decode" "*,*,double,direct,double")
4748 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4749 (set_attr "bdver1_decode" "*,*,double,direct,double")
4750 (set_attr "fp_int_src" "true")])
4752 (define_insn "*floatsi<mode>2_vector_mixed"
4753 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4754 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4755 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4756 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4760 [(set_attr "type" "fmov,sseicvt")
4761 (set_attr "mode" "<MODE>,<ssevecmode>")
4762 (set_attr "unit" "i387,*")
4763 (set_attr "athlon_decode" "*,direct")
4764 (set_attr "amdfam10_decode" "*,double")
4765 (set_attr "bdver1_decode" "*,direct")
4766 (set_attr "fp_int_src" "true")])
4768 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4769 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4771 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4772 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4773 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4775 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4776 (set_attr "mode" "<MODEF:MODE>")
4777 (set_attr "unit" "*,i387,*,*")
4778 (set_attr "athlon_decode" "*,*,double,direct")
4779 (set_attr "amdfam10_decode" "*,*,vector,double")
4780 (set_attr "bdver1_decode" "*,*,double,direct")
4781 (set_attr "fp_int_src" "true")])
4784 [(set (match_operand:MODEF 0 "register_operand")
4785 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4786 (clobber (match_operand:SWI48 2 "memory_operand"))]
4787 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4788 && TARGET_INTER_UNIT_CONVERSIONS
4789 && reload_completed && SSE_REG_P (operands[0])"
4790 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4793 [(set (match_operand:MODEF 0 "register_operand")
4794 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4795 (clobber (match_operand:SWI48 2 "memory_operand"))]
4796 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4797 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4798 && reload_completed && SSE_REG_P (operands[0])"
4799 [(set (match_dup 2) (match_dup 1))
4800 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4802 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4803 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4805 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4806 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4807 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4810 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4811 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4812 [(set_attr "type" "fmov,sseicvt,sseicvt")
4813 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4814 (set_attr "mode" "<MODEF:MODE>")
4815 (set (attr "prefix_rex")
4817 (and (eq_attr "prefix" "maybe_vex")
4818 (match_test "<SWI48:MODE>mode == DImode"))
4820 (const_string "*")))
4821 (set_attr "unit" "i387,*,*")
4822 (set_attr "athlon_decode" "*,double,direct")
4823 (set_attr "amdfam10_decode" "*,vector,double")
4824 (set_attr "bdver1_decode" "*,double,direct")
4825 (set_attr "fp_int_src" "true")])
4827 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4828 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4830 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4831 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4832 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4835 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4836 [(set_attr "type" "fmov,sseicvt")
4837 (set_attr "prefix" "orig,maybe_vex")
4838 (set_attr "mode" "<MODEF:MODE>")
4839 (set (attr "prefix_rex")
4841 (and (eq_attr "prefix" "maybe_vex")
4842 (match_test "<SWI48:MODE>mode == DImode"))
4844 (const_string "*")))
4845 (set_attr "athlon_decode" "*,direct")
4846 (set_attr "amdfam10_decode" "*,double")
4847 (set_attr "bdver1_decode" "*,direct")
4848 (set_attr "fp_int_src" "true")])
4850 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4851 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4853 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4854 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4855 "TARGET_SSE2 && TARGET_SSE_MATH
4856 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4858 [(set_attr "type" "sseicvt")
4859 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4860 (set_attr "athlon_decode" "double,direct,double")
4861 (set_attr "amdfam10_decode" "vector,double,double")
4862 (set_attr "bdver1_decode" "double,direct,double")
4863 (set_attr "fp_int_src" "true")])
4865 (define_insn "*floatsi<mode>2_vector_sse"
4866 [(set (match_operand:MODEF 0 "register_operand" "=x")
4867 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4868 "TARGET_SSE2 && TARGET_SSE_MATH
4869 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4871 [(set_attr "type" "sseicvt")
4872 (set_attr "mode" "<MODE>")
4873 (set_attr "athlon_decode" "direct")
4874 (set_attr "amdfam10_decode" "double")
4875 (set_attr "bdver1_decode" "direct")
4876 (set_attr "fp_int_src" "true")])
4879 [(set (match_operand:MODEF 0 "register_operand")
4880 (float:MODEF (match_operand:SI 1 "register_operand")))
4881 (clobber (match_operand:SI 2 "memory_operand"))]
4882 "TARGET_SSE2 && TARGET_SSE_MATH
4883 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4884 && reload_completed && SSE_REG_P (operands[0])"
4887 rtx op1 = operands[1];
4889 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4891 if (GET_CODE (op1) == SUBREG)
4892 op1 = SUBREG_REG (op1);
4894 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4896 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4897 emit_insn (gen_sse2_loadld (operands[4],
4898 CONST0_RTX (V4SImode), operands[1]));
4900 /* We can ignore possible trapping value in the
4901 high part of SSE register for non-trapping math. */
4902 else if (SSE_REG_P (op1) && !flag_trapping_math)
4903 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4906 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4907 emit_move_insn (operands[2], operands[1]);
4908 emit_insn (gen_sse2_loadld (operands[4],
4909 CONST0_RTX (V4SImode), operands[2]));
4911 if (<ssevecmode>mode == V4SFmode)
4912 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4914 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4919 [(set (match_operand:MODEF 0 "register_operand")
4920 (float:MODEF (match_operand:SI 1 "memory_operand")))
4921 (clobber (match_operand:SI 2 "memory_operand"))]
4922 "TARGET_SSE2 && TARGET_SSE_MATH
4923 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4924 && reload_completed && SSE_REG_P (operands[0])"
4927 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4929 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931 emit_insn (gen_sse2_loadld (operands[4],
4932 CONST0_RTX (V4SImode), operands[1]));
4933 if (<ssevecmode>mode == V4SFmode)
4934 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4936 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4941 [(set (match_operand:MODEF 0 "register_operand")
4942 (float:MODEF (match_operand:SI 1 "register_operand")))]
4943 "TARGET_SSE2 && TARGET_SSE_MATH
4944 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4945 && reload_completed && SSE_REG_P (operands[0])"
4948 rtx op1 = operands[1];
4950 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4952 if (GET_CODE (op1) == SUBREG)
4953 op1 = SUBREG_REG (op1);
4955 if (GENERAL_REG_P (op1))
4957 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4958 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4959 emit_insn (gen_sse2_loadld (operands[4],
4960 CONST0_RTX (V4SImode), operands[1]));
4963 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[5]));
4967 ix86_free_from_memory (GET_MODE (operands[1]));
4970 /* We can ignore possible trapping value in the
4971 high part of SSE register for non-trapping math. */
4972 else if (SSE_REG_P (op1) && !flag_trapping_math)
4973 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4976 if (<ssevecmode>mode == V4SFmode)
4977 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4979 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4984 [(set (match_operand:MODEF 0 "register_operand")
4985 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4986 "TARGET_SSE2 && TARGET_SSE_MATH
4987 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4988 && reload_completed && SSE_REG_P (operands[0])"
4991 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4993 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4995 emit_insn (gen_sse2_loadld (operands[4],
4996 CONST0_RTX (V4SImode), operands[1]));
4997 if (<ssevecmode>mode == V4SFmode)
4998 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5000 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5004 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5005 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5007 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5008 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5009 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "<MODEF:MODE>")
5013 (set_attr "athlon_decode" "double,direct")
5014 (set_attr "amdfam10_decode" "vector,double")
5015 (set_attr "bdver1_decode" "double,direct")
5016 (set_attr "btver2_decode" "double,double")
5017 (set_attr "fp_int_src" "true")])
5019 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5020 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5022 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5023 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5024 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5025 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5026 [(set_attr "type" "sseicvt")
5027 (set_attr "prefix" "maybe_vex")
5028 (set_attr "mode" "<MODEF:MODE>")
5029 (set (attr "prefix_rex")
5031 (and (eq_attr "prefix" "maybe_vex")
5032 (match_test "<SWI48:MODE>mode == DImode"))
5034 (const_string "*")))
5035 (set_attr "athlon_decode" "double,direct")
5036 (set_attr "amdfam10_decode" "vector,double")
5037 (set_attr "bdver1_decode" "double,direct")
5038 (set_attr "btver2_decode" "double,double")
5039 (set_attr "fp_int_src" "true")])
5042 [(set (match_operand:MODEF 0 "register_operand")
5043 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5044 (clobber (match_operand:SWI48 2 "memory_operand"))]
5045 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5046 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5047 && reload_completed && SSE_REG_P (operands[0])"
5048 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5050 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5051 [(set (match_operand:MODEF 0 "register_operand" "=x")
5053 (match_operand:SWI48 1 "memory_operand" "m")))]
5054 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5055 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5056 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5057 [(set_attr "type" "sseicvt")
5058 (set_attr "prefix" "maybe_vex")
5059 (set_attr "mode" "<MODEF:MODE>")
5060 (set (attr "prefix_rex")
5062 (and (eq_attr "prefix" "maybe_vex")
5063 (match_test "<SWI48:MODE>mode == DImode"))
5065 (const_string "*")))
5066 (set_attr "athlon_decode" "direct")
5067 (set_attr "amdfam10_decode" "double")
5068 (set_attr "bdver1_decode" "direct")
5069 (set_attr "fp_int_src" "true")])
5072 [(set (match_operand:MODEF 0 "register_operand")
5073 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5074 (clobber (match_operand:SWI48 2 "memory_operand"))]
5075 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5076 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5077 && reload_completed && SSE_REG_P (operands[0])"
5078 [(set (match_dup 2) (match_dup 1))
5079 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5082 [(set (match_operand:MODEF 0 "register_operand")
5083 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5084 (clobber (match_operand:SWI48 2 "memory_operand"))]
5085 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5086 && reload_completed && SSE_REG_P (operands[0])"
5087 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5089 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5090 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5092 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5093 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5095 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5099 [(set_attr "type" "fmov,multi")
5100 (set_attr "mode" "<X87MODEF:MODE>")
5101 (set_attr "unit" "*,i387")
5102 (set_attr "fp_int_src" "true")])
5104 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5105 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5107 (match_operand:SWI48x 1 "memory_operand" "m")))]
5109 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5111 [(set_attr "type" "fmov")
5112 (set_attr "mode" "<X87MODEF:MODE>")
5113 (set_attr "fp_int_src" "true")])
5116 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5117 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5118 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5120 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5121 && reload_completed"
5122 [(set (match_dup 2) (match_dup 1))
5123 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5126 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5127 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5128 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5130 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5131 && reload_completed"
5132 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5134 ;; Avoid partial SSE register dependency stalls
5137 [(set (match_operand:MODEF 0 "register_operand")
5138 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5139 "TARGET_SSE2 && TARGET_SSE_MATH
5140 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5141 && optimize_function_for_speed_p (cfun)
5142 && reload_completed && SSE_REG_P (operands[0])"
5144 (vec_merge:<ssevecmode>
5145 (vec_duplicate:<ssevecmode>
5146 (float:MODEF (match_dup 1)))
5150 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5152 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5156 [(set (match_operand:MODEF 0 "register_operand")
5157 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5158 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5159 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5160 && optimize_function_for_speed_p (cfun)
5161 && reload_completed && SSE_REG_P (operands[0])"
5163 (vec_merge:<ssevecmode>
5164 (vec_duplicate:<ssevecmode>
5165 (float:MODEF (match_dup 1)))
5169 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5171 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5174 ;; Break partial reg stall for cvtsd2ss.
5177 [(set (match_operand:SF 0 "register_operand")
5179 (match_operand:DF 1 "nonimmediate_operand")))]
5180 "TARGET_SSE2 && TARGET_SSE_MATH
5181 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5182 && optimize_function_for_speed_p (cfun)
5183 && SSE_REG_P (operands[0])
5184 && (!SSE_REG_P (operands[1])
5185 || REGNO (operands[0]) != REGNO (operands[1]))"
5189 (float_truncate:V2SF
5194 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5196 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5198 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5201 ;; Break partial reg stall for cvtss2sd.
5204 [(set (match_operand:DF 0 "register_operand")
5206 (match_operand:SF 1 "nonimmediate_operand")))]
5207 "TARGET_SSE2 && TARGET_SSE_MATH
5208 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5209 && optimize_function_for_speed_p (cfun)
5210 && SSE_REG_P (operands[0])
5211 && (!SSE_REG_P (operands[1])
5212 || REGNO (operands[0]) != REGNO (operands[1]))"
5218 (parallel [(const_int 0) (const_int 1)])))
5222 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5224 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5226 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5229 ;; Avoid store forwarding (partial memory) stall penalty
5230 ;; by passing DImode value through XMM registers. */
5232 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5233 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5235 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5236 (clobber (match_scratch:V4SI 3 "=X,x"))
5237 (clobber (match_scratch:V4SI 4 "=X,x"))
5238 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5239 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5240 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5241 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5243 [(set_attr "type" "multi")
5244 (set_attr "mode" "<X87MODEF:MODE>")
5245 (set_attr "unit" "i387")
5246 (set_attr "fp_int_src" "true")])
5249 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5250 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5251 (clobber (match_scratch:V4SI 3))
5252 (clobber (match_scratch:V4SI 4))
5253 (clobber (match_operand:DI 2 "memory_operand"))]
5254 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5256 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5257 && reload_completed"
5258 [(set (match_dup 2) (match_dup 3))
5259 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5261 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5262 Assemble the 64-bit DImode value in an xmm register. */
5263 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5264 gen_rtx_SUBREG (SImode, operands[1], 0)));
5265 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5266 gen_rtx_SUBREG (SImode, operands[1], 4)));
5267 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5270 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5274 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5275 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5276 (clobber (match_scratch:V4SI 3))
5277 (clobber (match_scratch:V4SI 4))
5278 (clobber (match_operand:DI 2 "memory_operand"))]
5279 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5280 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5281 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5282 && reload_completed"
5283 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5285 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5286 [(set (match_operand:MODEF 0 "register_operand")
5287 (unsigned_float:MODEF
5288 (match_operand:SWI12 1 "nonimmediate_operand")))]
5290 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5292 operands[1] = convert_to_mode (SImode, operands[1], 1);
5293 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5297 ;; Avoid store forwarding (partial memory) stall penalty by extending
5298 ;; SImode value to DImode through XMM register instead of pushing two
5299 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5300 ;; targets benefit from this optimization. Also note that fild
5301 ;; loads from memory only.
5303 (define_insn "*floatunssi<mode>2_1"
5304 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5305 (unsigned_float:X87MODEF
5306 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5307 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5308 (clobber (match_scratch:SI 3 "=X,x"))]
5310 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5313 [(set_attr "type" "multi")
5314 (set_attr "mode" "<MODE>")])
5317 [(set (match_operand:X87MODEF 0 "register_operand")
5318 (unsigned_float:X87MODEF
5319 (match_operand:SI 1 "register_operand")))
5320 (clobber (match_operand:DI 2 "memory_operand"))
5321 (clobber (match_scratch:SI 3))]
5323 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5325 && reload_completed"
5326 [(set (match_dup 2) (match_dup 1))
5328 (float:X87MODEF (match_dup 2)))]
5329 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5332 [(set (match_operand:X87MODEF 0 "register_operand")
5333 (unsigned_float:X87MODEF
5334 (match_operand:SI 1 "memory_operand")))
5335 (clobber (match_operand:DI 2 "memory_operand"))
5336 (clobber (match_scratch:SI 3))]
5338 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5340 && reload_completed"
5341 [(set (match_dup 2) (match_dup 3))
5343 (float:X87MODEF (match_dup 2)))]
5345 emit_move_insn (operands[3], operands[1]);
5346 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5349 (define_expand "floatunssi<mode>2"
5351 [(set (match_operand:X87MODEF 0 "register_operand")
5352 (unsigned_float:X87MODEF
5353 (match_operand:SI 1 "nonimmediate_operand")))
5354 (clobber (match_dup 2))
5355 (clobber (match_scratch:SI 3))])]
5357 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5359 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5361 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5363 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5367 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5370 (define_expand "floatunsdisf2"
5371 [(use (match_operand:SF 0 "register_operand"))
5372 (use (match_operand:DI 1 "nonimmediate_operand"))]
5373 "TARGET_64BIT && TARGET_SSE_MATH"
5374 "x86_emit_floatuns (operands); DONE;")
5376 (define_expand "floatunsdidf2"
5377 [(use (match_operand:DF 0 "register_operand"))
5378 (use (match_operand:DI 1 "nonimmediate_operand"))]
5379 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5380 && TARGET_SSE2 && TARGET_SSE_MATH"
5383 x86_emit_floatuns (operands);
5385 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5389 ;; Load effective address instructions
5391 (define_insn_and_split "*lea<mode>"
5392 [(set (match_operand:SWI48 0 "register_operand" "=r")
5393 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5396 if (SImode_address_operand (operands[1], VOIDmode))
5398 gcc_assert (TARGET_64BIT);
5399 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5402 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5404 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5407 enum machine_mode mode = <MODE>mode;
5410 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5411 change operands[] array behind our back. */
5412 pat = PATTERN (curr_insn);
5414 operands[0] = SET_DEST (pat);
5415 operands[1] = SET_SRC (pat);
5417 /* Emit all operations in SImode for zero-extended addresses. Recall
5418 that x86_64 inheretly zero-extends SImode operations to DImode. */
5419 if (SImode_address_operand (operands[1], VOIDmode))
5422 ix86_split_lea_for_addr (curr_insn, operands, mode);
5425 [(set_attr "type" "lea")
5428 (match_operand 1 "SImode_address_operand")
5430 (const_string "<MODE>")))])
5434 (define_expand "add<mode>3"
5435 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5436 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5437 (match_operand:SDWIM 2 "<general_operand>")))]
5439 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5441 (define_insn_and_split "*add<dwi>3_doubleword"
5442 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5444 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5445 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5446 (clobber (reg:CC FLAGS_REG))]
5447 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5450 [(parallel [(set (reg:CC FLAGS_REG)
5451 (unspec:CC [(match_dup 1) (match_dup 2)]
5454 (plus:DWIH (match_dup 1) (match_dup 2)))])
5455 (parallel [(set (match_dup 3)
5459 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5461 (clobber (reg:CC FLAGS_REG))])]
5462 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5464 (define_insn "*add<mode>3_cc"
5465 [(set (reg:CC FLAGS_REG)
5467 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5468 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5470 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5471 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5472 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5473 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5474 [(set_attr "type" "alu")
5475 (set_attr "mode" "<MODE>")])
5477 (define_insn "addqi3_cc"
5478 [(set (reg:CC FLAGS_REG)
5480 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5481 (match_operand:QI 2 "general_operand" "qn,qm")]
5483 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5484 (plus:QI (match_dup 1) (match_dup 2)))]
5485 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5486 "add{b}\t{%2, %0|%0, %2}"
5487 [(set_attr "type" "alu")
5488 (set_attr "mode" "QI")])
5490 (define_insn "*add<mode>_1"
5491 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5493 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5494 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5495 (clobber (reg:CC FLAGS_REG))]
5496 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5498 switch (get_attr_type (insn))
5504 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5505 if (operands[2] == const1_rtx)
5506 return "inc{<imodesuffix>}\t%0";
5509 gcc_assert (operands[2] == constm1_rtx);
5510 return "dec{<imodesuffix>}\t%0";
5514 /* For most processors, ADD is faster than LEA. This alternative
5515 was added to use ADD as much as possible. */
5516 if (which_alternative == 2)
5519 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5522 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5523 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5524 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5526 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5530 (cond [(eq_attr "alternative" "3")
5531 (const_string "lea")
5532 (match_operand:SWI48 2 "incdec_operand")
5533 (const_string "incdec")
5535 (const_string "alu")))
5536 (set (attr "length_immediate")
5538 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5540 (const_string "*")))
5541 (set_attr "mode" "<MODE>")])
5543 ;; It may seem that nonimmediate operand is proper one for operand 1.
5544 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5545 ;; we take care in ix86_binary_operator_ok to not allow two memory
5546 ;; operands so proper swapping will be done in reload. This allow
5547 ;; patterns constructed from addsi_1 to match.
5549 (define_insn "addsi_1_zext"
5550 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5552 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5553 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5554 (clobber (reg:CC FLAGS_REG))]
5555 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5557 switch (get_attr_type (insn))
5563 if (operands[2] == const1_rtx)
5564 return "inc{l}\t%k0";
5567 gcc_assert (operands[2] == constm1_rtx);
5568 return "dec{l}\t%k0";
5572 /* For most processors, ADD is faster than LEA. This alternative
5573 was added to use ADD as much as possible. */
5574 if (which_alternative == 1)
5577 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5580 if (x86_maybe_negate_const_int (&operands[2], SImode))
5581 return "sub{l}\t{%2, %k0|%k0, %2}";
5583 return "add{l}\t{%2, %k0|%k0, %2}";
5587 (cond [(eq_attr "alternative" "2")
5588 (const_string "lea")
5589 (match_operand:SI 2 "incdec_operand")
5590 (const_string "incdec")
5592 (const_string "alu")))
5593 (set (attr "length_immediate")
5595 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5597 (const_string "*")))
5598 (set_attr "mode" "SI")])
5600 (define_insn "*addhi_1"
5601 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5602 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5603 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5604 (clobber (reg:CC FLAGS_REG))]
5605 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5607 switch (get_attr_type (insn))
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{w}\t%0";
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{w}\t%0";
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], HImode))
5633 return "sub{w}\t{%2, %0|%0, %2}";
5635 return "add{w}\t{%2, %0|%0, %2}";
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:HI 2 "incdec_operand")
5642 (const_string "incdec")
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5649 (const_string "*")))
5650 (set_attr "mode" "HI,HI,HI,SI")])
5652 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5653 (define_insn "*addqi_1"
5654 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5655 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5656 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5657 (clobber (reg:CC FLAGS_REG))]
5658 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5660 bool widen = (which_alternative == 3 || which_alternative == 4);
5662 switch (get_attr_type (insn))
5668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5669 if (operands[2] == const1_rtx)
5670 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5673 gcc_assert (operands[2] == constm1_rtx);
5674 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5678 /* For most processors, ADD is faster than LEA. These alternatives
5679 were added to use ADD as much as possible. */
5680 if (which_alternative == 2 || which_alternative == 4)
5683 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5686 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5687 if (x86_maybe_negate_const_int (&operands[2], QImode))
5690 return "sub{l}\t{%2, %k0|%k0, %2}";
5692 return "sub{b}\t{%2, %0|%0, %2}";
5695 return "add{l}\t{%k2, %k0|%k0, %k2}";
5697 return "add{b}\t{%2, %0|%0, %2}";
5701 (cond [(eq_attr "alternative" "5")
5702 (const_string "lea")
5703 (match_operand:QI 2 "incdec_operand")
5704 (const_string "incdec")
5706 (const_string "alu")))
5707 (set (attr "length_immediate")
5709 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5711 (const_string "*")))
5712 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5714 (define_insn "*addqi_1_slp"
5715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5716 (plus:QI (match_dup 0)
5717 (match_operand:QI 1 "general_operand" "qn,qm")))
5718 (clobber (reg:CC FLAGS_REG))]
5719 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5720 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5722 switch (get_attr_type (insn))
5725 if (operands[1] == const1_rtx)
5726 return "inc{b}\t%0";
5729 gcc_assert (operands[1] == constm1_rtx);
5730 return "dec{b}\t%0";
5734 if (x86_maybe_negate_const_int (&operands[1], QImode))
5735 return "sub{b}\t{%1, %0|%0, %1}";
5737 return "add{b}\t{%1, %0|%0, %1}";
5741 (if_then_else (match_operand:QI 1 "incdec_operand")
5742 (const_string "incdec")
5743 (const_string "alu1")))
5744 (set (attr "memory")
5745 (if_then_else (match_operand 1 "memory_operand")
5746 (const_string "load")
5747 (const_string "none")))
5748 (set_attr "mode" "QI")])
5750 ;; Split non destructive adds if we cannot use lea.
5752 [(set (match_operand:SWI48 0 "register_operand")
5753 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5754 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5755 (clobber (reg:CC FLAGS_REG))]
5756 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5757 [(set (match_dup 0) (match_dup 1))
5758 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5759 (clobber (reg:CC FLAGS_REG))])])
5761 ;; Convert add to the lea pattern to avoid flags dependency.
5763 [(set (match_operand:SWI 0 "register_operand")
5764 (plus:SWI (match_operand:SWI 1 "register_operand")
5765 (match_operand:SWI 2 "<nonmemory_operand>")))
5766 (clobber (reg:CC FLAGS_REG))]
5767 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5770 enum machine_mode mode = <MODE>mode;
5773 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5776 operands[0] = gen_lowpart (mode, operands[0]);
5777 operands[1] = gen_lowpart (mode, operands[1]);
5778 operands[2] = gen_lowpart (mode, operands[2]);
5781 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5783 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5787 ;; Split non destructive adds if we cannot use lea.
5789 [(set (match_operand:DI 0 "register_operand")
5791 (plus:SI (match_operand:SI 1 "register_operand")
5792 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5793 (clobber (reg:CC FLAGS_REG))]
5795 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5796 [(set (match_dup 3) (match_dup 1))
5797 (parallel [(set (match_dup 0)
5798 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5799 (clobber (reg:CC FLAGS_REG))])]
5800 "operands[3] = gen_lowpart (SImode, operands[0]);")
5802 ;; Convert add to the lea pattern to avoid flags dependency.
5804 [(set (match_operand:DI 0 "register_operand")
5806 (plus:SI (match_operand:SI 1 "register_operand")
5807 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5808 (clobber (reg:CC FLAGS_REG))]
5809 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5811 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5813 (define_insn "*add<mode>_2"
5814 [(set (reg FLAGS_REG)
5817 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5818 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5820 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5821 (plus:SWI (match_dup 1) (match_dup 2)))]
5822 "ix86_match_ccmode (insn, CCGOCmode)
5823 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5825 switch (get_attr_type (insn))
5828 if (operands[2] == const1_rtx)
5829 return "inc{<imodesuffix>}\t%0";
5832 gcc_assert (operands[2] == constm1_rtx);
5833 return "dec{<imodesuffix>}\t%0";
5837 if (which_alternative == 2)
5840 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5843 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5844 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5845 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5847 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5851 (if_then_else (match_operand:SWI 2 "incdec_operand")
5852 (const_string "incdec")
5853 (const_string "alu")))
5854 (set (attr "length_immediate")
5856 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5858 (const_string "*")))
5859 (set_attr "mode" "<MODE>")])
5861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5862 (define_insn "*addsi_2_zext"
5863 [(set (reg FLAGS_REG)
5865 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5866 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5868 (set (match_operand:DI 0 "register_operand" "=r,r")
5869 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5870 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5871 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5873 switch (get_attr_type (insn))
5876 if (operands[2] == const1_rtx)
5877 return "inc{l}\t%k0";
5880 gcc_assert (operands[2] == constm1_rtx);
5881 return "dec{l}\t%k0";
5885 if (which_alternative == 1)
5888 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5891 if (x86_maybe_negate_const_int (&operands[2], SImode))
5892 return "sub{l}\t{%2, %k0|%k0, %2}";
5894 return "add{l}\t{%2, %k0|%k0, %2}";
5898 (if_then_else (match_operand:SI 2 "incdec_operand")
5899 (const_string "incdec")
5900 (const_string "alu")))
5901 (set (attr "length_immediate")
5903 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5905 (const_string "*")))
5906 (set_attr "mode" "SI")])
5908 (define_insn "*add<mode>_3"
5909 [(set (reg FLAGS_REG)
5911 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5912 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5913 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5914 "ix86_match_ccmode (insn, CCZmode)
5915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5917 switch (get_attr_type (insn))
5920 if (operands[2] == const1_rtx)
5921 return "inc{<imodesuffix>}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{<imodesuffix>}\t%0";
5929 if (which_alternative == 1)
5932 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5935 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5936 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5937 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5939 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5943 (if_then_else (match_operand:SWI 2 "incdec_operand")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set (attr "length_immediate")
5948 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5950 (const_string "*")))
5951 (set_attr "mode" "<MODE>")])
5953 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5954 (define_insn "*addsi_3_zext"
5955 [(set (reg FLAGS_REG)
5957 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5958 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5959 (set (match_operand:DI 0 "register_operand" "=r,r")
5960 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5961 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5962 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5964 switch (get_attr_type (insn))
5967 if (operands[2] == const1_rtx)
5968 return "inc{l}\t%k0";
5971 gcc_assert (operands[2] == constm1_rtx);
5972 return "dec{l}\t%k0";
5976 if (which_alternative == 1)
5979 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5982 if (x86_maybe_negate_const_int (&operands[2], SImode))
5983 return "sub{l}\t{%2, %k0|%k0, %2}";
5985 return "add{l}\t{%2, %k0|%k0, %2}";
5989 (if_then_else (match_operand:SI 2 "incdec_operand")
5990 (const_string "incdec")
5991 (const_string "alu")))
5992 (set (attr "length_immediate")
5994 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5996 (const_string "*")))
5997 (set_attr "mode" "SI")])
5999 ; For comparisons against 1, -1 and 128, we may generate better code
6000 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6001 ; is matched then. We can't accept general immediate, because for
6002 ; case of overflows, the result is messed up.
6003 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6004 ; only for comparisons not depending on it.
6006 (define_insn "*adddi_4"
6007 [(set (reg FLAGS_REG)
6009 (match_operand:DI 1 "nonimmediate_operand" "0")
6010 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6011 (clobber (match_scratch:DI 0 "=rm"))]
6013 && ix86_match_ccmode (insn, CCGCmode)"
6015 switch (get_attr_type (insn))
6018 if (operands[2] == constm1_rtx)
6019 return "inc{q}\t%0";
6022 gcc_assert (operands[2] == const1_rtx);
6023 return "dec{q}\t%0";
6027 if (x86_maybe_negate_const_int (&operands[2], DImode))
6028 return "add{q}\t{%2, %0|%0, %2}";
6030 return "sub{q}\t{%2, %0|%0, %2}";
6034 (if_then_else (match_operand:DI 2 "incdec_operand")
6035 (const_string "incdec")
6036 (const_string "alu")))
6037 (set (attr "length_immediate")
6039 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6041 (const_string "*")))
6042 (set_attr "mode" "DI")])
6044 ; For comparisons against 1, -1 and 128, we may generate better code
6045 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6046 ; is matched then. We can't accept general immediate, because for
6047 ; case of overflows, the result is messed up.
6048 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6049 ; only for comparisons not depending on it.
6051 (define_insn "*add<mode>_4"
6052 [(set (reg FLAGS_REG)
6054 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6055 (match_operand:SWI124 2 "const_int_operand" "n")))
6056 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6057 "ix86_match_ccmode (insn, CCGCmode)"
6059 switch (get_attr_type (insn))
6062 if (operands[2] == constm1_rtx)
6063 return "inc{<imodesuffix>}\t%0";
6066 gcc_assert (operands[2] == const1_rtx);
6067 return "dec{<imodesuffix>}\t%0";
6071 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6072 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6074 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6078 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6085 (const_string "*")))
6086 (set_attr "mode" "<MODE>")])
6088 (define_insn "*add<mode>_5"
6089 [(set (reg FLAGS_REG)
6092 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6093 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6095 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6096 "ix86_match_ccmode (insn, CCGOCmode)
6097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6099 switch (get_attr_type (insn))
6102 if (operands[2] == const1_rtx)
6103 return "inc{<imodesuffix>}\t%0";
6106 gcc_assert (operands[2] == constm1_rtx);
6107 return "dec{<imodesuffix>}\t%0";
6111 if (which_alternative == 1)
6114 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6117 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6118 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6119 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6121 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6125 (if_then_else (match_operand:SWI 2 "incdec_operand")
6126 (const_string "incdec")
6127 (const_string "alu")))
6128 (set (attr "length_immediate")
6130 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6132 (const_string "*")))
6133 (set_attr "mode" "<MODE>")])
6135 (define_insn "addqi_ext_1"
6136 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6141 (match_operand 1 "ext_register_operand" "0,0")
6144 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6145 (clobber (reg:CC FLAGS_REG))]
6148 switch (get_attr_type (insn))
6151 if (operands[2] == const1_rtx)
6152 return "inc{b}\t%h0";
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{b}\t%h0";
6160 return "add{b}\t{%2, %h0|%h0, %2}";
6163 [(set_attr "isa" "*,nox64")
6165 (if_then_else (match_operand:QI 2 "incdec_operand")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "modrm" "1")
6169 (set_attr "mode" "QI")])
6171 (define_insn "*addqi_ext_2"
6172 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6177 (match_operand 1 "ext_register_operand" "%0")
6181 (match_operand 2 "ext_register_operand" "Q")
6184 (clobber (reg:CC FLAGS_REG))]
6186 "add{b}\t{%h2, %h0|%h0, %h2}"
6187 [(set_attr "type" "alu")
6188 (set_attr "mode" "QI")])
6190 ;; Add with jump on overflow.
6191 (define_expand "addv<mode>4"
6192 [(parallel [(set (reg:CCO FLAGS_REG)
6195 (match_operand:SWI 1 "nonimmediate_operand"))
6197 (match_operand:SWI 2 "<general_operand>")))
6199 (plus:SWI (match_dup 1) (match_dup 2)))))
6200 (set (match_operand:SWI 0 "register_operand")
6201 (plus:SWI (match_dup 1) (match_dup 2)))])
6202 (set (pc) (if_then_else
6203 (eq (reg:CCO FLAGS_REG) (const_int 0))
6204 (label_ref (match_operand 3))
6207 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6209 (define_insn "*addv<mode>4"
6210 [(set (reg:CCO FLAGS_REG)
6213 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6215 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")))
6217 (plus:SWI (match_dup 1) (match_dup 2)))))
6218 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6219 (plus:SWI (match_dup 1) (match_dup 2)))]
6220 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6221 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6222 [(set_attr "type" "alu")
6223 (set_attr "mode" "<MODE>")])
6225 ;; The lea patterns for modes less than 32 bits need to be matched by
6226 ;; several insns converted to real lea by splitters.
6228 (define_insn_and_split "*lea_general_1"
6229 [(set (match_operand 0 "register_operand" "=r")
6230 (plus (plus (match_operand 1 "index_register_operand" "l")
6231 (match_operand 2 "register_operand" "r"))
6232 (match_operand 3 "immediate_operand" "i")))]
6233 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6235 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6236 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6237 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6238 || GET_MODE (operands[3]) == VOIDmode)"
6240 "&& reload_completed"
6243 enum machine_mode mode = SImode;
6246 operands[0] = gen_lowpart (mode, operands[0]);
6247 operands[1] = gen_lowpart (mode, operands[1]);
6248 operands[2] = gen_lowpart (mode, operands[2]);
6249 operands[3] = gen_lowpart (mode, operands[3]);
6251 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6254 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6257 [(set_attr "type" "lea")
6258 (set_attr "mode" "SI")])
6260 (define_insn_and_split "*lea_general_2"
6261 [(set (match_operand 0 "register_operand" "=r")
6262 (plus (mult (match_operand 1 "index_register_operand" "l")
6263 (match_operand 2 "const248_operand" "n"))
6264 (match_operand 3 "nonmemory_operand" "ri")))]
6265 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6266 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6267 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6268 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6269 || GET_MODE (operands[3]) == VOIDmode)"
6271 "&& reload_completed"
6274 enum machine_mode mode = SImode;
6277 operands[0] = gen_lowpart (mode, operands[0]);
6278 operands[1] = gen_lowpart (mode, operands[1]);
6279 operands[3] = gen_lowpart (mode, operands[3]);
6281 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6284 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6287 [(set_attr "type" "lea")
6288 (set_attr "mode" "SI")])
6290 (define_insn_and_split "*lea_general_3"
6291 [(set (match_operand 0 "register_operand" "=r")
6292 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6293 (match_operand 2 "const248_operand" "n"))
6294 (match_operand 3 "register_operand" "r"))
6295 (match_operand 4 "immediate_operand" "i")))]
6296 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6297 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6298 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6299 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6301 "&& reload_completed"
6304 enum machine_mode mode = SImode;
6307 operands[0] = gen_lowpart (mode, operands[0]);
6308 operands[1] = gen_lowpart (mode, operands[1]);
6309 operands[3] = gen_lowpart (mode, operands[3]);
6310 operands[4] = gen_lowpart (mode, operands[4]);
6312 pat = gen_rtx_PLUS (mode,
6314 gen_rtx_MULT (mode, operands[1],
6319 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6322 [(set_attr "type" "lea")
6323 (set_attr "mode" "SI")])
6325 (define_insn_and_split "*lea_general_4"
6326 [(set (match_operand 0 "register_operand" "=r")
6328 (match_operand 1 "index_register_operand" "l")
6329 (match_operand 2 "const_int_operand" "n"))
6330 (match_operand 3 "const_int_operand" "n")))]
6331 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6333 || GET_MODE (operands[0]) == SImode
6334 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6335 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6336 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6337 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6338 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6340 "&& reload_completed"
6343 enum machine_mode mode = GET_MODE (operands[0]);
6346 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6349 operands[0] = gen_lowpart (mode, operands[0]);
6350 operands[1] = gen_lowpart (mode, operands[1]);
6353 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6355 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6356 INTVAL (operands[3]));
6358 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6361 [(set_attr "type" "lea")
6363 (if_then_else (match_operand:DI 0)
6365 (const_string "SI")))])
6367 ;; Subtract instructions
6369 (define_expand "sub<mode>3"
6370 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6371 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6372 (match_operand:SDWIM 2 "<general_operand>")))]
6374 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6376 (define_insn_and_split "*sub<dwi>3_doubleword"
6377 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6379 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6380 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6381 (clobber (reg:CC FLAGS_REG))]
6382 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6385 [(parallel [(set (reg:CC FLAGS_REG)
6386 (compare:CC (match_dup 1) (match_dup 2)))
6388 (minus:DWIH (match_dup 1) (match_dup 2)))])
6389 (parallel [(set (match_dup 3)
6393 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6395 (clobber (reg:CC FLAGS_REG))])]
6396 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6398 (define_insn "*sub<mode>_1"
6399 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6401 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6402 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6403 (clobber (reg:CC FLAGS_REG))]
6404 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "<MODE>")])
6409 (define_insn "*subsi_1_zext"
6410 [(set (match_operand:DI 0 "register_operand" "=r")
6412 (minus:SI (match_operand:SI 1 "register_operand" "0")
6413 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6414 (clobber (reg:CC FLAGS_REG))]
6415 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6416 "sub{l}\t{%2, %k0|%k0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "mode" "SI")])
6420 (define_insn "*subqi_1_slp"
6421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6422 (minus:QI (match_dup 0)
6423 (match_operand:QI 1 "general_operand" "qn,qm")))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6427 "sub{b}\t{%1, %0|%0, %1}"
6428 [(set_attr "type" "alu1")
6429 (set_attr "mode" "QI")])
6431 (define_insn "*sub<mode>_2"
6432 [(set (reg FLAGS_REG)
6435 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6436 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_match_ccmode (insn, CCGOCmode)
6441 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6442 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "<MODE>")])
6446 (define_insn "*subsi_2_zext"
6447 [(set (reg FLAGS_REG)
6449 (minus:SI (match_operand:SI 1 "register_operand" "0")
6450 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6452 (set (match_operand:DI 0 "register_operand" "=r")
6454 (minus:SI (match_dup 1)
6456 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6457 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6458 "sub{l}\t{%2, %k0|%k0, %2}"
6459 [(set_attr "type" "alu")
6460 (set_attr "mode" "SI")])
6462 ;; Subtract with jump on overflow.
6463 (define_expand "subv<mode>4"
6464 [(parallel [(set (reg:CCO FLAGS_REG)
6465 (eq:CCO (minus:<DWI>
6467 (match_operand:SWI 1 "nonimmediate_operand"))
6469 (match_operand:SWI 2 "<general_operand>")))
6471 (minus:SWI (match_dup 1) (match_dup 2)))))
6472 (set (match_operand:SWI 0 "register_operand")
6473 (minus:SWI (match_dup 1) (match_dup 2)))])
6474 (set (pc) (if_then_else
6475 (eq (reg:CCO FLAGS_REG) (const_int 0))
6476 (label_ref (match_operand 3))
6479 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6481 (define_insn "*subv<mode>4"
6482 [(set (reg:CCO FLAGS_REG)
6483 (eq:CCO (minus:<DWI>
6485 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6487 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6489 (minus:SWI (match_dup 1) (match_dup 2)))))
6490 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6491 (minus:SWI (match_dup 1) (match_dup 2)))]
6492 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6493 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6494 [(set_attr "type" "alu")
6495 (set_attr "mode" "<MODE>")])
6497 (define_insn "*sub<mode>_3"
6498 [(set (reg FLAGS_REG)
6499 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6500 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6501 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502 (minus:SWI (match_dup 1) (match_dup 2)))]
6503 "ix86_match_ccmode (insn, CCmode)
6504 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6509 (define_insn "*subsi_3_zext"
6510 [(set (reg FLAGS_REG)
6511 (compare (match_operand:SI 1 "register_operand" "0")
6512 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6513 (set (match_operand:DI 0 "register_operand" "=r")
6515 (minus:SI (match_dup 1)
6517 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6518 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6519 "sub{l}\t{%2, %1|%1, %2}"
6520 [(set_attr "type" "alu")
6521 (set_attr "mode" "SI")])
6523 ;; Add with carry and subtract with borrow
6525 (define_expand "<plusminus_insn><mode>3_carry"
6527 [(set (match_operand:SWI 0 "nonimmediate_operand")
6529 (match_operand:SWI 1 "nonimmediate_operand")
6530 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6531 [(match_operand 3 "flags_reg_operand")
6533 (match_operand:SWI 2 "<general_operand>"))))
6534 (clobber (reg:CC FLAGS_REG))])]
6535 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6537 (define_insn "*<plusminus_insn><mode>3_carry"
6538 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6540 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6542 (match_operator 3 "ix86_carry_flag_operator"
6543 [(reg FLAGS_REG) (const_int 0)])
6544 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6545 (clobber (reg:CC FLAGS_REG))]
6546 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6547 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "use_carry" "1")
6550 (set_attr "pent_pair" "pu")
6551 (set_attr "mode" "<MODE>")])
6553 (define_insn "*addsi3_carry_zext"
6554 [(set (match_operand:DI 0 "register_operand" "=r")
6556 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6557 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6558 [(reg FLAGS_REG) (const_int 0)])
6559 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6562 "adc{l}\t{%2, %k0|%k0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "use_carry" "1")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "SI")])
6568 (define_insn "*subsi3_carry_zext"
6569 [(set (match_operand:DI 0 "register_operand" "=r")
6571 (minus:SI (match_operand:SI 1 "register_operand" "0")
6572 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6573 [(reg FLAGS_REG) (const_int 0)])
6574 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6575 (clobber (reg:CC FLAGS_REG))]
6576 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6577 "sbb{l}\t{%2, %k0|%k0, %2}"
6578 [(set_attr "type" "alu")
6579 (set_attr "pent_pair" "pu")
6580 (set_attr "mode" "SI")])
6584 (define_insn "adcx<mode>3"
6585 [(set (reg:CCC FLAGS_REG)
6588 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6590 (match_operator 4 "ix86_carry_flag_operator"
6591 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6592 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6594 (set (match_operand:SWI48 0 "register_operand" "=r")
6595 (plus:SWI48 (match_dup 1)
6596 (plus:SWI48 (match_op_dup 4
6597 [(match_dup 3) (const_int 0)])
6599 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6600 "adcx\t{%2, %0|%0, %2}"
6601 [(set_attr "type" "alu")
6602 (set_attr "use_carry" "1")
6603 (set_attr "mode" "<MODE>")])
6605 ;; Overflow setting add instructions
6607 (define_insn "*add<mode>3_cconly_overflow"
6608 [(set (reg:CCC FLAGS_REG)
6611 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6612 (match_operand:SWI 2 "<general_operand>" "<g>"))
6614 (clobber (match_scratch:SWI 0 "=<r>"))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "mode" "<MODE>")])
6620 (define_insn "*add<mode>3_cc_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6625 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6627 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6628 (plus:SWI (match_dup 1) (match_dup 2)))]
6629 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6630 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "<MODE>")])
6634 (define_insn "*addsi3_zext_cc_overflow"
6635 [(set (reg:CCC FLAGS_REG)
6638 (match_operand:SI 1 "nonimmediate_operand" "%0")
6639 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6641 (set (match_operand:DI 0 "register_operand" "=r")
6642 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6643 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6644 "add{l}\t{%2, %k0|%k0, %2}"
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "SI")])
6648 ;; The patterns that match these are at the end of this file.
6650 (define_expand "<plusminus_insn>xf3"
6651 [(set (match_operand:XF 0 "register_operand")
6653 (match_operand:XF 1 "register_operand")
6654 (match_operand:XF 2 "register_operand")))]
6657 (define_expand "<plusminus_insn><mode>3"
6658 [(set (match_operand:MODEF 0 "register_operand")
6660 (match_operand:MODEF 1 "register_operand")
6661 (match_operand:MODEF 2 "nonimmediate_operand")))]
6662 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6663 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6665 ;; Multiply instructions
6667 (define_expand "mul<mode>3"
6668 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6670 (match_operand:SWIM248 1 "register_operand")
6671 (match_operand:SWIM248 2 "<general_operand>")))
6672 (clobber (reg:CC FLAGS_REG))])])
6674 (define_expand "mulqi3"
6675 [(parallel [(set (match_operand:QI 0 "register_operand")
6677 (match_operand:QI 1 "register_operand")
6678 (match_operand:QI 2 "nonimmediate_operand")))
6679 (clobber (reg:CC FLAGS_REG))])]
6680 "TARGET_QIMODE_MATH")
6683 ;; IMUL reg32/64, reg32/64, imm8 Direct
6684 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6685 ;; IMUL reg32/64, reg32/64, imm32 Direct
6686 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6687 ;; IMUL reg32/64, reg32/64 Direct
6688 ;; IMUL reg32/64, mem32/64 Direct
6690 ;; On BDVER1, all above IMULs use DirectPath
6692 (define_insn "*mul<mode>3_1"
6693 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6695 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6696 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6697 (clobber (reg:CC FLAGS_REG))]
6698 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6700 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6701 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6702 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6703 [(set_attr "type" "imul")
6704 (set_attr "prefix_0f" "0,0,1")
6705 (set (attr "athlon_decode")
6706 (cond [(eq_attr "cpu" "athlon")
6707 (const_string "vector")
6708 (eq_attr "alternative" "1")
6709 (const_string "vector")
6710 (and (eq_attr "alternative" "2")
6711 (match_operand 1 "memory_operand"))
6712 (const_string "vector")]
6713 (const_string "direct")))
6714 (set (attr "amdfam10_decode")
6715 (cond [(and (eq_attr "alternative" "0,1")
6716 (match_operand 1 "memory_operand"))
6717 (const_string "vector")]
6718 (const_string "direct")))
6719 (set_attr "bdver1_decode" "direct")
6720 (set_attr "mode" "<MODE>")])
6722 (define_insn "*mulsi3_1_zext"
6723 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6725 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6726 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6727 (clobber (reg:CC FLAGS_REG))]
6729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6731 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6732 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6733 imul{l}\t{%2, %k0|%k0, %2}"
6734 [(set_attr "type" "imul")
6735 (set_attr "prefix_0f" "0,0,1")
6736 (set (attr "athlon_decode")
6737 (cond [(eq_attr "cpu" "athlon")
6738 (const_string "vector")
6739 (eq_attr "alternative" "1")
6740 (const_string "vector")
6741 (and (eq_attr "alternative" "2")
6742 (match_operand 1 "memory_operand"))
6743 (const_string "vector")]
6744 (const_string "direct")))
6745 (set (attr "amdfam10_decode")
6746 (cond [(and (eq_attr "alternative" "0,1")
6747 (match_operand 1 "memory_operand"))
6748 (const_string "vector")]
6749 (const_string "direct")))
6750 (set_attr "bdver1_decode" "direct")
6751 (set_attr "mode" "SI")])
6754 ;; IMUL reg16, reg16, imm8 VectorPath
6755 ;; IMUL reg16, mem16, imm8 VectorPath
6756 ;; IMUL reg16, reg16, imm16 VectorPath
6757 ;; IMUL reg16, mem16, imm16 VectorPath
6758 ;; IMUL reg16, reg16 Direct
6759 ;; IMUL reg16, mem16 Direct
6761 ;; On BDVER1, all HI MULs use DoublePath
6763 (define_insn "*mulhi3_1"
6764 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6765 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6766 (match_operand:HI 2 "general_operand" "K,n,mr")))
6767 (clobber (reg:CC FLAGS_REG))]
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6771 imul{w}\t{%2, %1, %0|%0, %1, %2}
6772 imul{w}\t{%2, %1, %0|%0, %1, %2}
6773 imul{w}\t{%2, %0|%0, %2}"
6774 [(set_attr "type" "imul")
6775 (set_attr "prefix_0f" "0,0,1")
6776 (set (attr "athlon_decode")
6777 (cond [(eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (eq_attr "alternative" "1,2")
6780 (const_string "vector")]
6781 (const_string "direct")))
6782 (set (attr "amdfam10_decode")
6783 (cond [(eq_attr "alternative" "0,1")
6784 (const_string "vector")]
6785 (const_string "direct")))
6786 (set_attr "bdver1_decode" "double")
6787 (set_attr "mode" "HI")])
6789 ;;On AMDFAM10 and BDVER1
6793 (define_insn "*mulqi3_1"
6794 [(set (match_operand:QI 0 "register_operand" "=a")
6795 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6796 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6797 (clobber (reg:CC FLAGS_REG))]
6799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6801 [(set_attr "type" "imul")
6802 (set_attr "length_immediate" "0")
6803 (set (attr "athlon_decode")
6804 (if_then_else (eq_attr "cpu" "athlon")
6805 (const_string "vector")
6806 (const_string "direct")))
6807 (set_attr "amdfam10_decode" "direct")
6808 (set_attr "bdver1_decode" "direct")
6809 (set_attr "mode" "QI")])
6811 ;; Multiply with jump on overflow.
6812 (define_expand "mulv<mode>4"
6813 [(parallel [(set (reg:CCO FLAGS_REG)
6816 (match_operand:SWI48 1 "register_operand"))
6818 (match_operand:SWI48 2 "<general_operand>")))
6820 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6821 (set (match_operand:SWI48 0 "register_operand")
6822 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6823 (set (pc) (if_then_else
6824 (eq (reg:CCO FLAGS_REG) (const_int 0))
6825 (label_ref (match_operand 3))
6828 (define_insn "*mulv<mode>4"
6829 [(set (reg:CCO FLAGS_REG)
6832 (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0"))
6834 (match_operand:SWI 2 "<general_operand>" "K,<i>,mr")))
6836 (mult:SWI (match_dup 1) (match_dup 2)))))
6837 (set (match_operand:SWI 0 "register_operand" "=r,r,r")
6838 (mult:SWI (match_dup 1) (match_dup 2)))]
6839 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6842 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6843 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6844 [(set_attr "type" "imul")
6845 (set_attr "prefix_0f" "0,0,1")
6846 (set (attr "athlon_decode")
6847 (cond [(eq_attr "cpu" "athlon")
6848 (const_string "vector")
6849 (eq_attr "alternative" "1")
6850 (const_string "vector")
6851 (and (eq_attr "alternative" "2")
6852 (match_operand 1 "memory_operand"))
6853 (const_string "vector")]
6854 (const_string "direct")))
6855 (set (attr "amdfam10_decode")
6856 (cond [(and (eq_attr "alternative" "0,1")
6857 (match_operand 1 "memory_operand"))
6858 (const_string "vector")]
6859 (const_string "direct")))
6860 (set_attr "bdver1_decode" "direct")
6861 (set_attr "mode" "<MODE>")])
6863 (define_expand "<u>mul<mode><dwi>3"
6864 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6867 (match_operand:DWIH 1 "nonimmediate_operand"))
6869 (match_operand:DWIH 2 "register_operand"))))
6870 (clobber (reg:CC FLAGS_REG))])])
6872 (define_expand "<u>mulqihi3"
6873 [(parallel [(set (match_operand:HI 0 "register_operand")
6876 (match_operand:QI 1 "nonimmediate_operand"))
6878 (match_operand:QI 2 "register_operand"))))
6879 (clobber (reg:CC FLAGS_REG))])]
6880 "TARGET_QIMODE_MATH")
6882 (define_insn "*bmi2_umulditi3_1"
6883 [(set (match_operand:DI 0 "register_operand" "=r")
6885 (match_operand:DI 2 "nonimmediate_operand" "%d")
6886 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6887 (set (match_operand:DI 1 "register_operand" "=r")
6890 (mult:TI (zero_extend:TI (match_dup 2))
6891 (zero_extend:TI (match_dup 3)))
6893 "TARGET_64BIT && TARGET_BMI2
6894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6895 "mulx\t{%3, %0, %1|%1, %0, %3}"
6896 [(set_attr "type" "imulx")
6897 (set_attr "prefix" "vex")
6898 (set_attr "mode" "DI")])
6900 (define_insn "*bmi2_umulsidi3_1"
6901 [(set (match_operand:SI 0 "register_operand" "=r")
6903 (match_operand:SI 2 "nonimmediate_operand" "%d")
6904 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6905 (set (match_operand:SI 1 "register_operand" "=r")
6908 (mult:DI (zero_extend:DI (match_dup 2))
6909 (zero_extend:DI (match_dup 3)))
6911 "!TARGET_64BIT && TARGET_BMI2
6912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6913 "mulx\t{%3, %0, %1|%1, %0, %3}"
6914 [(set_attr "type" "imulx")
6915 (set_attr "prefix" "vex")
6916 (set_attr "mode" "SI")])
6918 (define_insn "*umul<mode><dwi>3_1"
6919 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6922 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6924 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6929 mul{<imodesuffix>}\t%2"
6930 [(set_attr "isa" "bmi2,*")
6931 (set_attr "type" "imulx,imul")
6932 (set_attr "length_immediate" "*,0")
6933 (set (attr "athlon_decode")
6934 (cond [(eq_attr "alternative" "1")
6935 (if_then_else (eq_attr "cpu" "athlon")
6936 (const_string "vector")
6937 (const_string "double"))]
6938 (const_string "*")))
6939 (set_attr "amdfam10_decode" "*,double")
6940 (set_attr "bdver1_decode" "*,direct")
6941 (set_attr "prefix" "vex,orig")
6942 (set_attr "mode" "<MODE>")])
6944 ;; Convert mul to the mulx pattern to avoid flags dependency.
6946 [(set (match_operand:<DWI> 0 "register_operand")
6949 (match_operand:DWIH 1 "register_operand"))
6951 (match_operand:DWIH 2 "nonimmediate_operand"))))
6952 (clobber (reg:CC FLAGS_REG))]
6953 "TARGET_BMI2 && reload_completed
6954 && true_regnum (operands[1]) == DX_REG"
6955 [(parallel [(set (match_dup 3)
6956 (mult:DWIH (match_dup 1) (match_dup 2)))
6960 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6961 (zero_extend:<DWI> (match_dup 2)))
6964 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6966 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6969 (define_insn "*mul<mode><dwi>3_1"
6970 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6973 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6975 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6976 (clobber (reg:CC FLAGS_REG))]
6977 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6978 "imul{<imodesuffix>}\t%2"
6979 [(set_attr "type" "imul")
6980 (set_attr "length_immediate" "0")
6981 (set (attr "athlon_decode")
6982 (if_then_else (eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (const_string "double")))
6985 (set_attr "amdfam10_decode" "double")
6986 (set_attr "bdver1_decode" "direct")
6987 (set_attr "mode" "<MODE>")])
6989 (define_insn "*<u>mulqihi3_1"
6990 [(set (match_operand:HI 0 "register_operand" "=a")
6993 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6995 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6996 (clobber (reg:CC FLAGS_REG))]
6998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 "<sgnprefix>mul{b}\t%2"
7000 [(set_attr "type" "imul")
7001 (set_attr "length_immediate" "0")
7002 (set (attr "athlon_decode")
7003 (if_then_else (eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (const_string "direct")))
7006 (set_attr "amdfam10_decode" "direct")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "QI")])
7010 (define_expand "<s>mul<mode>3_highpart"
7011 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7016 (match_operand:SWI48 1 "nonimmediate_operand"))
7018 (match_operand:SWI48 2 "register_operand")))
7020 (clobber (match_scratch:SWI48 3))
7021 (clobber (reg:CC FLAGS_REG))])]
7023 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7025 (define_insn "*<s>muldi3_highpart_1"
7026 [(set (match_operand:DI 0 "register_operand" "=d")
7031 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7033 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7035 (clobber (match_scratch:DI 3 "=1"))
7036 (clobber (reg:CC FLAGS_REG))]
7038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039 "<sgnprefix>mul{q}\t%2"
7040 [(set_attr "type" "imul")
7041 (set_attr "length_immediate" "0")
7042 (set (attr "athlon_decode")
7043 (if_then_else (eq_attr "cpu" "athlon")
7044 (const_string "vector")
7045 (const_string "double")))
7046 (set_attr "amdfam10_decode" "double")
7047 (set_attr "bdver1_decode" "direct")
7048 (set_attr "mode" "DI")])
7050 (define_insn "*<s>mulsi3_highpart_1"
7051 [(set (match_operand:SI 0 "register_operand" "=d")
7056 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7058 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7060 (clobber (match_scratch:SI 3 "=1"))
7061 (clobber (reg:CC FLAGS_REG))]
7062 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7063 "<sgnprefix>mul{l}\t%2"
7064 [(set_attr "type" "imul")
7065 (set_attr "length_immediate" "0")
7066 (set (attr "athlon_decode")
7067 (if_then_else (eq_attr "cpu" "athlon")
7068 (const_string "vector")
7069 (const_string "double")))
7070 (set_attr "amdfam10_decode" "double")
7071 (set_attr "bdver1_decode" "direct")
7072 (set_attr "mode" "SI")])
7074 (define_insn "*<s>mulsi3_highpart_zext"
7075 [(set (match_operand:DI 0 "register_operand" "=d")
7076 (zero_extend:DI (truncate:SI
7078 (mult:DI (any_extend:DI
7079 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7081 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7083 (clobber (match_scratch:SI 3 "=1"))
7084 (clobber (reg:CC FLAGS_REG))]
7086 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7087 "<sgnprefix>mul{l}\t%2"
7088 [(set_attr "type" "imul")
7089 (set_attr "length_immediate" "0")
7090 (set (attr "athlon_decode")
7091 (if_then_else (eq_attr "cpu" "athlon")
7092 (const_string "vector")
7093 (const_string "double")))
7094 (set_attr "amdfam10_decode" "double")
7095 (set_attr "bdver1_decode" "direct")
7096 (set_attr "mode" "SI")])
7098 ;; The patterns that match these are at the end of this file.
7100 (define_expand "mulxf3"
7101 [(set (match_operand:XF 0 "register_operand")
7102 (mult:XF (match_operand:XF 1 "register_operand")
7103 (match_operand:XF 2 "register_operand")))]
7106 (define_expand "mul<mode>3"
7107 [(set (match_operand:MODEF 0 "register_operand")
7108 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7109 (match_operand:MODEF 2 "nonimmediate_operand")))]
7110 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7111 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7113 ;; Divide instructions
7115 ;; The patterns that match these are at the end of this file.
7117 (define_expand "divxf3"
7118 [(set (match_operand:XF 0 "register_operand")
7119 (div:XF (match_operand:XF 1 "register_operand")
7120 (match_operand:XF 2 "register_operand")))]
7123 (define_expand "divdf3"
7124 [(set (match_operand:DF 0 "register_operand")
7125 (div:DF (match_operand:DF 1 "register_operand")
7126 (match_operand:DF 2 "nonimmediate_operand")))]
7127 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7128 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7130 (define_expand "divsf3"
7131 [(set (match_operand:SF 0 "register_operand")
7132 (div:SF (match_operand:SF 1 "register_operand")
7133 (match_operand:SF 2 "nonimmediate_operand")))]
7134 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7139 && optimize_insn_for_speed_p ()
7140 && flag_finite_math_only && !flag_trapping_math
7141 && flag_unsafe_math_optimizations)
7143 ix86_emit_swdivsf (operands[0], operands[1],
7144 operands[2], SFmode);
7149 ;; Divmod instructions.
7151 (define_expand "divmod<mode>4"
7152 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7154 (match_operand:SWIM248 1 "register_operand")
7155 (match_operand:SWIM248 2 "nonimmediate_operand")))
7156 (set (match_operand:SWIM248 3 "register_operand")
7157 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7158 (clobber (reg:CC FLAGS_REG))])])
7160 ;; Split with 8bit unsigned divide:
7161 ;; if (dividend an divisor are in [0-255])
7162 ;; use 8bit unsigned integer divide
7164 ;; use original integer divide
7166 [(set (match_operand:SWI48 0 "register_operand")
7167 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7168 (match_operand:SWI48 3 "nonimmediate_operand")))
7169 (set (match_operand:SWI48 1 "register_operand")
7170 (mod:SWI48 (match_dup 2) (match_dup 3)))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "TARGET_USE_8BIT_IDIV
7173 && TARGET_QIMODE_MATH
7174 && can_create_pseudo_p ()
7175 && !optimize_insn_for_size_p ()"
7177 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7179 (define_insn_and_split "divmod<mode>4_1"
7180 [(set (match_operand:SWI48 0 "register_operand" "=a")
7181 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7182 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7183 (set (match_operand:SWI48 1 "register_operand" "=&d")
7184 (mod:SWI48 (match_dup 2) (match_dup 3)))
7185 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7186 (clobber (reg:CC FLAGS_REG))]
7190 [(parallel [(set (match_dup 1)
7191 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7192 (clobber (reg:CC FLAGS_REG))])
7193 (parallel [(set (match_dup 0)
7194 (div:SWI48 (match_dup 2) (match_dup 3)))
7196 (mod:SWI48 (match_dup 2) (match_dup 3)))
7198 (clobber (reg:CC FLAGS_REG))])]
7200 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7202 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7203 operands[4] = operands[2];
7206 /* Avoid use of cltd in favor of a mov+shift. */
7207 emit_move_insn (operands[1], operands[2]);
7208 operands[4] = operands[1];
7211 [(set_attr "type" "multi")
7212 (set_attr "mode" "<MODE>")])
7214 (define_insn_and_split "*divmod<mode>4"
7215 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7216 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7217 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7218 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7219 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))]
7224 [(parallel [(set (match_dup 1)
7225 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7226 (clobber (reg:CC FLAGS_REG))])
7227 (parallel [(set (match_dup 0)
7228 (div:SWIM248 (match_dup 2) (match_dup 3)))
7230 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7232 (clobber (reg:CC FLAGS_REG))])]
7234 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7236 if (<MODE>mode != HImode
7237 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7238 operands[4] = operands[2];
7241 /* Avoid use of cltd in favor of a mov+shift. */
7242 emit_move_insn (operands[1], operands[2]);
7243 operands[4] = operands[1];
7246 [(set_attr "type" "multi")
7247 (set_attr "mode" "<MODE>")])
7249 (define_insn "*divmod<mode>4_noext"
7250 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7251 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7252 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7253 (set (match_operand:SWIM248 1 "register_operand" "=d")
7254 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7255 (use (match_operand:SWIM248 4 "register_operand" "1"))
7256 (clobber (reg:CC FLAGS_REG))]
7258 "idiv{<imodesuffix>}\t%3"
7259 [(set_attr "type" "idiv")
7260 (set_attr "mode" "<MODE>")])
7262 (define_expand "divmodqi4"
7263 [(parallel [(set (match_operand:QI 0 "register_operand")
7265 (match_operand:QI 1 "register_operand")
7266 (match_operand:QI 2 "nonimmediate_operand")))
7267 (set (match_operand:QI 3 "register_operand")
7268 (mod:QI (match_dup 1) (match_dup 2)))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH"
7275 tmp0 = gen_reg_rtx (HImode);
7276 tmp1 = gen_reg_rtx (HImode);
7278 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7280 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7281 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7283 /* Extract remainder from AH. */
7284 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7285 insn = emit_move_insn (operands[3], tmp1);
7287 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7288 set_unique_reg_note (insn, REG_EQUAL, mod);
7290 /* Extract quotient from AL. */
7291 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7293 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7294 set_unique_reg_note (insn, REG_EQUAL, div);
7299 ;; Divide AX by r/m8, with result stored in
7302 ;; Change div/mod to HImode and extend the second argument to HImode
7303 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7304 ;; combine may fail.
7305 (define_insn "divmodhiqi3"
7306 [(set (match_operand:HI 0 "register_operand" "=a")
7311 (mod:HI (match_operand:HI 1 "register_operand" "0")
7313 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7317 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "TARGET_QIMODE_MATH"
7321 [(set_attr "type" "idiv")
7322 (set_attr "mode" "QI")])
7324 (define_expand "udivmod<mode>4"
7325 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7327 (match_operand:SWIM248 1 "register_operand")
7328 (match_operand:SWIM248 2 "nonimmediate_operand")))
7329 (set (match_operand:SWIM248 3 "register_operand")
7330 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7331 (clobber (reg:CC FLAGS_REG))])])
7333 ;; Split with 8bit unsigned divide:
7334 ;; if (dividend an divisor are in [0-255])
7335 ;; use 8bit unsigned integer divide
7337 ;; use original integer divide
7339 [(set (match_operand:SWI48 0 "register_operand")
7340 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7341 (match_operand:SWI48 3 "nonimmediate_operand")))
7342 (set (match_operand:SWI48 1 "register_operand")
7343 (umod:SWI48 (match_dup 2) (match_dup 3)))
7344 (clobber (reg:CC FLAGS_REG))]
7345 "TARGET_USE_8BIT_IDIV
7346 && TARGET_QIMODE_MATH
7347 && can_create_pseudo_p ()
7348 && !optimize_insn_for_size_p ()"
7350 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7352 (define_insn_and_split "udivmod<mode>4_1"
7353 [(set (match_operand:SWI48 0 "register_operand" "=a")
7354 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7355 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7356 (set (match_operand:SWI48 1 "register_operand" "=&d")
7357 (umod:SWI48 (match_dup 2) (match_dup 3)))
7358 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7359 (clobber (reg:CC FLAGS_REG))]
7363 [(set (match_dup 1) (const_int 0))
7364 (parallel [(set (match_dup 0)
7365 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7367 (umod:SWI48 (match_dup 2) (match_dup 3)))
7369 (clobber (reg:CC FLAGS_REG))])]
7371 [(set_attr "type" "multi")
7372 (set_attr "mode" "<MODE>")])
7374 (define_insn_and_split "*udivmod<mode>4"
7375 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7376 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7377 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7378 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7379 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7380 (clobber (reg:CC FLAGS_REG))]
7384 [(set (match_dup 1) (const_int 0))
7385 (parallel [(set (match_dup 0)
7386 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7388 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7390 (clobber (reg:CC FLAGS_REG))])]
7392 [(set_attr "type" "multi")
7393 (set_attr "mode" "<MODE>")])
7395 (define_insn "*udivmod<mode>4_noext"
7396 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7397 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7398 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7399 (set (match_operand:SWIM248 1 "register_operand" "=d")
7400 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7401 (use (match_operand:SWIM248 4 "register_operand" "1"))
7402 (clobber (reg:CC FLAGS_REG))]
7404 "div{<imodesuffix>}\t%3"
7405 [(set_attr "type" "idiv")
7406 (set_attr "mode" "<MODE>")])
7408 (define_expand "udivmodqi4"
7409 [(parallel [(set (match_operand:QI 0 "register_operand")
7411 (match_operand:QI 1 "register_operand")
7412 (match_operand:QI 2 "nonimmediate_operand")))
7413 (set (match_operand:QI 3 "register_operand")
7414 (umod:QI (match_dup 1) (match_dup 2)))
7415 (clobber (reg:CC FLAGS_REG))])]
7416 "TARGET_QIMODE_MATH"
7421 tmp0 = gen_reg_rtx (HImode);
7422 tmp1 = gen_reg_rtx (HImode);
7424 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7426 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7427 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7429 /* Extract remainder from AH. */
7430 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7431 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7432 insn = emit_move_insn (operands[3], tmp1);
7434 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7435 set_unique_reg_note (insn, REG_EQUAL, mod);
7437 /* Extract quotient from AL. */
7438 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7440 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7441 set_unique_reg_note (insn, REG_EQUAL, div);
7446 (define_insn "udivmodhiqi3"
7447 [(set (match_operand:HI 0 "register_operand" "=a")
7452 (mod:HI (match_operand:HI 1 "register_operand" "0")
7454 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7458 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7459 (clobber (reg:CC FLAGS_REG))]
7460 "TARGET_QIMODE_MATH"
7462 [(set_attr "type" "idiv")
7463 (set_attr "mode" "QI")])
7465 ;; We cannot use div/idiv for double division, because it causes
7466 ;; "division by zero" on the overflow and that's not what we expect
7467 ;; from truncate. Because true (non truncating) double division is
7468 ;; never generated, we can't create this insn anyway.
7471 ; [(set (match_operand:SI 0 "register_operand" "=a")
7473 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7475 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7476 ; (set (match_operand:SI 3 "register_operand" "=d")
7478 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7479 ; (clobber (reg:CC FLAGS_REG))]
7481 ; "div{l}\t{%2, %0|%0, %2}"
7482 ; [(set_attr "type" "idiv")])
7484 ;;- Logical AND instructions
7486 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7487 ;; Note that this excludes ah.
7489 (define_expand "testsi_ccno_1"
7490 [(set (reg:CCNO FLAGS_REG)
7492 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7493 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7496 (define_expand "testqi_ccz_1"
7497 [(set (reg:CCZ FLAGS_REG)
7498 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7499 (match_operand:QI 1 "nonmemory_operand"))
7502 (define_expand "testdi_ccno_1"
7503 [(set (reg:CCNO FLAGS_REG)
7505 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7506 (match_operand:DI 1 "x86_64_szext_general_operand"))
7508 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7510 (define_insn "*testdi_1"
7511 [(set (reg FLAGS_REG)
7514 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7515 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7517 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7518 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7520 test{l}\t{%k1, %k0|%k0, %k1}
7521 test{l}\t{%k1, %k0|%k0, %k1}
7522 test{q}\t{%1, %0|%0, %1}
7523 test{q}\t{%1, %0|%0, %1}
7524 test{q}\t{%1, %0|%0, %1}"
7525 [(set_attr "type" "test")
7526 (set_attr "modrm" "0,1,0,1,1")
7527 (set_attr "mode" "SI,SI,DI,DI,DI")])
7529 (define_insn "*testqi_1_maybe_si"
7530 [(set (reg FLAGS_REG)
7533 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7534 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7536 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7537 && ix86_match_ccmode (insn,
7538 CONST_INT_P (operands[1])
7539 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7541 if (which_alternative == 3)
7543 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7544 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7545 return "test{l}\t{%1, %k0|%k0, %1}";
7547 return "test{b}\t{%1, %0|%0, %1}";
7549 [(set_attr "type" "test")
7550 (set_attr "modrm" "0,1,1,1")
7551 (set_attr "mode" "QI,QI,QI,SI")
7552 (set_attr "pent_pair" "uv,np,uv,np")])
7554 (define_insn "*test<mode>_1"
7555 [(set (reg FLAGS_REG)
7558 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7559 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7561 "ix86_match_ccmode (insn, CCNOmode)
7562 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7563 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7564 [(set_attr "type" "test")
7565 (set_attr "modrm" "0,1,1")
7566 (set_attr "mode" "<MODE>")
7567 (set_attr "pent_pair" "uv,np,uv")])
7569 (define_expand "testqi_ext_ccno_0"
7570 [(set (reg:CCNO FLAGS_REG)
7574 (match_operand 0 "ext_register_operand")
7577 (match_operand 1 "const_int_operand"))
7580 (define_insn "*testqi_ext_0"
7581 [(set (reg FLAGS_REG)
7585 (match_operand 0 "ext_register_operand" "Q")
7588 (match_operand 1 "const_int_operand" "n"))
7590 "ix86_match_ccmode (insn, CCNOmode)"
7591 "test{b}\t{%1, %h0|%h0, %1}"
7592 [(set_attr "type" "test")
7593 (set_attr "mode" "QI")
7594 (set_attr "length_immediate" "1")
7595 (set_attr "modrm" "1")
7596 (set_attr "pent_pair" "np")])
7598 (define_insn "*testqi_ext_1"
7599 [(set (reg FLAGS_REG)
7603 (match_operand 0 "ext_register_operand" "Q,Q")
7607 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7609 "ix86_match_ccmode (insn, CCNOmode)"
7610 "test{b}\t{%1, %h0|%h0, %1}"
7611 [(set_attr "isa" "*,nox64")
7612 (set_attr "type" "test")
7613 (set_attr "mode" "QI")])
7615 (define_insn "*testqi_ext_2"
7616 [(set (reg FLAGS_REG)
7620 (match_operand 0 "ext_register_operand" "Q")
7624 (match_operand 1 "ext_register_operand" "Q")
7628 "ix86_match_ccmode (insn, CCNOmode)"
7629 "test{b}\t{%h1, %h0|%h0, %h1}"
7630 [(set_attr "type" "test")
7631 (set_attr "mode" "QI")])
7633 ;; Combine likes to form bit extractions for some tests. Humor it.
7634 (define_insn "*testqi_ext_3"
7635 [(set (reg FLAGS_REG)
7636 (compare (zero_extract:SWI48
7637 (match_operand 0 "nonimmediate_operand" "rm")
7638 (match_operand:SWI48 1 "const_int_operand")
7639 (match_operand:SWI48 2 "const_int_operand"))
7641 "ix86_match_ccmode (insn, CCNOmode)
7642 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7643 || GET_MODE (operands[0]) == SImode
7644 || GET_MODE (operands[0]) == HImode
7645 || GET_MODE (operands[0]) == QImode)
7646 /* Ensure that resulting mask is zero or sign extended operand. */
7647 && INTVAL (operands[2]) >= 0
7648 && ((INTVAL (operands[1]) > 0
7649 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7650 || (<MODE>mode == DImode
7651 && INTVAL (operands[1]) > 32
7652 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7656 [(set (match_operand 0 "flags_reg_operand")
7657 (match_operator 1 "compare_operator"
7659 (match_operand 2 "nonimmediate_operand")
7660 (match_operand 3 "const_int_operand")
7661 (match_operand 4 "const_int_operand"))
7663 "ix86_match_ccmode (insn, CCNOmode)"
7664 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7666 rtx val = operands[2];
7667 HOST_WIDE_INT len = INTVAL (operands[3]);
7668 HOST_WIDE_INT pos = INTVAL (operands[4]);
7670 enum machine_mode mode, submode;
7672 mode = GET_MODE (val);
7675 /* ??? Combine likes to put non-volatile mem extractions in QImode
7676 no matter the size of the test. So find a mode that works. */
7677 if (! MEM_VOLATILE_P (val))
7679 mode = smallest_mode_for_size (pos + len, MODE_INT);
7680 val = adjust_address (val, mode, 0);
7683 else if (GET_CODE (val) == SUBREG
7684 && (submode = GET_MODE (SUBREG_REG (val)),
7685 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7686 && pos + len <= GET_MODE_BITSIZE (submode)
7687 && GET_MODE_CLASS (submode) == MODE_INT)
7689 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7691 val = SUBREG_REG (val);
7693 else if (mode == HImode && pos + len <= 8)
7695 /* Small HImode tests can be converted to QImode. */
7697 val = gen_lowpart (QImode, val);
7700 if (len == HOST_BITS_PER_WIDE_INT)
7703 mask = ((HOST_WIDE_INT)1 << len) - 1;
7706 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7709 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7710 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7711 ;; this is relatively important trick.
7712 ;; Do the conversion only post-reload to avoid limiting of the register class
7715 [(set (match_operand 0 "flags_reg_operand")
7716 (match_operator 1 "compare_operator"
7717 [(and (match_operand 2 "register_operand")
7718 (match_operand 3 "const_int_operand"))
7721 && QI_REG_P (operands[2])
7722 && GET_MODE (operands[2]) != QImode
7723 && ((ix86_match_ccmode (insn, CCZmode)
7724 && !(INTVAL (operands[3]) & ~(255 << 8)))
7725 || (ix86_match_ccmode (insn, CCNOmode)
7726 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7729 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7733 operands[2] = gen_lowpart (SImode, operands[2]);
7734 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7738 [(set (match_operand 0 "flags_reg_operand")
7739 (match_operator 1 "compare_operator"
7740 [(and (match_operand 2 "nonimmediate_operand")
7741 (match_operand 3 "const_int_operand"))
7744 && GET_MODE (operands[2]) != QImode
7745 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7746 && ((ix86_match_ccmode (insn, CCZmode)
7747 && !(INTVAL (operands[3]) & ~255))
7748 || (ix86_match_ccmode (insn, CCNOmode)
7749 && !(INTVAL (operands[3]) & ~127)))"
7751 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7754 operands[2] = gen_lowpart (QImode, operands[2]);
7755 operands[3] = gen_lowpart (QImode, operands[3]);
7759 [(set (match_operand:SWI12 0 "mask_reg_operand")
7760 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7761 (match_operand:SWI12 2 "mask_reg_operand")))
7762 (clobber (reg:CC FLAGS_REG))]
7763 "TARGET_AVX512F && reload_completed"
7765 (any_logic:SWI12 (match_dup 1)
7768 (define_insn "*k<logic><mode>"
7769 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7770 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7771 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7773 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7774 [(set_attr "mode" "<MODE>")
7775 (set_attr "type" "msklog")
7776 (set_attr "prefix" "vex")])
7778 ;; %%% This used to optimize known byte-wide and operations to memory,
7779 ;; and sometimes to QImode registers. If this is considered useful,
7780 ;; it should be done with splitters.
7782 (define_expand "and<mode>3"
7783 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7784 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7785 (match_operand:SWIM 2 "<general_szext_operand>")))]
7788 enum machine_mode mode = <MODE>mode;
7789 rtx (*insn) (rtx, rtx);
7791 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7793 HOST_WIDE_INT ival = INTVAL (operands[2]);
7795 if (ival == (HOST_WIDE_INT) 0xffffffff)
7797 else if (ival == 0xffff)
7799 else if (ival == 0xff)
7803 if (mode == <MODE>mode)
7805 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7809 if (<MODE>mode == DImode)
7810 insn = (mode == SImode)
7811 ? gen_zero_extendsidi2
7813 ? gen_zero_extendhidi2
7814 : gen_zero_extendqidi2;
7815 else if (<MODE>mode == SImode)
7816 insn = (mode == HImode)
7817 ? gen_zero_extendhisi2
7818 : gen_zero_extendqisi2;
7819 else if (<MODE>mode == HImode)
7820 insn = gen_zero_extendqihi2;
7824 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7828 (define_insn "*anddi_1"
7829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7831 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7832 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7833 (clobber (reg:CC FLAGS_REG))]
7834 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7836 switch (get_attr_type (insn))
7842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7843 if (get_attr_mode (insn) == MODE_SI)
7844 return "and{l}\t{%k2, %k0|%k0, %k2}";
7846 return "and{q}\t{%2, %0|%0, %2}";
7849 [(set_attr "type" "alu,alu,alu,imovx")
7850 (set_attr "length_immediate" "*,*,*,0")
7851 (set (attr "prefix_rex")
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7857 (const_string "*")))
7858 (set_attr "mode" "SI,DI,DI,SI")])
7860 (define_insn "*andsi_1"
7861 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7862 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7863 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "ix86_binary_operator_ok (AND, SImode, operands)"
7867 switch (get_attr_type (insn))
7873 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7874 return "and{l}\t{%2, %0|%0, %2}";
7877 [(set_attr "type" "alu,alu,imovx")
7878 (set (attr "prefix_rex")
7880 (and (eq_attr "type" "imovx")
7881 (and (match_test "INTVAL (operands[2]) == 0xff")
7882 (match_operand 1 "ext_QIreg_operand")))
7884 (const_string "*")))
7885 (set_attr "length_immediate" "*,*,0")
7886 (set_attr "mode" "SI")])
7888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7889 (define_insn "*andsi_1_zext"
7890 [(set (match_operand:DI 0 "register_operand" "=r")
7892 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7893 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7896 "and{l}\t{%2, %k0|%k0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI")])
7900 (define_insn "*andhi_1"
7901 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7902 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7903 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "ix86_binary_operator_ok (AND, HImode, operands)"
7907 switch (get_attr_type (insn))
7913 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7916 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7917 return "and{w}\t{%2, %0|%0, %2}";
7920 [(set_attr "type" "alu,alu,imovx,msklog")
7921 (set_attr "length_immediate" "*,*,0,*")
7922 (set (attr "prefix_rex")
7924 (and (eq_attr "type" "imovx")
7925 (match_operand 1 "ext_QIreg_operand"))
7927 (const_string "*")))
7928 (set_attr "mode" "HI,HI,SI,HI")])
7930 ;; %%% Potential partial reg stall on alternative 2. What to do?
7931 (define_insn "*andqi_1"
7932 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7933 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7934 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7935 (clobber (reg:CC FLAGS_REG))]
7936 "ix86_binary_operator_ok (AND, QImode, operands)"
7938 and{b}\t{%2, %0|%0, %2}
7939 and{b}\t{%2, %0|%0, %2}
7940 and{l}\t{%k2, %k0|%k0, %k2}
7941 kandw\t{%2, %1, %0|%0, %1, %2}"
7942 [(set_attr "type" "alu,alu,alu,msklog")
7943 (set_attr "mode" "QI,QI,SI,HI")])
7945 (define_insn "*andqi_1_slp"
7946 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7947 (and:QI (match_dup 0)
7948 (match_operand:QI 1 "general_operand" "qn,qmn")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7951 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7952 "and{b}\t{%1, %0|%0, %1}"
7953 [(set_attr "type" "alu1")
7954 (set_attr "mode" "QI")])
7956 (define_insn "kandn<mode>"
7957 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7960 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7961 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7962 (clobber (reg:CC FLAGS_REG))]
7965 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7967 kandnw\t{%2, %1, %0|%0, %1, %2}"
7968 [(set_attr "isa" "bmi,*,avx512f")
7969 (set_attr "type" "bitmanip,*,msklog")
7970 (set_attr "prefix" "*,*,vex")
7971 (set_attr "btver2_decode" "direct,*,*")
7972 (set_attr "mode" "<MODE>")])
7975 [(set (match_operand:SWI12 0 "general_reg_operand")
7979 (match_operand:SWI12 1 "general_reg_operand")))
7980 (clobber (reg:CC FLAGS_REG))]
7981 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7983 (not:HI (match_dup 0)))
7984 (parallel [(set (match_dup 0)
7985 (and:HI (match_dup 0)
7987 (clobber (reg:CC FLAGS_REG))])])
7989 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7991 [(set (match_operand:DI 0 "register_operand")
7992 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7993 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7994 (clobber (reg:CC FLAGS_REG))]
7996 [(parallel [(set (match_dup 0)
7997 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7998 (clobber (reg:CC FLAGS_REG))])]
7999 "operands[2] = gen_lowpart (SImode, operands[2]);")
8002 [(set (match_operand:SWI248 0 "register_operand")
8003 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8004 (match_operand:SWI248 2 "const_int_operand")))
8005 (clobber (reg:CC FLAGS_REG))]
8007 && true_regnum (operands[0]) != true_regnum (operands[1])"
8010 HOST_WIDE_INT ival = INTVAL (operands[2]);
8011 enum machine_mode mode;
8012 rtx (*insn) (rtx, rtx);
8014 if (ival == (HOST_WIDE_INT) 0xffffffff)
8016 else if (ival == 0xffff)
8020 gcc_assert (ival == 0xff);
8024 if (<MODE>mode == DImode)
8025 insn = (mode == SImode)
8026 ? gen_zero_extendsidi2
8028 ? gen_zero_extendhidi2
8029 : gen_zero_extendqidi2;
8032 if (<MODE>mode != SImode)
8033 /* Zero extend to SImode to avoid partial register stalls. */
8034 operands[0] = gen_lowpart (SImode, operands[0]);
8036 insn = (mode == HImode)
8037 ? gen_zero_extendhisi2
8038 : gen_zero_extendqisi2;
8040 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8045 [(set (match_operand 0 "register_operand")
8047 (const_int -65536)))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8050 || optimize_function_for_size_p (cfun)"
8051 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8052 "operands[1] = gen_lowpart (HImode, operands[0]);")
8055 [(set (match_operand 0 "ext_register_operand")
8058 (clobber (reg:CC FLAGS_REG))]
8059 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8060 && reload_completed"
8061 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8062 "operands[1] = gen_lowpart (QImode, operands[0]);")
8065 [(set (match_operand 0 "ext_register_operand")
8067 (const_int -65281)))
8068 (clobber (reg:CC FLAGS_REG))]
8069 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8070 && reload_completed"
8071 [(parallel [(set (zero_extract:SI (match_dup 0)
8075 (zero_extract:SI (match_dup 0)
8078 (zero_extract:SI (match_dup 0)
8081 (clobber (reg:CC FLAGS_REG))])]
8082 "operands[0] = gen_lowpart (SImode, operands[0]);")
8084 (define_insn "*anddi_2"
8085 [(set (reg FLAGS_REG)
8088 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8089 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8091 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8092 (and:DI (match_dup 1) (match_dup 2)))]
8094 && ix86_match_ccmode
8096 /* If we are going to emit andl instead of andq, and the operands[2]
8097 constant might have the SImode sign bit set, make sure the sign
8098 flag isn't tested, because the instruction will set the sign flag
8099 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8100 conservatively assume it might have bit 31 set. */
8101 (satisfies_constraint_Z (operands[2])
8102 && (!CONST_INT_P (operands[2])
8103 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8104 ? CCZmode : CCNOmode)
8105 && ix86_binary_operator_ok (AND, DImode, operands)"
8107 and{l}\t{%k2, %k0|%k0, %k2}
8108 and{q}\t{%2, %0|%0, %2}
8109 and{q}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "mode" "SI,DI,DI")])
8113 (define_insn "*andqi_2_maybe_si"
8114 [(set (reg FLAGS_REG)
8116 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8117 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8119 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8120 (and:QI (match_dup 1) (match_dup 2)))]
8121 "ix86_binary_operator_ok (AND, QImode, operands)
8122 && ix86_match_ccmode (insn,
8123 CONST_INT_P (operands[2])
8124 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8126 if (which_alternative == 2)
8128 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8129 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8130 return "and{l}\t{%2, %k0|%k0, %2}";
8132 return "and{b}\t{%2, %0|%0, %2}";
8134 [(set_attr "type" "alu")
8135 (set_attr "mode" "QI,QI,SI")])
8137 (define_insn "*and<mode>_2"
8138 [(set (reg FLAGS_REG)
8139 (compare (and:SWI124
8140 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8141 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8143 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8144 (and:SWI124 (match_dup 1) (match_dup 2)))]
8145 "ix86_match_ccmode (insn, CCNOmode)
8146 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8147 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "<MODE>")])
8151 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8152 (define_insn "*andsi_2_zext"
8153 [(set (reg FLAGS_REG)
8155 (match_operand:SI 1 "nonimmediate_operand" "%0")
8156 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8158 (set (match_operand:DI 0 "register_operand" "=r")
8159 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8160 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8161 && ix86_binary_operator_ok (AND, SImode, operands)"
8162 "and{l}\t{%2, %k0|%k0, %2}"
8163 [(set_attr "type" "alu")
8164 (set_attr "mode" "SI")])
8166 (define_insn "*andqi_2_slp"
8167 [(set (reg FLAGS_REG)
8169 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8170 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8172 (set (strict_low_part (match_dup 0))
8173 (and:QI (match_dup 0) (match_dup 1)))]
8174 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8175 && ix86_match_ccmode (insn, CCNOmode)
8176 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177 "and{b}\t{%1, %0|%0, %1}"
8178 [(set_attr "type" "alu1")
8179 (set_attr "mode" "QI")])
8181 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8182 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8183 ;; for a QImode operand, which of course failed.
8184 (define_insn "andqi_ext_0"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "0")
8193 (match_operand 2 "const_int_operand" "n")))
8194 (clobber (reg:CC FLAGS_REG))]
8196 "and{b}\t{%2, %h0|%h0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "length_immediate" "1")
8199 (set_attr "modrm" "1")
8200 (set_attr "mode" "QI")])
8202 ;; Generated by peephole translating test to and. This shows up
8203 ;; often in fp comparisons.
8204 (define_insn "*andqi_ext_0_cc"
8205 [(set (reg FLAGS_REG)
8209 (match_operand 1 "ext_register_operand" "0")
8212 (match_operand 2 "const_int_operand" "n"))
8214 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223 "ix86_match_ccmode (insn, CCNOmode)"
8224 "and{b}\t{%2, %h0|%h0, %2}"
8225 [(set_attr "type" "alu")
8226 (set_attr "length_immediate" "1")
8227 (set_attr "modrm" "1")
8228 (set_attr "mode" "QI")])
8230 (define_insn "*andqi_ext_1"
8231 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8236 (match_operand 1 "ext_register_operand" "0,0")
8240 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8241 (clobber (reg:CC FLAGS_REG))]
8243 "and{b}\t{%2, %h0|%h0, %2}"
8244 [(set_attr "isa" "*,nox64")
8245 (set_attr "type" "alu")
8246 (set_attr "length_immediate" "0")
8247 (set_attr "mode" "QI")])
8249 (define_insn "*andqi_ext_2"
8250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8255 (match_operand 1 "ext_register_operand" "%0")
8259 (match_operand 2 "ext_register_operand" "Q")
8262 (clobber (reg:CC FLAGS_REG))]
8264 "and{b}\t{%h2, %h0|%h0, %h2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "length_immediate" "0")
8267 (set_attr "mode" "QI")])
8269 ;; Convert wide AND instructions with immediate operand to shorter QImode
8270 ;; equivalents when possible.
8271 ;; Don't do the splitting with memory operands, since it introduces risk
8272 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8273 ;; for size, but that can (should?) be handled by generic code instead.
8275 [(set (match_operand 0 "register_operand")
8276 (and (match_operand 1 "register_operand")
8277 (match_operand 2 "const_int_operand")))
8278 (clobber (reg:CC FLAGS_REG))]
8280 && QI_REG_P (operands[0])
8281 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8282 && !(~INTVAL (operands[2]) & ~(255 << 8))
8283 && GET_MODE (operands[0]) != QImode"
8284 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8285 (and:SI (zero_extract:SI (match_dup 1)
8286 (const_int 8) (const_int 8))
8288 (clobber (reg:CC FLAGS_REG))])]
8290 operands[0] = gen_lowpart (SImode, operands[0]);
8291 operands[1] = gen_lowpart (SImode, operands[1]);
8292 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8295 ;; Since AND can be encoded with sign extended immediate, this is only
8296 ;; profitable when 7th bit is not set.
8298 [(set (match_operand 0 "register_operand")
8299 (and (match_operand 1 "general_operand")
8300 (match_operand 2 "const_int_operand")))
8301 (clobber (reg:CC FLAGS_REG))]
8303 && ANY_QI_REG_P (operands[0])
8304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8305 && !(~INTVAL (operands[2]) & ~255)
8306 && !(INTVAL (operands[2]) & 128)
8307 && GET_MODE (operands[0]) != QImode"
8308 [(parallel [(set (strict_low_part (match_dup 0))
8309 (and:QI (match_dup 1)
8311 (clobber (reg:CC FLAGS_REG))])]
8313 operands[0] = gen_lowpart (QImode, operands[0]);
8314 operands[1] = gen_lowpart (QImode, operands[1]);
8315 operands[2] = gen_lowpart (QImode, operands[2]);
8318 ;; Logical inclusive and exclusive OR instructions
8320 ;; %%% This used to optimize known byte-wide and operations to memory.
8321 ;; If this is considered useful, it should be done with splitters.
8323 (define_expand "<code><mode>3"
8324 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8325 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8326 (match_operand:SWIM 2 "<general_operand>")))]
8328 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8330 (define_insn "*<code><mode>_1"
8331 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8333 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8334 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8337 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8338 [(set_attr "type" "alu")
8339 (set_attr "mode" "<MODE>")])
8341 (define_insn "*<code>hi_1"
8342 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8344 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8345 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8349 <logic>{w}\t{%2, %0|%0, %2}
8350 <logic>{w}\t{%2, %0|%0, %2}
8351 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8352 [(set_attr "type" "alu,alu,msklog")
8353 (set_attr "mode" "HI")])
8355 ;; %%% Potential partial reg stall on alternative 2. What to do?
8356 (define_insn "*<code>qi_1"
8357 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8358 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8359 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8363 <logic>{b}\t{%2, %0|%0, %2}
8364 <logic>{b}\t{%2, %0|%0, %2}
8365 <logic>{l}\t{%k2, %k0|%k0, %k2}
8366 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8367 [(set_attr "type" "alu,alu,alu,msklog")
8368 (set_attr "mode" "QI,QI,SI,HI")])
8370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8371 (define_insn "*<code>si_1_zext"
8372 [(set (match_operand:DI 0 "register_operand" "=r")
8374 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378 "<logic>{l}\t{%2, %k0|%k0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "mode" "SI")])
8382 (define_insn "*<code>si_1_zext_imm"
8383 [(set (match_operand:DI 0 "register_operand" "=r")
8385 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8386 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8387 (clobber (reg:CC FLAGS_REG))]
8388 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8389 "<logic>{l}\t{%2, %k0|%k0, %2}"
8390 [(set_attr "type" "alu")
8391 (set_attr "mode" "SI")])
8393 (define_insn "*<code>qi_1_slp"
8394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8395 (any_or:QI (match_dup 0)
8396 (match_operand:QI 1 "general_operand" "qmn,qn")))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400 "<logic>{b}\t{%1, %0|%0, %1}"
8401 [(set_attr "type" "alu1")
8402 (set_attr "mode" "QI")])
8404 (define_insn "*<code><mode>_2"
8405 [(set (reg FLAGS_REG)
8406 (compare (any_or:SWI
8407 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8408 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8410 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8411 (any_or:SWI (match_dup 1) (match_dup 2)))]
8412 "ix86_match_ccmode (insn, CCNOmode)
8413 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8414 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "mode" "<MODE>")])
8418 (define_insn "kxnor<mode>"
8419 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8422 (match_operand:SWI12 1 "register_operand" "0,Yk")
8423 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8424 (clobber (reg:CC FLAGS_REG))]
8428 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8429 [(set_attr "type" "*,msklog")
8430 (set_attr "prefix" "*,vex")
8431 (set_attr "mode" "<MODE>")])
8434 [(set (match_operand:SWI12 0 "general_reg_operand")
8438 (match_operand:SWI12 1 "general_reg_operand"))))
8439 (clobber (reg:CC FLAGS_REG))]
8440 "TARGET_AVX512F && reload_completed"
8441 [(parallel [(set (match_dup 0)
8442 (xor:HI (match_dup 0)
8444 (clobber (reg:CC FLAGS_REG))])
8446 (not:HI (match_dup 0)))])
8448 (define_insn "kortestzhi"
8449 [(set (reg:CCZ FLAGS_REG)
8452 (match_operand:HI 0 "register_operand" "Yk")
8453 (match_operand:HI 1 "register_operand" "Yk"))
8455 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8456 "kortestw\t{%1, %0|%0, %1}"
8457 [(set_attr "mode" "HI")
8458 (set_attr "type" "msklog")
8459 (set_attr "prefix" "vex")])
8461 (define_insn "kortestchi"
8462 [(set (reg:CCC FLAGS_REG)
8465 (match_operand:HI 0 "register_operand" "Yk")
8466 (match_operand:HI 1 "register_operand" "Yk"))
8468 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8469 "kortestw\t{%1, %0|%0, %1}"
8470 [(set_attr "mode" "HI")
8471 (set_attr "type" "msklog")
8472 (set_attr "prefix" "vex")])
8474 (define_insn "kunpckhi"
8475 [(set (match_operand:HI 0 "register_operand" "=Yk")
8478 (match_operand:HI 1 "register_operand" "Yk")
8480 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8482 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8483 [(set_attr "mode" "HI")
8484 (set_attr "type" "msklog")
8485 (set_attr "prefix" "vex")])
8487 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8488 ;; ??? Special case for immediate operand is missing - it is tricky.
8489 (define_insn "*<code>si_2_zext"
8490 [(set (reg FLAGS_REG)
8491 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8492 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8494 (set (match_operand:DI 0 "register_operand" "=r")
8495 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8496 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8497 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8498 "<logic>{l}\t{%2, %k0|%k0, %2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "mode" "SI")])
8502 (define_insn "*<code>si_2_zext_imm"
8503 [(set (reg FLAGS_REG)
8505 (match_operand:SI 1 "nonimmediate_operand" "%0")
8506 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8508 (set (match_operand:DI 0 "register_operand" "=r")
8509 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8510 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8511 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8512 "<logic>{l}\t{%2, %k0|%k0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "mode" "SI")])
8516 (define_insn "*<code>qi_2_slp"
8517 [(set (reg FLAGS_REG)
8518 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8519 (match_operand:QI 1 "general_operand" "qmn,qn"))
8521 (set (strict_low_part (match_dup 0))
8522 (any_or:QI (match_dup 0) (match_dup 1)))]
8523 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524 && ix86_match_ccmode (insn, CCNOmode)
8525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8526 "<logic>{b}\t{%1, %0|%0, %1}"
8527 [(set_attr "type" "alu1")
8528 (set_attr "mode" "QI")])
8530 (define_insn "*<code><mode>_3"
8531 [(set (reg FLAGS_REG)
8532 (compare (any_or:SWI
8533 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SWI 2 "<general_operand>" "<g>"))
8536 (clobber (match_scratch:SWI 0 "=<r>"))]
8537 "ix86_match_ccmode (insn, CCNOmode)
8538 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8539 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8540 [(set_attr "type" "alu")
8541 (set_attr "mode" "<MODE>")])
8543 (define_insn "*<code>qi_ext_0"
8544 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8549 (match_operand 1 "ext_register_operand" "0")
8552 (match_operand 2 "const_int_operand" "n")))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8555 "<logic>{b}\t{%2, %h0|%h0, %2}"
8556 [(set_attr "type" "alu")
8557 (set_attr "length_immediate" "1")
8558 (set_attr "modrm" "1")
8559 (set_attr "mode" "QI")])
8561 (define_insn "*<code>qi_ext_1"
8562 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8567 (match_operand 1 "ext_register_operand" "0,0")
8571 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8574 "<logic>{b}\t{%2, %h0|%h0, %2}"
8575 [(set_attr "isa" "*,nox64")
8576 (set_attr "type" "alu")
8577 (set_attr "length_immediate" "0")
8578 (set_attr "mode" "QI")])
8580 (define_insn "*<code>qi_ext_2"
8581 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8585 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8588 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8591 (clobber (reg:CC FLAGS_REG))]
8592 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8593 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "length_immediate" "0")
8596 (set_attr "mode" "QI")])
8599 [(set (match_operand 0 "register_operand")
8600 (any_or (match_operand 1 "register_operand")
8601 (match_operand 2 "const_int_operand")))
8602 (clobber (reg:CC FLAGS_REG))]
8604 && QI_REG_P (operands[0])
8605 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8606 && !(INTVAL (operands[2]) & ~(255 << 8))
8607 && GET_MODE (operands[0]) != QImode"
8608 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8609 (any_or:SI (zero_extract:SI (match_dup 1)
8610 (const_int 8) (const_int 8))
8612 (clobber (reg:CC FLAGS_REG))])]
8614 operands[0] = gen_lowpart (SImode, operands[0]);
8615 operands[1] = gen_lowpart (SImode, operands[1]);
8616 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8619 ;; Since OR can be encoded with sign extended immediate, this is only
8620 ;; profitable when 7th bit is set.
8622 [(set (match_operand 0 "register_operand")
8623 (any_or (match_operand 1 "general_operand")
8624 (match_operand 2 "const_int_operand")))
8625 (clobber (reg:CC FLAGS_REG))]
8627 && ANY_QI_REG_P (operands[0])
8628 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8629 && !(INTVAL (operands[2]) & ~255)
8630 && (INTVAL (operands[2]) & 128)
8631 && GET_MODE (operands[0]) != QImode"
8632 [(parallel [(set (strict_low_part (match_dup 0))
8633 (any_or:QI (match_dup 1)
8635 (clobber (reg:CC FLAGS_REG))])]
8637 operands[0] = gen_lowpart (QImode, operands[0]);
8638 operands[1] = gen_lowpart (QImode, operands[1]);
8639 operands[2] = gen_lowpart (QImode, operands[2]);
8642 (define_expand "xorqi_cc_ext_1"
8644 (set (reg:CCNO FLAGS_REG)
8648 (match_operand 1 "ext_register_operand")
8651 (match_operand:QI 2 "const_int_operand"))
8653 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8663 (define_insn "*xorqi_cc_ext_1"
8664 [(set (reg FLAGS_REG)
8668 (match_operand 1 "ext_register_operand" "0,0")
8671 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8673 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8682 "ix86_match_ccmode (insn, CCNOmode)"
8683 "xor{b}\t{%2, %h0|%h0, %2}"
8684 [(set_attr "isa" "*,nox64")
8685 (set_attr "type" "alu")
8686 (set_attr "modrm" "1")
8687 (set_attr "mode" "QI")])
8689 ;; Negation instructions
8691 (define_expand "neg<mode>2"
8692 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8693 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8695 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8697 (define_insn_and_split "*neg<dwi>2_doubleword"
8698 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8699 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8700 (clobber (reg:CC FLAGS_REG))]
8701 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8705 [(set (reg:CCZ FLAGS_REG)
8706 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8707 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8710 (plus:DWIH (match_dup 3)
8711 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8713 (clobber (reg:CC FLAGS_REG))])
8716 (neg:DWIH (match_dup 2)))
8717 (clobber (reg:CC FLAGS_REG))])]
8718 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8720 (define_insn "*neg<mode>2_1"
8721 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8723 (clobber (reg:CC FLAGS_REG))]
8724 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8725 "neg{<imodesuffix>}\t%0"
8726 [(set_attr "type" "negnot")
8727 (set_attr "mode" "<MODE>")])
8729 ;; Combine is quite creative about this pattern.
8730 (define_insn "*negsi2_1_zext"
8731 [(set (match_operand:DI 0 "register_operand" "=r")
8733 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8736 (clobber (reg:CC FLAGS_REG))]
8737 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8739 [(set_attr "type" "negnot")
8740 (set_attr "mode" "SI")])
8742 ;; The problem with neg is that it does not perform (compare x 0),
8743 ;; it really performs (compare 0 x), which leaves us with the zero
8744 ;; flag being the only useful item.
8746 (define_insn "*neg<mode>2_cmpz"
8747 [(set (reg:CCZ FLAGS_REG)
8749 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8751 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8752 (neg:SWI (match_dup 1)))]
8753 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8754 "neg{<imodesuffix>}\t%0"
8755 [(set_attr "type" "negnot")
8756 (set_attr "mode" "<MODE>")])
8758 (define_insn "*negsi2_cmpz_zext"
8759 [(set (reg:CCZ FLAGS_REG)
8763 (match_operand:DI 1 "register_operand" "0")
8767 (set (match_operand:DI 0 "register_operand" "=r")
8768 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8771 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8773 [(set_attr "type" "negnot")
8774 (set_attr "mode" "SI")])
8776 ;; Negate with jump on overflow.
8777 (define_expand "negv<mode>3"
8778 [(parallel [(set (reg:CCO FLAGS_REG)
8779 (ne:CCO (match_operand:SWI 1 "register_operand")
8781 (set (match_operand:SWI 0 "register_operand")
8782 (neg:SWI (match_dup 1)))])
8783 (set (pc) (if_then_else
8784 (eq (reg:CCO FLAGS_REG) (const_int 0))
8785 (label_ref (match_operand 2))
8790 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8794 (define_insn "*negv<mode>3"
8795 [(set (reg:CCO FLAGS_REG)
8796 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8797 (match_operand:SWI 2 "const_int_operand")))
8798 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8799 (neg:SWI (match_dup 1)))]
8800 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8801 && mode_signbit_p (<MODE>mode, operands[2])"
8802 "neg{<imodesuffix>}\t%0"
8803 [(set_attr "type" "negnot")
8804 (set_attr "mode" "<MODE>")])
8806 ;; Changing of sign for FP values is doable using integer unit too.
8808 (define_expand "<code><mode>2"
8809 [(set (match_operand:X87MODEF 0 "register_operand")
8810 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8811 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8812 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8814 (define_insn "*absneg<mode>2_mixed"
8815 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8816 (match_operator:MODEF 3 "absneg_operator"
8817 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8818 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8819 (clobber (reg:CC FLAGS_REG))]
8820 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8823 (define_insn "*absneg<mode>2_sse"
8824 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8825 (match_operator:MODEF 3 "absneg_operator"
8826 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8827 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8832 (define_insn "*absneg<mode>2_i387"
8833 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8834 (match_operator:X87MODEF 3 "absneg_operator"
8835 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8836 (use (match_operand 2))
8837 (clobber (reg:CC FLAGS_REG))]
8838 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8841 (define_expand "<code>tf2"
8842 [(set (match_operand:TF 0 "register_operand")
8843 (absneg:TF (match_operand:TF 1 "register_operand")))]
8845 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8847 (define_insn "*absnegtf2_sse"
8848 [(set (match_operand:TF 0 "register_operand" "=x,x")
8849 (match_operator:TF 3 "absneg_operator"
8850 [(match_operand:TF 1 "register_operand" "0,x")]))
8851 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8852 (clobber (reg:CC FLAGS_REG))]
8856 ;; Splitters for fp abs and neg.
8859 [(set (match_operand 0 "fp_register_operand")
8860 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8861 (use (match_operand 2))
8862 (clobber (reg:CC FLAGS_REG))]
8864 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8867 [(set (match_operand 0 "register_operand")
8868 (match_operator 3 "absneg_operator"
8869 [(match_operand 1 "register_operand")]))
8870 (use (match_operand 2 "nonimmediate_operand"))
8871 (clobber (reg:CC FLAGS_REG))]
8872 "reload_completed && SSE_REG_P (operands[0])"
8873 [(set (match_dup 0) (match_dup 3))]
8875 enum machine_mode mode = GET_MODE (operands[0]);
8876 enum machine_mode vmode = GET_MODE (operands[2]);
8879 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8880 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8881 if (operands_match_p (operands[0], operands[2]))
8884 operands[1] = operands[2];
8887 if (GET_CODE (operands[3]) == ABS)
8888 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8890 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8895 [(set (match_operand:SF 0 "register_operand")
8896 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8897 (use (match_operand:V4SF 2))
8898 (clobber (reg:CC FLAGS_REG))]
8900 [(parallel [(set (match_dup 0) (match_dup 1))
8901 (clobber (reg:CC FLAGS_REG))])]
8904 operands[0] = gen_lowpart (SImode, operands[0]);
8905 if (GET_CODE (operands[1]) == ABS)
8907 tmp = gen_int_mode (0x7fffffff, SImode);
8908 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8912 tmp = gen_int_mode (0x80000000, SImode);
8913 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8919 [(set (match_operand:DF 0 "register_operand")
8920 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8921 (use (match_operand 2))
8922 (clobber (reg:CC FLAGS_REG))]
8924 [(parallel [(set (match_dup 0) (match_dup 1))
8925 (clobber (reg:CC FLAGS_REG))])]
8930 tmp = gen_lowpart (DImode, operands[0]);
8931 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8934 if (GET_CODE (operands[1]) == ABS)
8937 tmp = gen_rtx_NOT (DImode, tmp);
8941 operands[0] = gen_highpart (SImode, operands[0]);
8942 if (GET_CODE (operands[1]) == ABS)
8944 tmp = gen_int_mode (0x7fffffff, SImode);
8945 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8949 tmp = gen_int_mode (0x80000000, SImode);
8950 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8957 [(set (match_operand:XF 0 "register_operand")
8958 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8959 (use (match_operand 2))
8960 (clobber (reg:CC FLAGS_REG))]
8962 [(parallel [(set (match_dup 0) (match_dup 1))
8963 (clobber (reg:CC FLAGS_REG))])]
8966 operands[0] = gen_rtx_REG (SImode,
8967 true_regnum (operands[0])
8968 + (TARGET_64BIT ? 1 : 2));
8969 if (GET_CODE (operands[1]) == ABS)
8971 tmp = GEN_INT (0x7fff);
8972 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8976 tmp = GEN_INT (0x8000);
8977 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8982 ;; Conditionalize these after reload. If they match before reload, we
8983 ;; lose the clobber and ability to use integer instructions.
8985 (define_insn "*<code><mode>2_1"
8986 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8987 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8989 && (reload_completed
8990 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8991 "f<absneg_mnemonic>"
8992 [(set_attr "type" "fsgn")
8993 (set_attr "mode" "<MODE>")])
8995 (define_insn "*<code>extendsfdf2"
8996 [(set (match_operand:DF 0 "register_operand" "=f")
8997 (absneg:DF (float_extend:DF
8998 (match_operand:SF 1 "register_operand" "0"))))]
8999 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9000 "f<absneg_mnemonic>"
9001 [(set_attr "type" "fsgn")
9002 (set_attr "mode" "DF")])
9004 (define_insn "*<code>extendsfxf2"
9005 [(set (match_operand:XF 0 "register_operand" "=f")
9006 (absneg:XF (float_extend:XF
9007 (match_operand:SF 1 "register_operand" "0"))))]
9009 "f<absneg_mnemonic>"
9010 [(set_attr "type" "fsgn")
9011 (set_attr "mode" "XF")])
9013 (define_insn "*<code>extenddfxf2"
9014 [(set (match_operand:XF 0 "register_operand" "=f")
9015 (absneg:XF (float_extend:XF
9016 (match_operand:DF 1 "register_operand" "0"))))]
9018 "f<absneg_mnemonic>"
9019 [(set_attr "type" "fsgn")
9020 (set_attr "mode" "XF")])
9022 ;; Copysign instructions
9024 (define_mode_iterator CSGNMODE [SF DF TF])
9025 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9027 (define_expand "copysign<mode>3"
9028 [(match_operand:CSGNMODE 0 "register_operand")
9029 (match_operand:CSGNMODE 1 "nonmemory_operand")
9030 (match_operand:CSGNMODE 2 "register_operand")]
9031 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9032 || (TARGET_SSE && (<MODE>mode == TFmode))"
9033 "ix86_expand_copysign (operands); DONE;")
9035 (define_insn_and_split "copysign<mode>3_const"
9036 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9038 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9039 (match_operand:CSGNMODE 2 "register_operand" "0")
9040 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9042 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9043 || (TARGET_SSE && (<MODE>mode == TFmode))"
9045 "&& reload_completed"
9047 "ix86_split_copysign_const (operands); DONE;")
9049 (define_insn "copysign<mode>3_var"
9050 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9052 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9053 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9054 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9055 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9057 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9058 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9059 || (TARGET_SSE && (<MODE>mode == TFmode))"
9063 [(set (match_operand:CSGNMODE 0 "register_operand")
9065 [(match_operand:CSGNMODE 2 "register_operand")
9066 (match_operand:CSGNMODE 3 "register_operand")
9067 (match_operand:<CSGNVMODE> 4)
9068 (match_operand:<CSGNVMODE> 5)]
9070 (clobber (match_scratch:<CSGNVMODE> 1))]
9071 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9072 || (TARGET_SSE && (<MODE>mode == TFmode)))
9073 && reload_completed"
9075 "ix86_split_copysign_var (operands); DONE;")
9077 ;; One complement instructions
9079 (define_expand "one_cmpl<mode>2"
9080 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9081 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9083 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9085 (define_insn "*one_cmpl<mode>2_1"
9086 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9087 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
9088 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9089 "not{<imodesuffix>}\t%0"
9090 [(set_attr "type" "negnot")
9091 (set_attr "mode" "<MODE>")])
9093 (define_insn "*one_cmplhi2_1"
9094 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
9095 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
9096 "ix86_unary_operator_ok (NOT, HImode, operands)"
9099 knotw\t{%1, %0|%0, %1}"
9100 [(set_attr "isa" "*,avx512f")
9101 (set_attr "type" "negnot,msklog")
9102 (set_attr "prefix" "*,vex")
9103 (set_attr "mode" "HI")])
9105 ;; %%% Potential partial reg stall on alternative 1. What to do?
9106 (define_insn "*one_cmplqi2_1"
9107 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
9108 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
9109 "ix86_unary_operator_ok (NOT, QImode, operands)"
9113 knotw\t{%1, %0|%0, %1}"
9114 [(set_attr "isa" "*,*,avx512f")
9115 (set_attr "type" "negnot,negnot,msklog")
9116 (set_attr "prefix" "*,*,vex")
9117 (set_attr "mode" "QI,SI,QI")])
9119 ;; ??? Currently never generated - xor is used instead.
9120 (define_insn "*one_cmplsi2_1_zext"
9121 [(set (match_operand:DI 0 "register_operand" "=r")
9123 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9124 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9126 [(set_attr "type" "negnot")
9127 (set_attr "mode" "SI")])
9129 (define_insn "*one_cmpl<mode>2_2"
9130 [(set (reg FLAGS_REG)
9131 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9133 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9134 (not:SWI (match_dup 1)))]
9135 "ix86_match_ccmode (insn, CCNOmode)
9136 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "<MODE>")])
9142 [(set (match_operand 0 "flags_reg_operand")
9143 (match_operator 2 "compare_operator"
9144 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9146 (set (match_operand:SWI 1 "nonimmediate_operand")
9147 (not:SWI (match_dup 3)))]
9148 "ix86_match_ccmode (insn, CCNOmode)"
9149 [(parallel [(set (match_dup 0)
9150 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9153 (xor:SWI (match_dup 3) (const_int -1)))])])
9155 ;; ??? Currently never generated - xor is used instead.
9156 (define_insn "*one_cmplsi2_2_zext"
9157 [(set (reg FLAGS_REG)
9158 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9160 (set (match_operand:DI 0 "register_operand" "=r")
9161 (zero_extend:DI (not:SI (match_dup 1))))]
9162 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9163 && ix86_unary_operator_ok (NOT, SImode, operands)"
9165 [(set_attr "type" "alu1")
9166 (set_attr "mode" "SI")])
9169 [(set (match_operand 0 "flags_reg_operand")
9170 (match_operator 2 "compare_operator"
9171 [(not:SI (match_operand:SI 3 "register_operand"))
9173 (set (match_operand:DI 1 "register_operand")
9174 (zero_extend:DI (not:SI (match_dup 3))))]
9175 "ix86_match_ccmode (insn, CCNOmode)"
9176 [(parallel [(set (match_dup 0)
9177 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9180 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9182 ;; Shift instructions
9184 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9185 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9186 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9187 ;; from the assembler input.
9189 ;; This instruction shifts the target reg/mem as usual, but instead of
9190 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9191 ;; is a left shift double, bits are taken from the high order bits of
9192 ;; reg, else if the insn is a shift right double, bits are taken from the
9193 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9194 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9196 ;; Since sh[lr]d does not change the `reg' operand, that is done
9197 ;; separately, making all shifts emit pairs of shift double and normal
9198 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9199 ;; support a 63 bit shift, each shift where the count is in a reg expands
9200 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9202 ;; If the shift count is a constant, we need never emit more than one
9203 ;; shift pair, instead using moves and sign extension for counts greater
9206 (define_expand "ashl<mode>3"
9207 [(set (match_operand:SDWIM 0 "<shift_operand>")
9208 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9209 (match_operand:QI 2 "nonmemory_operand")))]
9211 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9213 (define_insn "*ashl<mode>3_doubleword"
9214 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9215 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9216 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9217 (clobber (reg:CC FLAGS_REG))]
9220 [(set_attr "type" "multi")])
9223 [(set (match_operand:DWI 0 "register_operand")
9224 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9225 (match_operand:QI 2 "nonmemory_operand")))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9229 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9231 ;; By default we don't ask for a scratch register, because when DWImode
9232 ;; values are manipulated, registers are already at a premium. But if
9233 ;; we have one handy, we won't turn it away.
9236 [(match_scratch:DWIH 3 "r")
9237 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9239 (match_operand:<DWI> 1 "nonmemory_operand")
9240 (match_operand:QI 2 "nonmemory_operand")))
9241 (clobber (reg:CC FLAGS_REG))])
9245 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9247 (define_insn "x86_64_shld"
9248 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9249 (ior:DI (ashift:DI (match_dup 0)
9250 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9251 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9252 (minus:QI (const_int 64) (match_dup 2)))))
9253 (clobber (reg:CC FLAGS_REG))]
9255 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9256 [(set_attr "type" "ishift")
9257 (set_attr "prefix_0f" "1")
9258 (set_attr "mode" "DI")
9259 (set_attr "athlon_decode" "vector")
9260 (set_attr "amdfam10_decode" "vector")
9261 (set_attr "bdver1_decode" "vector")])
9263 (define_insn "x86_shld"
9264 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9265 (ior:SI (ashift:SI (match_dup 0)
9266 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9267 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9268 (minus:QI (const_int 32) (match_dup 2)))))
9269 (clobber (reg:CC FLAGS_REG))]
9271 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9272 [(set_attr "type" "ishift")
9273 (set_attr "prefix_0f" "1")
9274 (set_attr "mode" "SI")
9275 (set_attr "pent_pair" "np")
9276 (set_attr "athlon_decode" "vector")
9277 (set_attr "amdfam10_decode" "vector")
9278 (set_attr "bdver1_decode" "vector")])
9280 (define_expand "x86_shift<mode>_adj_1"
9281 [(set (reg:CCZ FLAGS_REG)
9282 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9285 (set (match_operand:SWI48 0 "register_operand")
9286 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9287 (match_operand:SWI48 1 "register_operand")
9290 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9291 (match_operand:SWI48 3 "register_operand")
9294 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9296 (define_expand "x86_shift<mode>_adj_2"
9297 [(use (match_operand:SWI48 0 "register_operand"))
9298 (use (match_operand:SWI48 1 "register_operand"))
9299 (use (match_operand:QI 2 "register_operand"))]
9302 rtx label = gen_label_rtx ();
9305 emit_insn (gen_testqi_ccz_1 (operands[2],
9306 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9308 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9309 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9310 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9311 gen_rtx_LABEL_REF (VOIDmode, label),
9313 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9314 JUMP_LABEL (tmp) = label;
9316 emit_move_insn (operands[0], operands[1]);
9317 ix86_expand_clear (operands[1]);
9320 LABEL_NUSES (label) = 1;
9325 ;; Avoid useless masking of count operand.
9326 (define_insn "*ashl<mode>3_mask"
9327 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9329 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9332 (match_operand:SI 2 "register_operand" "c")
9333 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9336 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9337 == GET_MODE_BITSIZE (<MODE>mode)-1"
9339 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9341 [(set_attr "type" "ishift")
9342 (set_attr "mode" "<MODE>")])
9344 (define_insn "*bmi2_ashl<mode>3_1"
9345 [(set (match_operand:SWI48 0 "register_operand" "=r")
9346 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9347 (match_operand:SWI48 2 "register_operand" "r")))]
9349 "shlx\t{%2, %1, %0|%0, %1, %2}"
9350 [(set_attr "type" "ishiftx")
9351 (set_attr "mode" "<MODE>")])
9353 (define_insn "*ashl<mode>3_1"
9354 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9355 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9356 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9357 (clobber (reg:CC FLAGS_REG))]
9358 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9360 switch (get_attr_type (insn))
9367 gcc_assert (operands[2] == const1_rtx);
9368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9369 return "add{<imodesuffix>}\t%0, %0";
9372 if (operands[2] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9374 return "sal{<imodesuffix>}\t%0";
9376 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9379 [(set_attr "isa" "*,*,bmi2")
9381 (cond [(eq_attr "alternative" "1")
9382 (const_string "lea")
9383 (eq_attr "alternative" "2")
9384 (const_string "ishiftx")
9385 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9386 (match_operand 0 "register_operand"))
9387 (match_operand 2 "const1_operand"))
9388 (const_string "alu")
9390 (const_string "ishift")))
9391 (set (attr "length_immediate")
9393 (ior (eq_attr "type" "alu")
9394 (and (eq_attr "type" "ishift")
9395 (and (match_operand 2 "const1_operand")
9396 (ior (match_test "TARGET_SHIFT1")
9397 (match_test "optimize_function_for_size_p (cfun)")))))
9399 (const_string "*")))
9400 (set_attr "mode" "<MODE>")])
9402 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9404 [(set (match_operand:SWI48 0 "register_operand")
9405 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9406 (match_operand:QI 2 "register_operand")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "TARGET_BMI2 && reload_completed"
9410 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9411 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9413 (define_insn "*bmi2_ashlsi3_1_zext"
9414 [(set (match_operand:DI 0 "register_operand" "=r")
9416 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9417 (match_operand:SI 2 "register_operand" "r"))))]
9418 "TARGET_64BIT && TARGET_BMI2"
9419 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9420 [(set_attr "type" "ishiftx")
9421 (set_attr "mode" "SI")])
9423 (define_insn "*ashlsi3_1_zext"
9424 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9426 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9427 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9431 switch (get_attr_type (insn))
9438 gcc_assert (operands[2] == const1_rtx);
9439 return "add{l}\t%k0, %k0";
9442 if (operands[2] == const1_rtx
9443 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9444 return "sal{l}\t%k0";
9446 return "sal{l}\t{%2, %k0|%k0, %2}";
9449 [(set_attr "isa" "*,*,bmi2")
9451 (cond [(eq_attr "alternative" "1")
9452 (const_string "lea")
9453 (eq_attr "alternative" "2")
9454 (const_string "ishiftx")
9455 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9456 (match_operand 2 "const1_operand"))
9457 (const_string "alu")
9459 (const_string "ishift")))
9460 (set (attr "length_immediate")
9462 (ior (eq_attr "type" "alu")
9463 (and (eq_attr "type" "ishift")
9464 (and (match_operand 2 "const1_operand")
9465 (ior (match_test "TARGET_SHIFT1")
9466 (match_test "optimize_function_for_size_p (cfun)")))))
9468 (const_string "*")))
9469 (set_attr "mode" "SI")])
9471 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9473 [(set (match_operand:DI 0 "register_operand")
9475 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9476 (match_operand:QI 2 "register_operand"))))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9480 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9481 "operands[2] = gen_lowpart (SImode, operands[2]);")
9483 (define_insn "*ashlhi3_1"
9484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9485 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9486 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9487 (clobber (reg:CC FLAGS_REG))]
9488 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9490 switch (get_attr_type (insn))
9496 gcc_assert (operands[2] == const1_rtx);
9497 return "add{w}\t%0, %0";
9500 if (operands[2] == const1_rtx
9501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9502 return "sal{w}\t%0";
9504 return "sal{w}\t{%2, %0|%0, %2}";
9508 (cond [(eq_attr "alternative" "1")
9509 (const_string "lea")
9510 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9511 (match_operand 0 "register_operand"))
9512 (match_operand 2 "const1_operand"))
9513 (const_string "alu")
9515 (const_string "ishift")))
9516 (set (attr "length_immediate")
9518 (ior (eq_attr "type" "alu")
9519 (and (eq_attr "type" "ishift")
9520 (and (match_operand 2 "const1_operand")
9521 (ior (match_test "TARGET_SHIFT1")
9522 (match_test "optimize_function_for_size_p (cfun)")))))
9524 (const_string "*")))
9525 (set_attr "mode" "HI,SI")])
9527 ;; %%% Potential partial reg stall on alternative 1. What to do?
9528 (define_insn "*ashlqi3_1"
9529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9530 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9531 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9532 (clobber (reg:CC FLAGS_REG))]
9533 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9535 switch (get_attr_type (insn))
9541 gcc_assert (operands[2] == const1_rtx);
9542 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9543 return "add{l}\t%k0, %k0";
9545 return "add{b}\t%0, %0";
9548 if (operands[2] == const1_rtx
9549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9551 if (get_attr_mode (insn) == MODE_SI)
9552 return "sal{l}\t%k0";
9554 return "sal{b}\t%0";
9558 if (get_attr_mode (insn) == MODE_SI)
9559 return "sal{l}\t{%2, %k0|%k0, %2}";
9561 return "sal{b}\t{%2, %0|%0, %2}";
9566 (cond [(eq_attr "alternative" "2")
9567 (const_string "lea")
9568 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9569 (match_operand 0 "register_operand"))
9570 (match_operand 2 "const1_operand"))
9571 (const_string "alu")
9573 (const_string "ishift")))
9574 (set (attr "length_immediate")
9576 (ior (eq_attr "type" "alu")
9577 (and (eq_attr "type" "ishift")
9578 (and (match_operand 2 "const1_operand")
9579 (ior (match_test "TARGET_SHIFT1")
9580 (match_test "optimize_function_for_size_p (cfun)")))))
9582 (const_string "*")))
9583 (set_attr "mode" "QI,SI,SI")])
9585 (define_insn "*ashlqi3_1_slp"
9586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9587 (ashift:QI (match_dup 0)
9588 (match_operand:QI 1 "nonmemory_operand" "cI")))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "(optimize_function_for_size_p (cfun)
9591 || !TARGET_PARTIAL_FLAG_REG_STALL
9592 || (operands[1] == const1_rtx
9594 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9596 switch (get_attr_type (insn))
9599 gcc_assert (operands[1] == const1_rtx);
9600 return "add{b}\t%0, %0";
9603 if (operands[1] == const1_rtx
9604 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9605 return "sal{b}\t%0";
9607 return "sal{b}\t{%1, %0|%0, %1}";
9611 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9612 (match_operand 0 "register_operand"))
9613 (match_operand 1 "const1_operand"))
9614 (const_string "alu")
9616 (const_string "ishift1")))
9617 (set (attr "length_immediate")
9619 (ior (eq_attr "type" "alu")
9620 (and (eq_attr "type" "ishift1")
9621 (and (match_operand 1 "const1_operand")
9622 (ior (match_test "TARGET_SHIFT1")
9623 (match_test "optimize_function_for_size_p (cfun)")))))
9625 (const_string "*")))
9626 (set_attr "mode" "QI")])
9628 ;; Convert ashift to the lea pattern to avoid flags dependency.
9630 [(set (match_operand 0 "register_operand")
9631 (ashift (match_operand 1 "index_register_operand")
9632 (match_operand:QI 2 "const_int_operand")))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9636 && true_regnum (operands[0]) != true_regnum (operands[1])"
9639 enum machine_mode mode = GET_MODE (operands[0]);
9642 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9645 operands[0] = gen_lowpart (mode, operands[0]);
9646 operands[1] = gen_lowpart (mode, operands[1]);
9649 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9651 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9653 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9657 ;; Convert ashift to the lea pattern to avoid flags dependency.
9659 [(set (match_operand:DI 0 "register_operand")
9661 (ashift:SI (match_operand:SI 1 "index_register_operand")
9662 (match_operand:QI 2 "const_int_operand"))))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_64BIT && reload_completed
9665 && true_regnum (operands[0]) != true_regnum (operands[1])"
9667 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9669 operands[1] = gen_lowpart (SImode, operands[1]);
9670 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9673 ;; This pattern can't accept a variable shift count, since shifts by
9674 ;; zero don't affect the flags. We assume that shifts by constant
9675 ;; zero are optimized away.
9676 (define_insn "*ashl<mode>3_cmp"
9677 [(set (reg FLAGS_REG)
9679 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9680 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9682 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9683 (ashift:SWI (match_dup 1) (match_dup 2)))]
9684 "(optimize_function_for_size_p (cfun)
9685 || !TARGET_PARTIAL_FLAG_REG_STALL
9686 || (operands[2] == const1_rtx
9688 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9689 && ix86_match_ccmode (insn, CCGOCmode)
9690 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9692 switch (get_attr_type (insn))
9695 gcc_assert (operands[2] == const1_rtx);
9696 return "add{<imodesuffix>}\t%0, %0";
9699 if (operands[2] == const1_rtx
9700 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9701 return "sal{<imodesuffix>}\t%0";
9703 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9707 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9708 (match_operand 0 "register_operand"))
9709 (match_operand 2 "const1_operand"))
9710 (const_string "alu")
9712 (const_string "ishift")))
9713 (set (attr "length_immediate")
9715 (ior (eq_attr "type" "alu")
9716 (and (eq_attr "type" "ishift")
9717 (and (match_operand 2 "const1_operand")
9718 (ior (match_test "TARGET_SHIFT1")
9719 (match_test "optimize_function_for_size_p (cfun)")))))
9721 (const_string "*")))
9722 (set_attr "mode" "<MODE>")])
9724 (define_insn "*ashlsi3_cmp_zext"
9725 [(set (reg FLAGS_REG)
9727 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9728 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9730 (set (match_operand:DI 0 "register_operand" "=r")
9731 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9733 && (optimize_function_for_size_p (cfun)
9734 || !TARGET_PARTIAL_FLAG_REG_STALL
9735 || (operands[2] == const1_rtx
9737 || TARGET_DOUBLE_WITH_ADD)))
9738 && ix86_match_ccmode (insn, CCGOCmode)
9739 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9741 switch (get_attr_type (insn))
9744 gcc_assert (operands[2] == const1_rtx);
9745 return "add{l}\t%k0, %k0";
9748 if (operands[2] == const1_rtx
9749 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9750 return "sal{l}\t%k0";
9752 return "sal{l}\t{%2, %k0|%k0, %2}";
9756 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9757 (match_operand 2 "const1_operand"))
9758 (const_string "alu")
9760 (const_string "ishift")))
9761 (set (attr "length_immediate")
9763 (ior (eq_attr "type" "alu")
9764 (and (eq_attr "type" "ishift")
9765 (and (match_operand 2 "const1_operand")
9766 (ior (match_test "TARGET_SHIFT1")
9767 (match_test "optimize_function_for_size_p (cfun)")))))
9769 (const_string "*")))
9770 (set_attr "mode" "SI")])
9772 (define_insn "*ashl<mode>3_cconly"
9773 [(set (reg FLAGS_REG)
9775 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9776 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9778 (clobber (match_scratch:SWI 0 "=<r>"))]
9779 "(optimize_function_for_size_p (cfun)
9780 || !TARGET_PARTIAL_FLAG_REG_STALL
9781 || (operands[2] == const1_rtx
9783 || TARGET_DOUBLE_WITH_ADD)))
9784 && ix86_match_ccmode (insn, CCGOCmode)"
9786 switch (get_attr_type (insn))
9789 gcc_assert (operands[2] == const1_rtx);
9790 return "add{<imodesuffix>}\t%0, %0";
9793 if (operands[2] == const1_rtx
9794 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9795 return "sal{<imodesuffix>}\t%0";
9797 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9801 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9802 (match_operand 0 "register_operand"))
9803 (match_operand 2 "const1_operand"))
9804 (const_string "alu")
9806 (const_string "ishift")))
9807 (set (attr "length_immediate")
9809 (ior (eq_attr "type" "alu")
9810 (and (eq_attr "type" "ishift")
9811 (and (match_operand 2 "const1_operand")
9812 (ior (match_test "TARGET_SHIFT1")
9813 (match_test "optimize_function_for_size_p (cfun)")))))
9815 (const_string "*")))
9816 (set_attr "mode" "<MODE>")])
9818 ;; See comment above `ashl<mode>3' about how this works.
9820 (define_expand "<shift_insn><mode>3"
9821 [(set (match_operand:SDWIM 0 "<shift_operand>")
9822 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9823 (match_operand:QI 2 "nonmemory_operand")))]
9825 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9827 ;; Avoid useless masking of count operand.
9828 (define_insn "*<shift_insn><mode>3_mask"
9829 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9831 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9834 (match_operand:SI 2 "register_operand" "c")
9835 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9836 (clobber (reg:CC FLAGS_REG))]
9837 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9838 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9839 == GET_MODE_BITSIZE (<MODE>mode)-1"
9841 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9843 [(set_attr "type" "ishift")
9844 (set_attr "mode" "<MODE>")])
9846 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9847 [(set (match_operand:DWI 0 "register_operand" "=r")
9848 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9849 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9850 (clobber (reg:CC FLAGS_REG))]
9853 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9855 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9856 [(set_attr "type" "multi")])
9858 ;; By default we don't ask for a scratch register, because when DWImode
9859 ;; values are manipulated, registers are already at a premium. But if
9860 ;; we have one handy, we won't turn it away.
9863 [(match_scratch:DWIH 3 "r")
9864 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9866 (match_operand:<DWI> 1 "register_operand")
9867 (match_operand:QI 2 "nonmemory_operand")))
9868 (clobber (reg:CC FLAGS_REG))])
9872 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9874 (define_insn "x86_64_shrd"
9875 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9876 (ior:DI (ashiftrt:DI (match_dup 0)
9877 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9878 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9879 (minus:QI (const_int 64) (match_dup 2)))))
9880 (clobber (reg:CC FLAGS_REG))]
9882 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9883 [(set_attr "type" "ishift")
9884 (set_attr "prefix_0f" "1")
9885 (set_attr "mode" "DI")
9886 (set_attr "athlon_decode" "vector")
9887 (set_attr "amdfam10_decode" "vector")
9888 (set_attr "bdver1_decode" "vector")])
9890 (define_insn "x86_shrd"
9891 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9892 (ior:SI (ashiftrt:SI (match_dup 0)
9893 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9894 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9895 (minus:QI (const_int 32) (match_dup 2)))))
9896 (clobber (reg:CC FLAGS_REG))]
9898 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9899 [(set_attr "type" "ishift")
9900 (set_attr "prefix_0f" "1")
9901 (set_attr "mode" "SI")
9902 (set_attr "pent_pair" "np")
9903 (set_attr "athlon_decode" "vector")
9904 (set_attr "amdfam10_decode" "vector")
9905 (set_attr "bdver1_decode" "vector")])
9907 (define_insn "ashrdi3_cvt"
9908 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9909 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9910 (match_operand:QI 2 "const_int_operand")))
9911 (clobber (reg:CC FLAGS_REG))]
9912 "TARGET_64BIT && INTVAL (operands[2]) == 63
9913 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9914 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9917 sar{q}\t{%2, %0|%0, %2}"
9918 [(set_attr "type" "imovx,ishift")
9919 (set_attr "prefix_0f" "0,*")
9920 (set_attr "length_immediate" "0,*")
9921 (set_attr "modrm" "0,1")
9922 (set_attr "mode" "DI")])
9924 (define_insn "ashrsi3_cvt"
9925 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9926 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9927 (match_operand:QI 2 "const_int_operand")))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "INTVAL (operands[2]) == 31
9930 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9931 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9934 sar{l}\t{%2, %0|%0, %2}"
9935 [(set_attr "type" "imovx,ishift")
9936 (set_attr "prefix_0f" "0,*")
9937 (set_attr "length_immediate" "0,*")
9938 (set_attr "modrm" "0,1")
9939 (set_attr "mode" "SI")])
9941 (define_insn "*ashrsi3_cvt_zext"
9942 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9944 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9945 (match_operand:QI 2 "const_int_operand"))))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "TARGET_64BIT && INTVAL (operands[2]) == 31
9948 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9949 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9952 sar{l}\t{%2, %k0|%k0, %2}"
9953 [(set_attr "type" "imovx,ishift")
9954 (set_attr "prefix_0f" "0,*")
9955 (set_attr "length_immediate" "0,*")
9956 (set_attr "modrm" "0,1")
9957 (set_attr "mode" "SI")])
9959 (define_expand "x86_shift<mode>_adj_3"
9960 [(use (match_operand:SWI48 0 "register_operand"))
9961 (use (match_operand:SWI48 1 "register_operand"))
9962 (use (match_operand:QI 2 "register_operand"))]
9965 rtx label = gen_label_rtx ();
9968 emit_insn (gen_testqi_ccz_1 (operands[2],
9969 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9971 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9972 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9973 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9974 gen_rtx_LABEL_REF (VOIDmode, label),
9976 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9977 JUMP_LABEL (tmp) = label;
9979 emit_move_insn (operands[0], operands[1]);
9980 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9981 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9983 LABEL_NUSES (label) = 1;
9988 (define_insn "*bmi2_<shift_insn><mode>3_1"
9989 [(set (match_operand:SWI48 0 "register_operand" "=r")
9990 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9991 (match_operand:SWI48 2 "register_operand" "r")))]
9993 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9994 [(set_attr "type" "ishiftx")
9995 (set_attr "mode" "<MODE>")])
9997 (define_insn "*<shift_insn><mode>3_1"
9998 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10000 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10001 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10002 (clobber (reg:CC FLAGS_REG))]
10003 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10005 switch (get_attr_type (insn))
10011 if (operands[2] == const1_rtx
10012 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10013 return "<shift>{<imodesuffix>}\t%0";
10015 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10018 [(set_attr "isa" "*,bmi2")
10019 (set_attr "type" "ishift,ishiftx")
10020 (set (attr "length_immediate")
10022 (and (match_operand 2 "const1_operand")
10023 (ior (match_test "TARGET_SHIFT1")
10024 (match_test "optimize_function_for_size_p (cfun)")))
10026 (const_string "*")))
10027 (set_attr "mode" "<MODE>")])
10029 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10031 [(set (match_operand:SWI48 0 "register_operand")
10032 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10033 (match_operand:QI 2 "register_operand")))
10034 (clobber (reg:CC FLAGS_REG))]
10035 "TARGET_BMI2 && reload_completed"
10036 [(set (match_dup 0)
10037 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10038 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10040 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10041 [(set (match_operand:DI 0 "register_operand" "=r")
10043 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10044 (match_operand:SI 2 "register_operand" "r"))))]
10045 "TARGET_64BIT && TARGET_BMI2"
10046 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10047 [(set_attr "type" "ishiftx")
10048 (set_attr "mode" "SI")])
10050 (define_insn "*<shift_insn>si3_1_zext"
10051 [(set (match_operand:DI 0 "register_operand" "=r,r")
10053 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10054 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10058 switch (get_attr_type (insn))
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}";
10071 [(set_attr "isa" "*,bmi2")
10072 (set_attr "type" "ishift,ishiftx")
10073 (set (attr "length_immediate")
10075 (and (match_operand 2 "const1_operand")
10076 (ior (match_test "TARGET_SHIFT1")
10077 (match_test "optimize_function_for_size_p (cfun)")))
10079 (const_string "*")))
10080 (set_attr "mode" "SI")])
10082 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10084 [(set (match_operand:DI 0 "register_operand")
10086 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10087 (match_operand:QI 2 "register_operand"))))
10088 (clobber (reg:CC FLAGS_REG))]
10089 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10090 [(set (match_dup 0)
10091 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10092 "operands[2] = gen_lowpart (SImode, operands[2]);")
10094 (define_insn "*<shift_insn><mode>3_1"
10095 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10097 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10098 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10102 if (operands[2] == const1_rtx
10103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10104 return "<shift>{<imodesuffix>}\t%0";
10106 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10108 [(set_attr "type" "ishift")
10109 (set (attr "length_immediate")
10111 (and (match_operand 2 "const1_operand")
10112 (ior (match_test "TARGET_SHIFT1")
10113 (match_test "optimize_function_for_size_p (cfun)")))
10115 (const_string "*")))
10116 (set_attr "mode" "<MODE>")])
10118 (define_insn "*<shift_insn>qi3_1_slp"
10119 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10120 (any_shiftrt:QI (match_dup 0)
10121 (match_operand:QI 1 "nonmemory_operand" "cI")))
10122 (clobber (reg:CC FLAGS_REG))]
10123 "(optimize_function_for_size_p (cfun)
10124 || !TARGET_PARTIAL_REG_STALL
10125 || (operands[1] == const1_rtx
10126 && TARGET_SHIFT1))"
10128 if (operands[1] == const1_rtx
10129 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10130 return "<shift>{b}\t%0";
10132 return "<shift>{b}\t{%1, %0|%0, %1}";
10134 [(set_attr "type" "ishift1")
10135 (set (attr "length_immediate")
10137 (and (match_operand 1 "const1_operand")
10138 (ior (match_test "TARGET_SHIFT1")
10139 (match_test "optimize_function_for_size_p (cfun)")))
10141 (const_string "*")))
10142 (set_attr "mode" "QI")])
10144 ;; This pattern can't accept a variable shift count, since shifts by
10145 ;; zero don't affect the flags. We assume that shifts by constant
10146 ;; zero are optimized away.
10147 (define_insn "*<shift_insn><mode>3_cmp"
10148 [(set (reg FLAGS_REG)
10151 (match_operand:SWI 1 "nonimmediate_operand" "0")
10152 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10154 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10155 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10156 "(optimize_function_for_size_p (cfun)
10157 || !TARGET_PARTIAL_FLAG_REG_STALL
10158 || (operands[2] == const1_rtx
10160 && ix86_match_ccmode (insn, CCGOCmode)
10161 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10163 if (operands[2] == const1_rtx
10164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165 return "<shift>{<imodesuffix>}\t%0";
10167 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10169 [(set_attr "type" "ishift")
10170 (set (attr "length_immediate")
10172 (and (match_operand 2 "const1_operand")
10173 (ior (match_test "TARGET_SHIFT1")
10174 (match_test "optimize_function_for_size_p (cfun)")))
10176 (const_string "*")))
10177 (set_attr "mode" "<MODE>")])
10179 (define_insn "*<shift_insn>si3_cmp_zext"
10180 [(set (reg FLAGS_REG)
10182 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10183 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10185 (set (match_operand:DI 0 "register_operand" "=r")
10186 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10188 && (optimize_function_for_size_p (cfun)
10189 || !TARGET_PARTIAL_FLAG_REG_STALL
10190 || (operands[2] == const1_rtx
10192 && ix86_match_ccmode (insn, CCGOCmode)
10193 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10195 if (operands[2] == const1_rtx
10196 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10197 return "<shift>{l}\t%k0";
10199 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10201 [(set_attr "type" "ishift")
10202 (set (attr "length_immediate")
10204 (and (match_operand 2 "const1_operand")
10205 (ior (match_test "TARGET_SHIFT1")
10206 (match_test "optimize_function_for_size_p (cfun)")))
10208 (const_string "*")))
10209 (set_attr "mode" "SI")])
10211 (define_insn "*<shift_insn><mode>3_cconly"
10212 [(set (reg FLAGS_REG)
10215 (match_operand:SWI 1 "register_operand" "0")
10216 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10218 (clobber (match_scratch:SWI 0 "=<r>"))]
10219 "(optimize_function_for_size_p (cfun)
10220 || !TARGET_PARTIAL_FLAG_REG_STALL
10221 || (operands[2] == const1_rtx
10223 && ix86_match_ccmode (insn, CCGOCmode)"
10225 if (operands[2] == const1_rtx
10226 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10227 return "<shift>{<imodesuffix>}\t%0";
10229 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10231 [(set_attr "type" "ishift")
10232 (set (attr "length_immediate")
10234 (and (match_operand 2 "const1_operand")
10235 (ior (match_test "TARGET_SHIFT1")
10236 (match_test "optimize_function_for_size_p (cfun)")))
10238 (const_string "*")))
10239 (set_attr "mode" "<MODE>")])
10241 ;; Rotate instructions
10243 (define_expand "<rotate_insn>ti3"
10244 [(set (match_operand:TI 0 "register_operand")
10245 (any_rotate:TI (match_operand:TI 1 "register_operand")
10246 (match_operand:QI 2 "nonmemory_operand")))]
10249 if (const_1_to_63_operand (operands[2], VOIDmode))
10250 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10251 (operands[0], operands[1], operands[2]));
10258 (define_expand "<rotate_insn>di3"
10259 [(set (match_operand:DI 0 "shiftdi_operand")
10260 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10261 (match_operand:QI 2 "nonmemory_operand")))]
10265 ix86_expand_binary_operator (<CODE>, DImode, operands);
10266 else if (const_1_to_31_operand (operands[2], VOIDmode))
10267 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10268 (operands[0], operands[1], operands[2]));
10275 (define_expand "<rotate_insn><mode>3"
10276 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10277 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10278 (match_operand:QI 2 "nonmemory_operand")))]
10280 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10282 ;; Avoid useless masking of count operand.
10283 (define_insn "*<rotate_insn><mode>3_mask"
10284 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10286 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10289 (match_operand:SI 2 "register_operand" "c")
10290 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10291 (clobber (reg:CC FLAGS_REG))]
10292 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10293 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10294 == GET_MODE_BITSIZE (<MODE>mode)-1"
10296 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10298 [(set_attr "type" "rotate")
10299 (set_attr "mode" "<MODE>")])
10301 ;; Implement rotation using two double-precision
10302 ;; shift instructions and a scratch register.
10304 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10305 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10306 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10307 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10308 (clobber (reg:CC FLAGS_REG))
10309 (clobber (match_scratch:DWIH 3 "=&r"))]
10313 [(set (match_dup 3) (match_dup 4))
10315 [(set (match_dup 4)
10316 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10317 (lshiftrt:DWIH (match_dup 5)
10318 (minus:QI (match_dup 6) (match_dup 2)))))
10319 (clobber (reg:CC FLAGS_REG))])
10321 [(set (match_dup 5)
10322 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10323 (lshiftrt:DWIH (match_dup 3)
10324 (minus:QI (match_dup 6) (match_dup 2)))))
10325 (clobber (reg:CC FLAGS_REG))])]
10327 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10329 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10332 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10333 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10334 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10335 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10336 (clobber (reg:CC FLAGS_REG))
10337 (clobber (match_scratch:DWIH 3 "=&r"))]
10341 [(set (match_dup 3) (match_dup 4))
10343 [(set (match_dup 4)
10344 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10345 (ashift:DWIH (match_dup 5)
10346 (minus:QI (match_dup 6) (match_dup 2)))))
10347 (clobber (reg:CC FLAGS_REG))])
10349 [(set (match_dup 5)
10350 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10351 (ashift:DWIH (match_dup 3)
10352 (minus:QI (match_dup 6) (match_dup 2)))))
10353 (clobber (reg:CC FLAGS_REG))])]
10355 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10357 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10360 (define_insn "*bmi2_rorx<mode>3_1"
10361 [(set (match_operand:SWI48 0 "register_operand" "=r")
10362 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10363 (match_operand:QI 2 "immediate_operand" "<S>")))]
10365 "rorx\t{%2, %1, %0|%0, %1, %2}"
10366 [(set_attr "type" "rotatex")
10367 (set_attr "mode" "<MODE>")])
10369 (define_insn "*<rotate_insn><mode>3_1"
10370 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10372 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10373 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10374 (clobber (reg:CC FLAGS_REG))]
10375 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10377 switch (get_attr_type (insn))
10383 if (operands[2] == const1_rtx
10384 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10385 return "<rotate>{<imodesuffix>}\t%0";
10387 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10390 [(set_attr "isa" "*,bmi2")
10391 (set_attr "type" "rotate,rotatex")
10392 (set (attr "length_immediate")
10394 (and (eq_attr "type" "rotate")
10395 (and (match_operand 2 "const1_operand")
10396 (ior (match_test "TARGET_SHIFT1")
10397 (match_test "optimize_function_for_size_p (cfun)"))))
10399 (const_string "*")))
10400 (set_attr "mode" "<MODE>")])
10402 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10404 [(set (match_operand:SWI48 0 "register_operand")
10405 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10406 (match_operand:QI 2 "immediate_operand")))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_BMI2 && reload_completed"
10409 [(set (match_dup 0)
10410 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10413 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10417 [(set (match_operand:SWI48 0 "register_operand")
10418 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10419 (match_operand:QI 2 "immediate_operand")))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_BMI2 && reload_completed"
10422 [(set (match_dup 0)
10423 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10425 (define_insn "*bmi2_rorxsi3_1_zext"
10426 [(set (match_operand:DI 0 "register_operand" "=r")
10428 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10429 (match_operand:QI 2 "immediate_operand" "I"))))]
10430 "TARGET_64BIT && TARGET_BMI2"
10431 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10432 [(set_attr "type" "rotatex")
10433 (set_attr "mode" "SI")])
10435 (define_insn "*<rotate_insn>si3_1_zext"
10436 [(set (match_operand:DI 0 "register_operand" "=r,r")
10438 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10439 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10440 (clobber (reg:CC FLAGS_REG))]
10441 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10443 switch (get_attr_type (insn))
10449 if (operands[2] == const1_rtx
10450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10451 return "<rotate>{l}\t%k0";
10453 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10456 [(set_attr "isa" "*,bmi2")
10457 (set_attr "type" "rotate,rotatex")
10458 (set (attr "length_immediate")
10460 (and (eq_attr "type" "rotate")
10461 (and (match_operand 2 "const1_operand")
10462 (ior (match_test "TARGET_SHIFT1")
10463 (match_test "optimize_function_for_size_p (cfun)"))))
10465 (const_string "*")))
10466 (set_attr "mode" "SI")])
10468 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10470 [(set (match_operand:DI 0 "register_operand")
10472 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10473 (match_operand:QI 2 "immediate_operand"))))
10474 (clobber (reg:CC FLAGS_REG))]
10475 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10476 [(set (match_dup 0)
10477 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10480 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10484 [(set (match_operand:DI 0 "register_operand")
10486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10487 (match_operand:QI 2 "immediate_operand"))))
10488 (clobber (reg:CC FLAGS_REG))]
10489 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10490 [(set (match_dup 0)
10491 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10493 (define_insn "*<rotate_insn><mode>3_1"
10494 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10495 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10496 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10500 if (operands[2] == const1_rtx
10501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10502 return "<rotate>{<imodesuffix>}\t%0";
10504 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10506 [(set_attr "type" "rotate")
10507 (set (attr "length_immediate")
10509 (and (match_operand 2 "const1_operand")
10510 (ior (match_test "TARGET_SHIFT1")
10511 (match_test "optimize_function_for_size_p (cfun)")))
10513 (const_string "*")))
10514 (set_attr "mode" "<MODE>")])
10516 (define_insn "*<rotate_insn>qi3_1_slp"
10517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10518 (any_rotate:QI (match_dup 0)
10519 (match_operand:QI 1 "nonmemory_operand" "cI")))
10520 (clobber (reg:CC FLAGS_REG))]
10521 "(optimize_function_for_size_p (cfun)
10522 || !TARGET_PARTIAL_REG_STALL
10523 || (operands[1] == const1_rtx
10524 && TARGET_SHIFT1))"
10526 if (operands[1] == const1_rtx
10527 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10528 return "<rotate>{b}\t%0";
10530 return "<rotate>{b}\t{%1, %0|%0, %1}";
10532 [(set_attr "type" "rotate1")
10533 (set (attr "length_immediate")
10535 (and (match_operand 1 "const1_operand")
10536 (ior (match_test "TARGET_SHIFT1")
10537 (match_test "optimize_function_for_size_p (cfun)")))
10539 (const_string "*")))
10540 (set_attr "mode" "QI")])
10543 [(set (match_operand:HI 0 "register_operand")
10544 (any_rotate:HI (match_dup 0) (const_int 8)))
10545 (clobber (reg:CC FLAGS_REG))]
10547 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10548 [(parallel [(set (strict_low_part (match_dup 0))
10549 (bswap:HI (match_dup 0)))
10550 (clobber (reg:CC FLAGS_REG))])])
10552 ;; Bit set / bit test instructions
10554 (define_expand "extv"
10555 [(set (match_operand:SI 0 "register_operand")
10556 (sign_extract:SI (match_operand:SI 1 "register_operand")
10557 (match_operand:SI 2 "const8_operand")
10558 (match_operand:SI 3 "const8_operand")))]
10561 /* Handle extractions from %ah et al. */
10562 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10565 /* From mips.md: extract_bit_field doesn't verify that our source
10566 matches the predicate, so check it again here. */
10567 if (! ext_register_operand (operands[1], VOIDmode))
10571 (define_expand "extzv"
10572 [(set (match_operand:SI 0 "register_operand")
10573 (zero_extract:SI (match_operand 1 "ext_register_operand")
10574 (match_operand:SI 2 "const8_operand")
10575 (match_operand:SI 3 "const8_operand")))]
10578 /* Handle extractions from %ah et al. */
10579 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10582 /* From mips.md: extract_bit_field doesn't verify that our source
10583 matches the predicate, so check it again here. */
10584 if (! ext_register_operand (operands[1], VOIDmode))
10588 (define_expand "insv"
10589 [(set (zero_extract (match_operand 0 "register_operand")
10590 (match_operand 1 "const_int_operand")
10591 (match_operand 2 "const_int_operand"))
10592 (match_operand 3 "register_operand"))]
10595 rtx (*gen_mov_insv_1) (rtx, rtx);
10597 if (ix86_expand_pinsr (operands))
10600 /* Handle insertions to %ah et al. */
10601 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10604 /* From mips.md: insert_bit_field doesn't verify that our source
10605 matches the predicate, so check it again here. */
10606 if (! ext_register_operand (operands[0], VOIDmode))
10609 gen_mov_insv_1 = (TARGET_64BIT
10610 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10612 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10616 ;; %%% bts, btr, btc, bt.
10617 ;; In general these instructions are *slow* when applied to memory,
10618 ;; since they enforce atomic operation. When applied to registers,
10619 ;; it depends on the cpu implementation. They're never faster than
10620 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10621 ;; no point. But in 64-bit, we can't hold the relevant immediates
10622 ;; within the instruction itself, so operating on bits in the high
10623 ;; 32-bits of a register becomes easier.
10625 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10626 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10627 ;; negdf respectively, so they can never be disabled entirely.
10629 (define_insn "*btsq"
10630 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10632 (match_operand:DI 1 "const_0_to_63_operand"))
10634 (clobber (reg:CC FLAGS_REG))]
10635 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10636 "bts{q}\t{%1, %0|%0, %1}"
10637 [(set_attr "type" "alu1")
10638 (set_attr "prefix_0f" "1")
10639 (set_attr "mode" "DI")])
10641 (define_insn "*btrq"
10642 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10644 (match_operand:DI 1 "const_0_to_63_operand"))
10646 (clobber (reg:CC FLAGS_REG))]
10647 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10648 "btr{q}\t{%1, %0|%0, %1}"
10649 [(set_attr "type" "alu1")
10650 (set_attr "prefix_0f" "1")
10651 (set_attr "mode" "DI")])
10653 (define_insn "*btcq"
10654 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10656 (match_operand:DI 1 "const_0_to_63_operand"))
10657 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10658 (clobber (reg:CC FLAGS_REG))]
10659 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10660 "btc{q}\t{%1, %0|%0, %1}"
10661 [(set_attr "type" "alu1")
10662 (set_attr "prefix_0f" "1")
10663 (set_attr "mode" "DI")])
10665 ;; Allow Nocona to avoid these instructions if a register is available.
10668 [(match_scratch:DI 2 "r")
10669 (parallel [(set (zero_extract:DI
10670 (match_operand:DI 0 "register_operand")
10672 (match_operand:DI 1 "const_0_to_63_operand"))
10674 (clobber (reg:CC FLAGS_REG))])]
10675 "TARGET_64BIT && !TARGET_USE_BT"
10678 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10681 if (HOST_BITS_PER_WIDE_INT >= 64)
10682 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10683 else if (i < HOST_BITS_PER_WIDE_INT)
10684 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10686 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10688 op1 = immed_double_const (lo, hi, DImode);
10691 emit_move_insn (operands[2], op1);
10695 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10700 [(match_scratch:DI 2 "r")
10701 (parallel [(set (zero_extract:DI
10702 (match_operand:DI 0 "register_operand")
10704 (match_operand:DI 1 "const_0_to_63_operand"))
10706 (clobber (reg:CC FLAGS_REG))])]
10707 "TARGET_64BIT && !TARGET_USE_BT"
10710 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10713 if (HOST_BITS_PER_WIDE_INT >= 64)
10714 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10715 else if (i < HOST_BITS_PER_WIDE_INT)
10716 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10718 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10720 op1 = immed_double_const (~lo, ~hi, DImode);
10723 emit_move_insn (operands[2], op1);
10727 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10732 [(match_scratch:DI 2 "r")
10733 (parallel [(set (zero_extract:DI
10734 (match_operand:DI 0 "register_operand")
10736 (match_operand:DI 1 "const_0_to_63_operand"))
10737 (not:DI (zero_extract:DI
10738 (match_dup 0) (const_int 1) (match_dup 1))))
10739 (clobber (reg:CC FLAGS_REG))])]
10740 "TARGET_64BIT && !TARGET_USE_BT"
10743 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10746 if (HOST_BITS_PER_WIDE_INT >= 64)
10747 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10748 else if (i < HOST_BITS_PER_WIDE_INT)
10749 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10751 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10753 op1 = immed_double_const (lo, hi, DImode);
10756 emit_move_insn (operands[2], op1);
10760 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10764 (define_insn "*bt<mode>"
10765 [(set (reg:CCC FLAGS_REG)
10767 (zero_extract:SWI48
10768 (match_operand:SWI48 0 "register_operand" "r")
10770 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10772 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10773 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10774 [(set_attr "type" "alu1")
10775 (set_attr "prefix_0f" "1")
10776 (set_attr "mode" "<MODE>")])
10778 ;; Store-flag instructions.
10780 ;; For all sCOND expanders, also expand the compare or test insn that
10781 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10783 (define_insn_and_split "*setcc_di_1"
10784 [(set (match_operand:DI 0 "register_operand" "=q")
10785 (match_operator:DI 1 "ix86_comparison_operator"
10786 [(reg FLAGS_REG) (const_int 0)]))]
10787 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10789 "&& reload_completed"
10790 [(set (match_dup 2) (match_dup 1))
10791 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10793 PUT_MODE (operands[1], QImode);
10794 operands[2] = gen_lowpart (QImode, operands[0]);
10797 (define_insn_and_split "*setcc_si_1_and"
10798 [(set (match_operand:SI 0 "register_operand" "=q")
10799 (match_operator:SI 1 "ix86_comparison_operator"
10800 [(reg FLAGS_REG) (const_int 0)]))
10801 (clobber (reg:CC FLAGS_REG))]
10802 "!TARGET_PARTIAL_REG_STALL
10803 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10805 "&& reload_completed"
10806 [(set (match_dup 2) (match_dup 1))
10807 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10808 (clobber (reg:CC FLAGS_REG))])]
10810 PUT_MODE (operands[1], QImode);
10811 operands[2] = gen_lowpart (QImode, operands[0]);
10814 (define_insn_and_split "*setcc_si_1_movzbl"
10815 [(set (match_operand:SI 0 "register_operand" "=q")
10816 (match_operator:SI 1 "ix86_comparison_operator"
10817 [(reg FLAGS_REG) (const_int 0)]))]
10818 "!TARGET_PARTIAL_REG_STALL
10819 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10821 "&& reload_completed"
10822 [(set (match_dup 2) (match_dup 1))
10823 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10825 PUT_MODE (operands[1], QImode);
10826 operands[2] = gen_lowpart (QImode, operands[0]);
10829 (define_insn "*setcc_qi"
10830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10831 (match_operator:QI 1 "ix86_comparison_operator"
10832 [(reg FLAGS_REG) (const_int 0)]))]
10835 [(set_attr "type" "setcc")
10836 (set_attr "mode" "QI")])
10838 (define_insn "*setcc_qi_slp"
10839 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10840 (match_operator:QI 1 "ix86_comparison_operator"
10841 [(reg FLAGS_REG) (const_int 0)]))]
10844 [(set_attr "type" "setcc")
10845 (set_attr "mode" "QI")])
10847 ;; In general it is not safe to assume too much about CCmode registers,
10848 ;; so simplify-rtx stops when it sees a second one. Under certain
10849 ;; conditions this is safe on x86, so help combine not create
10856 [(set (match_operand:QI 0 "nonimmediate_operand")
10857 (ne:QI (match_operator 1 "ix86_comparison_operator"
10858 [(reg FLAGS_REG) (const_int 0)])
10861 [(set (match_dup 0) (match_dup 1))]
10862 "PUT_MODE (operands[1], QImode);")
10865 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10866 (ne:QI (match_operator 1 "ix86_comparison_operator"
10867 [(reg FLAGS_REG) (const_int 0)])
10870 [(set (match_dup 0) (match_dup 1))]
10871 "PUT_MODE (operands[1], QImode);")
10874 [(set (match_operand:QI 0 "nonimmediate_operand")
10875 (eq:QI (match_operator 1 "ix86_comparison_operator"
10876 [(reg FLAGS_REG) (const_int 0)])
10879 [(set (match_dup 0) (match_dup 1))]
10881 rtx new_op1 = copy_rtx (operands[1]);
10882 operands[1] = new_op1;
10883 PUT_MODE (new_op1, QImode);
10884 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10885 GET_MODE (XEXP (new_op1, 0))));
10887 /* Make sure that (a) the CCmode we have for the flags is strong
10888 enough for the reversed compare or (b) we have a valid FP compare. */
10889 if (! ix86_comparison_operator (new_op1, VOIDmode))
10894 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10895 (eq:QI (match_operator 1 "ix86_comparison_operator"
10896 [(reg FLAGS_REG) (const_int 0)])
10899 [(set (match_dup 0) (match_dup 1))]
10901 rtx new_op1 = copy_rtx (operands[1]);
10902 operands[1] = new_op1;
10903 PUT_MODE (new_op1, QImode);
10904 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10905 GET_MODE (XEXP (new_op1, 0))));
10907 /* Make sure that (a) the CCmode we have for the flags is strong
10908 enough for the reversed compare or (b) we have a valid FP compare. */
10909 if (! ix86_comparison_operator (new_op1, VOIDmode))
10913 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10914 ;; subsequent logical operations are used to imitate conditional moves.
10915 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10918 (define_insn "setcc_<mode>_sse"
10919 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10920 (match_operator:MODEF 3 "sse_comparison_operator"
10921 [(match_operand:MODEF 1 "register_operand" "0,x")
10922 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10923 "SSE_FLOAT_MODE_P (<MODE>mode)"
10925 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10926 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10927 [(set_attr "isa" "noavx,avx")
10928 (set_attr "type" "ssecmp")
10929 (set_attr "length_immediate" "1")
10930 (set_attr "prefix" "orig,vex")
10931 (set_attr "mode" "<MODE>")])
10933 ;; Basic conditional jump instructions.
10934 ;; We ignore the overflow flag for signed branch instructions.
10936 (define_insn "*jcc_1"
10938 (if_then_else (match_operator 1 "ix86_comparison_operator"
10939 [(reg FLAGS_REG) (const_int 0)])
10940 (label_ref (match_operand 0))
10944 [(set_attr "type" "ibr")
10945 (set_attr "modrm" "0")
10946 (set (attr "length")
10947 (if_then_else (and (ge (minus (match_dup 0) (pc))
10949 (lt (minus (match_dup 0) (pc))
10954 (define_insn "*jcc_2"
10956 (if_then_else (match_operator 1 "ix86_comparison_operator"
10957 [(reg FLAGS_REG) (const_int 0)])
10959 (label_ref (match_operand 0))))]
10962 [(set_attr "type" "ibr")
10963 (set_attr "modrm" "0")
10964 (set (attr "length")
10965 (if_then_else (and (ge (minus (match_dup 0) (pc))
10967 (lt (minus (match_dup 0) (pc))
10972 ;; In general it is not safe to assume too much about CCmode registers,
10973 ;; so simplify-rtx stops when it sees a second one. Under certain
10974 ;; conditions this is safe on x86, so help combine not create
10982 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10983 [(reg FLAGS_REG) (const_int 0)])
10985 (label_ref (match_operand 1))
10989 (if_then_else (match_dup 0)
10990 (label_ref (match_dup 1))
10992 "PUT_MODE (operands[0], VOIDmode);")
10996 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10997 [(reg FLAGS_REG) (const_int 0)])
10999 (label_ref (match_operand 1))
11003 (if_then_else (match_dup 0)
11004 (label_ref (match_dup 1))
11007 rtx new_op0 = copy_rtx (operands[0]);
11008 operands[0] = new_op0;
11009 PUT_MODE (new_op0, VOIDmode);
11010 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11011 GET_MODE (XEXP (new_op0, 0))));
11013 /* Make sure that (a) the CCmode we have for the flags is strong
11014 enough for the reversed compare or (b) we have a valid FP compare. */
11015 if (! ix86_comparison_operator (new_op0, VOIDmode))
11019 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11020 ;; pass generates from shift insn with QImode operand. Actually, the mode
11021 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11022 ;; appropriate modulo of the bit offset value.
11024 (define_insn_and_split "*jcc_bt<mode>"
11026 (if_then_else (match_operator 0 "bt_comparison_operator"
11027 [(zero_extract:SWI48
11028 (match_operand:SWI48 1 "register_operand" "r")
11031 (match_operand:QI 2 "register_operand" "r")))
11033 (label_ref (match_operand 3))
11035 (clobber (reg:CC FLAGS_REG))]
11036 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11039 [(set (reg:CCC FLAGS_REG)
11041 (zero_extract:SWI48
11047 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11048 (label_ref (match_dup 3))
11051 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11053 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11056 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11057 ;; zero extended to SImode.
11058 (define_insn_and_split "*jcc_bt<mode>_1"
11060 (if_then_else (match_operator 0 "bt_comparison_operator"
11061 [(zero_extract:SWI48
11062 (match_operand:SWI48 1 "register_operand" "r")
11064 (match_operand:SI 2 "register_operand" "r"))
11066 (label_ref (match_operand 3))
11068 (clobber (reg:CC FLAGS_REG))]
11069 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11072 [(set (reg:CCC FLAGS_REG)
11074 (zero_extract:SWI48
11080 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11081 (label_ref (match_dup 3))
11084 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11086 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11089 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11090 ;; also for DImode, this is what combine produces.
11091 (define_insn_and_split "*jcc_bt<mode>_mask"
11093 (if_then_else (match_operator 0 "bt_comparison_operator"
11094 [(zero_extract:SWI48
11095 (match_operand:SWI48 1 "register_operand" "r")
11098 (match_operand:SI 2 "register_operand" "r")
11099 (match_operand:SI 3 "const_int_operand" "n")))])
11100 (label_ref (match_operand 4))
11102 (clobber (reg:CC FLAGS_REG))]
11103 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11104 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11105 == GET_MODE_BITSIZE (<MODE>mode)-1"
11108 [(set (reg:CCC FLAGS_REG)
11110 (zero_extract:SWI48
11116 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11117 (label_ref (match_dup 4))
11120 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11122 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11125 (define_insn_and_split "*jcc_btsi_1"
11127 (if_then_else (match_operator 0 "bt_comparison_operator"
11130 (match_operand:SI 1 "register_operand" "r")
11131 (match_operand:QI 2 "register_operand" "r"))
11134 (label_ref (match_operand 3))
11136 (clobber (reg:CC FLAGS_REG))]
11137 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11140 [(set (reg:CCC FLAGS_REG)
11148 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11149 (label_ref (match_dup 3))
11152 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11154 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11157 ;; avoid useless masking of bit offset operand
11158 (define_insn_and_split "*jcc_btsi_mask_1"
11161 (match_operator 0 "bt_comparison_operator"
11164 (match_operand:SI 1 "register_operand" "r")
11167 (match_operand:SI 2 "register_operand" "r")
11168 (match_operand:SI 3 "const_int_operand" "n")) 0))
11171 (label_ref (match_operand 4))
11173 (clobber (reg:CC FLAGS_REG))]
11174 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11175 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11178 [(set (reg:CCC FLAGS_REG)
11186 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11187 (label_ref (match_dup 4))
11189 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11191 ;; Define combination compare-and-branch fp compare instructions to help
11194 (define_insn "*jcc<mode>_0_i387"
11196 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11197 [(match_operand:X87MODEF 1 "register_operand" "f")
11198 (match_operand:X87MODEF 2 "const0_operand")])
11199 (label_ref (match_operand 3))
11201 (clobber (reg:CCFP FPSR_REG))
11202 (clobber (reg:CCFP FLAGS_REG))
11203 (clobber (match_scratch:HI 4 "=a"))]
11204 "TARGET_80387 && !TARGET_CMOVE"
11207 (define_insn "*jcc<mode>_0_r_i387"
11209 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11210 [(match_operand:X87MODEF 1 "register_operand" "f")
11211 (match_operand:X87MODEF 2 "const0_operand")])
11213 (label_ref (match_operand 3))))
11214 (clobber (reg:CCFP FPSR_REG))
11215 (clobber (reg:CCFP FLAGS_REG))
11216 (clobber (match_scratch:HI 4 "=a"))]
11217 "TARGET_80387 && !TARGET_CMOVE"
11220 (define_insn "*jccxf_i387"
11222 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11223 [(match_operand:XF 1 "register_operand" "f")
11224 (match_operand:XF 2 "register_operand" "f")])
11225 (label_ref (match_operand 3))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 4 "=a"))]
11230 "TARGET_80387 && !TARGET_CMOVE"
11233 (define_insn "*jccxf_r_i387"
11235 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11236 [(match_operand:XF 1 "register_operand" "f")
11237 (match_operand:XF 2 "register_operand" "f")])
11239 (label_ref (match_operand 3))))
11240 (clobber (reg:CCFP FPSR_REG))
11241 (clobber (reg:CCFP FLAGS_REG))
11242 (clobber (match_scratch:HI 4 "=a"))]
11243 "TARGET_80387 && !TARGET_CMOVE"
11246 (define_insn "*jcc<mode>_i387"
11248 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11249 [(match_operand:MODEF 1 "register_operand" "f")
11250 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11251 (label_ref (match_operand 3))
11253 (clobber (reg:CCFP FPSR_REG))
11254 (clobber (reg:CCFP FLAGS_REG))
11255 (clobber (match_scratch:HI 4 "=a"))]
11256 "TARGET_80387 && !TARGET_CMOVE"
11259 (define_insn "*jcc<mode>_r_i387"
11261 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11262 [(match_operand:MODEF 1 "register_operand" "f")
11263 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11265 (label_ref (match_operand 3))))
11266 (clobber (reg:CCFP FPSR_REG))
11267 (clobber (reg:CCFP FLAGS_REG))
11268 (clobber (match_scratch:HI 4 "=a"))]
11269 "TARGET_80387 && !TARGET_CMOVE"
11272 (define_insn "*jccu<mode>_i387"
11274 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11275 [(match_operand:X87MODEF 1 "register_operand" "f")
11276 (match_operand:X87MODEF 2 "register_operand" "f")])
11277 (label_ref (match_operand 3))
11279 (clobber (reg:CCFP FPSR_REG))
11280 (clobber (reg:CCFP FLAGS_REG))
11281 (clobber (match_scratch:HI 4 "=a"))]
11282 "TARGET_80387 && !TARGET_CMOVE"
11285 (define_insn "*jccu<mode>_r_i387"
11287 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11288 [(match_operand:X87MODEF 1 "register_operand" "f")
11289 (match_operand:X87MODEF 2 "register_operand" "f")])
11291 (label_ref (match_operand 3))))
11292 (clobber (reg:CCFP FPSR_REG))
11293 (clobber (reg:CCFP FLAGS_REG))
11294 (clobber (match_scratch:HI 4 "=a"))]
11295 "TARGET_80387 && !TARGET_CMOVE"
11300 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11301 [(match_operand:X87MODEF 1 "register_operand")
11302 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11304 (match_operand 4)))
11305 (clobber (reg:CCFP FPSR_REG))
11306 (clobber (reg:CCFP FLAGS_REG))]
11307 "TARGET_80387 && !TARGET_CMOVE
11308 && reload_completed"
11311 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11312 operands[3], operands[4], NULL_RTX, NULL_RTX);
11318 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11319 [(match_operand:X87MODEF 1 "register_operand")
11320 (match_operand:X87MODEF 2 "general_operand")])
11322 (match_operand 4)))
11323 (clobber (reg:CCFP FPSR_REG))
11324 (clobber (reg:CCFP FLAGS_REG))
11325 (clobber (match_scratch:HI 5))]
11326 "TARGET_80387 && !TARGET_CMOVE
11327 && reload_completed"
11330 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11331 operands[3], operands[4], operands[5], NULL_RTX);
11335 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11336 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11337 ;; with a precedence over other operators and is always put in the first
11338 ;; place. Swap condition and operands to match ficom instruction.
11340 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11343 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11344 [(match_operator:X87MODEF 1 "float_operator"
11345 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11346 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11347 (label_ref (match_operand 4))
11349 (clobber (reg:CCFP FPSR_REG))
11350 (clobber (reg:CCFP FLAGS_REG))
11351 (clobber (match_scratch:HI 5 "=a,a"))]
11352 "TARGET_80387 && !TARGET_CMOVE
11353 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11354 || optimize_function_for_size_p (cfun))"
11357 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11360 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11361 [(match_operator:X87MODEF 1 "float_operator"
11362 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11363 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11365 (label_ref (match_operand 4))))
11366 (clobber (reg:CCFP FPSR_REG))
11367 (clobber (reg:CCFP FLAGS_REG))
11368 (clobber (match_scratch:HI 5 "=a,a"))]
11369 "TARGET_80387 && !TARGET_CMOVE
11370 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11371 || optimize_function_for_size_p (cfun))"
11377 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11378 [(match_operator:X87MODEF 1 "float_operator"
11379 [(match_operand:SWI24 2 "memory_operand")])
11380 (match_operand:X87MODEF 3 "register_operand")])
11382 (match_operand 5)))
11383 (clobber (reg:CCFP FPSR_REG))
11384 (clobber (reg:CCFP FLAGS_REG))
11385 (clobber (match_scratch:HI 6))]
11386 "TARGET_80387 && !TARGET_CMOVE
11387 && reload_completed"
11390 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11391 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11392 operands[4], operands[5], operands[6], NULL_RTX);
11396 ;; %%% Kill this when reload knows how to do it.
11400 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11401 [(match_operator:X87MODEF 1 "float_operator"
11402 [(match_operand:SWI24 2 "register_operand")])
11403 (match_operand:X87MODEF 3 "register_operand")])
11405 (match_operand 5)))
11406 (clobber (reg:CCFP FPSR_REG))
11407 (clobber (reg:CCFP FLAGS_REG))
11408 (clobber (match_scratch:HI 6))]
11409 "TARGET_80387 && !TARGET_CMOVE
11410 && reload_completed"
11413 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11415 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11416 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11417 operands[4], operands[5], operands[6], operands[2]);
11421 ;; Unconditional and other jump instructions
11423 (define_insn "jump"
11425 (label_ref (match_operand 0)))]
11428 [(set_attr "type" "ibr")
11429 (set (attr "length")
11430 (if_then_else (and (ge (minus (match_dup 0) (pc))
11432 (lt (minus (match_dup 0) (pc))
11436 (set_attr "modrm" "0")])
11438 (define_expand "indirect_jump"
11439 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11443 operands[0] = convert_memory_address (word_mode, operands[0]);
11446 (define_insn "*indirect_jump"
11447 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11450 [(set_attr "type" "ibr")
11451 (set_attr "length_immediate" "0")])
11453 (define_expand "tablejump"
11454 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11455 (use (label_ref (match_operand 1)))])]
11458 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11459 relative. Convert the relative address to an absolute address. */
11463 enum rtx_code code;
11465 /* We can't use @GOTOFF for text labels on VxWorks;
11466 see gotoff_operand. */
11467 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11471 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11473 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11477 op1 = pic_offset_table_rtx;
11482 op0 = pic_offset_table_rtx;
11486 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11491 operands[0] = convert_memory_address (word_mode, operands[0]);
11494 (define_insn "*tablejump_1"
11495 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11496 (use (label_ref (match_operand 1)))]
11499 [(set_attr "type" "ibr")
11500 (set_attr "length_immediate" "0")])
11502 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11505 [(set (reg FLAGS_REG) (match_operand 0))
11506 (set (match_operand:QI 1 "register_operand")
11507 (match_operator:QI 2 "ix86_comparison_operator"
11508 [(reg FLAGS_REG) (const_int 0)]))
11509 (set (match_operand 3 "q_regs_operand")
11510 (zero_extend (match_dup 1)))]
11511 "(peep2_reg_dead_p (3, operands[1])
11512 || operands_match_p (operands[1], operands[3]))
11513 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11514 [(set (match_dup 4) (match_dup 0))
11515 (set (strict_low_part (match_dup 5))
11518 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11519 operands[5] = gen_lowpart (QImode, operands[3]);
11520 ix86_expand_clear (operands[3]);
11524 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11525 (match_operand 4)])
11526 (set (match_operand:QI 1 "register_operand")
11527 (match_operator:QI 2 "ix86_comparison_operator"
11528 [(reg FLAGS_REG) (const_int 0)]))
11529 (set (match_operand 3 "q_regs_operand")
11530 (zero_extend (match_dup 1)))]
11531 "(peep2_reg_dead_p (3, operands[1])
11532 || operands_match_p (operands[1], operands[3]))
11533 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11534 [(parallel [(set (match_dup 5) (match_dup 0))
11536 (set (strict_low_part (match_dup 6))
11539 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11540 operands[6] = gen_lowpart (QImode, operands[3]);
11541 ix86_expand_clear (operands[3]);
11544 ;; Similar, but match zero extend with andsi3.
11547 [(set (reg FLAGS_REG) (match_operand 0))
11548 (set (match_operand:QI 1 "register_operand")
11549 (match_operator:QI 2 "ix86_comparison_operator"
11550 [(reg FLAGS_REG) (const_int 0)]))
11551 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11552 (and:SI (match_dup 3) (const_int 255)))
11553 (clobber (reg:CC FLAGS_REG))])]
11554 "REGNO (operands[1]) == REGNO (operands[3])
11555 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11556 [(set (match_dup 4) (match_dup 0))
11557 (set (strict_low_part (match_dup 5))
11560 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11561 operands[5] = gen_lowpart (QImode, operands[3]);
11562 ix86_expand_clear (operands[3]);
11566 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11567 (match_operand 4)])
11568 (set (match_operand:QI 1 "register_operand")
11569 (match_operator:QI 2 "ix86_comparison_operator"
11570 [(reg FLAGS_REG) (const_int 0)]))
11571 (parallel [(set (match_operand 3 "q_regs_operand")
11572 (zero_extend (match_dup 1)))
11573 (clobber (reg:CC FLAGS_REG))])]
11574 "(peep2_reg_dead_p (3, operands[1])
11575 || operands_match_p (operands[1], operands[3]))
11576 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11577 [(parallel [(set (match_dup 5) (match_dup 0))
11579 (set (strict_low_part (match_dup 6))
11582 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11583 operands[6] = gen_lowpart (QImode, operands[3]);
11584 ix86_expand_clear (operands[3]);
11587 ;; Call instructions.
11589 ;; The predicates normally associated with named expanders are not properly
11590 ;; checked for calls. This is a bug in the generic code, but it isn't that
11591 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11593 ;; P6 processors will jump to the address after the decrement when %esp
11594 ;; is used as a call operand, so they will execute return address as a code.
11595 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11597 ;; Register constraint for call instruction.
11598 (define_mode_attr c [(SI "l") (DI "r")])
11600 ;; Call subroutine returning no value.
11602 (define_expand "call"
11603 [(call (match_operand:QI 0)
11605 (use (match_operand 2))]
11608 ix86_expand_call (NULL, operands[0], operands[1],
11609 operands[2], NULL, false);
11613 (define_expand "sibcall"
11614 [(call (match_operand:QI 0)
11616 (use (match_operand 2))]
11619 ix86_expand_call (NULL, operands[0], operands[1],
11620 operands[2], NULL, true);
11624 (define_insn "*call"
11625 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11626 (match_operand 1))]
11627 "!SIBLING_CALL_P (insn)"
11628 "* return ix86_output_call_insn (insn, operands[0]);"
11629 [(set_attr "type" "call")])
11631 (define_insn "*call_rex64_ms_sysv"
11632 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11633 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11635 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11636 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11637 "* return ix86_output_call_insn (insn, operands[0]);"
11638 [(set_attr "type" "call")])
11640 (define_insn "*sibcall"
11641 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11642 (match_operand 1))]
11643 "SIBLING_CALL_P (insn)"
11644 "* return ix86_output_call_insn (insn, operands[0]);"
11645 [(set_attr "type" "call")])
11647 (define_expand "call_pop"
11648 [(parallel [(call (match_operand:QI 0)
11649 (match_operand:SI 1))
11650 (set (reg:SI SP_REG)
11651 (plus:SI (reg:SI SP_REG)
11652 (match_operand:SI 3)))])]
11655 ix86_expand_call (NULL, operands[0], operands[1],
11656 operands[2], operands[3], false);
11660 (define_insn "*call_pop"
11661 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11663 (set (reg:SI SP_REG)
11664 (plus:SI (reg:SI SP_REG)
11665 (match_operand:SI 2 "immediate_operand" "i")))]
11666 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11667 "* return ix86_output_call_insn (insn, operands[0]);"
11668 [(set_attr "type" "call")])
11670 (define_insn "*sibcall_pop"
11671 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11673 (set (reg:SI SP_REG)
11674 (plus:SI (reg:SI SP_REG)
11675 (match_operand:SI 2 "immediate_operand" "i")))]
11676 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11677 "* return ix86_output_call_insn (insn, operands[0]);"
11678 [(set_attr "type" "call")])
11680 ;; Call subroutine, returning value in operand 0
11682 (define_expand "call_value"
11683 [(set (match_operand 0)
11684 (call (match_operand:QI 1)
11685 (match_operand 2)))
11686 (use (match_operand 3))]
11689 ix86_expand_call (operands[0], operands[1], operands[2],
11690 operands[3], NULL, false);
11694 (define_expand "sibcall_value"
11695 [(set (match_operand 0)
11696 (call (match_operand:QI 1)
11697 (match_operand 2)))
11698 (use (match_operand 3))]
11701 ix86_expand_call (operands[0], operands[1], operands[2],
11702 operands[3], NULL, true);
11706 (define_insn "*call_value"
11707 [(set (match_operand 0)
11708 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11709 (match_operand 2)))]
11710 "!SIBLING_CALL_P (insn)"
11711 "* return ix86_output_call_insn (insn, operands[1]);"
11712 [(set_attr "type" "callv")])
11714 (define_insn "*sibcall_value"
11715 [(set (match_operand 0)
11716 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11717 (match_operand 2)))]
11718 "SIBLING_CALL_P (insn)"
11719 "* return ix86_output_call_insn (insn, operands[1]);"
11720 [(set_attr "type" "callv")])
11722 (define_insn "*call_value_rex64_ms_sysv"
11723 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11724 [(set (match_operand 0)
11725 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11726 (match_operand 2)))
11727 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11728 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11729 "* return ix86_output_call_insn (insn, operands[1]);"
11730 [(set_attr "type" "callv")])
11732 (define_expand "call_value_pop"
11733 [(parallel [(set (match_operand 0)
11734 (call (match_operand:QI 1)
11735 (match_operand:SI 2)))
11736 (set (reg:SI SP_REG)
11737 (plus:SI (reg:SI SP_REG)
11738 (match_operand:SI 4)))])]
11741 ix86_expand_call (operands[0], operands[1], operands[2],
11742 operands[3], operands[4], false);
11746 (define_insn "*call_value_pop"
11747 [(set (match_operand 0)
11748 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11749 (match_operand 2)))
11750 (set (reg:SI SP_REG)
11751 (plus:SI (reg:SI SP_REG)
11752 (match_operand:SI 3 "immediate_operand" "i")))]
11753 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11754 "* return ix86_output_call_insn (insn, operands[1]);"
11755 [(set_attr "type" "callv")])
11757 (define_insn "*sibcall_value_pop"
11758 [(set (match_operand 0)
11759 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11760 (match_operand 2)))
11761 (set (reg:SI SP_REG)
11762 (plus:SI (reg:SI SP_REG)
11763 (match_operand:SI 3 "immediate_operand" "i")))]
11764 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11765 "* return ix86_output_call_insn (insn, operands[1]);"
11766 [(set_attr "type" "callv")])
11768 ;; Call subroutine returning any type.
11770 (define_expand "untyped_call"
11771 [(parallel [(call (match_operand 0)
11774 (match_operand 2)])]
11779 /* In order to give reg-stack an easier job in validating two
11780 coprocessor registers as containing a possible return value,
11781 simply pretend the untyped call returns a complex long double
11784 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11785 and should have the default ABI. */
11787 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11788 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11789 operands[0], const0_rtx,
11790 GEN_INT ((TARGET_64BIT
11791 ? (ix86_abi == SYSV_ABI
11792 ? X86_64_SSE_REGPARM_MAX
11793 : X86_64_MS_SSE_REGPARM_MAX)
11794 : X86_32_SSE_REGPARM_MAX)
11798 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11800 rtx set = XVECEXP (operands[2], 0, i);
11801 emit_move_insn (SET_DEST (set), SET_SRC (set));
11804 /* The optimizer does not know that the call sets the function value
11805 registers we stored in the result block. We avoid problems by
11806 claiming that all hard registers are used and clobbered at this
11808 emit_insn (gen_blockage ());
11813 ;; Prologue and epilogue instructions
11815 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11816 ;; all of memory. This blocks insns from being moved across this point.
11818 (define_insn "blockage"
11819 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11822 [(set_attr "length" "0")])
11824 ;; Do not schedule instructions accessing memory across this point.
11826 (define_expand "memory_blockage"
11827 [(set (match_dup 0)
11828 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11831 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11832 MEM_VOLATILE_P (operands[0]) = 1;
11835 (define_insn "*memory_blockage"
11836 [(set (match_operand:BLK 0)
11837 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11840 [(set_attr "length" "0")])
11842 ;; As USE insns aren't meaningful after reload, this is used instead
11843 ;; to prevent deleting instructions setting registers for PIC code
11844 (define_insn "prologue_use"
11845 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11848 [(set_attr "length" "0")])
11850 ;; Insn emitted into the body of a function to return from a function.
11851 ;; This is only done if the function's epilogue is known to be simple.
11852 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11854 (define_expand "return"
11856 "ix86_can_use_return_insn_p ()"
11858 if (crtl->args.pops_args)
11860 rtx popc = GEN_INT (crtl->args.pops_args);
11861 emit_jump_insn (gen_simple_return_pop_internal (popc));
11866 ;; We need to disable this for TARGET_SEH, as otherwise
11867 ;; shrink-wrapped prologue gets enabled too. This might exceed
11868 ;; the maximum size of prologue in unwind information.
11870 (define_expand "simple_return"
11874 if (crtl->args.pops_args)
11876 rtx popc = GEN_INT (crtl->args.pops_args);
11877 emit_jump_insn (gen_simple_return_pop_internal (popc));
11882 (define_insn "simple_return_internal"
11886 [(set_attr "length" "1")
11887 (set_attr "atom_unit" "jeu")
11888 (set_attr "length_immediate" "0")
11889 (set_attr "modrm" "0")])
11891 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11892 ;; instruction Athlon and K8 have.
11894 (define_insn "simple_return_internal_long"
11896 (unspec [(const_int 0)] UNSPEC_REP)]
11899 [(set_attr "length" "2")
11900 (set_attr "atom_unit" "jeu")
11901 (set_attr "length_immediate" "0")
11902 (set_attr "prefix_rep" "1")
11903 (set_attr "modrm" "0")])
11905 (define_insn "simple_return_pop_internal"
11907 (use (match_operand:SI 0 "const_int_operand"))]
11910 [(set_attr "length" "3")
11911 (set_attr "atom_unit" "jeu")
11912 (set_attr "length_immediate" "2")
11913 (set_attr "modrm" "0")])
11915 (define_insn "simple_return_indirect_internal"
11917 (use (match_operand:SI 0 "register_operand" "r"))]
11920 [(set_attr "type" "ibr")
11921 (set_attr "length_immediate" "0")])
11927 [(set_attr "length" "1")
11928 (set_attr "length_immediate" "0")
11929 (set_attr "modrm" "0")])
11931 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11932 (define_insn "nops"
11933 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11937 int num = INTVAL (operands[0]);
11939 gcc_assert (IN_RANGE (num, 1, 8));
11942 fputs ("\tnop\n", asm_out_file);
11946 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11947 (set_attr "length_immediate" "0")
11948 (set_attr "modrm" "0")])
11950 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11951 ;; branch prediction penalty for the third jump in a 16-byte
11955 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11958 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11959 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11961 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11962 The align insn is used to avoid 3 jump instructions in the row to improve
11963 branch prediction and the benefits hardly outweigh the cost of extra 8
11964 nops on the average inserted by full alignment pseudo operation. */
11968 [(set_attr "length" "16")])
11970 (define_expand "prologue"
11973 "ix86_expand_prologue (); DONE;")
11975 (define_insn "set_got"
11976 [(set (match_operand:SI 0 "register_operand" "=r")
11977 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11978 (clobber (reg:CC FLAGS_REG))]
11980 "* return output_set_got (operands[0], NULL_RTX);"
11981 [(set_attr "type" "multi")
11982 (set_attr "length" "12")])
11984 (define_insn "set_got_labelled"
11985 [(set (match_operand:SI 0 "register_operand" "=r")
11986 (unspec:SI [(label_ref (match_operand 1))]
11988 (clobber (reg:CC FLAGS_REG))]
11990 "* return output_set_got (operands[0], operands[1]);"
11991 [(set_attr "type" "multi")
11992 (set_attr "length" "12")])
11994 (define_insn "set_got_rex64"
11995 [(set (match_operand:DI 0 "register_operand" "=r")
11996 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11998 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11999 [(set_attr "type" "lea")
12000 (set_attr "length_address" "4")
12001 (set_attr "mode" "DI")])
12003 (define_insn "set_rip_rex64"
12004 [(set (match_operand:DI 0 "register_operand" "=r")
12005 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12007 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12008 [(set_attr "type" "lea")
12009 (set_attr "length_address" "4")
12010 (set_attr "mode" "DI")])
12012 (define_insn "set_got_offset_rex64"
12013 [(set (match_operand:DI 0 "register_operand" "=r")
12015 [(label_ref (match_operand 1))]
12016 UNSPEC_SET_GOT_OFFSET))]
12018 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12019 [(set_attr "type" "imov")
12020 (set_attr "length_immediate" "0")
12021 (set_attr "length_address" "8")
12022 (set_attr "mode" "DI")])
12024 (define_expand "epilogue"
12027 "ix86_expand_epilogue (1); DONE;")
12029 (define_expand "sibcall_epilogue"
12032 "ix86_expand_epilogue (0); DONE;")
12034 (define_expand "eh_return"
12035 [(use (match_operand 0 "register_operand"))]
12038 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12040 /* Tricky bit: we write the address of the handler to which we will
12041 be returning into someone else's stack frame, one word below the
12042 stack address we wish to restore. */
12043 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12044 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12045 tmp = gen_rtx_MEM (Pmode, tmp);
12046 emit_move_insn (tmp, ra);
12048 emit_jump_insn (gen_eh_return_internal ());
12053 (define_insn_and_split "eh_return_internal"
12057 "epilogue_completed"
12059 "ix86_expand_epilogue (2); DONE;")
12061 (define_insn "leave"
12062 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12063 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12064 (clobber (mem:BLK (scratch)))]
12067 [(set_attr "type" "leave")])
12069 (define_insn "leave_rex64"
12070 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12071 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12072 (clobber (mem:BLK (scratch)))]
12075 [(set_attr "type" "leave")])
12077 ;; Handle -fsplit-stack.
12079 (define_expand "split_stack_prologue"
12083 ix86_expand_split_stack_prologue ();
12087 ;; In order to support the call/return predictor, we use a return
12088 ;; instruction which the middle-end doesn't see.
12089 (define_insn "split_stack_return"
12090 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12091 UNSPECV_SPLIT_STACK_RETURN)]
12094 if (operands[0] == const0_rtx)
12099 [(set_attr "atom_unit" "jeu")
12100 (set_attr "modrm" "0")
12101 (set (attr "length")
12102 (if_then_else (match_operand:SI 0 "const0_operand")
12105 (set (attr "length_immediate")
12106 (if_then_else (match_operand:SI 0 "const0_operand")
12110 ;; If there are operand 0 bytes available on the stack, jump to
12113 (define_expand "split_stack_space_check"
12114 [(set (pc) (if_then_else
12115 (ltu (minus (reg SP_REG)
12116 (match_operand 0 "register_operand"))
12117 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12118 (label_ref (match_operand 1))
12122 rtx reg, size, limit;
12124 reg = gen_reg_rtx (Pmode);
12125 size = force_reg (Pmode, operands[0]);
12126 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12127 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12128 UNSPEC_STACK_CHECK);
12129 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12130 ix86_expand_branch (GEU, reg, limit, operands[1]);
12135 ;; Bit manipulation instructions.
12137 (define_expand "ffs<mode>2"
12138 [(set (match_dup 2) (const_int -1))
12139 (parallel [(set (match_dup 3) (match_dup 4))
12140 (set (match_operand:SWI48 0 "register_operand")
12142 (match_operand:SWI48 1 "nonimmediate_operand")))])
12143 (set (match_dup 0) (if_then_else:SWI48
12144 (eq (match_dup 3) (const_int 0))
12147 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12148 (clobber (reg:CC FLAGS_REG))])]
12151 enum machine_mode flags_mode;
12153 if (<MODE>mode == SImode && !TARGET_CMOVE)
12155 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12159 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12161 operands[2] = gen_reg_rtx (<MODE>mode);
12162 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12163 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12166 (define_insn_and_split "ffssi2_no_cmove"
12167 [(set (match_operand:SI 0 "register_operand" "=r")
12168 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12169 (clobber (match_scratch:SI 2 "=&q"))
12170 (clobber (reg:CC FLAGS_REG))]
12173 "&& reload_completed"
12174 [(parallel [(set (match_dup 4) (match_dup 5))
12175 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12176 (set (strict_low_part (match_dup 3))
12177 (eq:QI (match_dup 4) (const_int 0)))
12178 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12179 (clobber (reg:CC FLAGS_REG))])
12180 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12181 (clobber (reg:CC FLAGS_REG))])
12182 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12183 (clobber (reg:CC FLAGS_REG))])]
12185 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12187 operands[3] = gen_lowpart (QImode, operands[2]);
12188 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12189 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12191 ix86_expand_clear (operands[2]);
12194 (define_insn "*tzcnt<mode>_1"
12195 [(set (reg:CCC FLAGS_REG)
12196 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12198 (set (match_operand:SWI48 0 "register_operand" "=r")
12199 (ctz:SWI48 (match_dup 1)))]
12201 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12202 [(set_attr "type" "alu1")
12203 (set_attr "prefix_0f" "1")
12204 (set_attr "prefix_rep" "1")
12205 (set_attr "btver2_decode" "double")
12206 (set_attr "mode" "<MODE>")])
12208 (define_insn "*bsf<mode>_1"
12209 [(set (reg:CCZ FLAGS_REG)
12210 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12212 (set (match_operand:SWI48 0 "register_operand" "=r")
12213 (ctz:SWI48 (match_dup 1)))]
12215 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12216 [(set_attr "type" "alu1")
12217 (set_attr "prefix_0f" "1")
12218 (set_attr "btver2_decode" "double")
12219 (set_attr "mode" "<MODE>")])
12221 (define_insn "ctz<mode>2"
12222 [(set (match_operand:SWI248 0 "register_operand" "=r")
12223 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12224 (clobber (reg:CC FLAGS_REG))]
12228 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12229 else if (optimize_function_for_size_p (cfun))
12231 else if (TARGET_GENERIC)
12232 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12233 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12235 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12237 [(set_attr "type" "alu1")
12238 (set_attr "prefix_0f" "1")
12239 (set (attr "prefix_rep")
12241 (ior (match_test "TARGET_BMI")
12242 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12243 (match_test "TARGET_GENERIC")))
12245 (const_string "0")))
12246 (set_attr "mode" "<MODE>")])
12248 (define_expand "clz<mode>2"
12250 [(set (match_operand:SWI248 0 "register_operand")
12253 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12254 (clobber (reg:CC FLAGS_REG))])
12256 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12257 (clobber (reg:CC FLAGS_REG))])]
12262 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12265 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12268 (define_insn "clz<mode>2_lzcnt"
12269 [(set (match_operand:SWI248 0 "register_operand" "=r")
12270 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12271 (clobber (reg:CC FLAGS_REG))]
12273 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12274 [(set_attr "prefix_rep" "1")
12275 (set_attr "type" "bitmanip")
12276 (set_attr "mode" "<MODE>")])
12278 ;; BMI instructions.
12279 (define_insn "*bmi_andn_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12283 (match_operand:SWI48 1 "register_operand" "r,r"))
12284 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12285 (clobber (reg:CC FLAGS_REG))]
12287 "andn\t{%2, %1, %0|%0, %1, %2}"
12288 [(set_attr "type" "bitmanip")
12289 (set_attr "btver2_decode" "direct, double")
12290 (set_attr "mode" "<MODE>")])
12292 (define_insn "bmi_bextr_<mode>"
12293 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12294 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12295 (match_operand:SWI48 2 "register_operand" "r,r")]
12297 (clobber (reg:CC FLAGS_REG))]
12299 "bextr\t{%2, %1, %0|%0, %1, %2}"
12300 [(set_attr "type" "bitmanip")
12301 (set_attr "btver2_decode" "direct, double")
12302 (set_attr "mode" "<MODE>")])
12304 (define_insn "*bmi_blsi_<mode>"
12305 [(set (match_operand:SWI48 0 "register_operand" "=r")
12308 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12310 (clobber (reg:CC FLAGS_REG))]
12312 "blsi\t{%1, %0|%0, %1}"
12313 [(set_attr "type" "bitmanip")
12314 (set_attr "btver2_decode" "double")
12315 (set_attr "mode" "<MODE>")])
12317 (define_insn "*bmi_blsmsk_<mode>"
12318 [(set (match_operand:SWI48 0 "register_operand" "=r")
12321 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12324 (clobber (reg:CC FLAGS_REG))]
12326 "blsmsk\t{%1, %0|%0, %1}"
12327 [(set_attr "type" "bitmanip")
12328 (set_attr "btver2_decode" "double")
12329 (set_attr "mode" "<MODE>")])
12331 (define_insn "*bmi_blsr_<mode>"
12332 [(set (match_operand:SWI48 0 "register_operand" "=r")
12335 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12338 (clobber (reg:CC FLAGS_REG))]
12340 "blsr\t{%1, %0|%0, %1}"
12341 [(set_attr "type" "bitmanip")
12342 (set_attr "btver2_decode" "double")
12343 (set_attr "mode" "<MODE>")])
12345 ;; BMI2 instructions.
12346 (define_insn "bmi2_bzhi_<mode>3"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12348 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12349 (match_operand:SWI48 2 "register_operand" "r"))
12350 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12351 (clobber (reg:CC FLAGS_REG))]
12353 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12354 [(set_attr "type" "bitmanip")
12355 (set_attr "prefix" "vex")
12356 (set_attr "mode" "<MODE>")])
12358 (define_insn "bmi2_pdep_<mode>3"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12361 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12364 "pdep\t{%2, %1, %0|%0, %1, %2}"
12365 [(set_attr "type" "bitmanip")
12366 (set_attr "prefix" "vex")
12367 (set_attr "mode" "<MODE>")])
12369 (define_insn "bmi2_pext_<mode>3"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12371 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12372 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12375 "pext\t{%2, %1, %0|%0, %1, %2}"
12376 [(set_attr "type" "bitmanip")
12377 (set_attr "prefix" "vex")
12378 (set_attr "mode" "<MODE>")])
12380 ;; TBM instructions.
12381 (define_insn "tbm_bextri_<mode>"
12382 [(set (match_operand:SWI48 0 "register_operand" "=r")
12383 (zero_extract:SWI48
12384 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12385 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12386 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12387 (clobber (reg:CC FLAGS_REG))]
12390 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12391 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12393 [(set_attr "type" "bitmanip")
12394 (set_attr "mode" "<MODE>")])
12396 (define_insn "*tbm_blcfill_<mode>"
12397 [(set (match_operand:SWI48 0 "register_operand" "=r")
12400 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12403 (clobber (reg:CC FLAGS_REG))]
12405 "blcfill\t{%1, %0|%0, %1}"
12406 [(set_attr "type" "bitmanip")
12407 (set_attr "mode" "<MODE>")])
12409 (define_insn "*tbm_blci_<mode>"
12410 [(set (match_operand:SWI48 0 "register_operand" "=r")
12414 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12417 (clobber (reg:CC FLAGS_REG))]
12419 "blci\t{%1, %0|%0, %1}"
12420 [(set_attr "type" "bitmanip")
12421 (set_attr "mode" "<MODE>")])
12423 (define_insn "*tbm_blcic_<mode>"
12424 [(set (match_operand:SWI48 0 "register_operand" "=r")
12427 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12431 (clobber (reg:CC FLAGS_REG))]
12433 "blcic\t{%1, %0|%0, %1}"
12434 [(set_attr "type" "bitmanip")
12435 (set_attr "mode" "<MODE>")])
12437 (define_insn "*tbm_blcmsk_<mode>"
12438 [(set (match_operand:SWI48 0 "register_operand" "=r")
12441 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12444 (clobber (reg:CC FLAGS_REG))]
12446 "blcmsk\t{%1, %0|%0, %1}"
12447 [(set_attr "type" "bitmanip")
12448 (set_attr "mode" "<MODE>")])
12450 (define_insn "*tbm_blcs_<mode>"
12451 [(set (match_operand:SWI48 0 "register_operand" "=r")
12454 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12457 (clobber (reg:CC FLAGS_REG))]
12459 "blcs\t{%1, %0|%0, %1}"
12460 [(set_attr "type" "bitmanip")
12461 (set_attr "mode" "<MODE>")])
12463 (define_insn "*tbm_blsfill_<mode>"
12464 [(set (match_operand:SWI48 0 "register_operand" "=r")
12467 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12470 (clobber (reg:CC FLAGS_REG))]
12472 "blsfill\t{%1, %0|%0, %1}"
12473 [(set_attr "type" "bitmanip")
12474 (set_attr "mode" "<MODE>")])
12476 (define_insn "*tbm_blsic_<mode>"
12477 [(set (match_operand:SWI48 0 "register_operand" "=r")
12480 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12484 (clobber (reg:CC FLAGS_REG))]
12486 "blsic\t{%1, %0|%0, %1}"
12487 [(set_attr "type" "bitmanip")
12488 (set_attr "mode" "<MODE>")])
12490 (define_insn "*tbm_t1mskc_<mode>"
12491 [(set (match_operand:SWI48 0 "register_operand" "=r")
12494 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12498 (clobber (reg:CC FLAGS_REG))]
12500 "t1mskc\t{%1, %0|%0, %1}"
12501 [(set_attr "type" "bitmanip")
12502 (set_attr "mode" "<MODE>")])
12504 (define_insn "*tbm_tzmsk_<mode>"
12505 [(set (match_operand:SWI48 0 "register_operand" "=r")
12508 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12512 (clobber (reg:CC FLAGS_REG))]
12514 "tzmsk\t{%1, %0|%0, %1}"
12515 [(set_attr "type" "bitmanip")
12516 (set_attr "mode" "<MODE>")])
12518 (define_insn "bsr_rex64"
12519 [(set (match_operand:DI 0 "register_operand" "=r")
12520 (minus:DI (const_int 63)
12521 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12522 (clobber (reg:CC FLAGS_REG))]
12524 "bsr{q}\t{%1, %0|%0, %1}"
12525 [(set_attr "type" "alu1")
12526 (set_attr "prefix_0f" "1")
12527 (set_attr "mode" "DI")])
12530 [(set (match_operand:SI 0 "register_operand" "=r")
12531 (minus:SI (const_int 31)
12532 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12533 (clobber (reg:CC FLAGS_REG))]
12535 "bsr{l}\t{%1, %0|%0, %1}"
12536 [(set_attr "type" "alu1")
12537 (set_attr "prefix_0f" "1")
12538 (set_attr "mode" "SI")])
12540 (define_insn "*bsrhi"
12541 [(set (match_operand:HI 0 "register_operand" "=r")
12542 (minus:HI (const_int 15)
12543 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12544 (clobber (reg:CC FLAGS_REG))]
12546 "bsr{w}\t{%1, %0|%0, %1}"
12547 [(set_attr "type" "alu1")
12548 (set_attr "prefix_0f" "1")
12549 (set_attr "mode" "HI")])
12551 (define_insn "popcount<mode>2"
12552 [(set (match_operand:SWI248 0 "register_operand" "=r")
12554 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12555 (clobber (reg:CC FLAGS_REG))]
12559 return "popcnt\t{%1, %0|%0, %1}";
12561 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12564 [(set_attr "prefix_rep" "1")
12565 (set_attr "type" "bitmanip")
12566 (set_attr "mode" "<MODE>")])
12568 (define_insn "*popcount<mode>2_cmp"
12569 [(set (reg FLAGS_REG)
12572 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12574 (set (match_operand:SWI248 0 "register_operand" "=r")
12575 (popcount:SWI248 (match_dup 1)))]
12576 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12579 return "popcnt\t{%1, %0|%0, %1}";
12581 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12584 [(set_attr "prefix_rep" "1")
12585 (set_attr "type" "bitmanip")
12586 (set_attr "mode" "<MODE>")])
12588 (define_insn "*popcountsi2_cmp_zext"
12589 [(set (reg FLAGS_REG)
12591 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12593 (set (match_operand:DI 0 "register_operand" "=r")
12594 (zero_extend:DI(popcount:SI (match_dup 1))))]
12595 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12598 return "popcnt\t{%1, %0|%0, %1}";
12600 return "popcnt{l}\t{%1, %0|%0, %1}";
12603 [(set_attr "prefix_rep" "1")
12604 (set_attr "type" "bitmanip")
12605 (set_attr "mode" "SI")])
12607 (define_expand "bswapdi2"
12608 [(set (match_operand:DI 0 "register_operand")
12609 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12613 operands[1] = force_reg (DImode, operands[1]);
12616 (define_expand "bswapsi2"
12617 [(set (match_operand:SI 0 "register_operand")
12618 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12623 else if (TARGET_BSWAP)
12624 operands[1] = force_reg (SImode, operands[1]);
12627 rtx x = operands[0];
12629 emit_move_insn (x, operands[1]);
12630 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12631 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12632 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12637 (define_insn "*bswap<mode>2_movbe"
12638 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12639 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12644 movbe\t{%1, %0|%0, %1}
12645 movbe\t{%1, %0|%0, %1}"
12646 [(set_attr "type" "bitmanip,imov,imov")
12647 (set_attr "modrm" "0,1,1")
12648 (set_attr "prefix_0f" "*,1,1")
12649 (set_attr "prefix_extra" "*,1,1")
12650 (set_attr "mode" "<MODE>")])
12652 (define_insn "*bswap<mode>2"
12653 [(set (match_operand:SWI48 0 "register_operand" "=r")
12654 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12657 [(set_attr "type" "bitmanip")
12658 (set_attr "modrm" "0")
12659 (set_attr "mode" "<MODE>")])
12661 (define_insn "*bswaphi_lowpart_1"
12662 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12663 (bswap:HI (match_dup 0)))
12664 (clobber (reg:CC FLAGS_REG))]
12665 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12667 xchg{b}\t{%h0, %b0|%b0, %h0}
12668 rol{w}\t{$8, %0|%0, 8}"
12669 [(set_attr "length" "2,4")
12670 (set_attr "mode" "QI,HI")])
12672 (define_insn "bswaphi_lowpart"
12673 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12674 (bswap:HI (match_dup 0)))
12675 (clobber (reg:CC FLAGS_REG))]
12677 "rol{w}\t{$8, %0|%0, 8}"
12678 [(set_attr "length" "4")
12679 (set_attr "mode" "HI")])
12681 (define_expand "paritydi2"
12682 [(set (match_operand:DI 0 "register_operand")
12683 (parity:DI (match_operand:DI 1 "register_operand")))]
12686 rtx scratch = gen_reg_rtx (QImode);
12689 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12690 NULL_RTX, operands[1]));
12692 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12693 gen_rtx_REG (CCmode, FLAGS_REG),
12695 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12698 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12701 rtx tmp = gen_reg_rtx (SImode);
12703 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12704 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12709 (define_expand "paritysi2"
12710 [(set (match_operand:SI 0 "register_operand")
12711 (parity:SI (match_operand:SI 1 "register_operand")))]
12714 rtx scratch = gen_reg_rtx (QImode);
12717 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12719 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12720 gen_rtx_REG (CCmode, FLAGS_REG),
12722 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12724 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12728 (define_insn_and_split "paritydi2_cmp"
12729 [(set (reg:CC FLAGS_REG)
12730 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12732 (clobber (match_scratch:DI 0 "=r"))
12733 (clobber (match_scratch:SI 1 "=&r"))
12734 (clobber (match_scratch:HI 2 "=Q"))]
12737 "&& reload_completed"
12739 [(set (match_dup 1)
12740 (xor:SI (match_dup 1) (match_dup 4)))
12741 (clobber (reg:CC FLAGS_REG))])
12743 [(set (reg:CC FLAGS_REG)
12744 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12745 (clobber (match_dup 1))
12746 (clobber (match_dup 2))])]
12748 operands[4] = gen_lowpart (SImode, operands[3]);
12752 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12753 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12756 operands[1] = gen_highpart (SImode, operands[3]);
12759 (define_insn_and_split "paritysi2_cmp"
12760 [(set (reg:CC FLAGS_REG)
12761 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12763 (clobber (match_scratch:SI 0 "=r"))
12764 (clobber (match_scratch:HI 1 "=&Q"))]
12767 "&& reload_completed"
12769 [(set (match_dup 1)
12770 (xor:HI (match_dup 1) (match_dup 3)))
12771 (clobber (reg:CC FLAGS_REG))])
12773 [(set (reg:CC FLAGS_REG)
12774 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12775 (clobber (match_dup 1))])]
12777 operands[3] = gen_lowpart (HImode, operands[2]);
12779 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12780 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12783 (define_insn "*parityhi2_cmp"
12784 [(set (reg:CC FLAGS_REG)
12785 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12787 (clobber (match_scratch:HI 0 "=Q"))]
12789 "xor{b}\t{%h0, %b0|%b0, %h0}"
12790 [(set_attr "length" "2")
12791 (set_attr "mode" "HI")])
12794 ;; Thread-local storage patterns for ELF.
12796 ;; Note that these code sequences must appear exactly as shown
12797 ;; in order to allow linker relaxation.
12799 (define_insn "*tls_global_dynamic_32_gnu"
12800 [(set (match_operand:SI 0 "register_operand" "=a")
12802 [(match_operand:SI 1 "register_operand" "b")
12803 (match_operand 2 "tls_symbolic_operand")
12804 (match_operand 3 "constant_call_address_operand" "z")]
12806 (clobber (match_scratch:SI 4 "=d"))
12807 (clobber (match_scratch:SI 5 "=c"))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "!TARGET_64BIT && TARGET_GNU_TLS"
12812 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12813 if (TARGET_SUN_TLS)
12814 #ifdef HAVE_AS_IX86_TLSGDPLT
12815 return "call\t%a2@tlsgdplt";
12817 return "call\t%p3@plt";
12819 return "call\t%P3";
12821 [(set_attr "type" "multi")
12822 (set_attr "length" "12")])
12824 (define_expand "tls_global_dynamic_32"
12826 [(set (match_operand:SI 0 "register_operand")
12827 (unspec:SI [(match_operand:SI 2 "register_operand")
12828 (match_operand 1 "tls_symbolic_operand")
12829 (match_operand 3 "constant_call_address_operand")]
12831 (clobber (match_scratch:SI 4))
12832 (clobber (match_scratch:SI 5))
12833 (clobber (reg:CC FLAGS_REG))])])
12835 (define_insn "*tls_global_dynamic_64_<mode>"
12836 [(set (match_operand:P 0 "register_operand" "=a")
12838 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12839 (match_operand 3)))
12840 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12845 fputs (ASM_BYTE "0x66\n", asm_out_file);
12847 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12848 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12849 fputs ("\trex64\n", asm_out_file);
12850 if (TARGET_SUN_TLS)
12851 return "call\t%p2@plt";
12852 return "call\t%P2";
12854 [(set_attr "type" "multi")
12855 (set (attr "length")
12856 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12858 (define_insn "*tls_global_dynamic_64_largepic"
12859 [(set (match_operand:DI 0 "register_operand" "=a")
12861 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12862 (match_operand:DI 3 "immediate_operand" "i")))
12863 (match_operand 4)))
12864 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12866 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12867 && GET_CODE (operands[3]) == CONST
12868 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12869 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12872 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12873 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12874 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12875 return "call\t{*%%rax|rax}";
12877 [(set_attr "type" "multi")
12878 (set_attr "length" "22")])
12880 (define_expand "tls_global_dynamic_64_<mode>"
12882 [(set (match_operand:P 0 "register_operand")
12884 (mem:QI (match_operand 2))
12886 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12890 (define_insn "*tls_local_dynamic_base_32_gnu"
12891 [(set (match_operand:SI 0 "register_operand" "=a")
12893 [(match_operand:SI 1 "register_operand" "b")
12894 (match_operand 2 "constant_call_address_operand" "z")]
12895 UNSPEC_TLS_LD_BASE))
12896 (clobber (match_scratch:SI 3 "=d"))
12897 (clobber (match_scratch:SI 4 "=c"))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "!TARGET_64BIT && TARGET_GNU_TLS"
12902 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12903 if (TARGET_SUN_TLS)
12904 #ifdef HAVE_AS_IX86_TLSLDMPLT
12905 return "call\t%&@tlsldmplt";
12907 return "call\t%p2@plt";
12909 return "call\t%P2";
12911 [(set_attr "type" "multi")
12912 (set_attr "length" "11")])
12914 (define_expand "tls_local_dynamic_base_32"
12916 [(set (match_operand:SI 0 "register_operand")
12918 [(match_operand:SI 1 "register_operand")
12919 (match_operand 2 "constant_call_address_operand")]
12920 UNSPEC_TLS_LD_BASE))
12921 (clobber (match_scratch:SI 3))
12922 (clobber (match_scratch:SI 4))
12923 (clobber (reg:CC FLAGS_REG))])])
12925 (define_insn "*tls_local_dynamic_base_64_<mode>"
12926 [(set (match_operand:P 0 "register_operand" "=a")
12928 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12929 (match_operand 2)))
12930 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12934 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12935 if (TARGET_SUN_TLS)
12936 return "call\t%p1@plt";
12937 return "call\t%P1";
12939 [(set_attr "type" "multi")
12940 (set_attr "length" "12")])
12942 (define_insn "*tls_local_dynamic_base_64_largepic"
12943 [(set (match_operand:DI 0 "register_operand" "=a")
12945 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12946 (match_operand:DI 2 "immediate_operand" "i")))
12947 (match_operand 3)))
12948 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12949 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12950 && GET_CODE (operands[2]) == CONST
12951 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12952 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12955 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12956 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12957 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12958 return "call\t{*%%rax|rax}";
12960 [(set_attr "type" "multi")
12961 (set_attr "length" "22")])
12963 (define_expand "tls_local_dynamic_base_64_<mode>"
12965 [(set (match_operand:P 0 "register_operand")
12967 (mem:QI (match_operand 1))
12969 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12972 ;; Local dynamic of a single variable is a lose. Show combine how
12973 ;; to convert that back to global dynamic.
12975 (define_insn_and_split "*tls_local_dynamic_32_once"
12976 [(set (match_operand:SI 0 "register_operand" "=a")
12978 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12979 (match_operand 2 "constant_call_address_operand" "z")]
12980 UNSPEC_TLS_LD_BASE)
12981 (const:SI (unspec:SI
12982 [(match_operand 3 "tls_symbolic_operand")]
12984 (clobber (match_scratch:SI 4 "=d"))
12985 (clobber (match_scratch:SI 5 "=c"))
12986 (clobber (reg:CC FLAGS_REG))]
12991 [(set (match_dup 0)
12992 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12994 (clobber (match_dup 4))
12995 (clobber (match_dup 5))
12996 (clobber (reg:CC FLAGS_REG))])])
12998 ;; Segment register for the thread base ptr load
12999 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13001 ;; Load and add the thread base pointer from %<tp_seg>:0.
13002 (define_insn "*load_tp_x32"
13003 [(set (match_operand:SI 0 "register_operand" "=r")
13004 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13006 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13007 [(set_attr "type" "imov")
13008 (set_attr "modrm" "0")
13009 (set_attr "length" "7")
13010 (set_attr "memory" "load")
13011 (set_attr "imm_disp" "false")])
13013 (define_insn "*load_tp_x32_zext"
13014 [(set (match_operand:DI 0 "register_operand" "=r")
13015 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13017 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13018 [(set_attr "type" "imov")
13019 (set_attr "modrm" "0")
13020 (set_attr "length" "7")
13021 (set_attr "memory" "load")
13022 (set_attr "imm_disp" "false")])
13024 (define_insn "*load_tp_<mode>"
13025 [(set (match_operand:P 0 "register_operand" "=r")
13026 (unspec:P [(const_int 0)] UNSPEC_TP))]
13028 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13029 [(set_attr "type" "imov")
13030 (set_attr "modrm" "0")
13031 (set_attr "length" "7")
13032 (set_attr "memory" "load")
13033 (set_attr "imm_disp" "false")])
13035 (define_insn "*add_tp_x32"
13036 [(set (match_operand:SI 0 "register_operand" "=r")
13037 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13038 (match_operand:SI 1 "register_operand" "0")))
13039 (clobber (reg:CC FLAGS_REG))]
13041 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13042 [(set_attr "type" "alu")
13043 (set_attr "modrm" "0")
13044 (set_attr "length" "7")
13045 (set_attr "memory" "load")
13046 (set_attr "imm_disp" "false")])
13048 (define_insn "*add_tp_x32_zext"
13049 [(set (match_operand:DI 0 "register_operand" "=r")
13051 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13052 (match_operand:SI 1 "register_operand" "0"))))
13053 (clobber (reg:CC FLAGS_REG))]
13055 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13056 [(set_attr "type" "alu")
13057 (set_attr "modrm" "0")
13058 (set_attr "length" "7")
13059 (set_attr "memory" "load")
13060 (set_attr "imm_disp" "false")])
13062 (define_insn "*add_tp_<mode>"
13063 [(set (match_operand:P 0 "register_operand" "=r")
13064 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13065 (match_operand:P 1 "register_operand" "0")))
13066 (clobber (reg:CC FLAGS_REG))]
13068 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13069 [(set_attr "type" "alu")
13070 (set_attr "modrm" "0")
13071 (set_attr "length" "7")
13072 (set_attr "memory" "load")
13073 (set_attr "imm_disp" "false")])
13075 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13076 ;; %rax as destination of the initial executable code sequence.
13077 (define_insn "tls_initial_exec_64_sun"
13078 [(set (match_operand:DI 0 "register_operand" "=a")
13080 [(match_operand 1 "tls_symbolic_operand")]
13081 UNSPEC_TLS_IE_SUN))
13082 (clobber (reg:CC FLAGS_REG))]
13083 "TARGET_64BIT && TARGET_SUN_TLS"
13086 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13087 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13089 [(set_attr "type" "multi")])
13091 ;; GNU2 TLS patterns can be split.
13093 (define_expand "tls_dynamic_gnu2_32"
13094 [(set (match_dup 3)
13095 (plus:SI (match_operand:SI 2 "register_operand")
13097 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13100 [(set (match_operand:SI 0 "register_operand")
13101 (unspec:SI [(match_dup 1) (match_dup 3)
13102 (match_dup 2) (reg:SI SP_REG)]
13104 (clobber (reg:CC FLAGS_REG))])]
13105 "!TARGET_64BIT && TARGET_GNU2_TLS"
13107 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13108 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13111 (define_insn "*tls_dynamic_gnu2_lea_32"
13112 [(set (match_operand:SI 0 "register_operand" "=r")
13113 (plus:SI (match_operand:SI 1 "register_operand" "b")
13115 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13116 UNSPEC_TLSDESC))))]
13117 "!TARGET_64BIT && TARGET_GNU2_TLS"
13118 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13119 [(set_attr "type" "lea")
13120 (set_attr "mode" "SI")
13121 (set_attr "length" "6")
13122 (set_attr "length_address" "4")])
13124 (define_insn "*tls_dynamic_gnu2_call_32"
13125 [(set (match_operand:SI 0 "register_operand" "=a")
13126 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13127 (match_operand:SI 2 "register_operand" "0")
13128 ;; we have to make sure %ebx still points to the GOT
13129 (match_operand:SI 3 "register_operand" "b")
13132 (clobber (reg:CC FLAGS_REG))]
13133 "!TARGET_64BIT && TARGET_GNU2_TLS"
13134 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13135 [(set_attr "type" "call")
13136 (set_attr "length" "2")
13137 (set_attr "length_address" "0")])
13139 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13140 [(set (match_operand:SI 0 "register_operand" "=&a")
13142 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13143 (match_operand:SI 4)
13144 (match_operand:SI 2 "register_operand" "b")
13147 (const:SI (unspec:SI
13148 [(match_operand 1 "tls_symbolic_operand")]
13150 (clobber (reg:CC FLAGS_REG))]
13151 "!TARGET_64BIT && TARGET_GNU2_TLS"
13154 [(set (match_dup 0) (match_dup 5))]
13156 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13157 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13160 (define_expand "tls_dynamic_gnu2_64"
13161 [(set (match_dup 2)
13162 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13165 [(set (match_operand:DI 0 "register_operand")
13166 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13168 (clobber (reg:CC FLAGS_REG))])]
13169 "TARGET_64BIT && TARGET_GNU2_TLS"
13171 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13172 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13175 (define_insn "*tls_dynamic_gnu2_lea_64"
13176 [(set (match_operand:DI 0 "register_operand" "=r")
13177 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13179 "TARGET_64BIT && TARGET_GNU2_TLS"
13180 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13181 [(set_attr "type" "lea")
13182 (set_attr "mode" "DI")
13183 (set_attr "length" "7")
13184 (set_attr "length_address" "4")])
13186 (define_insn "*tls_dynamic_gnu2_call_64"
13187 [(set (match_operand:DI 0 "register_operand" "=a")
13188 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13189 (match_operand:DI 2 "register_operand" "0")
13192 (clobber (reg:CC FLAGS_REG))]
13193 "TARGET_64BIT && TARGET_GNU2_TLS"
13194 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13195 [(set_attr "type" "call")
13196 (set_attr "length" "2")
13197 (set_attr "length_address" "0")])
13199 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13200 [(set (match_operand:DI 0 "register_operand" "=&a")
13202 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13203 (match_operand:DI 3)
13206 (const:DI (unspec:DI
13207 [(match_operand 1 "tls_symbolic_operand")]
13209 (clobber (reg:CC FLAGS_REG))]
13210 "TARGET_64BIT && TARGET_GNU2_TLS"
13213 [(set (match_dup 0) (match_dup 4))]
13215 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13216 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13219 ;; These patterns match the binary 387 instructions for addM3, subM3,
13220 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13221 ;; SFmode. The first is the normal insn, the second the same insn but
13222 ;; with one operand a conversion, and the third the same insn but with
13223 ;; the other operand a conversion. The conversion may be SFmode or
13224 ;; SImode if the target mode DFmode, but only SImode if the target mode
13227 ;; Gcc is slightly more smart about handling normal two address instructions
13228 ;; so use special patterns for add and mull.
13230 (define_insn "*fop_<mode>_comm_mixed"
13231 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13232 (match_operator:MODEF 3 "binary_fp_operator"
13233 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13234 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13235 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13236 && COMMUTATIVE_ARITH_P (operands[3])
13237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13238 "* return output_387_binary_op (insn, operands);"
13239 [(set (attr "type")
13240 (if_then_else (eq_attr "alternative" "1,2")
13241 (if_then_else (match_operand:MODEF 3 "mult_operator")
13242 (const_string "ssemul")
13243 (const_string "sseadd"))
13244 (if_then_else (match_operand:MODEF 3 "mult_operator")
13245 (const_string "fmul")
13246 (const_string "fop"))))
13247 (set_attr "isa" "*,noavx,avx")
13248 (set_attr "prefix" "orig,orig,vex")
13249 (set_attr "mode" "<MODE>")])
13251 (define_insn "*fop_<mode>_comm_sse"
13252 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13253 (match_operator:MODEF 3 "binary_fp_operator"
13254 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13255 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13256 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13257 && COMMUTATIVE_ARITH_P (operands[3])
13258 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13259 "* return output_387_binary_op (insn, operands);"
13260 [(set (attr "type")
13261 (if_then_else (match_operand:MODEF 3 "mult_operator")
13262 (const_string "ssemul")
13263 (const_string "sseadd")))
13264 (set_attr "isa" "noavx,avx")
13265 (set_attr "prefix" "orig,vex")
13266 (set_attr "mode" "<MODE>")])
13268 (define_insn "*fop_<mode>_comm_i387"
13269 [(set (match_operand:MODEF 0 "register_operand" "=f")
13270 (match_operator:MODEF 3 "binary_fp_operator"
13271 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13272 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13273 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13274 && COMMUTATIVE_ARITH_P (operands[3])
13275 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13276 "* return output_387_binary_op (insn, operands);"
13277 [(set (attr "type")
13278 (if_then_else (match_operand:MODEF 3 "mult_operator")
13279 (const_string "fmul")
13280 (const_string "fop")))
13281 (set_attr "mode" "<MODE>")])
13283 (define_insn "*fop_<mode>_1_mixed"
13284 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13285 (match_operator:MODEF 3 "binary_fp_operator"
13286 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13287 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13288 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13289 && !COMMUTATIVE_ARITH_P (operands[3])
13290 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13291 "* return output_387_binary_op (insn, operands);"
13292 [(set (attr "type")
13293 (cond [(and (eq_attr "alternative" "2,3")
13294 (match_operand:MODEF 3 "mult_operator"))
13295 (const_string "ssemul")
13296 (and (eq_attr "alternative" "2,3")
13297 (match_operand:MODEF 3 "div_operator"))
13298 (const_string "ssediv")
13299 (eq_attr "alternative" "2,3")
13300 (const_string "sseadd")
13301 (match_operand:MODEF 3 "mult_operator")
13302 (const_string "fmul")
13303 (match_operand:MODEF 3 "div_operator")
13304 (const_string "fdiv")
13306 (const_string "fop")))
13307 (set_attr "isa" "*,*,noavx,avx")
13308 (set_attr "prefix" "orig,orig,orig,vex")
13309 (set_attr "mode" "<MODE>")])
13311 (define_insn "*rcpsf2_sse"
13312 [(set (match_operand:SF 0 "register_operand" "=x")
13313 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13316 "%vrcpss\t{%1, %d0|%d0, %1}"
13317 [(set_attr "type" "sse")
13318 (set_attr "atom_sse_attr" "rcp")
13319 (set_attr "btver2_sse_attr" "rcp")
13320 (set_attr "prefix" "maybe_vex")
13321 (set_attr "mode" "SF")])
13323 (define_insn "*fop_<mode>_1_sse"
13324 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13325 (match_operator:MODEF 3 "binary_fp_operator"
13326 [(match_operand:MODEF 1 "register_operand" "0,x")
13327 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13328 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13329 && !COMMUTATIVE_ARITH_P (operands[3])"
13330 "* return output_387_binary_op (insn, operands);"
13331 [(set (attr "type")
13332 (cond [(match_operand:MODEF 3 "mult_operator")
13333 (const_string "ssemul")
13334 (match_operand:MODEF 3 "div_operator")
13335 (const_string "ssediv")
13337 (const_string "sseadd")))
13338 (set_attr "isa" "noavx,avx")
13339 (set_attr "prefix" "orig,vex")
13340 (set_attr "mode" "<MODE>")])
13342 ;; This pattern is not fully shadowed by the pattern above.
13343 (define_insn "*fop_<mode>_1_i387"
13344 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13345 (match_operator:MODEF 3 "binary_fp_operator"
13346 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13347 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13348 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13349 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13350 && !COMMUTATIVE_ARITH_P (operands[3])
13351 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13352 "* return output_387_binary_op (insn, operands);"
13353 [(set (attr "type")
13354 (cond [(match_operand:MODEF 3 "mult_operator")
13355 (const_string "fmul")
13356 (match_operand:MODEF 3 "div_operator")
13357 (const_string "fdiv")
13359 (const_string "fop")))
13360 (set_attr "mode" "<MODE>")])
13362 ;; ??? Add SSE splitters for these!
13363 (define_insn "*fop_<MODEF:mode>_2_i387"
13364 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13365 (match_operator:MODEF 3 "binary_fp_operator"
13367 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13368 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13369 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13370 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13371 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13372 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13373 [(set (attr "type")
13374 (cond [(match_operand:MODEF 3 "mult_operator")
13375 (const_string "fmul")
13376 (match_operand:MODEF 3 "div_operator")
13377 (const_string "fdiv")
13379 (const_string "fop")))
13380 (set_attr "fp_int_src" "true")
13381 (set_attr "mode" "<SWI24:MODE>")])
13383 (define_insn "*fop_<MODEF:mode>_3_i387"
13384 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13385 (match_operator:MODEF 3 "binary_fp_operator"
13386 [(match_operand:MODEF 1 "register_operand" "0,0")
13388 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13389 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13390 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13391 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13392 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13393 [(set (attr "type")
13394 (cond [(match_operand:MODEF 3 "mult_operator")
13395 (const_string "fmul")
13396 (match_operand:MODEF 3 "div_operator")
13397 (const_string "fdiv")
13399 (const_string "fop")))
13400 (set_attr "fp_int_src" "true")
13401 (set_attr "mode" "<MODE>")])
13403 (define_insn "*fop_df_4_i387"
13404 [(set (match_operand:DF 0 "register_operand" "=f,f")
13405 (match_operator:DF 3 "binary_fp_operator"
13407 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13408 (match_operand:DF 2 "register_operand" "0,f")]))]
13409 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13410 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13411 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13412 "* return output_387_binary_op (insn, operands);"
13413 [(set (attr "type")
13414 (cond [(match_operand:DF 3 "mult_operator")
13415 (const_string "fmul")
13416 (match_operand:DF 3 "div_operator")
13417 (const_string "fdiv")
13419 (const_string "fop")))
13420 (set_attr "mode" "SF")])
13422 (define_insn "*fop_df_5_i387"
13423 [(set (match_operand:DF 0 "register_operand" "=f,f")
13424 (match_operator:DF 3 "binary_fp_operator"
13425 [(match_operand:DF 1 "register_operand" "0,f")
13427 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13428 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13429 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13430 "* return output_387_binary_op (insn, operands);"
13431 [(set (attr "type")
13432 (cond [(match_operand:DF 3 "mult_operator")
13433 (const_string "fmul")
13434 (match_operand:DF 3 "div_operator")
13435 (const_string "fdiv")
13437 (const_string "fop")))
13438 (set_attr "mode" "SF")])
13440 (define_insn "*fop_df_6_i387"
13441 [(set (match_operand:DF 0 "register_operand" "=f,f")
13442 (match_operator:DF 3 "binary_fp_operator"
13444 (match_operand:SF 1 "register_operand" "0,f"))
13446 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13447 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13448 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13449 "* return output_387_binary_op (insn, operands);"
13450 [(set (attr "type")
13451 (cond [(match_operand:DF 3 "mult_operator")
13452 (const_string "fmul")
13453 (match_operand:DF 3 "div_operator")
13454 (const_string "fdiv")
13456 (const_string "fop")))
13457 (set_attr "mode" "SF")])
13459 (define_insn "*fop_xf_comm_i387"
13460 [(set (match_operand:XF 0 "register_operand" "=f")
13461 (match_operator:XF 3 "binary_fp_operator"
13462 [(match_operand:XF 1 "register_operand" "%0")
13463 (match_operand:XF 2 "register_operand" "f")]))]
13465 && COMMUTATIVE_ARITH_P (operands[3])"
13466 "* return output_387_binary_op (insn, operands);"
13467 [(set (attr "type")
13468 (if_then_else (match_operand:XF 3 "mult_operator")
13469 (const_string "fmul")
13470 (const_string "fop")))
13471 (set_attr "mode" "XF")])
13473 (define_insn "*fop_xf_1_i387"
13474 [(set (match_operand:XF 0 "register_operand" "=f,f")
13475 (match_operator:XF 3 "binary_fp_operator"
13476 [(match_operand:XF 1 "register_operand" "0,f")
13477 (match_operand:XF 2 "register_operand" "f,0")]))]
13479 && !COMMUTATIVE_ARITH_P (operands[3])"
13480 "* return output_387_binary_op (insn, operands);"
13481 [(set (attr "type")
13482 (cond [(match_operand:XF 3 "mult_operator")
13483 (const_string "fmul")
13484 (match_operand:XF 3 "div_operator")
13485 (const_string "fdiv")
13487 (const_string "fop")))
13488 (set_attr "mode" "XF")])
13490 (define_insn "*fop_xf_2_i387"
13491 [(set (match_operand:XF 0 "register_operand" "=f,f")
13492 (match_operator:XF 3 "binary_fp_operator"
13494 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13495 (match_operand:XF 2 "register_operand" "0,0")]))]
13496 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13497 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13498 [(set (attr "type")
13499 (cond [(match_operand:XF 3 "mult_operator")
13500 (const_string "fmul")
13501 (match_operand:XF 3 "div_operator")
13502 (const_string "fdiv")
13504 (const_string "fop")))
13505 (set_attr "fp_int_src" "true")
13506 (set_attr "mode" "<MODE>")])
13508 (define_insn "*fop_xf_3_i387"
13509 [(set (match_operand:XF 0 "register_operand" "=f,f")
13510 (match_operator:XF 3 "binary_fp_operator"
13511 [(match_operand:XF 1 "register_operand" "0,0")
13513 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13514 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13515 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13516 [(set (attr "type")
13517 (cond [(match_operand:XF 3 "mult_operator")
13518 (const_string "fmul")
13519 (match_operand:XF 3 "div_operator")
13520 (const_string "fdiv")
13522 (const_string "fop")))
13523 (set_attr "fp_int_src" "true")
13524 (set_attr "mode" "<MODE>")])
13526 (define_insn "*fop_xf_4_i387"
13527 [(set (match_operand:XF 0 "register_operand" "=f,f")
13528 (match_operator:XF 3 "binary_fp_operator"
13530 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13531 (match_operand:XF 2 "register_operand" "0,f")]))]
13533 "* return output_387_binary_op (insn, operands);"
13534 [(set (attr "type")
13535 (cond [(match_operand:XF 3 "mult_operator")
13536 (const_string "fmul")
13537 (match_operand:XF 3 "div_operator")
13538 (const_string "fdiv")
13540 (const_string "fop")))
13541 (set_attr "mode" "<MODE>")])
13543 (define_insn "*fop_xf_5_i387"
13544 [(set (match_operand:XF 0 "register_operand" "=f,f")
13545 (match_operator:XF 3 "binary_fp_operator"
13546 [(match_operand:XF 1 "register_operand" "0,f")
13548 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13550 "* return output_387_binary_op (insn, operands);"
13551 [(set (attr "type")
13552 (cond [(match_operand:XF 3 "mult_operator")
13553 (const_string "fmul")
13554 (match_operand:XF 3 "div_operator")
13555 (const_string "fdiv")
13557 (const_string "fop")))
13558 (set_attr "mode" "<MODE>")])
13560 (define_insn "*fop_xf_6_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f,f")
13562 (match_operator:XF 3 "binary_fp_operator"
13564 (match_operand:MODEF 1 "register_operand" "0,f"))
13566 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13568 "* return output_387_binary_op (insn, operands);"
13569 [(set (attr "type")
13570 (cond [(match_operand:XF 3 "mult_operator")
13571 (const_string "fmul")
13572 (match_operand:XF 3 "div_operator")
13573 (const_string "fdiv")
13575 (const_string "fop")))
13576 (set_attr "mode" "<MODE>")])
13579 [(set (match_operand 0 "register_operand")
13580 (match_operator 3 "binary_fp_operator"
13581 [(float (match_operand:SWI24 1 "register_operand"))
13582 (match_operand 2 "register_operand")]))]
13584 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13585 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13588 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13589 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13590 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13591 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13592 GET_MODE (operands[3]),
13595 ix86_free_from_memory (GET_MODE (operands[1]));
13600 [(set (match_operand 0 "register_operand")
13601 (match_operator 3 "binary_fp_operator"
13602 [(match_operand 1 "register_operand")
13603 (float (match_operand:SWI24 2 "register_operand"))]))]
13605 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13606 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13609 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13610 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13611 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13612 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13613 GET_MODE (operands[3]),
13616 ix86_free_from_memory (GET_MODE (operands[2]));
13620 ;; FPU special functions.
13622 ;; This pattern implements a no-op XFmode truncation for
13623 ;; all fancy i386 XFmode math functions.
13625 (define_insn "truncxf<mode>2_i387_noop_unspec"
13626 [(set (match_operand:MODEF 0 "register_operand" "=f")
13627 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13628 UNSPEC_TRUNC_NOOP))]
13629 "TARGET_USE_FANCY_MATH_387"
13630 "* return output_387_reg_move (insn, operands);"
13631 [(set_attr "type" "fmov")
13632 (set_attr "mode" "<MODE>")])
13634 (define_insn "sqrtxf2"
13635 [(set (match_operand:XF 0 "register_operand" "=f")
13636 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13637 "TARGET_USE_FANCY_MATH_387"
13639 [(set_attr "type" "fpspc")
13640 (set_attr "mode" "XF")
13641 (set_attr "athlon_decode" "direct")
13642 (set_attr "amdfam10_decode" "direct")
13643 (set_attr "bdver1_decode" "direct")])
13645 (define_insn "sqrt_extend<mode>xf2_i387"
13646 [(set (match_operand:XF 0 "register_operand" "=f")
13649 (match_operand:MODEF 1 "register_operand" "0"))))]
13650 "TARGET_USE_FANCY_MATH_387"
13652 [(set_attr "type" "fpspc")
13653 (set_attr "mode" "XF")
13654 (set_attr "athlon_decode" "direct")
13655 (set_attr "amdfam10_decode" "direct")
13656 (set_attr "bdver1_decode" "direct")])
13658 (define_insn "*rsqrtsf2_sse"
13659 [(set (match_operand:SF 0 "register_operand" "=x")
13660 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13663 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13664 [(set_attr "type" "sse")
13665 (set_attr "atom_sse_attr" "rcp")
13666 (set_attr "btver2_sse_attr" "rcp")
13667 (set_attr "prefix" "maybe_vex")
13668 (set_attr "mode" "SF")])
13670 (define_expand "rsqrtsf2"
13671 [(set (match_operand:SF 0 "register_operand")
13672 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13676 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13680 (define_insn "*sqrt<mode>2_sse"
13681 [(set (match_operand:MODEF 0 "register_operand" "=x")
13683 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13684 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13685 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13686 [(set_attr "type" "sse")
13687 (set_attr "atom_sse_attr" "sqrt")
13688 (set_attr "btver2_sse_attr" "sqrt")
13689 (set_attr "prefix" "maybe_vex")
13690 (set_attr "mode" "<MODE>")
13691 (set_attr "athlon_decode" "*")
13692 (set_attr "amdfam10_decode" "*")
13693 (set_attr "bdver1_decode" "*")])
13695 (define_expand "sqrt<mode>2"
13696 [(set (match_operand:MODEF 0 "register_operand")
13698 (match_operand:MODEF 1 "nonimmediate_operand")))]
13699 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13700 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13702 if (<MODE>mode == SFmode
13704 && TARGET_RECIP_SQRT
13705 && !optimize_function_for_size_p (cfun)
13706 && flag_finite_math_only && !flag_trapping_math
13707 && flag_unsafe_math_optimizations)
13709 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13713 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13715 rtx op0 = gen_reg_rtx (XFmode);
13716 rtx op1 = force_reg (<MODE>mode, operands[1]);
13718 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13719 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13724 (define_insn "fpremxf4_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13727 (match_operand:XF 3 "register_operand" "1")]
13729 (set (match_operand:XF 1 "register_operand" "=u")
13730 (unspec:XF [(match_dup 2) (match_dup 3)]
13732 (set (reg:CCFP FPSR_REG)
13733 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13735 "TARGET_USE_FANCY_MATH_387"
13737 [(set_attr "type" "fpspc")
13738 (set_attr "mode" "XF")])
13740 (define_expand "fmodxf3"
13741 [(use (match_operand:XF 0 "register_operand"))
13742 (use (match_operand:XF 1 "general_operand"))
13743 (use (match_operand:XF 2 "general_operand"))]
13744 "TARGET_USE_FANCY_MATH_387"
13746 rtx label = gen_label_rtx ();
13748 rtx op1 = gen_reg_rtx (XFmode);
13749 rtx op2 = gen_reg_rtx (XFmode);
13751 emit_move_insn (op2, operands[2]);
13752 emit_move_insn (op1, operands[1]);
13754 emit_label (label);
13755 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13756 ix86_emit_fp_unordered_jump (label);
13757 LABEL_NUSES (label) = 1;
13759 emit_move_insn (operands[0], op1);
13763 (define_expand "fmod<mode>3"
13764 [(use (match_operand:MODEF 0 "register_operand"))
13765 (use (match_operand:MODEF 1 "general_operand"))
13766 (use (match_operand:MODEF 2 "general_operand"))]
13767 "TARGET_USE_FANCY_MATH_387"
13769 rtx (*gen_truncxf) (rtx, rtx);
13771 rtx label = gen_label_rtx ();
13773 rtx op1 = gen_reg_rtx (XFmode);
13774 rtx op2 = gen_reg_rtx (XFmode);
13776 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13779 emit_label (label);
13780 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13781 ix86_emit_fp_unordered_jump (label);
13782 LABEL_NUSES (label) = 1;
13784 /* Truncate the result properly for strict SSE math. */
13785 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13786 && !TARGET_MIX_SSE_I387)
13787 gen_truncxf = gen_truncxf<mode>2;
13789 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13791 emit_insn (gen_truncxf (operands[0], op1));
13795 (define_insn "fprem1xf4_i387"
13796 [(set (match_operand:XF 0 "register_operand" "=f")
13797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13798 (match_operand:XF 3 "register_operand" "1")]
13800 (set (match_operand:XF 1 "register_operand" "=u")
13801 (unspec:XF [(match_dup 2) (match_dup 3)]
13803 (set (reg:CCFP FPSR_REG)
13804 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13806 "TARGET_USE_FANCY_MATH_387"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13811 (define_expand "remainderxf3"
13812 [(use (match_operand:XF 0 "register_operand"))
13813 (use (match_operand:XF 1 "general_operand"))
13814 (use (match_operand:XF 2 "general_operand"))]
13815 "TARGET_USE_FANCY_MATH_387"
13817 rtx label = gen_label_rtx ();
13819 rtx op1 = gen_reg_rtx (XFmode);
13820 rtx op2 = gen_reg_rtx (XFmode);
13822 emit_move_insn (op2, operands[2]);
13823 emit_move_insn (op1, operands[1]);
13825 emit_label (label);
13826 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13827 ix86_emit_fp_unordered_jump (label);
13828 LABEL_NUSES (label) = 1;
13830 emit_move_insn (operands[0], op1);
13834 (define_expand "remainder<mode>3"
13835 [(use (match_operand:MODEF 0 "register_operand"))
13836 (use (match_operand:MODEF 1 "general_operand"))
13837 (use (match_operand:MODEF 2 "general_operand"))]
13838 "TARGET_USE_FANCY_MATH_387"
13840 rtx (*gen_truncxf) (rtx, rtx);
13842 rtx label = gen_label_rtx ();
13844 rtx op1 = gen_reg_rtx (XFmode);
13845 rtx op2 = gen_reg_rtx (XFmode);
13847 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13848 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13850 emit_label (label);
13852 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13853 ix86_emit_fp_unordered_jump (label);
13854 LABEL_NUSES (label) = 1;
13856 /* Truncate the result properly for strict SSE math. */
13857 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13858 && !TARGET_MIX_SSE_I387)
13859 gen_truncxf = gen_truncxf<mode>2;
13861 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13863 emit_insn (gen_truncxf (operands[0], op1));
13867 (define_int_iterator SINCOS
13871 (define_int_attr sincos
13872 [(UNSPEC_SIN "sin")
13873 (UNSPEC_COS "cos")])
13875 (define_insn "*<sincos>xf2_i387"
13876 [(set (match_operand:XF 0 "register_operand" "=f")
13877 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13879 "TARGET_USE_FANCY_MATH_387
13880 && flag_unsafe_math_optimizations"
13882 [(set_attr "type" "fpspc")
13883 (set_attr "mode" "XF")])
13885 (define_insn "*<sincos>_extend<mode>xf2_i387"
13886 [(set (match_operand:XF 0 "register_operand" "=f")
13887 (unspec:XF [(float_extend:XF
13888 (match_operand:MODEF 1 "register_operand" "0"))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13895 [(set_attr "type" "fpspc")
13896 (set_attr "mode" "XF")])
13898 ;; When sincos pattern is defined, sin and cos builtin functions will be
13899 ;; expanded to sincos pattern with one of its outputs left unused.
13900 ;; CSE pass will figure out if two sincos patterns can be combined,
13901 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13902 ;; depending on the unused output.
13904 (define_insn "sincosxf3"
13905 [(set (match_operand:XF 0 "register_operand" "=f")
13906 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13907 UNSPEC_SINCOS_COS))
13908 (set (match_operand:XF 1 "register_operand" "=u")
13909 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")])
13917 [(set (match_operand:XF 0 "register_operand")
13918 (unspec:XF [(match_operand:XF 2 "register_operand")]
13919 UNSPEC_SINCOS_COS))
13920 (set (match_operand:XF 1 "register_operand")
13921 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13922 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13923 && can_create_pseudo_p ()"
13924 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13927 [(set (match_operand:XF 0 "register_operand")
13928 (unspec:XF [(match_operand:XF 2 "register_operand")]
13929 UNSPEC_SINCOS_COS))
13930 (set (match_operand:XF 1 "register_operand")
13931 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13932 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13933 && can_create_pseudo_p ()"
13934 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13936 (define_insn "sincos_extend<mode>xf3_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (unspec:XF [(float_extend:XF
13939 (match_operand:MODEF 2 "register_operand" "0"))]
13940 UNSPEC_SINCOS_COS))
13941 (set (match_operand:XF 1 "register_operand" "=u")
13942 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945 || TARGET_MIX_SSE_I387)
13946 && flag_unsafe_math_optimizations"
13948 [(set_attr "type" "fpspc")
13949 (set_attr "mode" "XF")])
13952 [(set (match_operand:XF 0 "register_operand")
13953 (unspec:XF [(float_extend:XF
13954 (match_operand:MODEF 2 "register_operand"))]
13955 UNSPEC_SINCOS_COS))
13956 (set (match_operand:XF 1 "register_operand")
13957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13958 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13959 && can_create_pseudo_p ()"
13960 [(set (match_dup 1)
13961 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13964 [(set (match_operand:XF 0 "register_operand")
13965 (unspec:XF [(float_extend:XF
13966 (match_operand:MODEF 2 "register_operand"))]
13967 UNSPEC_SINCOS_COS))
13968 (set (match_operand:XF 1 "register_operand")
13969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13971 && can_create_pseudo_p ()"
13972 [(set (match_dup 0)
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13975 (define_expand "sincos<mode>3"
13976 [(use (match_operand:MODEF 0 "register_operand"))
13977 (use (match_operand:MODEF 1 "register_operand"))
13978 (use (match_operand:MODEF 2 "register_operand"))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13984 rtx op0 = gen_reg_rtx (XFmode);
13985 rtx op1 = gen_reg_rtx (XFmode);
13987 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13993 (define_insn "fptanxf4_i387"
13994 [(set (match_operand:XF 0 "register_operand" "=f")
13995 (match_operand:XF 3 "const_double_operand" "F"))
13996 (set (match_operand:XF 1 "register_operand" "=u")
13997 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations
14001 && standard_80387_constant_p (operands[3]) == 2"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_insn "fptan_extend<mode>xf4_i387"
14007 [(set (match_operand:MODEF 0 "register_operand" "=f")
14008 (match_operand:MODEF 3 "const_double_operand" "F"))
14009 (set (match_operand:XF 1 "register_operand" "=u")
14010 (unspec:XF [(float_extend:XF
14011 (match_operand:MODEF 2 "register_operand" "0"))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations
14017 && standard_80387_constant_p (operands[3]) == 2"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14022 (define_expand "tanxf2"
14023 [(use (match_operand:XF 0 "register_operand"))
14024 (use (match_operand:XF 1 "register_operand"))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14028 rtx one = gen_reg_rtx (XFmode);
14029 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14031 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14035 (define_expand "tan<mode>2"
14036 [(use (match_operand:MODEF 0 "register_operand"))
14037 (use (match_operand:MODEF 1 "register_operand"))]
14038 "TARGET_USE_FANCY_MATH_387
14039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040 || TARGET_MIX_SSE_I387)
14041 && flag_unsafe_math_optimizations"
14043 rtx op0 = gen_reg_rtx (XFmode);
14045 rtx one = gen_reg_rtx (<MODE>mode);
14046 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14048 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14049 operands[1], op2));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054 (define_insn "*fpatanxf3_i387"
14055 [(set (match_operand:XF 0 "register_operand" "=f")
14056 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14057 (match_operand:XF 2 "register_operand" "u")]
14059 (clobber (match_scratch:XF 3 "=2"))]
14060 "TARGET_USE_FANCY_MATH_387
14061 && flag_unsafe_math_optimizations"
14063 [(set_attr "type" "fpspc")
14064 (set_attr "mode" "XF")])
14066 (define_insn "fpatan_extend<mode>xf3_i387"
14067 [(set (match_operand:XF 0 "register_operand" "=f")
14068 (unspec:XF [(float_extend:XF
14069 (match_operand:MODEF 1 "register_operand" "0"))
14071 (match_operand:MODEF 2 "register_operand" "u"))]
14073 (clobber (match_scratch:XF 3 "=2"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14082 (define_expand "atan2xf3"
14083 [(parallel [(set (match_operand:XF 0 "register_operand")
14084 (unspec:XF [(match_operand:XF 2 "register_operand")
14085 (match_operand:XF 1 "register_operand")]
14087 (clobber (match_scratch:XF 3))])]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations")
14091 (define_expand "atan2<mode>3"
14092 [(use (match_operand:MODEF 0 "register_operand"))
14093 (use (match_operand:MODEF 1 "register_operand"))
14094 (use (match_operand:MODEF 2 "register_operand"))]
14095 "TARGET_USE_FANCY_MATH_387
14096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14097 || TARGET_MIX_SSE_I387)
14098 && flag_unsafe_math_optimizations"
14100 rtx op0 = gen_reg_rtx (XFmode);
14102 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14107 (define_expand "atanxf2"
14108 [(parallel [(set (match_operand:XF 0 "register_operand")
14109 (unspec:XF [(match_dup 2)
14110 (match_operand:XF 1 "register_operand")]
14112 (clobber (match_scratch:XF 3))])]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14116 operands[2] = gen_reg_rtx (XFmode);
14117 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14120 (define_expand "atan<mode>2"
14121 [(use (match_operand:MODEF 0 "register_operand"))
14122 (use (match_operand:MODEF 1 "register_operand"))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations"
14128 rtx op0 = gen_reg_rtx (XFmode);
14130 rtx op2 = gen_reg_rtx (<MODE>mode);
14131 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14133 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14138 (define_expand "asinxf2"
14139 [(set (match_dup 2)
14140 (mult:XF (match_operand:XF 1 "register_operand")
14142 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14143 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14144 (parallel [(set (match_operand:XF 0 "register_operand")
14145 (unspec:XF [(match_dup 5) (match_dup 1)]
14147 (clobber (match_scratch:XF 6))])]
14148 "TARGET_USE_FANCY_MATH_387
14149 && flag_unsafe_math_optimizations"
14153 if (optimize_insn_for_size_p ())
14156 for (i = 2; i < 6; i++)
14157 operands[i] = gen_reg_rtx (XFmode);
14159 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14162 (define_expand "asin<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand"))
14164 (use (match_operand:MODEF 1 "general_operand"))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14170 rtx op0 = gen_reg_rtx (XFmode);
14171 rtx op1 = gen_reg_rtx (XFmode);
14173 if (optimize_insn_for_size_p ())
14176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14177 emit_insn (gen_asinxf2 (op0, op1));
14178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14182 (define_expand "acosxf2"
14183 [(set (match_dup 2)
14184 (mult:XF (match_operand:XF 1 "register_operand")
14186 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14187 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14188 (parallel [(set (match_operand:XF 0 "register_operand")
14189 (unspec:XF [(match_dup 1) (match_dup 5)]
14191 (clobber (match_scratch:XF 6))])]
14192 "TARGET_USE_FANCY_MATH_387
14193 && flag_unsafe_math_optimizations"
14197 if (optimize_insn_for_size_p ())
14200 for (i = 2; i < 6; i++)
14201 operands[i] = gen_reg_rtx (XFmode);
14203 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14206 (define_expand "acos<mode>2"
14207 [(use (match_operand:MODEF 0 "register_operand"))
14208 (use (match_operand:MODEF 1 "general_operand"))]
14209 "TARGET_USE_FANCY_MATH_387
14210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14211 || TARGET_MIX_SSE_I387)
14212 && flag_unsafe_math_optimizations"
14214 rtx op0 = gen_reg_rtx (XFmode);
14215 rtx op1 = gen_reg_rtx (XFmode);
14217 if (optimize_insn_for_size_p ())
14220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14221 emit_insn (gen_acosxf2 (op0, op1));
14222 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14226 (define_insn "fyl2xxf3_i387"
14227 [(set (match_operand:XF 0 "register_operand" "=f")
14228 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14229 (match_operand:XF 2 "register_operand" "u")]
14231 (clobber (match_scratch:XF 3 "=2"))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14235 [(set_attr "type" "fpspc")
14236 (set_attr "mode" "XF")])
14238 (define_insn "fyl2x_extend<mode>xf3_i387"
14239 [(set (match_operand:XF 0 "register_operand" "=f")
14240 (unspec:XF [(float_extend:XF
14241 (match_operand:MODEF 1 "register_operand" "0"))
14242 (match_operand:XF 2 "register_operand" "u")]
14244 (clobber (match_scratch:XF 3 "=2"))]
14245 "TARGET_USE_FANCY_MATH_387
14246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14247 || TARGET_MIX_SSE_I387)
14248 && flag_unsafe_math_optimizations"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")])
14253 (define_expand "logxf2"
14254 [(parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_operand:XF 1 "register_operand")
14256 (match_dup 2)] UNSPEC_FYL2X))
14257 (clobber (match_scratch:XF 3))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14261 operands[2] = gen_reg_rtx (XFmode);
14262 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14265 (define_expand "log<mode>2"
14266 [(use (match_operand:MODEF 0 "register_operand"))
14267 (use (match_operand:MODEF 1 "register_operand"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14273 rtx op0 = gen_reg_rtx (XFmode);
14275 rtx op2 = gen_reg_rtx (XFmode);
14276 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14278 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 (define_expand "log10xf2"
14284 [(parallel [(set (match_operand:XF 0 "register_operand")
14285 (unspec:XF [(match_operand:XF 1 "register_operand")
14286 (match_dup 2)] UNSPEC_FYL2X))
14287 (clobber (match_scratch:XF 3))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14291 operands[2] = gen_reg_rtx (XFmode);
14292 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14295 (define_expand "log10<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand"))
14297 (use (match_operand:MODEF 1 "register_operand"))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14303 rtx op0 = gen_reg_rtx (XFmode);
14305 rtx op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14308 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 (define_expand "log2xf2"
14314 [(parallel [(set (match_operand:XF 0 "register_operand")
14315 (unspec:XF [(match_operand:XF 1 "register_operand")
14316 (match_dup 2)] UNSPEC_FYL2X))
14317 (clobber (match_scratch:XF 3))])]
14318 "TARGET_USE_FANCY_MATH_387
14319 && flag_unsafe_math_optimizations"
14321 operands[2] = gen_reg_rtx (XFmode);
14322 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14325 (define_expand "log2<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand"))
14327 (use (match_operand:MODEF 1 "register_operand"))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14333 rtx op0 = gen_reg_rtx (XFmode);
14335 rtx op2 = gen_reg_rtx (XFmode);
14336 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14338 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14343 (define_insn "fyl2xp1xf3_i387"
14344 [(set (match_operand:XF 0 "register_operand" "=f")
14345 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14346 (match_operand:XF 2 "register_operand" "u")]
14348 (clobber (match_scratch:XF 3 "=2"))]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14352 [(set_attr "type" "fpspc")
14353 (set_attr "mode" "XF")])
14355 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14356 [(set (match_operand:XF 0 "register_operand" "=f")
14357 (unspec:XF [(float_extend:XF
14358 (match_operand:MODEF 1 "register_operand" "0"))
14359 (match_operand:XF 2 "register_operand" "u")]
14361 (clobber (match_scratch:XF 3 "=2"))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "XF")])
14370 (define_expand "log1pxf2"
14371 [(use (match_operand:XF 0 "register_operand"))
14372 (use (match_operand:XF 1 "register_operand"))]
14373 "TARGET_USE_FANCY_MATH_387
14374 && flag_unsafe_math_optimizations"
14376 if (optimize_insn_for_size_p ())
14379 ix86_emit_i387_log1p (operands[0], operands[1]);
14383 (define_expand "log1p<mode>2"
14384 [(use (match_operand:MODEF 0 "register_operand"))
14385 (use (match_operand:MODEF 1 "register_operand"))]
14386 "TARGET_USE_FANCY_MATH_387
14387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14388 || TARGET_MIX_SSE_I387)
14389 && flag_unsafe_math_optimizations"
14393 if (optimize_insn_for_size_p ())
14396 op0 = gen_reg_rtx (XFmode);
14398 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14400 ix86_emit_i387_log1p (op0, operands[1]);
14401 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14405 (define_insn "fxtractxf3_i387"
14406 [(set (match_operand:XF 0 "register_operand" "=f")
14407 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14408 UNSPEC_XTRACT_FRACT))
14409 (set (match_operand:XF 1 "register_operand" "=u")
14410 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14414 [(set_attr "type" "fpspc")
14415 (set_attr "mode" "XF")])
14417 (define_insn "fxtract_extend<mode>xf3_i387"
14418 [(set (match_operand:XF 0 "register_operand" "=f")
14419 (unspec:XF [(float_extend:XF
14420 (match_operand:MODEF 2 "register_operand" "0"))]
14421 UNSPEC_XTRACT_FRACT))
14422 (set (match_operand:XF 1 "register_operand" "=u")
14423 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14429 [(set_attr "type" "fpspc")
14430 (set_attr "mode" "XF")])
14432 (define_expand "logbxf2"
14433 [(parallel [(set (match_dup 2)
14434 (unspec:XF [(match_operand:XF 1 "register_operand")]
14435 UNSPEC_XTRACT_FRACT))
14436 (set (match_operand:XF 0 "register_operand")
14437 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_unsafe_math_optimizations"
14440 "operands[2] = gen_reg_rtx (XFmode);")
14442 (define_expand "logb<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand"))
14444 (use (match_operand:MODEF 1 "register_operand"))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations"
14450 rtx op0 = gen_reg_rtx (XFmode);
14451 rtx op1 = gen_reg_rtx (XFmode);
14453 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14458 (define_expand "ilogbxf2"
14459 [(use (match_operand:SI 0 "register_operand"))
14460 (use (match_operand:XF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14466 if (optimize_insn_for_size_p ())
14469 op0 = gen_reg_rtx (XFmode);
14470 op1 = gen_reg_rtx (XFmode);
14472 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14473 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14477 (define_expand "ilogb<mode>2"
14478 [(use (match_operand:SI 0 "register_operand"))
14479 (use (match_operand:MODEF 1 "register_operand"))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482 || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14487 if (optimize_insn_for_size_p ())
14490 op0 = gen_reg_rtx (XFmode);
14491 op1 = gen_reg_rtx (XFmode);
14493 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14494 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14498 (define_insn "*f2xm1xf2_i387"
14499 [(set (match_operand:XF 0 "register_operand" "=f")
14500 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14502 "TARGET_USE_FANCY_MATH_387
14503 && flag_unsafe_math_optimizations"
14505 [(set_attr "type" "fpspc")
14506 (set_attr "mode" "XF")])
14508 (define_insn "*fscalexf4_i387"
14509 [(set (match_operand:XF 0 "register_operand" "=f")
14510 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14511 (match_operand:XF 3 "register_operand" "1")]
14512 UNSPEC_FSCALE_FRACT))
14513 (set (match_operand:XF 1 "register_operand" "=u")
14514 (unspec:XF [(match_dup 2) (match_dup 3)]
14515 UNSPEC_FSCALE_EXP))]
14516 "TARGET_USE_FANCY_MATH_387
14517 && flag_unsafe_math_optimizations"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "XF")])
14522 (define_expand "expNcorexf3"
14523 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14524 (match_operand:XF 2 "register_operand")))
14525 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14526 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14527 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14528 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14529 (parallel [(set (match_operand:XF 0 "register_operand")
14530 (unspec:XF [(match_dup 8) (match_dup 4)]
14531 UNSPEC_FSCALE_FRACT))
14533 (unspec:XF [(match_dup 8) (match_dup 4)]
14534 UNSPEC_FSCALE_EXP))])]
14535 "TARGET_USE_FANCY_MATH_387
14536 && flag_unsafe_math_optimizations"
14540 if (optimize_insn_for_size_p ())
14543 for (i = 3; i < 10; i++)
14544 operands[i] = gen_reg_rtx (XFmode);
14546 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14549 (define_expand "expxf2"
14550 [(use (match_operand:XF 0 "register_operand"))
14551 (use (match_operand:XF 1 "register_operand"))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14560 op2 = gen_reg_rtx (XFmode);
14561 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14563 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14567 (define_expand "exp<mode>2"
14568 [(use (match_operand:MODEF 0 "register_operand"))
14569 (use (match_operand:MODEF 1 "general_operand"))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572 || TARGET_MIX_SSE_I387)
14573 && flag_unsafe_math_optimizations"
14577 if (optimize_insn_for_size_p ())
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_expxf2 (op0, op1));
14585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14589 (define_expand "exp10xf2"
14590 [(use (match_operand:XF 0 "register_operand"))
14591 (use (match_operand:XF 1 "register_operand"))]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14597 if (optimize_insn_for_size_p ())
14600 op2 = gen_reg_rtx (XFmode);
14601 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14603 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14607 (define_expand "exp10<mode>2"
14608 [(use (match_operand:MODEF 0 "register_operand"))
14609 (use (match_operand:MODEF 1 "general_operand"))]
14610 "TARGET_USE_FANCY_MATH_387
14611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14612 || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations"
14617 if (optimize_insn_for_size_p ())
14620 op0 = gen_reg_rtx (XFmode);
14621 op1 = gen_reg_rtx (XFmode);
14623 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14624 emit_insn (gen_exp10xf2 (op0, op1));
14625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14629 (define_expand "exp2xf2"
14630 [(use (match_operand:XF 0 "register_operand"))
14631 (use (match_operand:XF 1 "register_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14637 if (optimize_insn_for_size_p ())
14640 op2 = gen_reg_rtx (XFmode);
14641 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14643 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14647 (define_expand "exp2<mode>2"
14648 [(use (match_operand:MODEF 0 "register_operand"))
14649 (use (match_operand:MODEF 1 "general_operand"))]
14650 "TARGET_USE_FANCY_MATH_387
14651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14652 || TARGET_MIX_SSE_I387)
14653 && flag_unsafe_math_optimizations"
14657 if (optimize_insn_for_size_p ())
14660 op0 = gen_reg_rtx (XFmode);
14661 op1 = gen_reg_rtx (XFmode);
14663 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14664 emit_insn (gen_exp2xf2 (op0, op1));
14665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14669 (define_expand "expm1xf2"
14670 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14672 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14673 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14674 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14675 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14676 (parallel [(set (match_dup 7)
14677 (unspec:XF [(match_dup 6) (match_dup 4)]
14678 UNSPEC_FSCALE_FRACT))
14680 (unspec:XF [(match_dup 6) (match_dup 4)]
14681 UNSPEC_FSCALE_EXP))])
14682 (parallel [(set (match_dup 10)
14683 (unspec:XF [(match_dup 9) (match_dup 8)]
14684 UNSPEC_FSCALE_FRACT))
14685 (set (match_dup 11)
14686 (unspec:XF [(match_dup 9) (match_dup 8)]
14687 UNSPEC_FSCALE_EXP))])
14688 (set (match_dup 12) (minus:XF (match_dup 10)
14689 (float_extend:XF (match_dup 13))))
14690 (set (match_operand:XF 0 "register_operand")
14691 (plus:XF (match_dup 12) (match_dup 7)))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && flag_unsafe_math_optimizations"
14697 if (optimize_insn_for_size_p ())
14700 for (i = 2; i < 13; i++)
14701 operands[i] = gen_reg_rtx (XFmode);
14704 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14706 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14709 (define_expand "expm1<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand"))
14711 (use (match_operand:MODEF 1 "general_operand"))]
14712 "TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations"
14719 if (optimize_insn_for_size_p ())
14722 op0 = gen_reg_rtx (XFmode);
14723 op1 = gen_reg_rtx (XFmode);
14725 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14726 emit_insn (gen_expm1xf2 (op0, op1));
14727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14731 (define_expand "ldexpxf3"
14732 [(set (match_dup 3)
14733 (float:XF (match_operand:SI 2 "register_operand")))
14734 (parallel [(set (match_operand:XF 0 " register_operand")
14735 (unspec:XF [(match_operand:XF 1 "register_operand")
14737 UNSPEC_FSCALE_FRACT))
14739 (unspec:XF [(match_dup 1) (match_dup 3)]
14740 UNSPEC_FSCALE_EXP))])]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14744 if (optimize_insn_for_size_p ())
14747 operands[3] = gen_reg_rtx (XFmode);
14748 operands[4] = gen_reg_rtx (XFmode);
14751 (define_expand "ldexp<mode>3"
14752 [(use (match_operand:MODEF 0 "register_operand"))
14753 (use (match_operand:MODEF 1 "general_operand"))
14754 (use (match_operand:SI 2 "register_operand"))]
14755 "TARGET_USE_FANCY_MATH_387
14756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14757 || TARGET_MIX_SSE_I387)
14758 && flag_unsafe_math_optimizations"
14762 if (optimize_insn_for_size_p ())
14765 op0 = gen_reg_rtx (XFmode);
14766 op1 = gen_reg_rtx (XFmode);
14768 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14769 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14770 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14774 (define_expand "scalbxf3"
14775 [(parallel [(set (match_operand:XF 0 " register_operand")
14776 (unspec:XF [(match_operand:XF 1 "register_operand")
14777 (match_operand:XF 2 "register_operand")]
14778 UNSPEC_FSCALE_FRACT))
14780 (unspec:XF [(match_dup 1) (match_dup 2)]
14781 UNSPEC_FSCALE_EXP))])]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14785 if (optimize_insn_for_size_p ())
14788 operands[3] = gen_reg_rtx (XFmode);
14791 (define_expand "scalb<mode>3"
14792 [(use (match_operand:MODEF 0 "register_operand"))
14793 (use (match_operand:MODEF 1 "general_operand"))
14794 (use (match_operand:MODEF 2 "general_operand"))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14797 || TARGET_MIX_SSE_I387)
14798 && flag_unsafe_math_optimizations"
14802 if (optimize_insn_for_size_p ())
14805 op0 = gen_reg_rtx (XFmode);
14806 op1 = gen_reg_rtx (XFmode);
14807 op2 = gen_reg_rtx (XFmode);
14809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14810 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14811 emit_insn (gen_scalbxf3 (op0, op1, op2));
14812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14816 (define_expand "significandxf2"
14817 [(parallel [(set (match_operand:XF 0 "register_operand")
14818 (unspec:XF [(match_operand:XF 1 "register_operand")]
14819 UNSPEC_XTRACT_FRACT))
14821 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14822 "TARGET_USE_FANCY_MATH_387
14823 && flag_unsafe_math_optimizations"
14824 "operands[2] = gen_reg_rtx (XFmode);")
14826 (define_expand "significand<mode>2"
14827 [(use (match_operand:MODEF 0 "register_operand"))
14828 (use (match_operand:MODEF 1 "register_operand"))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831 || TARGET_MIX_SSE_I387)
14832 && flag_unsafe_math_optimizations"
14834 rtx op0 = gen_reg_rtx (XFmode);
14835 rtx op1 = gen_reg_rtx (XFmode);
14837 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14843 (define_insn "sse4_1_round<mode>2"
14844 [(set (match_operand:MODEF 0 "register_operand" "=x")
14845 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14846 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14849 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14850 [(set_attr "type" "ssecvt")
14851 (set_attr "prefix_extra" "1")
14852 (set_attr "prefix" "maybe_vex")
14853 (set_attr "mode" "<MODE>")])
14855 (define_insn "rintxf2"
14856 [(set (match_operand:XF 0 "register_operand" "=f")
14857 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")])
14865 (define_expand "rint<mode>2"
14866 [(use (match_operand:MODEF 0 "register_operand"))
14867 (use (match_operand:MODEF 1 "register_operand"))]
14868 "(TARGET_USE_FANCY_MATH_387
14869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14870 || TARGET_MIX_SSE_I387)
14871 && flag_unsafe_math_optimizations)
14872 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14873 && !flag_trapping_math)"
14875 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14876 && !flag_trapping_math)
14879 emit_insn (gen_sse4_1_round<mode>2
14880 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14881 else if (optimize_insn_for_size_p ())
14884 ix86_expand_rint (operands[0], operands[1]);
14888 rtx op0 = gen_reg_rtx (XFmode);
14889 rtx op1 = gen_reg_rtx (XFmode);
14891 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14892 emit_insn (gen_rintxf2 (op0, op1));
14894 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14899 (define_expand "round<mode>2"
14900 [(match_operand:X87MODEF 0 "register_operand")
14901 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14902 "(TARGET_USE_FANCY_MATH_387
14903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14904 || TARGET_MIX_SSE_I387)
14905 && flag_unsafe_math_optimizations)
14906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math && !flag_rounding_math)"
14909 if (optimize_insn_for_size_p ())
14912 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14913 && !flag_trapping_math && !flag_rounding_math)
14917 operands[1] = force_reg (<MODE>mode, operands[1]);
14918 ix86_expand_round_sse4 (operands[0], operands[1]);
14920 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14921 ix86_expand_round (operands[0], operands[1]);
14923 ix86_expand_rounddf_32 (operands[0], operands[1]);
14927 operands[1] = force_reg (<MODE>mode, operands[1]);
14928 ix86_emit_i387_round (operands[0], operands[1]);
14933 (define_insn_and_split "*fistdi2_1"
14934 [(set (match_operand:DI 0 "nonimmediate_operand")
14935 (unspec:DI [(match_operand:XF 1 "register_operand")]
14937 "TARGET_USE_FANCY_MATH_387
14938 && can_create_pseudo_p ()"
14943 if (memory_operand (operands[0], VOIDmode))
14944 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14947 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14948 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "DI")])
14956 (define_insn "fistdi2"
14957 [(set (match_operand:DI 0 "memory_operand" "=m")
14958 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14960 (clobber (match_scratch:XF 2 "=&1f"))]
14961 "TARGET_USE_FANCY_MATH_387"
14962 "* return output_fix_trunc (insn, operands, false);"
14963 [(set_attr "type" "fpspc")
14964 (set_attr "mode" "DI")])
14966 (define_insn "fistdi2_with_temp"
14967 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14970 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14971 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14972 "TARGET_USE_FANCY_MATH_387"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "mode" "DI")])
14978 [(set (match_operand:DI 0 "register_operand")
14979 (unspec:DI [(match_operand:XF 1 "register_operand")]
14981 (clobber (match_operand:DI 2 "memory_operand"))
14982 (clobber (match_scratch 3))]
14984 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14985 (clobber (match_dup 3))])
14986 (set (match_dup 0) (match_dup 2))])
14989 [(set (match_operand:DI 0 "memory_operand")
14990 (unspec:DI [(match_operand:XF 1 "register_operand")]
14992 (clobber (match_operand:DI 2 "memory_operand"))
14993 (clobber (match_scratch 3))]
14995 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14996 (clobber (match_dup 3))])])
14998 (define_insn_and_split "*fist<mode>2_1"
14999 [(set (match_operand:SWI24 0 "register_operand")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15002 "TARGET_USE_FANCY_MATH_387
15003 && can_create_pseudo_p ()"
15008 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15009 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15013 [(set_attr "type" "fpspc")
15014 (set_attr "mode" "<MODE>")])
15016 (define_insn "fist<mode>2"
15017 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15018 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15020 "TARGET_USE_FANCY_MATH_387"
15021 "* return output_fix_trunc (insn, operands, false);"
15022 [(set_attr "type" "fpspc")
15023 (set_attr "mode" "<MODE>")])
15025 (define_insn "fist<mode>2_with_temp"
15026 [(set (match_operand:SWI24 0 "register_operand" "=r")
15027 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15029 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15030 "TARGET_USE_FANCY_MATH_387"
15032 [(set_attr "type" "fpspc")
15033 (set_attr "mode" "<MODE>")])
15036 [(set (match_operand:SWI24 0 "register_operand")
15037 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15039 (clobber (match_operand:SWI24 2 "memory_operand"))]
15041 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15042 (set (match_dup 0) (match_dup 2))])
15045 [(set (match_operand:SWI24 0 "memory_operand")
15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15048 (clobber (match_operand:SWI24 2 "memory_operand"))]
15050 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15052 (define_expand "lrintxf<mode>2"
15053 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15054 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15056 "TARGET_USE_FANCY_MATH_387")
15058 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15059 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15060 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15061 UNSPEC_FIX_NOTRUNC))]
15062 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15064 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15065 [(match_operand:SWI248x 0 "nonimmediate_operand")
15066 (match_operand:X87MODEF 1 "register_operand")]
15067 "(TARGET_USE_FANCY_MATH_387
15068 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15069 || TARGET_MIX_SSE_I387)
15070 && flag_unsafe_math_optimizations)
15071 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15072 && <SWI248x:MODE>mode != HImode
15073 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15074 && !flag_trapping_math && !flag_rounding_math)"
15076 if (optimize_insn_for_size_p ())
15079 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15080 && <SWI248x:MODE>mode != HImode
15081 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15082 && !flag_trapping_math && !flag_rounding_math)
15083 ix86_expand_lround (operands[0], operands[1]);
15085 ix86_emit_i387_round (operands[0], operands[1]);
15089 (define_int_iterator FRNDINT_ROUNDING
15090 [UNSPEC_FRNDINT_FLOOR
15091 UNSPEC_FRNDINT_CEIL
15092 UNSPEC_FRNDINT_TRUNC])
15094 (define_int_iterator FIST_ROUNDING
15098 ;; Base name for define_insn
15099 (define_int_attr rounding_insn
15100 [(UNSPEC_FRNDINT_FLOOR "floor")
15101 (UNSPEC_FRNDINT_CEIL "ceil")
15102 (UNSPEC_FRNDINT_TRUNC "btrunc")
15103 (UNSPEC_FIST_FLOOR "floor")
15104 (UNSPEC_FIST_CEIL "ceil")])
15106 (define_int_attr rounding
15107 [(UNSPEC_FRNDINT_FLOOR "floor")
15108 (UNSPEC_FRNDINT_CEIL "ceil")
15109 (UNSPEC_FRNDINT_TRUNC "trunc")
15110 (UNSPEC_FIST_FLOOR "floor")
15111 (UNSPEC_FIST_CEIL "ceil")])
15113 (define_int_attr ROUNDING
15114 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15115 (UNSPEC_FRNDINT_CEIL "CEIL")
15116 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15117 (UNSPEC_FIST_FLOOR "FLOOR")
15118 (UNSPEC_FIST_CEIL "CEIL")])
15120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15121 (define_insn_and_split "frndintxf2_<rounding>"
15122 [(set (match_operand:XF 0 "register_operand")
15123 (unspec:XF [(match_operand:XF 1 "register_operand")]
15125 (clobber (reg:CC FLAGS_REG))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && flag_unsafe_math_optimizations
15128 && can_create_pseudo_p ()"
15133 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15135 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15136 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15138 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15139 operands[2], operands[3]));
15142 [(set_attr "type" "frndint")
15143 (set_attr "i387_cw" "<rounding>")
15144 (set_attr "mode" "XF")])
15146 (define_insn "frndintxf2_<rounding>_i387"
15147 [(set (match_operand:XF 0 "register_operand" "=f")
15148 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15150 (use (match_operand:HI 2 "memory_operand" "m"))
15151 (use (match_operand:HI 3 "memory_operand" "m"))]
15152 "TARGET_USE_FANCY_MATH_387
15153 && flag_unsafe_math_optimizations"
15154 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15155 [(set_attr "type" "frndint")
15156 (set_attr "i387_cw" "<rounding>")
15157 (set_attr "mode" "XF")])
15159 (define_expand "<rounding_insn>xf2"
15160 [(parallel [(set (match_operand:XF 0 "register_operand")
15161 (unspec:XF [(match_operand:XF 1 "register_operand")]
15163 (clobber (reg:CC FLAGS_REG))])]
15164 "TARGET_USE_FANCY_MATH_387
15165 && flag_unsafe_math_optimizations
15166 && !optimize_insn_for_size_p ()")
15168 (define_expand "<rounding_insn><mode>2"
15169 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15170 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15172 (clobber (reg:CC FLAGS_REG))])]
15173 "(TARGET_USE_FANCY_MATH_387
15174 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15175 || TARGET_MIX_SSE_I387)
15176 && flag_unsafe_math_optimizations)
15177 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15178 && !flag_trapping_math)"
15180 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15181 && !flag_trapping_math)
15184 emit_insn (gen_sse4_1_round<mode>2
15185 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15186 else if (optimize_insn_for_size_p ())
15188 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15190 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15191 ix86_expand_floorceil (operands[0], operands[1], true);
15192 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15193 ix86_expand_floorceil (operands[0], operands[1], false);
15194 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15195 ix86_expand_trunc (operands[0], operands[1]);
15197 gcc_unreachable ();
15201 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15202 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15203 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15204 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15205 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15206 ix86_expand_truncdf_32 (operands[0], operands[1]);
15208 gcc_unreachable ();
15215 if (optimize_insn_for_size_p ())
15218 op0 = gen_reg_rtx (XFmode);
15219 op1 = gen_reg_rtx (XFmode);
15220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15221 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15228 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15229 (define_insn_and_split "frndintxf2_mask_pm"
15230 [(set (match_operand:XF 0 "register_operand")
15231 (unspec:XF [(match_operand:XF 1 "register_operand")]
15232 UNSPEC_FRNDINT_MASK_PM))
15233 (clobber (reg:CC FLAGS_REG))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations
15236 && can_create_pseudo_p ()"
15241 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15243 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15244 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15246 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15247 operands[2], operands[3]));
15250 [(set_attr "type" "frndint")
15251 (set_attr "i387_cw" "mask_pm")
15252 (set_attr "mode" "XF")])
15254 (define_insn "frndintxf2_mask_pm_i387"
15255 [(set (match_operand:XF 0 "register_operand" "=f")
15256 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15257 UNSPEC_FRNDINT_MASK_PM))
15258 (use (match_operand:HI 2 "memory_operand" "m"))
15259 (use (match_operand:HI 3 "memory_operand" "m"))]
15260 "TARGET_USE_FANCY_MATH_387
15261 && flag_unsafe_math_optimizations"
15262 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15263 [(set_attr "type" "frndint")
15264 (set_attr "i387_cw" "mask_pm")
15265 (set_attr "mode" "XF")])
15267 (define_expand "nearbyintxf2"
15268 [(parallel [(set (match_operand:XF 0 "register_operand")
15269 (unspec:XF [(match_operand:XF 1 "register_operand")]
15270 UNSPEC_FRNDINT_MASK_PM))
15271 (clobber (reg:CC FLAGS_REG))])]
15272 "TARGET_USE_FANCY_MATH_387
15273 && flag_unsafe_math_optimizations")
15275 (define_expand "nearbyint<mode>2"
15276 [(use (match_operand:MODEF 0 "register_operand"))
15277 (use (match_operand:MODEF 1 "register_operand"))]
15278 "TARGET_USE_FANCY_MATH_387
15279 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15280 || TARGET_MIX_SSE_I387)
15281 && flag_unsafe_math_optimizations"
15283 rtx op0 = gen_reg_rtx (XFmode);
15284 rtx op1 = gen_reg_rtx (XFmode);
15286 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15287 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15289 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15293 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15294 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15295 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15296 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15298 (clobber (reg:CC FLAGS_REG))]
15299 "TARGET_USE_FANCY_MATH_387
15300 && flag_unsafe_math_optimizations
15301 && can_create_pseudo_p ()"
15306 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15308 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15309 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15310 if (memory_operand (operands[0], VOIDmode))
15311 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15312 operands[2], operands[3]));
15315 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15316 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15317 (operands[0], operands[1], operands[2],
15318 operands[3], operands[4]));
15322 [(set_attr "type" "fistp")
15323 (set_attr "i387_cw" "<rounding>")
15324 (set_attr "mode" "<MODE>")])
15326 (define_insn "fistdi2_<rounding>"
15327 [(set (match_operand:DI 0 "memory_operand" "=m")
15328 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15330 (use (match_operand:HI 2 "memory_operand" "m"))
15331 (use (match_operand:HI 3 "memory_operand" "m"))
15332 (clobber (match_scratch:XF 4 "=&1f"))]
15333 "TARGET_USE_FANCY_MATH_387
15334 && flag_unsafe_math_optimizations"
15335 "* return output_fix_trunc (insn, operands, false);"
15336 [(set_attr "type" "fistp")
15337 (set_attr "i387_cw" "<rounding>")
15338 (set_attr "mode" "DI")])
15340 (define_insn "fistdi2_<rounding>_with_temp"
15341 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15342 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15344 (use (match_operand:HI 2 "memory_operand" "m,m"))
15345 (use (match_operand:HI 3 "memory_operand" "m,m"))
15346 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15347 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15348 "TARGET_USE_FANCY_MATH_387
15349 && flag_unsafe_math_optimizations"
15351 [(set_attr "type" "fistp")
15352 (set_attr "i387_cw" "<rounding>")
15353 (set_attr "mode" "DI")])
15356 [(set (match_operand:DI 0 "register_operand")
15357 (unspec:DI [(match_operand:XF 1 "register_operand")]
15359 (use (match_operand:HI 2 "memory_operand"))
15360 (use (match_operand:HI 3 "memory_operand"))
15361 (clobber (match_operand:DI 4 "memory_operand"))
15362 (clobber (match_scratch 5))]
15364 [(parallel [(set (match_dup 4)
15365 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15366 (use (match_dup 2))
15367 (use (match_dup 3))
15368 (clobber (match_dup 5))])
15369 (set (match_dup 0) (match_dup 4))])
15372 [(set (match_operand:DI 0 "memory_operand")
15373 (unspec:DI [(match_operand:XF 1 "register_operand")]
15375 (use (match_operand:HI 2 "memory_operand"))
15376 (use (match_operand:HI 3 "memory_operand"))
15377 (clobber (match_operand:DI 4 "memory_operand"))
15378 (clobber (match_scratch 5))]
15380 [(parallel [(set (match_dup 0)
15381 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15382 (use (match_dup 2))
15383 (use (match_dup 3))
15384 (clobber (match_dup 5))])])
15386 (define_insn "fist<mode>2_<rounding>"
15387 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15388 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15390 (use (match_operand:HI 2 "memory_operand" "m"))
15391 (use (match_operand:HI 3 "memory_operand" "m"))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && flag_unsafe_math_optimizations"
15394 "* return output_fix_trunc (insn, operands, false);"
15395 [(set_attr "type" "fistp")
15396 (set_attr "i387_cw" "<rounding>")
15397 (set_attr "mode" "<MODE>")])
15399 (define_insn "fist<mode>2_<rounding>_with_temp"
15400 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15401 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15403 (use (match_operand:HI 2 "memory_operand" "m,m"))
15404 (use (match_operand:HI 3 "memory_operand" "m,m"))
15405 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15406 "TARGET_USE_FANCY_MATH_387
15407 && flag_unsafe_math_optimizations"
15409 [(set_attr "type" "fistp")
15410 (set_attr "i387_cw" "<rounding>")
15411 (set_attr "mode" "<MODE>")])
15414 [(set (match_operand:SWI24 0 "register_operand")
15415 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15417 (use (match_operand:HI 2 "memory_operand"))
15418 (use (match_operand:HI 3 "memory_operand"))
15419 (clobber (match_operand:SWI24 4 "memory_operand"))]
15421 [(parallel [(set (match_dup 4)
15422 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15423 (use (match_dup 2))
15424 (use (match_dup 3))])
15425 (set (match_dup 0) (match_dup 4))])
15428 [(set (match_operand:SWI24 0 "memory_operand")
15429 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15431 (use (match_operand:HI 2 "memory_operand"))
15432 (use (match_operand:HI 3 "memory_operand"))
15433 (clobber (match_operand:SWI24 4 "memory_operand"))]
15435 [(parallel [(set (match_dup 0)
15436 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15437 (use (match_dup 2))
15438 (use (match_dup 3))])])
15440 (define_expand "l<rounding_insn>xf<mode>2"
15441 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15442 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15444 (clobber (reg:CC FLAGS_REG))])]
15445 "TARGET_USE_FANCY_MATH_387
15446 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15447 && flag_unsafe_math_optimizations")
15449 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15450 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15451 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15453 (clobber (reg:CC FLAGS_REG))])]
15454 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15455 && !flag_trapping_math"
15457 if (TARGET_64BIT && optimize_insn_for_size_p ())
15460 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15461 ix86_expand_lfloorceil (operands[0], operands[1], true);
15462 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15463 ix86_expand_lfloorceil (operands[0], operands[1], false);
15465 gcc_unreachable ();
15470 (define_insn "fxam<mode>2_i387"
15471 [(set (match_operand:HI 0 "register_operand" "=a")
15473 [(match_operand:X87MODEF 1 "register_operand" "f")]
15475 "TARGET_USE_FANCY_MATH_387"
15476 "fxam\n\tfnstsw\t%0"
15477 [(set_attr "type" "multi")
15478 (set_attr "length" "4")
15479 (set_attr "unit" "i387")
15480 (set_attr "mode" "<MODE>")])
15482 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15483 [(set (match_operand:HI 0 "register_operand")
15485 [(match_operand:MODEF 1 "memory_operand")]
15487 "TARGET_USE_FANCY_MATH_387
15488 && can_create_pseudo_p ()"
15491 [(set (match_dup 2)(match_dup 1))
15493 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15495 operands[2] = gen_reg_rtx (<MODE>mode);
15497 MEM_VOLATILE_P (operands[1]) = 1;
15499 [(set_attr "type" "multi")
15500 (set_attr "unit" "i387")
15501 (set_attr "mode" "<MODE>")])
15503 (define_expand "isinfxf2"
15504 [(use (match_operand:SI 0 "register_operand"))
15505 (use (match_operand:XF 1 "register_operand"))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && ix86_libc_has_function (function_c99_misc)"
15509 rtx mask = GEN_INT (0x45);
15510 rtx val = GEN_INT (0x05);
15514 rtx scratch = gen_reg_rtx (HImode);
15515 rtx res = gen_reg_rtx (QImode);
15517 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15519 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15520 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15521 cond = gen_rtx_fmt_ee (EQ, QImode,
15522 gen_rtx_REG (CCmode, FLAGS_REG),
15524 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15525 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15529 (define_expand "isinf<mode>2"
15530 [(use (match_operand:SI 0 "register_operand"))
15531 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15532 "TARGET_USE_FANCY_MATH_387
15533 && ix86_libc_has_function (function_c99_misc)
15534 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15536 rtx mask = GEN_INT (0x45);
15537 rtx val = GEN_INT (0x05);
15541 rtx scratch = gen_reg_rtx (HImode);
15542 rtx res = gen_reg_rtx (QImode);
15544 /* Remove excess precision by forcing value through memory. */
15545 if (memory_operand (operands[1], VOIDmode))
15546 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15549 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15551 emit_move_insn (temp, operands[1]);
15552 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15555 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15556 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15557 cond = gen_rtx_fmt_ee (EQ, QImode,
15558 gen_rtx_REG (CCmode, FLAGS_REG),
15560 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15561 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15565 (define_expand "signbitxf2"
15566 [(use (match_operand:SI 0 "register_operand"))
15567 (use (match_operand:XF 1 "register_operand"))]
15568 "TARGET_USE_FANCY_MATH_387"
15570 rtx scratch = gen_reg_rtx (HImode);
15572 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15573 emit_insn (gen_andsi3 (operands[0],
15574 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15578 (define_insn "movmsk_df"
15579 [(set (match_operand:SI 0 "register_operand" "=r")
15581 [(match_operand:DF 1 "register_operand" "x")]
15583 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15584 "%vmovmskpd\t{%1, %0|%0, %1}"
15585 [(set_attr "type" "ssemov")
15586 (set_attr "prefix" "maybe_vex")
15587 (set_attr "mode" "DF")])
15589 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15590 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15591 (define_expand "signbitdf2"
15592 [(use (match_operand:SI 0 "register_operand"))
15593 (use (match_operand:DF 1 "register_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15597 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15599 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15600 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15604 rtx scratch = gen_reg_rtx (HImode);
15606 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15607 emit_insn (gen_andsi3 (operands[0],
15608 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15613 (define_expand "signbitsf2"
15614 [(use (match_operand:SI 0 "register_operand"))
15615 (use (match_operand:SF 1 "register_operand"))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15619 rtx scratch = gen_reg_rtx (HImode);
15621 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15622 emit_insn (gen_andsi3 (operands[0],
15623 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15627 ;; Block operation instructions
15630 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15633 [(set_attr "length" "1")
15634 (set_attr "length_immediate" "0")
15635 (set_attr "modrm" "0")])
15637 (define_expand "movmem<mode>"
15638 [(use (match_operand:BLK 0 "memory_operand"))
15639 (use (match_operand:BLK 1 "memory_operand"))
15640 (use (match_operand:SWI48 2 "nonmemory_operand"))
15641 (use (match_operand:SWI48 3 "const_int_operand"))
15642 (use (match_operand:SI 4 "const_int_operand"))
15643 (use (match_operand:SI 5 "const_int_operand"))
15644 (use (match_operand:SI 6 ""))
15645 (use (match_operand:SI 7 ""))
15646 (use (match_operand:SI 8 ""))]
15649 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15650 operands[2], NULL, operands[3],
15651 operands[4], operands[5],
15652 operands[6], operands[7],
15653 operands[8], false))
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15662 (define_expand "strmov"
15663 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15664 (set (match_operand 1 "memory_operand") (match_dup 4))
15665 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15666 (clobber (reg:CC FLAGS_REG))])
15667 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15668 (clobber (reg:CC FLAGS_REG))])]
15671 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15673 /* If .md ever supports :P for Pmode, these can be directly
15674 in the pattern above. */
15675 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15676 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15678 /* Can't use this if the user has appropriated esi or edi. */
15679 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15682 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15683 operands[2], operands[3],
15684 operands[5], operands[6]));
15688 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15691 (define_expand "strmov_singleop"
15692 [(parallel [(set (match_operand 1 "memory_operand")
15693 (match_operand 3 "memory_operand"))
15694 (set (match_operand 0 "register_operand")
15696 (set (match_operand 2 "register_operand")
15697 (match_operand 5))])]
15699 "ix86_current_function_needs_cld = 1;")
15701 (define_insn "*strmovdi_rex_1"
15702 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15703 (mem:DI (match_operand:P 3 "register_operand" "1")))
15704 (set (match_operand:P 0 "register_operand" "=D")
15705 (plus:P (match_dup 2)
15707 (set (match_operand:P 1 "register_operand" "=S")
15708 (plus:P (match_dup 3)
15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15713 [(set_attr "type" "str")
15714 (set_attr "memory" "both")
15715 (set_attr "mode" "DI")])
15717 (define_insn "*strmovsi_1"
15718 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15719 (mem:SI (match_operand:P 3 "register_operand" "1")))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_dup 2)
15723 (set (match_operand:P 1 "register_operand" "=S")
15724 (plus:P (match_dup 3)
15726 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728 [(set_attr "type" "str")
15729 (set_attr "memory" "both")
15730 (set_attr "mode" "SI")])
15732 (define_insn "*strmovhi_1"
15733 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15734 (mem:HI (match_operand:P 3 "register_operand" "1")))
15735 (set (match_operand:P 0 "register_operand" "=D")
15736 (plus:P (match_dup 2)
15738 (set (match_operand:P 1 "register_operand" "=S")
15739 (plus:P (match_dup 3)
15741 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "both")
15745 (set_attr "mode" "HI")])
15747 (define_insn "*strmovqi_1"
15748 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15749 (mem:QI (match_operand:P 3 "register_operand" "1")))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 2)
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (match_dup 3)
15756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set (attr "prefix_rex")
15762 (match_test "<P:MODE>mode == DImode")
15764 (const_string "*")))
15765 (set_attr "mode" "QI")])
15767 (define_expand "rep_mov"
15768 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15769 (set (match_operand 0 "register_operand")
15771 (set (match_operand 2 "register_operand")
15773 (set (match_operand 1 "memory_operand")
15774 (match_operand 3 "memory_operand"))
15775 (use (match_dup 4))])]
15777 "ix86_current_function_needs_cld = 1;")
15779 (define_insn "*rep_movdi_rex64"
15780 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15784 (match_operand:P 3 "register_operand" "0")))
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (ashift:P (match_dup 5) (const_int 3))
15787 (match_operand:P 4 "register_operand" "1")))
15788 (set (mem:BLK (match_dup 3))
15789 (mem:BLK (match_dup 4)))
15790 (use (match_dup 5))]
15792 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "both")
15797 (set_attr "mode" "DI")])
15799 (define_insn "*rep_movsi"
15800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:P 0 "register_operand" "=D")
15802 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15804 (match_operand:P 3 "register_operand" "0")))
15805 (set (match_operand:P 1 "register_operand" "=S")
15806 (plus:P (ashift:P (match_dup 5) (const_int 2))
15807 (match_operand:P 4 "register_operand" "1")))
15808 (set (mem:BLK (match_dup 3))
15809 (mem:BLK (match_dup 4)))
15810 (use (match_dup 5))]
15811 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15812 "%^rep{%;} movs{l|d}"
15813 [(set_attr "type" "str")
15814 (set_attr "prefix_rep" "1")
15815 (set_attr "memory" "both")
15816 (set_attr "mode" "SI")])
15818 (define_insn "*rep_movqi"
15819 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15820 (set (match_operand:P 0 "register_operand" "=D")
15821 (plus:P (match_operand:P 3 "register_operand" "0")
15822 (match_operand:P 5 "register_operand" "2")))
15823 (set (match_operand:P 1 "register_operand" "=S")
15824 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15825 (set (mem:BLK (match_dup 3))
15826 (mem:BLK (match_dup 4)))
15827 (use (match_dup 5))]
15828 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "QI")])
15835 (define_expand "setmem<mode>"
15836 [(use (match_operand:BLK 0 "memory_operand"))
15837 (use (match_operand:SWI48 1 "nonmemory_operand"))
15838 (use (match_operand:QI 2 "nonmemory_operand"))
15839 (use (match_operand 3 "const_int_operand"))
15840 (use (match_operand:SI 4 "const_int_operand"))
15841 (use (match_operand:SI 5 "const_int_operand"))
15842 (use (match_operand:SI 6 ""))
15843 (use (match_operand:SI 7 ""))
15844 (use (match_operand:SI 8 ""))]
15847 if (ix86_expand_set_or_movmem (operands[0], NULL,
15848 operands[1], operands[2],
15849 operands[3], operands[4],
15850 operands[5], operands[6],
15851 operands[7], operands[8], true))
15857 ;; Most CPUs don't like single string operations
15858 ;; Handle this case here to simplify previous expander.
15860 (define_expand "strset"
15861 [(set (match_operand 1 "memory_operand")
15862 (match_operand 2 "register_operand"))
15863 (parallel [(set (match_operand 0 "register_operand")
15865 (clobber (reg:CC FLAGS_REG))])]
15868 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15869 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15871 /* If .md ever supports :P for Pmode, this can be directly
15872 in the pattern above. */
15873 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15874 GEN_INT (GET_MODE_SIZE (GET_MODE
15876 /* Can't use this if the user has appropriated eax or edi. */
15877 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15878 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15880 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15886 (define_expand "strset_singleop"
15887 [(parallel [(set (match_operand 1 "memory_operand")
15888 (match_operand 2 "register_operand"))
15889 (set (match_operand 0 "register_operand")
15891 (unspec [(const_int 0)] UNSPEC_STOS)])]
15893 "ix86_current_function_needs_cld = 1;")
15895 (define_insn "*strsetdi_rex_1"
15896 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15897 (match_operand:DI 2 "register_operand" "a"))
15898 (set (match_operand:P 0 "register_operand" "=D")
15899 (plus:P (match_dup 1)
15901 (unspec [(const_int 0)] UNSPEC_STOS)]
15903 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15905 [(set_attr "type" "str")
15906 (set_attr "memory" "store")
15907 (set_attr "mode" "DI")])
15909 (define_insn "*strsetsi_1"
15910 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15911 (match_operand:SI 2 "register_operand" "a"))
15912 (set (match_operand:P 0 "register_operand" "=D")
15913 (plus:P (match_dup 1)
15915 (unspec [(const_int 0)] UNSPEC_STOS)]
15916 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15918 [(set_attr "type" "str")
15919 (set_attr "memory" "store")
15920 (set_attr "mode" "SI")])
15922 (define_insn "*strsethi_1"
15923 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15924 (match_operand:HI 2 "register_operand" "a"))
15925 (set (match_operand:P 0 "register_operand" "=D")
15926 (plus:P (match_dup 1)
15928 (unspec [(const_int 0)] UNSPEC_STOS)]
15929 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15931 [(set_attr "type" "str")
15932 (set_attr "memory" "store")
15933 (set_attr "mode" "HI")])
15935 (define_insn "*strsetqi_1"
15936 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15937 (match_operand:QI 2 "register_operand" "a"))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (match_dup 1)
15941 (unspec [(const_int 0)] UNSPEC_STOS)]
15942 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15944 [(set_attr "type" "str")
15945 (set_attr "memory" "store")
15946 (set (attr "prefix_rex")
15948 (match_test "<P:MODE>mode == DImode")
15950 (const_string "*")))
15951 (set_attr "mode" "QI")])
15953 (define_expand "rep_stos"
15954 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15955 (set (match_operand 0 "register_operand")
15957 (set (match_operand 2 "memory_operand") (const_int 0))
15958 (use (match_operand 3 "register_operand"))
15959 (use (match_dup 1))])]
15961 "ix86_current_function_needs_cld = 1;")
15963 (define_insn "*rep_stosdi_rex64"
15964 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15965 (set (match_operand:P 0 "register_operand" "=D")
15966 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15968 (match_operand:P 3 "register_operand" "0")))
15969 (set (mem:BLK (match_dup 3))
15971 (use (match_operand:DI 2 "register_operand" "a"))
15972 (use (match_dup 4))]
15974 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15976 [(set_attr "type" "str")
15977 (set_attr "prefix_rep" "1")
15978 (set_attr "memory" "store")
15979 (set_attr "mode" "DI")])
15981 (define_insn "*rep_stossi"
15982 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15983 (set (match_operand:P 0 "register_operand" "=D")
15984 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15986 (match_operand:P 3 "register_operand" "0")))
15987 (set (mem:BLK (match_dup 3))
15989 (use (match_operand:SI 2 "register_operand" "a"))
15990 (use (match_dup 4))]
15991 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15992 "%^rep{%;} stos{l|d}"
15993 [(set_attr "type" "str")
15994 (set_attr "prefix_rep" "1")
15995 (set_attr "memory" "store")
15996 (set_attr "mode" "SI")])
15998 (define_insn "*rep_stosqi"
15999 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16000 (set (match_operand:P 0 "register_operand" "=D")
16001 (plus:P (match_operand:P 3 "register_operand" "0")
16002 (match_operand:P 4 "register_operand" "1")))
16003 (set (mem:BLK (match_dup 3))
16005 (use (match_operand:QI 2 "register_operand" "a"))
16006 (use (match_dup 4))]
16007 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16009 [(set_attr "type" "str")
16010 (set_attr "prefix_rep" "1")
16011 (set_attr "memory" "store")
16012 (set (attr "prefix_rex")
16014 (match_test "<P:MODE>mode == DImode")
16016 (const_string "*")))
16017 (set_attr "mode" "QI")])
16019 (define_expand "cmpstrnsi"
16020 [(set (match_operand:SI 0 "register_operand")
16021 (compare:SI (match_operand:BLK 1 "general_operand")
16022 (match_operand:BLK 2 "general_operand")))
16023 (use (match_operand 3 "general_operand"))
16024 (use (match_operand 4 "immediate_operand"))]
16027 rtx addr1, addr2, out, outlow, count, countreg, align;
16029 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16032 /* Can't use this if the user has appropriated ecx, esi or edi. */
16033 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16038 out = gen_reg_rtx (SImode);
16040 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16041 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16042 if (addr1 != XEXP (operands[1], 0))
16043 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16044 if (addr2 != XEXP (operands[2], 0))
16045 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16047 count = operands[3];
16048 countreg = ix86_zero_extend_to_Pmode (count);
16050 /* %%% Iff we are testing strict equality, we can use known alignment
16051 to good advantage. This may be possible with combine, particularly
16052 once cc0 is dead. */
16053 align = operands[4];
16055 if (CONST_INT_P (count))
16057 if (INTVAL (count) == 0)
16059 emit_move_insn (operands[0], const0_rtx);
16062 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16063 operands[1], operands[2]));
16067 rtx (*gen_cmp) (rtx, rtx);
16069 gen_cmp = (TARGET_64BIT
16070 ? gen_cmpdi_1 : gen_cmpsi_1);
16072 emit_insn (gen_cmp (countreg, countreg));
16073 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16074 operands[1], operands[2]));
16077 outlow = gen_lowpart (QImode, out);
16078 emit_insn (gen_cmpintqi (outlow));
16079 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16081 if (operands[0] != out)
16082 emit_move_insn (operands[0], out);
16087 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16089 (define_expand "cmpintqi"
16090 [(set (match_dup 1)
16091 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16093 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16094 (parallel [(set (match_operand:QI 0 "register_operand")
16095 (minus:QI (match_dup 1)
16097 (clobber (reg:CC FLAGS_REG))])]
16100 operands[1] = gen_reg_rtx (QImode);
16101 operands[2] = gen_reg_rtx (QImode);
16104 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16105 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16107 (define_expand "cmpstrnqi_nz_1"
16108 [(parallel [(set (reg:CC FLAGS_REG)
16109 (compare:CC (match_operand 4 "memory_operand")
16110 (match_operand 5 "memory_operand")))
16111 (use (match_operand 2 "register_operand"))
16112 (use (match_operand:SI 3 "immediate_operand"))
16113 (clobber (match_operand 0 "register_operand"))
16114 (clobber (match_operand 1 "register_operand"))
16115 (clobber (match_dup 2))])]
16117 "ix86_current_function_needs_cld = 1;")
16119 (define_insn "*cmpstrnqi_nz_1"
16120 [(set (reg:CC FLAGS_REG)
16121 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16122 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16123 (use (match_operand:P 6 "register_operand" "2"))
16124 (use (match_operand:SI 3 "immediate_operand" "i"))
16125 (clobber (match_operand:P 0 "register_operand" "=S"))
16126 (clobber (match_operand:P 1 "register_operand" "=D"))
16127 (clobber (match_operand:P 2 "register_operand" "=c"))]
16128 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16130 [(set_attr "type" "str")
16131 (set_attr "mode" "QI")
16132 (set (attr "prefix_rex")
16134 (match_test "<P:MODE>mode == DImode")
16136 (const_string "*")))
16137 (set_attr "prefix_rep" "1")])
16139 ;; The same, but the count is not known to not be zero.
16141 (define_expand "cmpstrnqi_1"
16142 [(parallel [(set (reg:CC FLAGS_REG)
16143 (if_then_else:CC (ne (match_operand 2 "register_operand")
16145 (compare:CC (match_operand 4 "memory_operand")
16146 (match_operand 5 "memory_operand"))
16148 (use (match_operand:SI 3 "immediate_operand"))
16149 (use (reg:CC FLAGS_REG))
16150 (clobber (match_operand 0 "register_operand"))
16151 (clobber (match_operand 1 "register_operand"))
16152 (clobber (match_dup 2))])]
16154 "ix86_current_function_needs_cld = 1;")
16156 (define_insn "*cmpstrnqi_1"
16157 [(set (reg:CC FLAGS_REG)
16158 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16160 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16161 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16163 (use (match_operand:SI 3 "immediate_operand" "i"))
16164 (use (reg:CC FLAGS_REG))
16165 (clobber (match_operand:P 0 "register_operand" "=S"))
16166 (clobber (match_operand:P 1 "register_operand" "=D"))
16167 (clobber (match_operand:P 2 "register_operand" "=c"))]
16168 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16170 [(set_attr "type" "str")
16171 (set_attr "mode" "QI")
16172 (set (attr "prefix_rex")
16174 (match_test "<P:MODE>mode == DImode")
16176 (const_string "*")))
16177 (set_attr "prefix_rep" "1")])
16179 (define_expand "strlen<mode>"
16180 [(set (match_operand:P 0 "register_operand")
16181 (unspec:P [(match_operand:BLK 1 "general_operand")
16182 (match_operand:QI 2 "immediate_operand")
16183 (match_operand 3 "immediate_operand")]
16187 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16193 (define_expand "strlenqi_1"
16194 [(parallel [(set (match_operand 0 "register_operand")
16196 (clobber (match_operand 1 "register_operand"))
16197 (clobber (reg:CC FLAGS_REG))])]
16199 "ix86_current_function_needs_cld = 1;")
16201 (define_insn "*strlenqi_1"
16202 [(set (match_operand:P 0 "register_operand" "=&c")
16203 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16204 (match_operand:QI 2 "register_operand" "a")
16205 (match_operand:P 3 "immediate_operand" "i")
16206 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16207 (clobber (match_operand:P 1 "register_operand" "=D"))
16208 (clobber (reg:CC FLAGS_REG))]
16209 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16210 "%^repnz{%;} scasb"
16211 [(set_attr "type" "str")
16212 (set_attr "mode" "QI")
16213 (set (attr "prefix_rex")
16215 (match_test "<P:MODE>mode == DImode")
16217 (const_string "*")))
16218 (set_attr "prefix_rep" "1")])
16220 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16221 ;; handled in combine, but it is not currently up to the task.
16222 ;; When used for their truth value, the cmpstrn* expanders generate
16231 ;; The intermediate three instructions are unnecessary.
16233 ;; This one handles cmpstrn*_nz_1...
16236 (set (reg:CC FLAGS_REG)
16237 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16238 (mem:BLK (match_operand 5 "register_operand"))))
16239 (use (match_operand 6 "register_operand"))
16240 (use (match_operand:SI 3 "immediate_operand"))
16241 (clobber (match_operand 0 "register_operand"))
16242 (clobber (match_operand 1 "register_operand"))
16243 (clobber (match_operand 2 "register_operand"))])
16244 (set (match_operand:QI 7 "register_operand")
16245 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16246 (set (match_operand:QI 8 "register_operand")
16247 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16248 (set (reg FLAGS_REG)
16249 (compare (match_dup 7) (match_dup 8)))
16251 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16253 (set (reg:CC FLAGS_REG)
16254 (compare:CC (mem:BLK (match_dup 4))
16255 (mem:BLK (match_dup 5))))
16256 (use (match_dup 6))
16257 (use (match_dup 3))
16258 (clobber (match_dup 0))
16259 (clobber (match_dup 1))
16260 (clobber (match_dup 2))])])
16262 ;; ...and this one handles cmpstrn*_1.
16265 (set (reg:CC FLAGS_REG)
16266 (if_then_else:CC (ne (match_operand 6 "register_operand")
16268 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16269 (mem:BLK (match_operand 5 "register_operand")))
16271 (use (match_operand:SI 3 "immediate_operand"))
16272 (use (reg:CC FLAGS_REG))
16273 (clobber (match_operand 0 "register_operand"))
16274 (clobber (match_operand 1 "register_operand"))
16275 (clobber (match_operand 2 "register_operand"))])
16276 (set (match_operand:QI 7 "register_operand")
16277 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16278 (set (match_operand:QI 8 "register_operand")
16279 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16280 (set (reg FLAGS_REG)
16281 (compare (match_dup 7) (match_dup 8)))
16283 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16285 (set (reg:CC FLAGS_REG)
16286 (if_then_else:CC (ne (match_dup 6)
16288 (compare:CC (mem:BLK (match_dup 4))
16289 (mem:BLK (match_dup 5)))
16291 (use (match_dup 3))
16292 (use (reg:CC FLAGS_REG))
16293 (clobber (match_dup 0))
16294 (clobber (match_dup 1))
16295 (clobber (match_dup 2))])])
16297 ;; Conditional move instructions.
16299 (define_expand "mov<mode>cc"
16300 [(set (match_operand:SWIM 0 "register_operand")
16301 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16302 (match_operand:SWIM 2 "<general_operand>")
16303 (match_operand:SWIM 3 "<general_operand>")))]
16305 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16307 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16308 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16309 ;; So just document what we're doing explicitly.
16311 (define_expand "x86_mov<mode>cc_0_m1"
16313 [(set (match_operand:SWI48 0 "register_operand")
16314 (if_then_else:SWI48
16315 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16316 [(match_operand 1 "flags_reg_operand")
16320 (clobber (reg:CC FLAGS_REG))])])
16322 (define_insn "*x86_mov<mode>cc_0_m1"
16323 [(set (match_operand:SWI48 0 "register_operand" "=r")
16324 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16325 [(reg FLAGS_REG) (const_int 0)])
16328 (clobber (reg:CC FLAGS_REG))]
16330 "sbb{<imodesuffix>}\t%0, %0"
16331 ; Since we don't have the proper number of operands for an alu insn,
16332 ; fill in all the blanks.
16333 [(set_attr "type" "alu")
16334 (set_attr "use_carry" "1")
16335 (set_attr "pent_pair" "pu")
16336 (set_attr "memory" "none")
16337 (set_attr "imm_disp" "false")
16338 (set_attr "mode" "<MODE>")
16339 (set_attr "length_immediate" "0")])
16341 (define_insn "*x86_mov<mode>cc_0_m1_se"
16342 [(set (match_operand:SWI48 0 "register_operand" "=r")
16343 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16344 [(reg FLAGS_REG) (const_int 0)])
16347 (clobber (reg:CC FLAGS_REG))]
16349 "sbb{<imodesuffix>}\t%0, %0"
16350 [(set_attr "type" "alu")
16351 (set_attr "use_carry" "1")
16352 (set_attr "pent_pair" "pu")
16353 (set_attr "memory" "none")
16354 (set_attr "imm_disp" "false")
16355 (set_attr "mode" "<MODE>")
16356 (set_attr "length_immediate" "0")])
16358 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16359 [(set (match_operand:SWI48 0 "register_operand" "=r")
16360 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16361 [(reg FLAGS_REG) (const_int 0)])))
16362 (clobber (reg:CC FLAGS_REG))]
16364 "sbb{<imodesuffix>}\t%0, %0"
16365 [(set_attr "type" "alu")
16366 (set_attr "use_carry" "1")
16367 (set_attr "pent_pair" "pu")
16368 (set_attr "memory" "none")
16369 (set_attr "imm_disp" "false")
16370 (set_attr "mode" "<MODE>")
16371 (set_attr "length_immediate" "0")])
16373 (define_insn "*mov<mode>cc_noc"
16374 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16375 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16376 [(reg FLAGS_REG) (const_int 0)])
16377 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16378 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16379 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16381 cmov%O2%C1\t{%2, %0|%0, %2}
16382 cmov%O2%c1\t{%3, %0|%0, %3}"
16383 [(set_attr "type" "icmov")
16384 (set_attr "mode" "<MODE>")])
16386 ;; Don't do conditional moves with memory inputs. This splitter helps
16387 ;; register starved x86_32 by forcing inputs into registers before reload.
16389 [(set (match_operand:SWI248 0 "register_operand")
16390 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16391 [(reg FLAGS_REG) (const_int 0)])
16392 (match_operand:SWI248 2 "nonimmediate_operand")
16393 (match_operand:SWI248 3 "nonimmediate_operand")))]
16394 "!TARGET_64BIT && TARGET_CMOVE
16395 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16396 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16397 && can_create_pseudo_p ()
16398 && optimize_insn_for_speed_p ()"
16399 [(set (match_dup 0)
16400 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16402 if (MEM_P (operands[2]))
16403 operands[2] = force_reg (<MODE>mode, operands[2]);
16404 if (MEM_P (operands[3]))
16405 operands[3] = force_reg (<MODE>mode, operands[3]);
16408 (define_insn "*movqicc_noc"
16409 [(set (match_operand:QI 0 "register_operand" "=r,r")
16410 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16411 [(reg FLAGS_REG) (const_int 0)])
16412 (match_operand:QI 2 "register_operand" "r,0")
16413 (match_operand:QI 3 "register_operand" "0,r")))]
16414 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16416 [(set_attr "type" "icmov")
16417 (set_attr "mode" "QI")])
16420 [(set (match_operand:SWI12 0 "register_operand")
16421 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16422 [(reg FLAGS_REG) (const_int 0)])
16423 (match_operand:SWI12 2 "register_operand")
16424 (match_operand:SWI12 3 "register_operand")))]
16425 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16426 && reload_completed"
16427 [(set (match_dup 0)
16428 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16430 operands[0] = gen_lowpart (SImode, operands[0]);
16431 operands[2] = gen_lowpart (SImode, operands[2]);
16432 operands[3] = gen_lowpart (SImode, operands[3]);
16435 ;; Don't do conditional moves with memory inputs
16437 [(match_scratch:SWI248 2 "r")
16438 (set (match_operand:SWI248 0 "register_operand")
16439 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16440 [(reg FLAGS_REG) (const_int 0)])
16442 (match_operand:SWI248 3 "memory_operand")))]
16443 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16444 && optimize_insn_for_speed_p ()"
16445 [(set (match_dup 2) (match_dup 3))
16447 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16450 [(match_scratch:SWI248 2 "r")
16451 (set (match_operand:SWI248 0 "register_operand")
16452 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16453 [(reg FLAGS_REG) (const_int 0)])
16454 (match_operand:SWI248 3 "memory_operand")
16456 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16457 && optimize_insn_for_speed_p ()"
16458 [(set (match_dup 2) (match_dup 3))
16460 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16462 (define_expand "mov<mode>cc"
16463 [(set (match_operand:X87MODEF 0 "register_operand")
16464 (if_then_else:X87MODEF
16465 (match_operand 1 "comparison_operator")
16466 (match_operand:X87MODEF 2 "register_operand")
16467 (match_operand:X87MODEF 3 "register_operand")))]
16468 "(TARGET_80387 && TARGET_CMOVE)
16469 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16470 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16472 (define_insn "*movxfcc_1"
16473 [(set (match_operand:XF 0 "register_operand" "=f,f")
16474 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:XF 2 "register_operand" "f,0")
16477 (match_operand:XF 3 "register_operand" "0,f")))]
16478 "TARGET_80387 && TARGET_CMOVE"
16480 fcmov%F1\t{%2, %0|%0, %2}
16481 fcmov%f1\t{%3, %0|%0, %3}"
16482 [(set_attr "type" "fcmov")
16483 (set_attr "mode" "XF")])
16485 (define_insn "*movdfcc_1"
16486 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16487 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16488 [(reg FLAGS_REG) (const_int 0)])
16489 (match_operand:DF 2 "nonimmediate_operand"
16491 (match_operand:DF 3 "nonimmediate_operand"
16492 "0 ,f,0 ,rm,0, rm")))]
16493 "TARGET_80387 && TARGET_CMOVE
16494 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16496 fcmov%F1\t{%2, %0|%0, %2}
16497 fcmov%f1\t{%3, %0|%0, %3}
16500 cmov%O2%C1\t{%2, %0|%0, %2}
16501 cmov%O2%c1\t{%3, %0|%0, %3}"
16502 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16503 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16504 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16507 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16508 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16509 [(reg FLAGS_REG) (const_int 0)])
16510 (match_operand:DF 2 "nonimmediate_operand")
16511 (match_operand:DF 3 "nonimmediate_operand")))]
16512 "!TARGET_64BIT && reload_completed"
16513 [(set (match_dup 2)
16514 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16516 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16518 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16519 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16522 (define_insn "*movsfcc_1_387"
16523 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16524 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16525 [(reg FLAGS_REG) (const_int 0)])
16526 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16527 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16528 "TARGET_80387 && TARGET_CMOVE
16529 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16531 fcmov%F1\t{%2, %0|%0, %2}
16532 fcmov%f1\t{%3, %0|%0, %3}
16533 cmov%O2%C1\t{%2, %0|%0, %2}
16534 cmov%O2%c1\t{%3, %0|%0, %3}"
16535 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16536 (set_attr "mode" "SF,SF,SI,SI")])
16538 ;; Don't do conditional moves with memory inputs. This splitter helps
16539 ;; register starved x86_32 by forcing inputs into registers before reload.
16541 [(set (match_operand:MODEF 0 "register_operand")
16542 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16543 [(reg FLAGS_REG) (const_int 0)])
16544 (match_operand:MODEF 2 "nonimmediate_operand")
16545 (match_operand:MODEF 3 "nonimmediate_operand")))]
16546 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16547 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16548 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16549 && can_create_pseudo_p ()
16550 && optimize_insn_for_speed_p ()"
16551 [(set (match_dup 0)
16552 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16554 if (MEM_P (operands[2]))
16555 operands[2] = force_reg (<MODE>mode, operands[2]);
16556 if (MEM_P (operands[3]))
16557 operands[3] = force_reg (<MODE>mode, operands[3]);
16560 ;; Don't do conditional moves with memory inputs
16562 [(match_scratch:MODEF 2 "r")
16563 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16564 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16565 [(reg FLAGS_REG) (const_int 0)])
16567 (match_operand:MODEF 3 "memory_operand")))]
16568 "(<MODE>mode != DFmode || TARGET_64BIT)
16569 && TARGET_80387 && TARGET_CMOVE
16570 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16571 && optimize_insn_for_speed_p ()"
16572 [(set (match_dup 2) (match_dup 3))
16574 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16577 [(match_scratch:MODEF 2 "r")
16578 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16579 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16580 [(reg FLAGS_REG) (const_int 0)])
16581 (match_operand:MODEF 3 "memory_operand")
16583 "(<MODE>mode != DFmode || TARGET_64BIT)
16584 && TARGET_80387 && TARGET_CMOVE
16585 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16586 && optimize_insn_for_speed_p ()"
16587 [(set (match_dup 2) (match_dup 3))
16589 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16591 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16592 ;; the scalar versions to have only XMM registers as operands.
16594 ;; XOP conditional move
16595 (define_insn "*xop_pcmov_<mode>"
16596 [(set (match_operand:MODEF 0 "register_operand" "=x")
16597 (if_then_else:MODEF
16598 (match_operand:MODEF 1 "register_operand" "x")
16599 (match_operand:MODEF 2 "register_operand" "x")
16600 (match_operand:MODEF 3 "register_operand" "x")))]
16602 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16603 [(set_attr "type" "sse4arg")])
16605 ;; These versions of the min/max patterns are intentionally ignorant of
16606 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16607 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16608 ;; are undefined in this condition, we're certain this is correct.
16610 (define_insn "<code><mode>3"
16611 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16613 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16614 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16615 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16617 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16618 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16619 [(set_attr "isa" "noavx,avx")
16620 (set_attr "prefix" "orig,vex")
16621 (set_attr "type" "sseadd")
16622 (set_attr "mode" "<MODE>")])
16624 ;; These versions of the min/max patterns implement exactly the operations
16625 ;; min = (op1 < op2 ? op1 : op2)
16626 ;; max = (!(op1 < op2) ? op1 : op2)
16627 ;; Their operands are not commutative, and thus they may be used in the
16628 ;; presence of -0.0 and NaN.
16630 (define_int_iterator IEEE_MAXMIN
16634 (define_int_attr ieee_maxmin
16635 [(UNSPEC_IEEE_MAX "max")
16636 (UNSPEC_IEEE_MIN "min")])
16638 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16639 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16641 [(match_operand:MODEF 1 "register_operand" "0,x")
16642 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16644 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16646 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16647 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16648 [(set_attr "isa" "noavx,avx")
16649 (set_attr "prefix" "orig,vex")
16650 (set_attr "type" "sseadd")
16651 (set_attr "mode" "<MODE>")])
16653 ;; Make two stack loads independent:
16655 ;; fld %st(0) -> fld bb
16656 ;; fmul bb fmul %st(1), %st
16658 ;; Actually we only match the last two instructions for simplicity.
16660 [(set (match_operand 0 "fp_register_operand")
16661 (match_operand 1 "fp_register_operand"))
16663 (match_operator 2 "binary_fp_operator"
16665 (match_operand 3 "memory_operand")]))]
16666 "REGNO (operands[0]) != REGNO (operands[1])"
16667 [(set (match_dup 0) (match_dup 3))
16668 (set (match_dup 0) (match_dup 4))]
16670 ;; The % modifier is not operational anymore in peephole2's, so we have to
16671 ;; swap the operands manually in the case of addition and multiplication.
16675 if (COMMUTATIVE_ARITH_P (operands[2]))
16676 op0 = operands[0], op1 = operands[1];
16678 op0 = operands[1], op1 = operands[0];
16680 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16681 GET_MODE (operands[2]),
16685 ;; Conditional addition patterns
16686 (define_expand "add<mode>cc"
16687 [(match_operand:SWI 0 "register_operand")
16688 (match_operand 1 "ordered_comparison_operator")
16689 (match_operand:SWI 2 "register_operand")
16690 (match_operand:SWI 3 "const_int_operand")]
16692 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16694 ;; Misc patterns (?)
16696 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16697 ;; Otherwise there will be nothing to keep
16699 ;; [(set (reg ebp) (reg esp))]
16700 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16701 ;; (clobber (eflags)]
16702 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16704 ;; in proper program order.
16706 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16707 [(set (match_operand:P 0 "register_operand" "=r,r")
16708 (plus:P (match_operand:P 1 "register_operand" "0,r")
16709 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16710 (clobber (reg:CC FLAGS_REG))
16711 (clobber (mem:BLK (scratch)))]
16714 switch (get_attr_type (insn))
16717 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16720 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16721 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16722 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16724 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16727 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16728 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16731 [(set (attr "type")
16732 (cond [(and (eq_attr "alternative" "0")
16733 (not (match_test "TARGET_OPT_AGU")))
16734 (const_string "alu")
16735 (match_operand:<MODE> 2 "const0_operand")
16736 (const_string "imov")
16738 (const_string "lea")))
16739 (set (attr "length_immediate")
16740 (cond [(eq_attr "type" "imov")
16742 (and (eq_attr "type" "alu")
16743 (match_operand 2 "const128_operand"))
16746 (const_string "*")))
16747 (set_attr "mode" "<MODE>")])
16749 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16750 [(set (match_operand:P 0 "register_operand" "=r")
16751 (minus:P (match_operand:P 1 "register_operand" "0")
16752 (match_operand:P 2 "register_operand" "r")))
16753 (clobber (reg:CC FLAGS_REG))
16754 (clobber (mem:BLK (scratch)))]
16756 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16757 [(set_attr "type" "alu")
16758 (set_attr "mode" "<MODE>")])
16760 (define_insn "allocate_stack_worker_probe_<mode>"
16761 [(set (match_operand:P 0 "register_operand" "=a")
16762 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16763 UNSPECV_STACK_PROBE))
16764 (clobber (reg:CC FLAGS_REG))]
16765 "ix86_target_stack_probe ()"
16766 "call\t___chkstk_ms"
16767 [(set_attr "type" "multi")
16768 (set_attr "length" "5")])
16770 (define_expand "allocate_stack"
16771 [(match_operand 0 "register_operand")
16772 (match_operand 1 "general_operand")]
16773 "ix86_target_stack_probe ()"
16777 #ifndef CHECK_STACK_LIMIT
16778 #define CHECK_STACK_LIMIT 0
16781 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16782 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16786 rtx (*insn) (rtx, rtx);
16788 x = copy_to_mode_reg (Pmode, operands[1]);
16790 insn = (TARGET_64BIT
16791 ? gen_allocate_stack_worker_probe_di
16792 : gen_allocate_stack_worker_probe_si);
16794 emit_insn (insn (x, x));
16797 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16798 stack_pointer_rtx, 0, OPTAB_DIRECT);
16800 if (x != stack_pointer_rtx)
16801 emit_move_insn (stack_pointer_rtx, x);
16803 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16807 ;; Use IOR for stack probes, this is shorter.
16808 (define_expand "probe_stack"
16809 [(match_operand 0 "memory_operand")]
16812 rtx (*gen_ior3) (rtx, rtx, rtx);
16814 gen_ior3 = (GET_MODE (operands[0]) == DImode
16815 ? gen_iordi3 : gen_iorsi3);
16817 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16821 (define_insn "adjust_stack_and_probe<mode>"
16822 [(set (match_operand:P 0 "register_operand" "=r")
16823 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16824 UNSPECV_PROBE_STACK_RANGE))
16825 (set (reg:P SP_REG)
16826 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16827 (clobber (reg:CC FLAGS_REG))
16828 (clobber (mem:BLK (scratch)))]
16830 "* return output_adjust_stack_and_probe (operands[0]);"
16831 [(set_attr "type" "multi")])
16833 (define_insn "probe_stack_range<mode>"
16834 [(set (match_operand:P 0 "register_operand" "=r")
16835 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16836 (match_operand:P 2 "const_int_operand" "n")]
16837 UNSPECV_PROBE_STACK_RANGE))
16838 (clobber (reg:CC FLAGS_REG))]
16840 "* return output_probe_stack_range (operands[0], operands[2]);"
16841 [(set_attr "type" "multi")])
16843 (define_expand "builtin_setjmp_receiver"
16844 [(label_ref (match_operand 0))]
16845 "!TARGET_64BIT && flag_pic"
16851 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16852 rtx label_rtx = gen_label_rtx ();
16853 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16854 xops[0] = xops[1] = picreg;
16855 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16856 ix86_expand_binary_operator (MINUS, SImode, xops);
16860 emit_insn (gen_set_got (pic_offset_table_rtx));
16864 (define_insn_and_split "nonlocal_goto_receiver"
16865 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16866 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16868 "&& reload_completed"
16871 if (crtl->uses_pic_offset_table)
16874 rtx label_rtx = gen_label_rtx ();
16877 /* Get a new pic base. */
16878 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16879 /* Correct this with the offset from the new to the old. */
16880 xops[0] = xops[1] = pic_offset_table_rtx;
16881 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16882 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16883 UNSPEC_MACHOPIC_OFFSET);
16884 xops[2] = gen_rtx_CONST (Pmode, tmp);
16885 ix86_expand_binary_operator (MINUS, SImode, xops);
16888 /* No pic reg restore needed. */
16889 emit_note (NOTE_INSN_DELETED);
16894 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16895 ;; Do not split instructions with mask registers.
16897 [(set (match_operand 0 "general_reg_operand")
16898 (match_operator 3 "promotable_binary_operator"
16899 [(match_operand 1 "general_reg_operand")
16900 (match_operand 2 "aligned_operand")]))
16901 (clobber (reg:CC FLAGS_REG))]
16902 "! TARGET_PARTIAL_REG_STALL && reload_completed
16903 && ((GET_MODE (operands[0]) == HImode
16904 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16905 /* ??? next two lines just !satisfies_constraint_K (...) */
16906 || !CONST_INT_P (operands[2])
16907 || satisfies_constraint_K (operands[2])))
16908 || (GET_MODE (operands[0]) == QImode
16909 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16910 [(parallel [(set (match_dup 0)
16911 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16912 (clobber (reg:CC FLAGS_REG))])]
16914 operands[0] = gen_lowpart (SImode, operands[0]);
16915 operands[1] = gen_lowpart (SImode, operands[1]);
16916 if (GET_CODE (operands[3]) != ASHIFT)
16917 operands[2] = gen_lowpart (SImode, operands[2]);
16918 PUT_MODE (operands[3], SImode);
16921 ; Promote the QImode tests, as i386 has encoding of the AND
16922 ; instruction with 32-bit sign-extended immediate and thus the
16923 ; instruction size is unchanged, except in the %eax case for
16924 ; which it is increased by one byte, hence the ! optimize_size.
16926 [(set (match_operand 0 "flags_reg_operand")
16927 (match_operator 2 "compare_operator"
16928 [(and (match_operand 3 "aligned_operand")
16929 (match_operand 4 "const_int_operand"))
16931 (set (match_operand 1 "register_operand")
16932 (and (match_dup 3) (match_dup 4)))]
16933 "! TARGET_PARTIAL_REG_STALL && reload_completed
16934 && optimize_insn_for_speed_p ()
16935 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16936 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16937 /* Ensure that the operand will remain sign-extended immediate. */
16938 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16939 [(parallel [(set (match_dup 0)
16940 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16943 (and:SI (match_dup 3) (match_dup 4)))])]
16946 = gen_int_mode (INTVAL (operands[4])
16947 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16948 operands[1] = gen_lowpart (SImode, operands[1]);
16949 operands[3] = gen_lowpart (SImode, operands[3]);
16952 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16953 ; the TEST instruction with 32-bit sign-extended immediate and thus
16954 ; the instruction size would at least double, which is not what we
16955 ; want even with ! optimize_size.
16957 [(set (match_operand 0 "flags_reg_operand")
16958 (match_operator 1 "compare_operator"
16959 [(and (match_operand:HI 2 "aligned_operand")
16960 (match_operand:HI 3 "const_int_operand"))
16962 "! TARGET_PARTIAL_REG_STALL && reload_completed
16963 && ! TARGET_FAST_PREFIX
16964 && optimize_insn_for_speed_p ()
16965 /* Ensure that the operand will remain sign-extended immediate. */
16966 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16967 [(set (match_dup 0)
16968 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16972 = gen_int_mode (INTVAL (operands[3])
16973 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16974 operands[2] = gen_lowpart (SImode, operands[2]);
16978 [(set (match_operand 0 "register_operand")
16979 (neg (match_operand 1 "register_operand")))
16980 (clobber (reg:CC FLAGS_REG))]
16981 "! TARGET_PARTIAL_REG_STALL && reload_completed
16982 && (GET_MODE (operands[0]) == HImode
16983 || (GET_MODE (operands[0]) == QImode
16984 && (TARGET_PROMOTE_QImode
16985 || optimize_insn_for_size_p ())))"
16986 [(parallel [(set (match_dup 0)
16987 (neg:SI (match_dup 1)))
16988 (clobber (reg:CC FLAGS_REG))])]
16990 operands[0] = gen_lowpart (SImode, operands[0]);
16991 operands[1] = gen_lowpart (SImode, operands[1]);
16994 ;; Do not split instructions with mask regs.
16996 [(set (match_operand 0 "general_reg_operand")
16997 (not (match_operand 1 "general_reg_operand")))]
16998 "! TARGET_PARTIAL_REG_STALL && reload_completed
16999 && (GET_MODE (operands[0]) == HImode
17000 || (GET_MODE (operands[0]) == QImode
17001 && (TARGET_PROMOTE_QImode
17002 || optimize_insn_for_size_p ())))"
17003 [(set (match_dup 0)
17004 (not:SI (match_dup 1)))]
17006 operands[0] = gen_lowpart (SImode, operands[0]);
17007 operands[1] = gen_lowpart (SImode, operands[1]);
17010 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17011 ;; transform a complex memory operation into two memory to register operations.
17013 ;; Don't push memory operands
17015 [(set (match_operand:SWI 0 "push_operand")
17016 (match_operand:SWI 1 "memory_operand"))
17017 (match_scratch:SWI 2 "<r>")]
17018 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17019 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17020 [(set (match_dup 2) (match_dup 1))
17021 (set (match_dup 0) (match_dup 2))])
17023 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17026 [(set (match_operand:SF 0 "push_operand")
17027 (match_operand:SF 1 "memory_operand"))
17028 (match_scratch:SF 2 "r")]
17029 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17030 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17031 [(set (match_dup 2) (match_dup 1))
17032 (set (match_dup 0) (match_dup 2))])
17034 ;; Don't move an immediate directly to memory when the instruction
17035 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17037 [(match_scratch:SWI124 1 "<r>")
17038 (set (match_operand:SWI124 0 "memory_operand")
17040 "optimize_insn_for_speed_p ()
17041 && ((<MODE>mode == HImode
17042 && TARGET_LCP_STALL)
17043 || (!TARGET_USE_MOV0
17044 && TARGET_SPLIT_LONG_MOVES
17045 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17046 && peep2_regno_dead_p (0, FLAGS_REG)"
17047 [(parallel [(set (match_dup 2) (const_int 0))
17048 (clobber (reg:CC FLAGS_REG))])
17049 (set (match_dup 0) (match_dup 1))]
17050 "operands[2] = gen_lowpart (SImode, operands[1]);")
17053 [(match_scratch:SWI124 2 "<r>")
17054 (set (match_operand:SWI124 0 "memory_operand")
17055 (match_operand:SWI124 1 "immediate_operand"))]
17056 "optimize_insn_for_speed_p ()
17057 && ((<MODE>mode == HImode
17058 && TARGET_LCP_STALL)
17059 || (TARGET_SPLIT_LONG_MOVES
17060 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17061 [(set (match_dup 2) (match_dup 1))
17062 (set (match_dup 0) (match_dup 2))])
17064 ;; Don't compare memory with zero, load and use a test instead.
17066 [(set (match_operand 0 "flags_reg_operand")
17067 (match_operator 1 "compare_operator"
17068 [(match_operand:SI 2 "memory_operand")
17070 (match_scratch:SI 3 "r")]
17071 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17072 [(set (match_dup 3) (match_dup 2))
17073 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17075 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17076 ;; Don't split NOTs with a displacement operand, because resulting XOR
17077 ;; will not be pairable anyway.
17079 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17080 ;; represented using a modRM byte. The XOR replacement is long decoded,
17081 ;; so this split helps here as well.
17083 ;; Note: Can't do this as a regular split because we can't get proper
17084 ;; lifetime information then.
17087 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17088 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17089 "optimize_insn_for_speed_p ()
17090 && ((TARGET_NOT_UNPAIRABLE
17091 && (!MEM_P (operands[0])
17092 || !memory_displacement_operand (operands[0], <MODE>mode)))
17093 || (TARGET_NOT_VECTORMODE
17094 && long_memory_operand (operands[0], <MODE>mode)))
17095 && peep2_regno_dead_p (0, FLAGS_REG)"
17096 [(parallel [(set (match_dup 0)
17097 (xor:SWI124 (match_dup 1) (const_int -1)))
17098 (clobber (reg:CC FLAGS_REG))])])
17100 ;; Non pairable "test imm, reg" instructions can be translated to
17101 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17102 ;; byte opcode instead of two, have a short form for byte operands),
17103 ;; so do it for other CPUs as well. Given that the value was dead,
17104 ;; this should not create any new dependencies. Pass on the sub-word
17105 ;; versions if we're concerned about partial register stalls.
17108 [(set (match_operand 0 "flags_reg_operand")
17109 (match_operator 1 "compare_operator"
17110 [(and:SI (match_operand:SI 2 "register_operand")
17111 (match_operand:SI 3 "immediate_operand"))
17113 "ix86_match_ccmode (insn, CCNOmode)
17114 && (true_regnum (operands[2]) != AX_REG
17115 || satisfies_constraint_K (operands[3]))
17116 && peep2_reg_dead_p (1, operands[2])"
17118 [(set (match_dup 0)
17119 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17122 (and:SI (match_dup 2) (match_dup 3)))])])
17124 ;; We don't need to handle HImode case, because it will be promoted to SImode
17125 ;; on ! TARGET_PARTIAL_REG_STALL
17128 [(set (match_operand 0 "flags_reg_operand")
17129 (match_operator 1 "compare_operator"
17130 [(and:QI (match_operand:QI 2 "register_operand")
17131 (match_operand:QI 3 "immediate_operand"))
17133 "! TARGET_PARTIAL_REG_STALL
17134 && ix86_match_ccmode (insn, CCNOmode)
17135 && true_regnum (operands[2]) != AX_REG
17136 && peep2_reg_dead_p (1, operands[2])"
17138 [(set (match_dup 0)
17139 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17142 (and:QI (match_dup 2) (match_dup 3)))])])
17145 [(set (match_operand 0 "flags_reg_operand")
17146 (match_operator 1 "compare_operator"
17149 (match_operand 2 "ext_register_operand")
17152 (match_operand 3 "const_int_operand"))
17154 "! TARGET_PARTIAL_REG_STALL
17155 && ix86_match_ccmode (insn, CCNOmode)
17156 && true_regnum (operands[2]) != AX_REG
17157 && peep2_reg_dead_p (1, operands[2])"
17158 [(parallel [(set (match_dup 0)
17167 (set (zero_extract:SI (match_dup 2)
17175 (match_dup 3)))])])
17177 ;; Don't do logical operations with memory inputs.
17179 [(match_scratch:SI 2 "r")
17180 (parallel [(set (match_operand:SI 0 "register_operand")
17181 (match_operator:SI 3 "arith_or_logical_operator"
17183 (match_operand:SI 1 "memory_operand")]))
17184 (clobber (reg:CC FLAGS_REG))])]
17185 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17186 [(set (match_dup 2) (match_dup 1))
17187 (parallel [(set (match_dup 0)
17188 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17189 (clobber (reg:CC FLAGS_REG))])])
17192 [(match_scratch:SI 2 "r")
17193 (parallel [(set (match_operand:SI 0 "register_operand")
17194 (match_operator:SI 3 "arith_or_logical_operator"
17195 [(match_operand:SI 1 "memory_operand")
17197 (clobber (reg:CC FLAGS_REG))])]
17198 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17199 [(set (match_dup 2) (match_dup 1))
17200 (parallel [(set (match_dup 0)
17201 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17202 (clobber (reg:CC FLAGS_REG))])])
17204 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17205 ;; refers to the destination of the load!
17208 [(set (match_operand:SI 0 "register_operand")
17209 (match_operand:SI 1 "register_operand"))
17210 (parallel [(set (match_dup 0)
17211 (match_operator:SI 3 "commutative_operator"
17213 (match_operand:SI 2 "memory_operand")]))
17214 (clobber (reg:CC FLAGS_REG))])]
17215 "REGNO (operands[0]) != REGNO (operands[1])
17216 && GENERAL_REGNO_P (REGNO (operands[0]))
17217 && GENERAL_REGNO_P (REGNO (operands[1]))"
17218 [(set (match_dup 0) (match_dup 4))
17219 (parallel [(set (match_dup 0)
17220 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17221 (clobber (reg:CC FLAGS_REG))])]
17222 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17225 [(set (match_operand 0 "register_operand")
17226 (match_operand 1 "register_operand"))
17228 (match_operator 3 "commutative_operator"
17230 (match_operand 2 "memory_operand")]))]
17231 "REGNO (operands[0]) != REGNO (operands[1])
17232 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17233 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17234 [(set (match_dup 0) (match_dup 2))
17236 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17238 ; Don't do logical operations with memory outputs
17240 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17241 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17242 ; the same decoder scheduling characteristics as the original.
17245 [(match_scratch:SI 2 "r")
17246 (parallel [(set (match_operand:SI 0 "memory_operand")
17247 (match_operator:SI 3 "arith_or_logical_operator"
17249 (match_operand:SI 1 "nonmemory_operand")]))
17250 (clobber (reg:CC FLAGS_REG))])]
17251 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17252 /* Do not split stack checking probes. */
17253 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17254 [(set (match_dup 2) (match_dup 0))
17255 (parallel [(set (match_dup 2)
17256 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17257 (clobber (reg:CC FLAGS_REG))])
17258 (set (match_dup 0) (match_dup 2))])
17261 [(match_scratch:SI 2 "r")
17262 (parallel [(set (match_operand:SI 0 "memory_operand")
17263 (match_operator:SI 3 "arith_or_logical_operator"
17264 [(match_operand:SI 1 "nonmemory_operand")
17266 (clobber (reg:CC FLAGS_REG))])]
17267 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17268 /* Do not split stack checking probes. */
17269 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17270 [(set (match_dup 2) (match_dup 0))
17271 (parallel [(set (match_dup 2)
17272 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17273 (clobber (reg:CC FLAGS_REG))])
17274 (set (match_dup 0) (match_dup 2))])
17276 ;; Attempt to use arith or logical operations with memory outputs with
17277 ;; setting of flags.
17279 [(set (match_operand:SWI 0 "register_operand")
17280 (match_operand:SWI 1 "memory_operand"))
17281 (parallel [(set (match_dup 0)
17282 (match_operator:SWI 3 "plusminuslogic_operator"
17284 (match_operand:SWI 2 "<nonmemory_operand>")]))
17285 (clobber (reg:CC FLAGS_REG))])
17286 (set (match_dup 1) (match_dup 0))
17287 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17288 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17289 && peep2_reg_dead_p (4, operands[0])
17290 && !reg_overlap_mentioned_p (operands[0], operands[1])
17291 && !reg_overlap_mentioned_p (operands[0], operands[2])
17292 && (<MODE>mode != QImode
17293 || immediate_operand (operands[2], QImode)
17294 || q_regs_operand (operands[2], QImode))
17295 && ix86_match_ccmode (peep2_next_insn (3),
17296 (GET_CODE (operands[3]) == PLUS
17297 || GET_CODE (operands[3]) == MINUS)
17298 ? CCGOCmode : CCNOmode)"
17299 [(parallel [(set (match_dup 4) (match_dup 5))
17300 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17301 (match_dup 2)]))])]
17303 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17304 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17305 copy_rtx (operands[1]),
17306 copy_rtx (operands[2]));
17307 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17308 operands[5], const0_rtx);
17312 [(parallel [(set (match_operand:SWI 0 "register_operand")
17313 (match_operator:SWI 2 "plusminuslogic_operator"
17315 (match_operand:SWI 1 "memory_operand")]))
17316 (clobber (reg:CC FLAGS_REG))])
17317 (set (match_dup 1) (match_dup 0))
17318 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17319 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17320 && GET_CODE (operands[2]) != MINUS
17321 && peep2_reg_dead_p (3, operands[0])
17322 && !reg_overlap_mentioned_p (operands[0], operands[1])
17323 && ix86_match_ccmode (peep2_next_insn (2),
17324 GET_CODE (operands[2]) == PLUS
17325 ? CCGOCmode : CCNOmode)"
17326 [(parallel [(set (match_dup 3) (match_dup 4))
17327 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17328 (match_dup 0)]))])]
17330 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17331 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17332 copy_rtx (operands[1]),
17333 copy_rtx (operands[0]));
17334 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17335 operands[4], const0_rtx);
17339 [(set (match_operand:SWI12 0 "register_operand")
17340 (match_operand:SWI12 1 "memory_operand"))
17341 (parallel [(set (match_operand:SI 4 "register_operand")
17342 (match_operator:SI 3 "plusminuslogic_operator"
17344 (match_operand:SI 2 "nonmemory_operand")]))
17345 (clobber (reg:CC FLAGS_REG))])
17346 (set (match_dup 1) (match_dup 0))
17347 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17348 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17349 && REG_P (operands[0]) && REG_P (operands[4])
17350 && REGNO (operands[0]) == REGNO (operands[4])
17351 && peep2_reg_dead_p (4, operands[0])
17352 && (<MODE>mode != QImode
17353 || immediate_operand (operands[2], SImode)
17354 || q_regs_operand (operands[2], SImode))
17355 && !reg_overlap_mentioned_p (operands[0], operands[1])
17356 && !reg_overlap_mentioned_p (operands[0], operands[2])
17357 && ix86_match_ccmode (peep2_next_insn (3),
17358 (GET_CODE (operands[3]) == PLUS
17359 || GET_CODE (operands[3]) == MINUS)
17360 ? CCGOCmode : CCNOmode)"
17361 [(parallel [(set (match_dup 4) (match_dup 5))
17362 (set (match_dup 1) (match_dup 6))])]
17364 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17365 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17366 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17367 copy_rtx (operands[1]), operands[2]);
17368 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17369 operands[5], const0_rtx);
17370 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17371 copy_rtx (operands[1]),
17372 copy_rtx (operands[2]));
17375 ;; Attempt to always use XOR for zeroing registers.
17377 [(set (match_operand 0 "register_operand")
17378 (match_operand 1 "const0_operand"))]
17379 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17380 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17381 && GENERAL_REG_P (operands[0])
17382 && peep2_regno_dead_p (0, FLAGS_REG)"
17383 [(parallel [(set (match_dup 0) (const_int 0))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17388 [(set (strict_low_part (match_operand 0 "register_operand"))
17390 "(GET_MODE (operands[0]) == QImode
17391 || GET_MODE (operands[0]) == HImode)
17392 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17393 && peep2_regno_dead_p (0, FLAGS_REG)"
17394 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17395 (clobber (reg:CC FLAGS_REG))])])
17397 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17399 [(set (match_operand:SWI248 0 "register_operand")
17401 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17402 && peep2_regno_dead_p (0, FLAGS_REG)"
17403 [(parallel [(set (match_dup 0) (const_int -1))
17404 (clobber (reg:CC FLAGS_REG))])]
17406 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17407 operands[0] = gen_lowpart (SImode, operands[0]);
17410 ;; Attempt to convert simple lea to add/shift.
17411 ;; These can be created by move expanders.
17412 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17413 ;; relevant lea instructions were already split.
17416 [(set (match_operand:SWI48 0 "register_operand")
17417 (plus:SWI48 (match_dup 0)
17418 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17420 && peep2_regno_dead_p (0, FLAGS_REG)"
17421 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17422 (clobber (reg:CC FLAGS_REG))])])
17425 [(set (match_operand:SWI48 0 "register_operand")
17426 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17429 && peep2_regno_dead_p (0, FLAGS_REG)"
17430 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17431 (clobber (reg:CC FLAGS_REG))])])
17434 [(set (match_operand:DI 0 "register_operand")
17436 (plus:SI (match_operand:SI 1 "register_operand")
17437 (match_operand:SI 2 "nonmemory_operand"))))]
17438 "TARGET_64BIT && !TARGET_OPT_AGU
17439 && REGNO (operands[0]) == REGNO (operands[1])
17440 && peep2_regno_dead_p (0, FLAGS_REG)"
17441 [(parallel [(set (match_dup 0)
17442 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17443 (clobber (reg:CC FLAGS_REG))])])
17446 [(set (match_operand:DI 0 "register_operand")
17448 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17449 (match_operand:SI 2 "register_operand"))))]
17450 "TARGET_64BIT && !TARGET_OPT_AGU
17451 && REGNO (operands[0]) == REGNO (operands[2])
17452 && peep2_regno_dead_p (0, FLAGS_REG)"
17453 [(parallel [(set (match_dup 0)
17454 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17455 (clobber (reg:CC FLAGS_REG))])])
17458 [(set (match_operand:SWI48 0 "register_operand")
17459 (mult:SWI48 (match_dup 0)
17460 (match_operand:SWI48 1 "const_int_operand")))]
17461 "exact_log2 (INTVAL (operands[1])) >= 0
17462 && peep2_regno_dead_p (0, FLAGS_REG)"
17463 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17464 (clobber (reg:CC FLAGS_REG))])]
17465 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17468 [(set (match_operand:DI 0 "register_operand")
17470 (mult:SI (match_operand:SI 1 "register_operand")
17471 (match_operand:SI 2 "const_int_operand"))))]
17473 && exact_log2 (INTVAL (operands[2])) >= 0
17474 && REGNO (operands[0]) == REGNO (operands[1])
17475 && peep2_regno_dead_p (0, FLAGS_REG)"
17476 [(parallel [(set (match_dup 0)
17477 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17481 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17482 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17483 ;; On many CPUs it is also faster, since special hardware to avoid esp
17484 ;; dependencies is present.
17486 ;; While some of these conversions may be done using splitters, we use
17487 ;; peepholes in order to allow combine_stack_adjustments pass to see
17488 ;; nonobfuscated RTL.
17490 ;; Convert prologue esp subtractions to push.
17491 ;; We need register to push. In order to keep verify_flow_info happy we have
17493 ;; - use scratch and clobber it in order to avoid dependencies
17494 ;; - use already live register
17495 ;; We can't use the second way right now, since there is no reliable way how to
17496 ;; verify that given register is live. First choice will also most likely in
17497 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17498 ;; call clobbered registers are dead. We may want to use base pointer as an
17499 ;; alternative when no register is available later.
17502 [(match_scratch:W 1 "r")
17503 (parallel [(set (reg:P SP_REG)
17504 (plus:P (reg:P SP_REG)
17505 (match_operand:P 0 "const_int_operand")))
17506 (clobber (reg:CC FLAGS_REG))
17507 (clobber (mem:BLK (scratch)))])]
17508 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17509 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17510 [(clobber (match_dup 1))
17511 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17512 (clobber (mem:BLK (scratch)))])])
17515 [(match_scratch:W 1 "r")
17516 (parallel [(set (reg:P SP_REG)
17517 (plus:P (reg:P SP_REG)
17518 (match_operand:P 0 "const_int_operand")))
17519 (clobber (reg:CC FLAGS_REG))
17520 (clobber (mem:BLK (scratch)))])]
17521 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17522 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17523 [(clobber (match_dup 1))
17524 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17525 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17526 (clobber (mem:BLK (scratch)))])])
17528 ;; Convert esp subtractions to push.
17530 [(match_scratch:W 1 "r")
17531 (parallel [(set (reg:P SP_REG)
17532 (plus:P (reg:P SP_REG)
17533 (match_operand:P 0 "const_int_operand")))
17534 (clobber (reg:CC FLAGS_REG))])]
17535 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17536 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17537 [(clobber (match_dup 1))
17538 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17541 [(match_scratch:W 1 "r")
17542 (parallel [(set (reg:P SP_REG)
17543 (plus:P (reg:P SP_REG)
17544 (match_operand:P 0 "const_int_operand")))
17545 (clobber (reg:CC FLAGS_REG))])]
17546 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17547 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17548 [(clobber (match_dup 1))
17549 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17550 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17552 ;; Convert epilogue deallocator to pop.
17554 [(match_scratch:W 1 "r")
17555 (parallel [(set (reg:P SP_REG)
17556 (plus:P (reg:P SP_REG)
17557 (match_operand:P 0 "const_int_operand")))
17558 (clobber (reg:CC FLAGS_REG))
17559 (clobber (mem:BLK (scratch)))])]
17560 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17561 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17562 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17563 (clobber (mem:BLK (scratch)))])])
17565 ;; Two pops case is tricky, since pop causes dependency
17566 ;; on destination register. We use two registers if available.
17568 [(match_scratch:W 1 "r")
17569 (match_scratch:W 2 "r")
17570 (parallel [(set (reg:P SP_REG)
17571 (plus:P (reg:P SP_REG)
17572 (match_operand:P 0 "const_int_operand")))
17573 (clobber (reg:CC FLAGS_REG))
17574 (clobber (mem:BLK (scratch)))])]
17575 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17576 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17577 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17578 (clobber (mem:BLK (scratch)))])
17579 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17582 [(match_scratch:W 1 "r")
17583 (parallel [(set (reg:P SP_REG)
17584 (plus:P (reg:P SP_REG)
17585 (match_operand:P 0 "const_int_operand")))
17586 (clobber (reg:CC FLAGS_REG))
17587 (clobber (mem:BLK (scratch)))])]
17588 "optimize_insn_for_size_p ()
17589 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17590 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17591 (clobber (mem:BLK (scratch)))])
17592 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17594 ;; Convert esp additions to pop.
17596 [(match_scratch:W 1 "r")
17597 (parallel [(set (reg:P SP_REG)
17598 (plus:P (reg:P SP_REG)
17599 (match_operand:P 0 "const_int_operand")))
17600 (clobber (reg:CC FLAGS_REG))])]
17601 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17602 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17604 ;; Two pops case is tricky, since pop causes dependency
17605 ;; on destination register. We use two registers if available.
17607 [(match_scratch:W 1 "r")
17608 (match_scratch:W 2 "r")
17609 (parallel [(set (reg:P SP_REG)
17610 (plus:P (reg:P SP_REG)
17611 (match_operand:P 0 "const_int_operand")))
17612 (clobber (reg:CC FLAGS_REG))])]
17613 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17614 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17615 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17618 [(match_scratch:W 1 "r")
17619 (parallel [(set (reg:P SP_REG)
17620 (plus:P (reg:P SP_REG)
17621 (match_operand:P 0 "const_int_operand")))
17622 (clobber (reg:CC FLAGS_REG))])]
17623 "optimize_insn_for_size_p ()
17624 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17625 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17626 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17628 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17629 ;; required and register dies. Similarly for 128 to -128.
17631 [(set (match_operand 0 "flags_reg_operand")
17632 (match_operator 1 "compare_operator"
17633 [(match_operand 2 "register_operand")
17634 (match_operand 3 "const_int_operand")]))]
17635 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17636 && incdec_operand (operands[3], GET_MODE (operands[3])))
17637 || (!TARGET_FUSE_CMP_AND_BRANCH
17638 && INTVAL (operands[3]) == 128))
17639 && ix86_match_ccmode (insn, CCGCmode)
17640 && peep2_reg_dead_p (1, operands[2])"
17641 [(parallel [(set (match_dup 0)
17642 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17643 (clobber (match_dup 2))])])
17645 ;; Convert imul by three, five and nine into lea
17648 [(set (match_operand:SWI48 0 "register_operand")
17649 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17650 (match_operand:SWI48 2 "const359_operand")))
17651 (clobber (reg:CC FLAGS_REG))])]
17652 "!TARGET_PARTIAL_REG_STALL
17653 || <MODE>mode == SImode
17654 || optimize_function_for_size_p (cfun)"
17655 [(set (match_dup 0)
17656 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17658 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17662 [(set (match_operand:SWI48 0 "register_operand")
17663 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17664 (match_operand:SWI48 2 "const359_operand")))
17665 (clobber (reg:CC FLAGS_REG))])]
17666 "optimize_insn_for_speed_p ()
17667 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17668 [(set (match_dup 0) (match_dup 1))
17670 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17672 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17674 ;; imul $32bit_imm, mem, reg is vector decoded, while
17675 ;; imul $32bit_imm, reg, reg is direct decoded.
17677 [(match_scratch:SWI48 3 "r")
17678 (parallel [(set (match_operand:SWI48 0 "register_operand")
17679 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17680 (match_operand:SWI48 2 "immediate_operand")))
17681 (clobber (reg:CC FLAGS_REG))])]
17682 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17683 && !satisfies_constraint_K (operands[2])"
17684 [(set (match_dup 3) (match_dup 1))
17685 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17686 (clobber (reg:CC FLAGS_REG))])])
17689 [(match_scratch:SI 3 "r")
17690 (parallel [(set (match_operand:DI 0 "register_operand")
17692 (mult:SI (match_operand:SI 1 "memory_operand")
17693 (match_operand:SI 2 "immediate_operand"))))
17694 (clobber (reg:CC FLAGS_REG))])]
17696 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17697 && !satisfies_constraint_K (operands[2])"
17698 [(set (match_dup 3) (match_dup 1))
17699 (parallel [(set (match_dup 0)
17700 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17701 (clobber (reg:CC FLAGS_REG))])])
17703 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17704 ;; Convert it into imul reg, reg
17705 ;; It would be better to force assembler to encode instruction using long
17706 ;; immediate, but there is apparently no way to do so.
17708 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17710 (match_operand:SWI248 1 "nonimmediate_operand")
17711 (match_operand:SWI248 2 "const_int_operand")))
17712 (clobber (reg:CC FLAGS_REG))])
17713 (match_scratch:SWI248 3 "r")]
17714 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17715 && satisfies_constraint_K (operands[2])"
17716 [(set (match_dup 3) (match_dup 2))
17717 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17718 (clobber (reg:CC FLAGS_REG))])]
17720 if (!rtx_equal_p (operands[0], operands[1]))
17721 emit_move_insn (operands[0], operands[1]);
17724 ;; After splitting up read-modify operations, array accesses with memory
17725 ;; operands might end up in form:
17727 ;; movl 4(%esp), %edx
17729 ;; instead of pre-splitting:
17731 ;; addl 4(%esp), %eax
17733 ;; movl 4(%esp), %edx
17734 ;; leal (%edx,%eax,4), %eax
17737 [(match_scratch:W 5 "r")
17738 (parallel [(set (match_operand 0 "register_operand")
17739 (ashift (match_operand 1 "register_operand")
17740 (match_operand 2 "const_int_operand")))
17741 (clobber (reg:CC FLAGS_REG))])
17742 (parallel [(set (match_operand 3 "register_operand")
17743 (plus (match_dup 0)
17744 (match_operand 4 "x86_64_general_operand")))
17745 (clobber (reg:CC FLAGS_REG))])]
17746 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17747 /* Validate MODE for lea. */
17748 && ((!TARGET_PARTIAL_REG_STALL
17749 && (GET_MODE (operands[0]) == QImode
17750 || GET_MODE (operands[0]) == HImode))
17751 || GET_MODE (operands[0]) == SImode
17752 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17753 && (rtx_equal_p (operands[0], operands[3])
17754 || peep2_reg_dead_p (2, operands[0]))
17755 /* We reorder load and the shift. */
17756 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17757 [(set (match_dup 5) (match_dup 4))
17758 (set (match_dup 0) (match_dup 1))]
17760 enum machine_mode op1mode = GET_MODE (operands[1]);
17761 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17762 int scale = 1 << INTVAL (operands[2]);
17763 rtx index = gen_lowpart (word_mode, operands[1]);
17764 rtx base = gen_lowpart (word_mode, operands[5]);
17765 rtx dest = gen_lowpart (mode, operands[3]);
17767 operands[1] = gen_rtx_PLUS (word_mode, base,
17768 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17769 operands[5] = base;
17770 if (mode != word_mode)
17771 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17772 if (op1mode != word_mode)
17773 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17774 operands[0] = dest;
17777 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17778 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17779 ;; caught for use by garbage collectors and the like. Using an insn that
17780 ;; maps to SIGILL makes it more likely the program will rightfully die.
17781 ;; Keeping with tradition, "6" is in honor of #UD.
17782 (define_insn "trap"
17783 [(trap_if (const_int 1) (const_int 6))]
17785 { return ASM_SHORT "0x0b0f"; }
17786 [(set_attr "length" "2")])
17788 (define_expand "prefetch"
17789 [(prefetch (match_operand 0 "address_operand")
17790 (match_operand:SI 1 "const_int_operand")
17791 (match_operand:SI 2 "const_int_operand"))]
17792 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_AVX512PF"
17794 bool write = INTVAL (operands[1]) != 0;
17795 int locality = INTVAL (operands[2]);
17797 gcc_assert (IN_RANGE (locality, 0, 3));
17799 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17800 supported by SSE counterpart or the SSE prefetch is not available
17801 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17803 if (TARGET_AVX512PF && write)
17804 operands[2] = const1_rtx;
17805 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17806 operands[2] = GEN_INT (3);
17808 operands[1] = const0_rtx;
17811 (define_insn "*prefetch_sse"
17812 [(prefetch (match_operand 0 "address_operand" "p")
17814 (match_operand:SI 1 "const_int_operand"))]
17815 "TARGET_PREFETCH_SSE"
17817 static const char * const patterns[4] = {
17818 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17821 int locality = INTVAL (operands[1]);
17822 gcc_assert (IN_RANGE (locality, 0, 3));
17824 return patterns[locality];
17826 [(set_attr "type" "sse")
17827 (set_attr "atom_sse_attr" "prefetch")
17828 (set (attr "length_address")
17829 (symbol_ref "memory_address_length (operands[0], false)"))
17830 (set_attr "memory" "none")])
17832 (define_insn "*prefetch_3dnow"
17833 [(prefetch (match_operand 0 "address_operand" "p")
17834 (match_operand:SI 1 "const_int_operand" "n")
17838 if (INTVAL (operands[1]) == 0)
17839 return "prefetch\t%a0";
17841 return "prefetchw\t%a0";
17843 [(set_attr "type" "mmx")
17844 (set (attr "length_address")
17845 (symbol_ref "memory_address_length (operands[0], false)"))
17846 (set_attr "memory" "none")])
17848 (define_insn "*prefetch_avx512pf_<mode>"
17849 [(prefetch (match_operand:P 0 "address_operand" "p")
17853 "prefetchwt1\t%a0";
17854 [(set_attr "type" "sse")
17855 (set_attr "prefix" "evex")
17856 (set (attr "length_address")
17857 (symbol_ref "memory_address_length (operands[0], false)"))
17858 (set_attr "memory" "none")])
17860 (define_expand "stack_protect_set"
17861 [(match_operand 0 "memory_operand")
17862 (match_operand 1 "memory_operand")]
17863 "TARGET_SSP_TLS_GUARD"
17865 rtx (*insn)(rtx, rtx);
17867 #ifdef TARGET_THREAD_SSP_OFFSET
17868 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17869 insn = (TARGET_LP64
17870 ? gen_stack_tls_protect_set_di
17871 : gen_stack_tls_protect_set_si);
17873 insn = (TARGET_LP64
17874 ? gen_stack_protect_set_di
17875 : gen_stack_protect_set_si);
17878 emit_insn (insn (operands[0], operands[1]));
17882 (define_insn "stack_protect_set_<mode>"
17883 [(set (match_operand:PTR 0 "memory_operand" "=m")
17884 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17886 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17887 (clobber (reg:CC FLAGS_REG))]
17888 "TARGET_SSP_TLS_GUARD"
17889 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17890 [(set_attr "type" "multi")])
17892 (define_insn "stack_tls_protect_set_<mode>"
17893 [(set (match_operand:PTR 0 "memory_operand" "=m")
17894 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17895 UNSPEC_SP_TLS_SET))
17896 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17897 (clobber (reg:CC FLAGS_REG))]
17899 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17900 [(set_attr "type" "multi")])
17902 (define_expand "stack_protect_test"
17903 [(match_operand 0 "memory_operand")
17904 (match_operand 1 "memory_operand")
17906 "TARGET_SSP_TLS_GUARD"
17908 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17910 rtx (*insn)(rtx, rtx, rtx);
17912 #ifdef TARGET_THREAD_SSP_OFFSET
17913 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17914 insn = (TARGET_LP64
17915 ? gen_stack_tls_protect_test_di
17916 : gen_stack_tls_protect_test_si);
17918 insn = (TARGET_LP64
17919 ? gen_stack_protect_test_di
17920 : gen_stack_protect_test_si);
17923 emit_insn (insn (flags, operands[0], operands[1]));
17925 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17926 flags, const0_rtx, operands[2]));
17930 (define_insn "stack_protect_test_<mode>"
17931 [(set (match_operand:CCZ 0 "flags_reg_operand")
17932 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17933 (match_operand:PTR 2 "memory_operand" "m")]
17935 (clobber (match_scratch:PTR 3 "=&r"))]
17936 "TARGET_SSP_TLS_GUARD"
17937 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17938 [(set_attr "type" "multi")])
17940 (define_insn "stack_tls_protect_test_<mode>"
17941 [(set (match_operand:CCZ 0 "flags_reg_operand")
17942 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17943 (match_operand:PTR 2 "const_int_operand" "i")]
17944 UNSPEC_SP_TLS_TEST))
17945 (clobber (match_scratch:PTR 3 "=r"))]
17947 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17948 [(set_attr "type" "multi")])
17950 (define_insn "sse4_2_crc32<mode>"
17951 [(set (match_operand:SI 0 "register_operand" "=r")
17953 [(match_operand:SI 1 "register_operand" "0")
17954 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17956 "TARGET_SSE4_2 || TARGET_CRC32"
17957 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17958 [(set_attr "type" "sselog1")
17959 (set_attr "prefix_rep" "1")
17960 (set_attr "prefix_extra" "1")
17961 (set (attr "prefix_data16")
17962 (if_then_else (match_operand:HI 2)
17964 (const_string "*")))
17965 (set (attr "prefix_rex")
17966 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17968 (const_string "*")))
17969 (set_attr "mode" "SI")])
17971 (define_insn "sse4_2_crc32di"
17972 [(set (match_operand:DI 0 "register_operand" "=r")
17974 [(match_operand:DI 1 "register_operand" "0")
17975 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17977 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17978 "crc32{q}\t{%2, %0|%0, %2}"
17979 [(set_attr "type" "sselog1")
17980 (set_attr "prefix_rep" "1")
17981 (set_attr "prefix_extra" "1")
17982 (set_attr "mode" "DI")])
17984 (define_insn "rdpmc"
17985 [(set (match_operand:DI 0 "register_operand" "=A")
17986 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17990 [(set_attr "type" "other")
17991 (set_attr "length" "2")])
17993 (define_insn "rdpmc_rex64"
17994 [(set (match_operand:DI 0 "register_operand" "=a")
17995 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17997 (set (match_operand:DI 1 "register_operand" "=d")
17998 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18001 [(set_attr "type" "other")
18002 (set_attr "length" "2")])
18004 (define_insn "rdtsc"
18005 [(set (match_operand:DI 0 "register_operand" "=A")
18006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18009 [(set_attr "type" "other")
18010 (set_attr "length" "2")])
18012 (define_insn "rdtsc_rex64"
18013 [(set (match_operand:DI 0 "register_operand" "=a")
18014 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18015 (set (match_operand:DI 1 "register_operand" "=d")
18016 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18019 [(set_attr "type" "other")
18020 (set_attr "length" "2")])
18022 (define_insn "rdtscp"
18023 [(set (match_operand:DI 0 "register_operand" "=A")
18024 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18025 (set (match_operand:SI 1 "register_operand" "=c")
18026 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18029 [(set_attr "type" "other")
18030 (set_attr "length" "3")])
18032 (define_insn "rdtscp_rex64"
18033 [(set (match_operand:DI 0 "register_operand" "=a")
18034 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18035 (set (match_operand:DI 1 "register_operand" "=d")
18036 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18037 (set (match_operand:SI 2 "register_operand" "=c")
18038 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18041 [(set_attr "type" "other")
18042 (set_attr "length" "3")])
18044 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18046 ;; FXSR, XSAVE and XSAVEOPT instructions
18048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18050 (define_insn "fxsave"
18051 [(set (match_operand:BLK 0 "memory_operand" "=m")
18052 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18055 [(set_attr "type" "other")
18056 (set_attr "memory" "store")
18057 (set (attr "length")
18058 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18060 (define_insn "fxsave64"
18061 [(set (match_operand:BLK 0 "memory_operand" "=m")
18062 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18063 "TARGET_64BIT && TARGET_FXSR"
18065 [(set_attr "type" "other")
18066 (set_attr "memory" "store")
18067 (set (attr "length")
18068 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18070 (define_insn "fxrstor"
18071 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18075 [(set_attr "type" "other")
18076 (set_attr "memory" "load")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18080 (define_insn "fxrstor64"
18081 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18082 UNSPECV_FXRSTOR64)]
18083 "TARGET_64BIT && TARGET_FXSR"
18085 [(set_attr "type" "other")
18086 (set_attr "memory" "load")
18087 (set (attr "length")
18088 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18090 (define_int_iterator ANY_XSAVE
18092 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18094 (define_int_iterator ANY_XSAVE64
18096 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18098 (define_int_attr xsave
18099 [(UNSPECV_XSAVE "xsave")
18100 (UNSPECV_XSAVE64 "xsave64")
18101 (UNSPECV_XSAVEOPT "xsaveopt")
18102 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18104 (define_insn "<xsave>"
18105 [(set (match_operand:BLK 0 "memory_operand" "=m")
18106 (unspec_volatile:BLK
18107 [(match_operand:DI 1 "register_operand" "A")]
18109 "!TARGET_64BIT && TARGET_XSAVE"
18111 [(set_attr "type" "other")
18112 (set_attr "memory" "store")
18113 (set (attr "length")
18114 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18116 (define_insn "<xsave>_rex64"
18117 [(set (match_operand:BLK 0 "memory_operand" "=m")
18118 (unspec_volatile:BLK
18119 [(match_operand:SI 1 "register_operand" "a")
18120 (match_operand:SI 2 "register_operand" "d")]
18122 "TARGET_64BIT && TARGET_XSAVE"
18124 [(set_attr "type" "other")
18125 (set_attr "memory" "store")
18126 (set (attr "length")
18127 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18129 (define_insn "<xsave>"
18130 [(set (match_operand:BLK 0 "memory_operand" "=m")
18131 (unspec_volatile:BLK
18132 [(match_operand:SI 1 "register_operand" "a")
18133 (match_operand:SI 2 "register_operand" "d")]
18135 "TARGET_64BIT && TARGET_XSAVE"
18137 [(set_attr "type" "other")
18138 (set_attr "memory" "store")
18139 (set (attr "length")
18140 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18142 (define_insn "xrstor"
18143 [(unspec_volatile:BLK
18144 [(match_operand:BLK 0 "memory_operand" "m")
18145 (match_operand:DI 1 "register_operand" "A")]
18147 "!TARGET_64BIT && TARGET_XSAVE"
18149 [(set_attr "type" "other")
18150 (set_attr "memory" "load")
18151 (set (attr "length")
18152 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18154 (define_insn "xrstor_rex64"
18155 [(unspec_volatile:BLK
18156 [(match_operand:BLK 0 "memory_operand" "m")
18157 (match_operand:SI 1 "register_operand" "a")
18158 (match_operand:SI 2 "register_operand" "d")]
18160 "TARGET_64BIT && TARGET_XSAVE"
18162 [(set_attr "type" "other")
18163 (set_attr "memory" "load")
18164 (set (attr "length")
18165 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18167 (define_insn "xrstor64"
18168 [(unspec_volatile:BLK
18169 [(match_operand:BLK 0 "memory_operand" "m")
18170 (match_operand:SI 1 "register_operand" "a")
18171 (match_operand:SI 2 "register_operand" "d")]
18173 "TARGET_64BIT && TARGET_XSAVE"
18175 [(set_attr "type" "other")
18176 (set_attr "memory" "load")
18177 (set (attr "length")
18178 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18182 ;; Floating-point instructions for atomic compound assignments
18184 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18186 ; Clobber all floating-point registers on environment save and restore
18187 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18188 (define_insn "fnstenv"
18189 [(set (match_operand:BLK 0 "memory_operand" "=m")
18190 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18191 (clobber (reg:HI FPCR_REG))
18192 (clobber (reg:XF ST0_REG))
18193 (clobber (reg:XF ST1_REG))
18194 (clobber (reg:XF ST2_REG))
18195 (clobber (reg:XF ST3_REG))
18196 (clobber (reg:XF ST4_REG))
18197 (clobber (reg:XF ST5_REG))
18198 (clobber (reg:XF ST6_REG))
18199 (clobber (reg:XF ST7_REG))]
18202 [(set_attr "type" "other")
18203 (set_attr "memory" "store")
18204 (set (attr "length")
18205 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18207 (define_insn "fldenv"
18208 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18210 (clobber (reg:CCFP FPSR_REG))
18211 (clobber (reg:HI FPCR_REG))
18212 (clobber (reg:XF ST0_REG))
18213 (clobber (reg:XF ST1_REG))
18214 (clobber (reg:XF ST2_REG))
18215 (clobber (reg:XF ST3_REG))
18216 (clobber (reg:XF ST4_REG))
18217 (clobber (reg:XF ST5_REG))
18218 (clobber (reg:XF ST6_REG))
18219 (clobber (reg:XF ST7_REG))]
18222 [(set_attr "type" "other")
18223 (set_attr "memory" "load")
18224 (set (attr "length")
18225 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18227 (define_insn "fnstsw"
18228 [(set (match_operand:HI 0 "memory_operand" "=m")
18229 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18232 [(set_attr "type" "other")
18233 (set_attr "memory" "store")
18234 (set (attr "length")
18235 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18237 (define_insn "fnclex"
18238 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18241 [(set_attr "type" "other")
18242 (set_attr "memory" "none")
18243 (set_attr "length" "2")])
18245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18247 ;; LWP instructions
18249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18251 (define_expand "lwp_llwpcb"
18252 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18253 UNSPECV_LLWP_INTRINSIC)]
18256 (define_insn "*lwp_llwpcb<mode>1"
18257 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18258 UNSPECV_LLWP_INTRINSIC)]
18261 [(set_attr "type" "lwp")
18262 (set_attr "mode" "<MODE>")
18263 (set_attr "length" "5")])
18265 (define_expand "lwp_slwpcb"
18266 [(set (match_operand 0 "register_operand" "=r")
18267 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18272 insn = (Pmode == DImode
18274 : gen_lwp_slwpcbsi);
18276 emit_insn (insn (operands[0]));
18280 (define_insn "lwp_slwpcb<mode>"
18281 [(set (match_operand:P 0 "register_operand" "=r")
18282 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18285 [(set_attr "type" "lwp")
18286 (set_attr "mode" "<MODE>")
18287 (set_attr "length" "5")])
18289 (define_expand "lwp_lwpval<mode>3"
18290 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18291 (match_operand:SI 2 "nonimmediate_operand" "rm")
18292 (match_operand:SI 3 "const_int_operand" "i")]
18293 UNSPECV_LWPVAL_INTRINSIC)]
18295 ;; Avoid unused variable warning.
18296 "(void) operands[0];")
18298 (define_insn "*lwp_lwpval<mode>3_1"
18299 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18300 (match_operand:SI 1 "nonimmediate_operand" "rm")
18301 (match_operand:SI 2 "const_int_operand" "i")]
18302 UNSPECV_LWPVAL_INTRINSIC)]
18304 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18305 [(set_attr "type" "lwp")
18306 (set_attr "mode" "<MODE>")
18307 (set (attr "length")
18308 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18310 (define_expand "lwp_lwpins<mode>3"
18311 [(set (reg:CCC FLAGS_REG)
18312 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18313 (match_operand:SI 2 "nonimmediate_operand" "rm")
18314 (match_operand:SI 3 "const_int_operand" "i")]
18315 UNSPECV_LWPINS_INTRINSIC))
18316 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18317 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18320 (define_insn "*lwp_lwpins<mode>3_1"
18321 [(set (reg:CCC FLAGS_REG)
18322 (unspec_volatile:CCC [(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_LWPINS_INTRINSIC))]
18327 "lwpins\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_int_iterator RDFSGSBASE
18337 (define_int_iterator WRFSGSBASE
18341 (define_int_attr fsgs
18342 [(UNSPECV_RDFSBASE "fs")
18343 (UNSPECV_RDGSBASE "gs")
18344 (UNSPECV_WRFSBASE "fs")
18345 (UNSPECV_WRGSBASE "gs")])
18347 (define_insn "rd<fsgs>base<mode>"
18348 [(set (match_operand:SWI48 0 "register_operand" "=r")
18349 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18350 "TARGET_64BIT && TARGET_FSGSBASE"
18352 [(set_attr "type" "other")
18353 (set_attr "prefix_extra" "2")])
18355 (define_insn "wr<fsgs>base<mode>"
18356 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18358 "TARGET_64BIT && TARGET_FSGSBASE"
18360 [(set_attr "type" "other")
18361 (set_attr "prefix_extra" "2")])
18363 (define_insn "rdrand<mode>_1"
18364 [(set (match_operand:SWI248 0 "register_operand" "=r")
18365 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18366 (set (reg:CCC FLAGS_REG)
18367 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18370 [(set_attr "type" "other")
18371 (set_attr "prefix_extra" "1")])
18373 (define_insn "rdseed<mode>_1"
18374 [(set (match_operand:SWI248 0 "register_operand" "=r")
18375 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18376 (set (reg:CCC FLAGS_REG)
18377 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18380 [(set_attr "type" "other")
18381 (set_attr "prefix_extra" "1")])
18383 (define_expand "pause"
18384 [(set (match_dup 0)
18385 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18388 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18389 MEM_VOLATILE_P (operands[0]) = 1;
18392 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18393 ;; They have the same encoding.
18394 (define_insn "*pause"
18395 [(set (match_operand:BLK 0)
18396 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18399 [(set_attr "length" "2")
18400 (set_attr "memory" "unknown")])
18402 (define_expand "xbegin"
18403 [(set (match_operand:SI 0 "register_operand")
18404 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18407 rtx label = gen_label_rtx ();
18409 /* xbegin is emitted as jump_insn, so reload won't be able
18410 to reload its operand. Force the value into AX hard register. */
18411 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18412 emit_move_insn (ax_reg, constm1_rtx);
18414 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18416 emit_label (label);
18417 LABEL_NUSES (label) = 1;
18419 emit_move_insn (operands[0], ax_reg);
18424 (define_insn "xbegin_1"
18426 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18428 (label_ref (match_operand 1))
18430 (set (match_operand:SI 0 "register_operand" "+a")
18431 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18434 [(set_attr "type" "other")
18435 (set_attr "length" "6")])
18437 (define_insn "xend"
18438 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18441 [(set_attr "type" "other")
18442 (set_attr "length" "3")])
18444 (define_insn "xabort"
18445 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18449 [(set_attr "type" "other")
18450 (set_attr "length" "3")])
18452 (define_expand "xtest"
18453 [(set (match_operand:QI 0 "register_operand")
18454 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18457 emit_insn (gen_xtest_1 ());
18459 ix86_expand_setcc (operands[0], NE,
18460 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18464 (define_insn "xtest_1"
18465 [(set (reg:CCZ FLAGS_REG)
18466 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18469 [(set_attr "type" "other")
18470 (set_attr "length" "3")])
18474 (include "sync.md")