1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 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
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_MS_TO_SYSV_CALL
116 ;; For SSE/MMX support:
124 ;; Generic math support
126 UNSPEC_IEEE_MIN ; not commutative
127 UNSPEC_IEEE_MAX ; not commutative
129 ;; x87 Floating point
145 UNSPEC_FRNDINT_MASK_PM
149 ;; x87 Double output FP
194 (define_c_enum "unspecv" [
197 UNSPECV_PROBE_STACK_RANGE
200 UNSPECV_SPLIT_STACK_RETURN
206 UNSPECV_LLWP_INTRINSIC
207 UNSPECV_SLWP_INTRINSIC
208 UNSPECV_LWPVAL_INTRINSIC
209 UNSPECV_LWPINS_INTRINSIC
225 ;; For RDRAND support
228 ;; For RDSEED support
240 ;; Constants to represent rounding modes in the ROUND instruction
249 ;; Constants to represent pcomtrue/pcomfalse variants
259 ;; Constants used in the XOP pperm instruction
261 [(PPERM_SRC 0x00) /* copy source */
262 (PPERM_INVERT 0x20) /* invert source */
263 (PPERM_REVERSE 0x40) /* bit reverse source */
264 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
265 (PPERM_ZERO 0x80) /* all 0's */
266 (PPERM_ONES 0xa0) /* all 1's */
267 (PPERM_SIGN 0xc0) /* propagate sign bit */
268 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
269 (PPERM_SRC1 0x00) /* use first source byte */
270 (PPERM_SRC2 0x10) /* use second source byte */
273 ;; Registers by name.
354 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
357 ;; In C guard expressions, put expressions which may be compile-time
358 ;; constants first. This allows for better optimization. For
359 ;; example, write "TARGET_64BIT && reload_completed", not
360 ;; "reload_completed && TARGET_64BIT".
364 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
365 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
366 (const (symbol_ref "ix86_schedule")))
368 ;; A basic instruction type. Refinements due to arguments to be
369 ;; provided in other attributes.
372 alu,alu1,negnot,imov,imovx,lea,
373 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
374 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
375 push,pop,call,callv,leave,
377 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
378 fxch,fistp,fisttp,frndint,
379 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
380 ssemul,sseimul,ssediv,sselog,sselog1,
381 sseishft,sseishft1,ssecmp,ssecomi,
382 ssecvt,ssecvt1,sseicvt,sseins,
383 sseshuf,sseshuf1,ssemuladd,sse4arg,
385 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
386 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
387 (const_string "other"))
389 ;; Main data type used by the insn
391 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
393 (const_string "unknown"))
395 ;; The CPU unit operations uses.
396 (define_attr "unit" "integer,i387,sse,mmx,unknown"
397 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
398 fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
401 ssemul,sseimul,ssediv,sselog,sselog1,
402 sseishft,sseishft1,ssecmp,ssecomi,
403 ssecvt,ssecvt1,sseicvt,sseins,
404 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
406 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
408 (eq_attr "type" "other")
409 (const_string "unknown")]
410 (const_string "integer")))
412 ;; The (bounding maximum) length of an instruction immediate.
413 (define_attr "length_immediate" ""
414 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
418 (eq_attr "unit" "i387,sse,mmx")
420 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
421 rotate,rotatex,rotate1,imul,icmp,push,pop")
422 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
423 (eq_attr "type" "imov,test")
424 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
425 (eq_attr "type" "call")
426 (if_then_else (match_operand 0 "constant_call_address_operand")
429 (eq_attr "type" "callv")
430 (if_then_else (match_operand 1 "constant_call_address_operand")
433 ;; We don't know the size before shorten_branches. Expect
434 ;; the instruction to fit for better scheduling.
435 (eq_attr "type" "ibr")
438 (symbol_ref "/* Update immediate_length and other attributes! */
439 gcc_unreachable (),1")))
441 ;; The (bounding maximum) length of an instruction address.
442 (define_attr "length_address" ""
443 (cond [(eq_attr "type" "str,other,multi,fxch")
445 (and (eq_attr "type" "call")
446 (match_operand 0 "constant_call_address_operand"))
448 (and (eq_attr "type" "callv")
449 (match_operand 1 "constant_call_address_operand"))
452 (symbol_ref "ix86_attr_length_address_default (insn)")))
454 ;; Set when length prefix is used.
455 (define_attr "prefix_data16" ""
456 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
458 (eq_attr "mode" "HI")
460 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
465 ;; Set when string REP prefix is used.
466 (define_attr "prefix_rep" ""
467 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
471 (and (eq_attr "type" "ibr,call,callv")
472 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
477 ;; Set when 0f opcode prefix is used.
478 (define_attr "prefix_0f" ""
480 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
481 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
482 (eq_attr "unit" "sse,mmx"))
486 ;; Set when REX opcode prefix is used.
487 (define_attr "prefix_rex" ""
488 (cond [(not (match_test "TARGET_64BIT"))
490 (and (eq_attr "mode" "DI")
491 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
492 (eq_attr "unit" "!mmx")))
494 (and (eq_attr "mode" "QI")
495 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
497 (match_test "x86_extended_reg_mentioned_p (insn)")
499 (and (eq_attr "type" "imovx")
500 (match_operand:QI 1 "ext_QIreg_operand"))
505 ;; There are also additional prefixes in 3DNOW, SSSE3.
506 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
507 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
508 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
509 (define_attr "prefix_extra" ""
510 (cond [(eq_attr "type" "ssemuladd,sse4arg")
512 (eq_attr "type" "sseiadd1,ssecvt1")
517 ;; Prefix used: original, VEX or maybe VEX.
518 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
519 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
521 (eq_attr "mode" "XI,V16SF,V8DF")
522 (const_string "evex")
524 (const_string "orig")))
526 ;; VEX W bit is used.
527 (define_attr "prefix_vex_w" "" (const_int 0))
529 ;; The length of VEX prefix
530 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
531 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
532 ;; still prefix_0f 1, with prefix_extra 1.
533 (define_attr "length_vex" ""
534 (if_then_else (and (eq_attr "prefix_0f" "1")
535 (eq_attr "prefix_extra" "0"))
536 (if_then_else (eq_attr "prefix_vex_w" "1")
537 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
538 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
539 (if_then_else (eq_attr "prefix_vex_w" "1")
540 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
541 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
543 ;; 4-bytes evex prefix and 1 byte opcode.
544 (define_attr "length_evex" "" (const_int 5))
546 ;; Set when modrm byte is used.
547 (define_attr "modrm" ""
548 (cond [(eq_attr "type" "str,leave")
550 (eq_attr "unit" "i387")
552 (and (eq_attr "type" "incdec")
553 (and (not (match_test "TARGET_64BIT"))
554 (ior (match_operand:SI 1 "register_operand")
555 (match_operand:HI 1 "register_operand"))))
557 (and (eq_attr "type" "push")
558 (not (match_operand 1 "memory_operand")))
560 (and (eq_attr "type" "pop")
561 (not (match_operand 0 "memory_operand")))
563 (and (eq_attr "type" "imov")
564 (and (not (eq_attr "mode" "DI"))
565 (ior (and (match_operand 0 "register_operand")
566 (match_operand 1 "immediate_operand"))
567 (ior (and (match_operand 0 "ax_reg_operand")
568 (match_operand 1 "memory_displacement_only_operand"))
569 (and (match_operand 0 "memory_displacement_only_operand")
570 (match_operand 1 "ax_reg_operand"))))))
572 (and (eq_attr "type" "call")
573 (match_operand 0 "constant_call_address_operand"))
575 (and (eq_attr "type" "callv")
576 (match_operand 1 "constant_call_address_operand"))
578 (and (eq_attr "type" "alu,alu1,icmp,test")
579 (match_operand 0 "ax_reg_operand"))
580 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
584 ;; When this attribute is set, calculate total insn length from
585 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
586 (define_attr "length_nobnd" "" (const_int 0))
588 ;; The (bounding maximum) length of an instruction in bytes.
589 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
590 ;; Later we may want to split them and compute proper length as for
592 (define_attr "length" ""
593 (cond [(eq_attr "length_nobnd" "!0")
594 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
595 (attr "length_nobnd"))
596 (eq_attr "type" "other,multi,fistp,frndint")
598 (eq_attr "type" "fcmp")
600 (eq_attr "unit" "i387")
602 (plus (attr "prefix_data16")
603 (attr "length_address")))
604 (ior (eq_attr "prefix" "evex")
605 (and (ior (eq_attr "prefix" "maybe_evex")
606 (eq_attr "prefix" "maybe_vex"))
607 (match_test "TARGET_AVX512F")))
608 (plus (attr "length_evex")
609 (plus (attr "length_immediate")
611 (attr "length_address"))))
612 (ior (eq_attr "prefix" "vex")
613 (and (ior (eq_attr "prefix" "maybe_vex")
614 (eq_attr "prefix" "maybe_evex"))
615 (match_test "TARGET_AVX")))
616 (plus (attr "length_vex")
617 (plus (attr "length_immediate")
619 (attr "length_address"))))]
620 (plus (plus (attr "modrm")
621 (plus (attr "prefix_0f")
622 (plus (attr "prefix_rex")
623 (plus (attr "prefix_extra")
625 (plus (attr "prefix_rep")
626 (plus (attr "prefix_data16")
627 (plus (attr "length_immediate")
628 (attr "length_address")))))))
630 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
631 ;; `store' if there is a simple memory reference therein, or `unknown'
632 ;; if the instruction is complex.
634 (define_attr "memory" "none,load,store,both,unknown"
635 (cond [(eq_attr "type" "other,multi,str,lwp")
636 (const_string "unknown")
637 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
638 (const_string "none")
639 (eq_attr "type" "fistp,leave")
640 (const_string "both")
641 (eq_attr "type" "frndint")
642 (const_string "load")
643 (eq_attr "type" "mpxld")
644 (const_string "load")
645 (eq_attr "type" "mpxst")
646 (const_string "store")
647 (eq_attr "type" "push")
648 (if_then_else (match_operand 1 "memory_operand")
649 (const_string "both")
650 (const_string "store"))
651 (eq_attr "type" "pop")
652 (if_then_else (match_operand 0 "memory_operand")
653 (const_string "both")
654 (const_string "load"))
655 (eq_attr "type" "setcc")
656 (if_then_else (match_operand 0 "memory_operand")
657 (const_string "store")
658 (const_string "none"))
659 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
660 (if_then_else (ior (match_operand 0 "memory_operand")
661 (match_operand 1 "memory_operand"))
662 (const_string "load")
663 (const_string "none"))
664 (eq_attr "type" "ibr")
665 (if_then_else (match_operand 0 "memory_operand")
666 (const_string "load")
667 (const_string "none"))
668 (eq_attr "type" "call")
669 (if_then_else (match_operand 0 "constant_call_address_operand")
670 (const_string "none")
671 (const_string "load"))
672 (eq_attr "type" "callv")
673 (if_then_else (match_operand 1 "constant_call_address_operand")
674 (const_string "none")
675 (const_string "load"))
676 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
677 (match_operand 1 "memory_operand"))
678 (const_string "both")
679 (and (match_operand 0 "memory_operand")
680 (match_operand 1 "memory_operand"))
681 (const_string "both")
682 (match_operand 0 "memory_operand")
683 (const_string "store")
684 (match_operand 1 "memory_operand")
685 (const_string "load")
687 "!alu1,negnot,ishift1,
688 imov,imovx,icmp,test,bitmanip,
690 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
691 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
692 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
693 (match_operand 2 "memory_operand"))
694 (const_string "load")
695 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
696 (match_operand 3 "memory_operand"))
697 (const_string "load")
699 (const_string "none")))
701 ;; Indicates if an instruction has both an immediate and a displacement.
703 (define_attr "imm_disp" "false,true,unknown"
704 (cond [(eq_attr "type" "other,multi")
705 (const_string "unknown")
706 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
707 (and (match_operand 0 "memory_displacement_operand")
708 (match_operand 1 "immediate_operand")))
709 (const_string "true")
710 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
711 (and (match_operand 0 "memory_displacement_operand")
712 (match_operand 2 "immediate_operand")))
713 (const_string "true")
715 (const_string "false")))
717 ;; Indicates if an FP operation has an integer source.
719 (define_attr "fp_int_src" "false,true"
720 (const_string "false"))
722 ;; Defines rounding mode of an FP operation.
724 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
725 (const_string "any"))
727 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
728 (define_attr "use_carry" "0,1" (const_string "0"))
730 ;; Define attribute to indicate unaligned ssemov insns
731 (define_attr "movu" "0,1" (const_string "0"))
733 ;; Used to control the "enabled" attribute on a per-instruction basis.
734 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
735 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
736 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
737 (const_string "base"))
739 (define_attr "enabled" ""
740 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
741 (eq_attr "isa" "x64_sse4")
742 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
743 (eq_attr "isa" "x64_sse4_noavx")
744 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
745 (eq_attr "isa" "x64_avx")
746 (symbol_ref "TARGET_64BIT && TARGET_AVX")
747 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
748 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
749 (eq_attr "isa" "sse2_noavx")
750 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
751 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
752 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
753 (eq_attr "isa" "sse4_noavx")
754 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
755 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
756 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
757 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
758 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
759 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
760 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
761 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
762 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
763 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
764 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
765 (eq_attr "isa" "fma_avx512f")
766 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
770 ;; Describe a user's asm statement.
771 (define_asm_attributes
772 [(set_attr "length" "128")
773 (set_attr "type" "multi")])
775 (define_code_iterator plusminus [plus minus])
777 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
779 (define_code_iterator multdiv [mult div])
781 ;; Base name for define_insn
782 (define_code_attr plusminus_insn
783 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
784 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
786 ;; Base name for insn mnemonic.
787 (define_code_attr plusminus_mnemonic
788 [(plus "add") (ss_plus "adds") (us_plus "addus")
789 (minus "sub") (ss_minus "subs") (us_minus "subus")])
790 (define_code_attr plusminus_carry_mnemonic
791 [(plus "adc") (minus "sbb")])
792 (define_code_attr multdiv_mnemonic
793 [(mult "mul") (div "div")])
795 ;; Mark commutative operators as such in constraints.
796 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
797 (minus "") (ss_minus "") (us_minus "")])
799 ;; Mapping of max and min
800 (define_code_iterator maxmin [smax smin umax umin])
802 ;; Mapping of signed max and min
803 (define_code_iterator smaxmin [smax smin])
805 ;; Mapping of unsigned max and min
806 (define_code_iterator umaxmin [umax umin])
808 ;; Base name for integer and FP insn mnemonic
809 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
810 (umax "maxu") (umin "minu")])
811 (define_code_attr maxmin_float [(smax "max") (smin "min")])
813 ;; Mapping of logic operators
814 (define_code_iterator any_logic [and ior xor])
815 (define_code_iterator any_or [ior xor])
816 (define_code_iterator fpint_logic [and xor])
818 ;; Base name for insn mnemonic.
819 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
821 ;; Mapping of logic-shift operators
822 (define_code_iterator any_lshift [ashift lshiftrt])
824 ;; Mapping of shift-right operators
825 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
827 ;; Mapping of all shift operators
828 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
830 ;; Base name for define_insn
831 (define_code_attr shift_insn
832 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
834 ;; Base name for insn mnemonic.
835 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
836 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
838 ;; Mapping of rotate operators
839 (define_code_iterator any_rotate [rotate rotatert])
841 ;; Base name for define_insn
842 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
844 ;; Base name for insn mnemonic.
845 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
847 ;; Mapping of abs neg operators
848 (define_code_iterator absneg [abs neg])
850 ;; Base name for x87 insn mnemonic.
851 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
853 ;; Used in signed and unsigned widening multiplications.
854 (define_code_iterator any_extend [sign_extend zero_extend])
856 ;; Prefix for insn menmonic.
857 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
859 ;; Prefix for define_insn
860 (define_code_attr u [(sign_extend "") (zero_extend "u")])
861 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
862 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
864 ;; Used in signed and unsigned truncations.
865 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
866 ;; Instruction suffix for truncations.
867 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
869 ;; Used in signed and unsigned fix.
870 (define_code_iterator any_fix [fix unsigned_fix])
871 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
873 ;; All integer modes.
874 (define_mode_iterator SWI1248x [QI HI SI DI])
876 ;; All integer modes without QImode.
877 (define_mode_iterator SWI248x [HI SI DI])
879 ;; All integer modes without QImode and HImode.
880 (define_mode_iterator SWI48x [SI DI])
882 ;; All integer modes without SImode and DImode.
883 (define_mode_iterator SWI12 [QI HI])
885 ;; All integer modes without DImode.
886 (define_mode_iterator SWI124 [QI HI SI])
888 ;; All integer modes without QImode and DImode.
889 (define_mode_iterator SWI24 [HI SI])
891 ;; Single word integer modes.
892 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
894 ;; Single word integer modes without QImode.
895 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
897 ;; Single word integer modes without QImode and HImode.
898 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
900 ;; All math-dependant single and double word integer modes.
901 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
902 (HI "TARGET_HIMODE_MATH")
903 SI DI (TI "TARGET_64BIT")])
905 ;; Math-dependant single word integer modes.
906 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
907 (HI "TARGET_HIMODE_MATH")
908 SI (DI "TARGET_64BIT")])
910 ;; Math-dependant integer modes without DImode.
911 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
912 (HI "TARGET_HIMODE_MATH")
915 ;; Math-dependant single word integer modes without QImode.
916 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
917 SI (DI "TARGET_64BIT")])
919 ;; Double word integer modes.
920 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
921 (TI "TARGET_64BIT")])
923 ;; Double word integer modes as mode attribute.
924 (define_mode_attr DWI [(SI "DI") (DI "TI")])
925 (define_mode_attr dwi [(SI "di") (DI "ti")])
927 ;; Half mode for double word integer modes.
928 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
929 (DI "TARGET_64BIT")])
932 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
933 (BND64 "TARGET_LP64")])
935 ;; Pointer mode corresponding to bound mode.
936 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
939 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
942 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
944 (UNSPEC_BNDCN "cn")])
946 ;; Instruction suffix for integer modes.
947 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
949 ;; Pointer size prefix for integer modes (Intel asm dialect)
950 (define_mode_attr iptrsize [(QI "BYTE")
955 ;; Register class for integer modes.
956 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
958 ;; Immediate operand constraint for integer modes.
959 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
961 ;; General operand constraint for word modes.
962 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
964 ;; Immediate operand constraint for double integer modes.
965 (define_mode_attr di [(SI "nF") (DI "e")])
967 ;; Immediate operand constraint for shifts.
968 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
970 ;; General operand predicate for integer modes.
971 (define_mode_attr general_operand
972 [(QI "general_operand")
973 (HI "general_operand")
974 (SI "x86_64_general_operand")
975 (DI "x86_64_general_operand")
976 (TI "x86_64_general_operand")])
978 ;; General sign/zero extend operand predicate for integer modes.
979 (define_mode_attr general_szext_operand
980 [(QI "general_operand")
981 (HI "general_operand")
982 (SI "x86_64_szext_general_operand")
983 (DI "x86_64_szext_general_operand")])
985 ;; Immediate operand predicate for integer modes.
986 (define_mode_attr immediate_operand
987 [(QI "immediate_operand")
988 (HI "immediate_operand")
989 (SI "x86_64_immediate_operand")
990 (DI "x86_64_immediate_operand")])
992 ;; Nonmemory operand predicate for integer modes.
993 (define_mode_attr nonmemory_operand
994 [(QI "nonmemory_operand")
995 (HI "nonmemory_operand")
996 (SI "x86_64_nonmemory_operand")
997 (DI "x86_64_nonmemory_operand")])
999 ;; Operand predicate for shifts.
1000 (define_mode_attr shift_operand
1001 [(QI "nonimmediate_operand")
1002 (HI "nonimmediate_operand")
1003 (SI "nonimmediate_operand")
1004 (DI "shiftdi_operand")
1005 (TI "register_operand")])
1007 ;; Operand predicate for shift argument.
1008 (define_mode_attr shift_immediate_operand
1009 [(QI "const_1_to_31_operand")
1010 (HI "const_1_to_31_operand")
1011 (SI "const_1_to_31_operand")
1012 (DI "const_1_to_63_operand")])
1014 ;; Input operand predicate for arithmetic left shifts.
1015 (define_mode_attr ashl_input_operand
1016 [(QI "nonimmediate_operand")
1017 (HI "nonimmediate_operand")
1018 (SI "nonimmediate_operand")
1019 (DI "ashldi_input_operand")
1020 (TI "reg_or_pm1_operand")])
1022 ;; SSE and x87 SFmode and DFmode floating point modes
1023 (define_mode_iterator MODEF [SF DF])
1025 ;; All x87 floating point modes
1026 (define_mode_iterator X87MODEF [SF DF XF])
1028 ;; SSE instruction suffix for various modes
1029 (define_mode_attr ssemodesuffix
1030 [(SF "ss") (DF "sd")
1031 (V16SF "ps") (V8DF "pd")
1032 (V8SF "ps") (V4DF "pd")
1033 (V4SF "ps") (V2DF "pd")
1034 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1035 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1036 (V64QI "b") (V16SI "d") (V8DI "q")])
1038 ;; SSE vector suffix for floating point modes
1039 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1041 ;; SSE vector mode corresponding to a scalar mode
1042 (define_mode_attr ssevecmode
1043 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1044 (define_mode_attr ssevecmodelower
1045 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1047 ;; Instruction suffix for REX 64bit operators.
1048 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1050 ;; This mode iterator allows :P to be used for patterns that operate on
1051 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1052 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1054 ;; This mode iterator allows :W to be used for patterns that operate on
1055 ;; word_mode sized quantities.
1056 (define_mode_iterator W
1057 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1059 ;; This mode iterator allows :PTR to be used for patterns that operate on
1060 ;; ptr_mode sized quantities.
1061 (define_mode_iterator PTR
1062 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1064 ;; Scheduling descriptions
1066 (include "pentium.md")
1069 (include "athlon.md")
1070 (include "bdver1.md")
1071 (include "bdver3.md")
1072 (include "btver2.md")
1073 (include "geode.md")
1076 (include "core2.md")
1079 ;; Operand and operator predicates and constraints
1081 (include "predicates.md")
1082 (include "constraints.md")
1085 ;; Compare and branch/compare and store instructions.
1087 (define_expand "cbranch<mode>4"
1088 [(set (reg:CC FLAGS_REG)
1089 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1090 (match_operand:SDWIM 2 "<general_operand>")))
1091 (set (pc) (if_then_else
1092 (match_operator 0 "ordered_comparison_operator"
1093 [(reg:CC FLAGS_REG) (const_int 0)])
1094 (label_ref (match_operand 3))
1098 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1099 operands[1] = force_reg (<MODE>mode, operands[1]);
1100 ix86_expand_branch (GET_CODE (operands[0]),
1101 operands[1], operands[2], operands[3]);
1105 (define_expand "cstore<mode>4"
1106 [(set (reg:CC FLAGS_REG)
1107 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1108 (match_operand:SWIM 3 "<general_operand>")))
1109 (set (match_operand:QI 0 "register_operand")
1110 (match_operator 1 "ordered_comparison_operator"
1111 [(reg:CC FLAGS_REG) (const_int 0)]))]
1114 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1115 operands[2] = force_reg (<MODE>mode, operands[2]);
1116 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1117 operands[2], operands[3]);
1121 (define_expand "cmp<mode>_1"
1122 [(set (reg:CC FLAGS_REG)
1123 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1124 (match_operand:SWI48 1 "<general_operand>")))])
1126 (define_insn "*cmp<mode>_ccno_1"
1127 [(set (reg FLAGS_REG)
1128 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1129 (match_operand:SWI 1 "const0_operand")))]
1130 "ix86_match_ccmode (insn, CCNOmode)"
1132 test{<imodesuffix>}\t%0, %0
1133 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1134 [(set_attr "type" "test,icmp")
1135 (set_attr "length_immediate" "0,1")
1136 (set_attr "mode" "<MODE>")])
1138 (define_insn "*cmp<mode>_1"
1139 [(set (reg FLAGS_REG)
1140 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1141 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "<MODE>")])
1147 (define_insn "*cmp<mode>_minus_1"
1148 [(set (reg FLAGS_REG)
1150 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1151 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1153 "ix86_match_ccmode (insn, CCGOCmode)"
1154 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1155 [(set_attr "type" "icmp")
1156 (set_attr "mode" "<MODE>")])
1158 (define_insn "*cmpqi_ext_1"
1159 [(set (reg FLAGS_REG)
1161 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1164 (match_operand 1 "ext_register_operand" "Q,Q")
1166 (const_int 8)) 0)))]
1167 "ix86_match_ccmode (insn, CCmode)"
1168 "cmp{b}\t{%h1, %0|%0, %h1}"
1169 [(set_attr "isa" "*,nox64")
1170 (set_attr "type" "icmp")
1171 (set_attr "mode" "QI")])
1173 (define_insn "*cmpqi_ext_2"
1174 [(set (reg FLAGS_REG)
1178 (match_operand 0 "ext_register_operand" "Q")
1181 (match_operand:QI 1 "const0_operand")))]
1182 "ix86_match_ccmode (insn, CCNOmode)"
1184 [(set_attr "type" "test")
1185 (set_attr "length_immediate" "0")
1186 (set_attr "mode" "QI")])
1188 (define_expand "cmpqi_ext_3"
1189 [(set (reg:CC FLAGS_REG)
1193 (match_operand 0 "ext_register_operand")
1196 (match_operand:QI 1 "const_int_operand")))])
1198 (define_insn "*cmpqi_ext_3"
1199 [(set (reg FLAGS_REG)
1203 (match_operand 0 "ext_register_operand" "Q,Q")
1206 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1207 "ix86_match_ccmode (insn, CCmode)"
1208 "cmp{b}\t{%1, %h0|%h0, %1}"
1209 [(set_attr "isa" "*,nox64")
1210 (set_attr "type" "icmp")
1211 (set_attr "modrm" "1")
1212 (set_attr "mode" "QI")])
1214 (define_insn "*cmpqi_ext_4"
1215 [(set (reg FLAGS_REG)
1219 (match_operand 0 "ext_register_operand" "Q")
1224 (match_operand 1 "ext_register_operand" "Q")
1226 (const_int 8)) 0)))]
1227 "ix86_match_ccmode (insn, CCmode)"
1228 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1229 [(set_attr "type" "icmp")
1230 (set_attr "mode" "QI")])
1232 ;; These implement float point compares.
1233 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1234 ;; which would allow mix and match FP modes on the compares. Which is what
1235 ;; the old patterns did, but with many more of them.
1237 (define_expand "cbranchxf4"
1238 [(set (reg:CC FLAGS_REG)
1239 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1240 (match_operand:XF 2 "nonmemory_operand")))
1241 (set (pc) (if_then_else
1242 (match_operator 0 "ix86_fp_comparison_operator"
1245 (label_ref (match_operand 3))
1249 ix86_expand_branch (GET_CODE (operands[0]),
1250 operands[1], operands[2], operands[3]);
1254 (define_expand "cstorexf4"
1255 [(set (reg:CC FLAGS_REG)
1256 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1257 (match_operand:XF 3 "nonmemory_operand")))
1258 (set (match_operand:QI 0 "register_operand")
1259 (match_operator 1 "ix86_fp_comparison_operator"
1264 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1265 operands[2], operands[3]);
1269 (define_expand "cbranch<mode>4"
1270 [(set (reg:CC FLAGS_REG)
1271 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1272 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1273 (set (pc) (if_then_else
1274 (match_operator 0 "ix86_fp_comparison_operator"
1277 (label_ref (match_operand 3))
1279 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1281 ix86_expand_branch (GET_CODE (operands[0]),
1282 operands[1], operands[2], operands[3]);
1286 (define_expand "cstore<mode>4"
1287 [(set (reg:CC FLAGS_REG)
1288 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1289 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1290 (set (match_operand:QI 0 "register_operand")
1291 (match_operator 1 "ix86_fp_comparison_operator"
1294 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1296 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1297 operands[2], operands[3]);
1301 (define_expand "cbranchcc4"
1302 [(set (pc) (if_then_else
1303 (match_operator 0 "comparison_operator"
1304 [(match_operand 1 "flags_reg_operand")
1305 (match_operand 2 "const0_operand")])
1306 (label_ref (match_operand 3))
1310 ix86_expand_branch (GET_CODE (operands[0]),
1311 operands[1], operands[2], operands[3]);
1315 (define_expand "cstorecc4"
1316 [(set (match_operand:QI 0 "register_operand")
1317 (match_operator 1 "comparison_operator"
1318 [(match_operand 2 "flags_reg_operand")
1319 (match_operand 3 "const0_operand")]))]
1322 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1323 operands[2], operands[3]);
1328 ;; FP compares, step 1:
1329 ;; Set the FP condition codes.
1331 ;; CCFPmode compare with exceptions
1332 ;; CCFPUmode compare with no exceptions
1334 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1335 ;; used to manage the reg stack popping would not be preserved.
1337 (define_insn "*cmp<mode>_0_i387"
1338 [(set (match_operand:HI 0 "register_operand" "=a")
1341 (match_operand:X87MODEF 1 "register_operand" "f")
1342 (match_operand:X87MODEF 2 "const0_operand"))]
1345 "* return output_fp_compare (insn, operands, false, false);"
1346 [(set_attr "type" "multi")
1347 (set_attr "unit" "i387")
1348 (set_attr "mode" "<MODE>")])
1350 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1351 [(set (reg:CCFP FLAGS_REG)
1353 (match_operand:X87MODEF 1 "register_operand" "f")
1354 (match_operand:X87MODEF 2 "const0_operand")))
1355 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1356 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1358 "&& reload_completed"
1361 [(compare:CCFP (match_dup 1)(match_dup 2))]
1363 (set (reg:CC FLAGS_REG)
1364 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1368 (set_attr "mode" "<MODE>")])
1370 (define_insn "*cmpxf_i387"
1371 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (match_operand:XF 1 "register_operand" "f")
1375 (match_operand:XF 2 "register_operand" "f"))]
1378 "* return output_fp_compare (insn, operands, false, false);"
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set_attr "mode" "XF")])
1383 (define_insn_and_split "*cmpxf_cc_i387"
1384 [(set (reg:CCFP FLAGS_REG)
1386 (match_operand:XF 1 "register_operand" "f")
1387 (match_operand:XF 2 "register_operand" "f")))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1391 "&& reload_completed"
1394 [(compare:CCFP (match_dup 1)(match_dup 2))]
1396 (set (reg:CC FLAGS_REG)
1397 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "mode" "XF")])
1403 (define_insn "*cmp<mode>_i387"
1404 [(set (match_operand:HI 0 "register_operand" "=a")
1407 (match_operand:MODEF 1 "register_operand" "f")
1408 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1411 "* return output_fp_compare (insn, operands, false, false);"
1412 [(set_attr "type" "multi")
1413 (set_attr "unit" "i387")
1414 (set_attr "mode" "<MODE>")])
1416 (define_insn_and_split "*cmp<mode>_cc_i387"
1417 [(set (reg:CCFP FLAGS_REG)
1419 (match_operand:MODEF 1 "register_operand" "f")
1420 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1421 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1422 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1424 "&& reload_completed"
1427 [(compare:CCFP (match_dup 1)(match_dup 2))]
1429 (set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "mode" "<MODE>")])
1436 (define_insn "*cmpu<mode>_i387"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1440 (match_operand:X87MODEF 1 "register_operand" "f")
1441 (match_operand:X87MODEF 2 "register_operand" "f"))]
1444 "* return output_fp_compare (insn, operands, false, true);"
1445 [(set_attr "type" "multi")
1446 (set_attr "unit" "i387")
1447 (set_attr "mode" "<MODE>")])
1449 (define_insn_and_split "*cmpu<mode>_cc_i387"
1450 [(set (reg:CCFPU FLAGS_REG)
1452 (match_operand:X87MODEF 1 "register_operand" "f")
1453 (match_operand:X87MODEF 2 "register_operand" "f")))
1454 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1455 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1457 "&& reload_completed"
1460 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1462 (set (reg:CC FLAGS_REG)
1463 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1465 [(set_attr "type" "multi")
1466 (set_attr "unit" "i387")
1467 (set_attr "mode" "<MODE>")])
1469 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1470 [(set (match_operand:HI 0 "register_operand" "=a")
1473 (match_operand:X87MODEF 1 "register_operand" "f")
1474 (match_operator:X87MODEF 3 "float_operator"
1475 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1478 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1479 || optimize_function_for_size_p (cfun))"
1480 "* return output_fp_compare (insn, operands, false, false);"
1481 [(set_attr "type" "multi")
1482 (set_attr "unit" "i387")
1483 (set_attr "fp_int_src" "true")
1484 (set_attr "mode" "<SWI24:MODE>")])
1486 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1487 [(set (reg:CCFP FLAGS_REG)
1489 (match_operand:X87MODEF 1 "register_operand" "f")
1490 (match_operator:X87MODEF 3 "float_operator"
1491 [(match_operand:SWI24 2 "memory_operand" "m")])))
1492 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1493 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1494 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1495 || optimize_function_for_size_p (cfun))"
1497 "&& reload_completed"
1502 (match_op_dup 3 [(match_dup 2)]))]
1504 (set (reg:CC FLAGS_REG)
1505 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1507 [(set_attr "type" "multi")
1508 (set_attr "unit" "i387")
1509 (set_attr "fp_int_src" "true")
1510 (set_attr "mode" "<SWI24:MODE>")])
1512 ;; FP compares, step 2
1513 ;; Move the fpsw to ax.
1515 (define_insn "x86_fnstsw_1"
1516 [(set (match_operand:HI 0 "register_operand" "=a")
1517 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1520 [(set (attr "length")
1521 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1522 (set_attr "mode" "SI")
1523 (set_attr "unit" "i387")])
1525 ;; FP compares, step 3
1526 ;; Get ax into flags, general case.
1528 (define_insn "x86_sahf_1"
1529 [(set (reg:CC FLAGS_REG)
1530 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1534 #ifndef HAVE_AS_IX86_SAHF
1536 return ASM_BYTE "0x9e";
1541 [(set_attr "length" "1")
1542 (set_attr "athlon_decode" "vector")
1543 (set_attr "amdfam10_decode" "direct")
1544 (set_attr "bdver1_decode" "direct")
1545 (set_attr "mode" "SI")])
1547 ;; Pentium Pro can do steps 1 through 3 in one go.
1548 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1549 ;; (these i387 instructions set flags directly)
1551 (define_mode_iterator FPCMP [CCFP CCFPU])
1552 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1554 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1555 [(set (reg:FPCMP FLAGS_REG)
1557 (match_operand:MODEF 0 "register_operand" "f,x")
1558 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1559 "TARGET_MIX_SSE_I387
1560 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1561 "* return output_fp_compare (insn, operands, true,
1562 <FPCMP:MODE>mode == CCFPUmode);"
1563 [(set_attr "type" "fcmp,ssecomi")
1564 (set_attr "prefix" "orig,maybe_vex")
1565 (set_attr "mode" "<MODEF:MODE>")
1566 (set (attr "prefix_rep")
1567 (if_then_else (eq_attr "type" "ssecomi")
1569 (const_string "*")))
1570 (set (attr "prefix_data16")
1571 (cond [(eq_attr "type" "fcmp")
1573 (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><MODEF:mode>_sse"
1582 [(set (reg:FPCMP FLAGS_REG)
1584 (match_operand:MODEF 0 "register_operand" "x")
1585 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1587 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1588 "* return output_fp_compare (insn, operands, true,
1589 <FPCMP:MODE>mode == CCFPUmode);"
1590 [(set_attr "type" "ssecomi")
1591 (set_attr "prefix" "maybe_vex")
1592 (set_attr "mode" "<MODEF:MODE>")
1593 (set_attr "prefix_rep" "0")
1594 (set (attr "prefix_data16")
1595 (if_then_else (eq_attr "mode" "DF")
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1602 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1603 [(set (reg:FPCMP FLAGS_REG)
1605 (match_operand:X87MODEF 0 "register_operand" "f")
1606 (match_operand:X87MODEF 1 "register_operand" "f")))]
1607 "TARGET_80387 && TARGET_CMOVE
1608 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1609 "* return output_fp_compare (insn, operands, true,
1610 <FPCMP:MODE>mode == CCFPUmode);"
1611 [(set_attr "type" "fcmp")
1612 (set_attr "mode" "<X87MODEF:MODE>")
1613 (set_attr "athlon_decode" "vector")
1614 (set_attr "amdfam10_decode" "direct")
1615 (set_attr "bdver1_decode" "double")])
1617 ;; Push/pop instructions.
1619 (define_insn "*push<mode>2"
1620 [(set (match_operand:DWI 0 "push_operand" "=<")
1621 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1624 [(set_attr "type" "multi")
1625 (set_attr "mode" "<MODE>")])
1628 [(set (match_operand:TI 0 "push_operand")
1629 (match_operand:TI 1 "general_operand"))]
1630 "TARGET_64BIT && reload_completed
1631 && !SSE_REG_P (operands[1])"
1633 "ix86_split_long_move (operands); DONE;")
1635 (define_insn "*pushdi2_rex64"
1636 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1637 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1642 [(set_attr "type" "push,multi")
1643 (set_attr "mode" "DI")])
1645 ;; Convert impossible pushes of immediate to existing instructions.
1646 ;; First try to get scratch register and go through it. In case this
1647 ;; fails, push sign extended lower part first and then overwrite
1648 ;; upper part by 32bit move.
1650 [(match_scratch:DI 2 "r")
1651 (set (match_operand:DI 0 "push_operand")
1652 (match_operand:DI 1 "immediate_operand"))]
1653 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 2) (match_dup 1))
1656 (set (match_dup 0) (match_dup 2))])
1658 ;; We need to define this as both peepholer and splitter for case
1659 ;; peephole2 pass is not run.
1660 ;; "&& 1" is needed to keep it from matching the previous pattern.
1662 [(set (match_operand:DI 0 "push_operand")
1663 (match_operand:DI 1 "immediate_operand"))]
1664 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1665 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1666 [(set (match_dup 0) (match_dup 1))
1667 (set (match_dup 2) (match_dup 3))]
1669 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1671 operands[1] = gen_lowpart (DImode, operands[2]);
1672 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1677 [(set (match_operand:DI 0 "push_operand")
1678 (match_operand:DI 1 "immediate_operand"))]
1679 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1680 ? epilogue_completed : reload_completed)
1681 && !symbolic_operand (operands[1], DImode)
1682 && !x86_64_immediate_operand (operands[1], DImode)"
1683 [(set (match_dup 0) (match_dup 1))
1684 (set (match_dup 2) (match_dup 3))]
1686 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1688 operands[1] = gen_lowpart (DImode, operands[2]);
1689 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1694 [(set (match_operand:DI 0 "push_operand")
1695 (match_operand:DI 1 "general_operand"))]
1696 "!TARGET_64BIT && reload_completed
1697 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1699 "ix86_split_long_move (operands); DONE;")
1701 (define_insn "*pushsi2"
1702 [(set (match_operand:SI 0 "push_operand" "=<")
1703 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1709 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1710 ;; "push a byte/word". But actually we use pushl, which has the effect
1711 ;; of rounding the amount pushed up to a word.
1713 ;; For TARGET_64BIT we always round up to 8 bytes.
1714 (define_insn "*push<mode>2_rex64"
1715 [(set (match_operand:SWI124 0 "push_operand" "=X")
1716 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1719 [(set_attr "type" "push")
1720 (set_attr "mode" "DI")])
1722 (define_insn "*push<mode>2"
1723 [(set (match_operand:SWI12 0 "push_operand" "=X")
1724 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1727 [(set_attr "type" "push")
1728 (set_attr "mode" "SI")])
1730 (define_insn "*push<mode>2_prologue"
1731 [(set (match_operand:W 0 "push_operand" "=<")
1732 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1733 (clobber (mem:BLK (scratch)))]
1735 "push{<imodesuffix>}\t%1"
1736 [(set_attr "type" "push")
1737 (set_attr "mode" "<MODE>")])
1739 (define_insn "*pop<mode>1"
1740 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1741 (match_operand:W 1 "pop_operand" ">"))]
1743 "pop{<imodesuffix>}\t%0"
1744 [(set_attr "type" "pop")
1745 (set_attr "mode" "<MODE>")])
1747 (define_insn "*pop<mode>1_epilogue"
1748 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1749 (match_operand:W 1 "pop_operand" ">"))
1750 (clobber (mem:BLK (scratch)))]
1752 "pop{<imodesuffix>}\t%0"
1753 [(set_attr "type" "pop")
1754 (set_attr "mode" "<MODE>")])
1756 ;; Move instructions.
1758 (define_expand "movxi"
1759 [(set (match_operand:XI 0 "nonimmediate_operand")
1760 (match_operand:XI 1 "general_operand"))]
1762 "ix86_expand_move (XImode, operands); DONE;")
1764 ;; Reload patterns to support multi-word load/store
1765 ;; with non-offsetable address.
1766 (define_expand "reload_noff_store"
1767 [(parallel [(match_operand 0 "memory_operand" "=m")
1768 (match_operand 1 "register_operand" "r")
1769 (match_operand:DI 2 "register_operand" "=&r")])]
1772 rtx mem = operands[0];
1773 rtx addr = XEXP (mem, 0);
1775 emit_move_insn (operands[2], addr);
1776 mem = replace_equiv_address_nv (mem, operands[2]);
1778 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1782 (define_expand "reload_noff_load"
1783 [(parallel [(match_operand 0 "register_operand" "=r")
1784 (match_operand 1 "memory_operand" "m")
1785 (match_operand:DI 2 "register_operand" "=r")])]
1788 rtx mem = operands[1];
1789 rtx addr = XEXP (mem, 0);
1791 emit_move_insn (operands[2], addr);
1792 mem = replace_equiv_address_nv (mem, operands[2]);
1794 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1798 (define_expand "movoi"
1799 [(set (match_operand:OI 0 "nonimmediate_operand")
1800 (match_operand:OI 1 "general_operand"))]
1802 "ix86_expand_move (OImode, operands); DONE;")
1804 (define_expand "movti"
1805 [(set (match_operand:TI 0 "nonimmediate_operand")
1806 (match_operand:TI 1 "nonimmediate_operand"))]
1807 "TARGET_64BIT || TARGET_SSE"
1810 ix86_expand_move (TImode, operands);
1811 else if (push_operand (operands[0], TImode))
1812 ix86_expand_push (TImode, operands[1]);
1814 ix86_expand_vector_move (TImode, operands);
1818 ;; This expands to what emit_move_complex would generate if we didn't
1819 ;; have a movti pattern. Having this avoids problems with reload on
1820 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1821 ;; to have around all the time.
1822 (define_expand "movcdi"
1823 [(set (match_operand:CDI 0 "nonimmediate_operand")
1824 (match_operand:CDI 1 "general_operand"))]
1827 if (push_operand (operands[0], CDImode))
1828 emit_move_complex_push (CDImode, operands[0], operands[1]);
1830 emit_move_complex_parts (operands[0], operands[1]);
1834 (define_expand "mov<mode>"
1835 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1836 (match_operand:SWI1248x 1 "general_operand"))]
1838 "ix86_expand_move (<MODE>mode, operands); DONE;")
1840 (define_insn "*mov<mode>_xor"
1841 [(set (match_operand:SWI48 0 "register_operand" "=r")
1842 (match_operand:SWI48 1 "const0_operand"))
1843 (clobber (reg:CC FLAGS_REG))]
1846 [(set_attr "type" "alu1")
1847 (set_attr "mode" "SI")
1848 (set_attr "length_immediate" "0")])
1850 (define_insn "*mov<mode>_or"
1851 [(set (match_operand:SWI48 0 "register_operand" "=r")
1852 (match_operand:SWI48 1 "const_int_operand"))
1853 (clobber (reg:CC FLAGS_REG))]
1855 && operands[1] == constm1_rtx"
1856 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1857 [(set_attr "type" "alu1")
1858 (set_attr "mode" "<MODE>")
1859 (set_attr "length_immediate" "1")])
1861 (define_insn "*movxi_internal_avx512f"
1862 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1863 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1864 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1866 switch (which_alternative)
1869 return standard_sse_constant_opcode (insn, operands[1]);
1872 if (misaligned_operand (operands[0], XImode)
1873 || misaligned_operand (operands[1], XImode))
1874 return "vmovdqu32\t{%1, %0|%0, %1}";
1876 return "vmovdqa32\t{%1, %0|%0, %1}";
1881 [(set_attr "type" "sselog1,ssemov,ssemov")
1882 (set_attr "prefix" "evex")
1883 (set_attr "mode" "XI")])
1885 (define_insn "*movoi_internal_avx"
1886 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1887 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1888 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1890 switch (get_attr_type (insn))
1893 return standard_sse_constant_opcode (insn, operands[1]);
1896 if (misaligned_operand (operands[0], OImode)
1897 || misaligned_operand (operands[1], OImode))
1899 if (get_attr_mode (insn) == MODE_V8SF)
1900 return "vmovups\t{%1, %0|%0, %1}";
1902 return "vmovdqu\t{%1, %0|%0, %1}";
1906 if (get_attr_mode (insn) == MODE_V8SF)
1907 return "vmovaps\t{%1, %0|%0, %1}";
1909 return "vmovdqa\t{%1, %0|%0, %1}";
1916 [(set_attr "type" "sselog1,ssemov,ssemov")
1917 (set_attr "prefix" "vex")
1919 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1920 (const_string "V8SF")
1921 (and (eq_attr "alternative" "2")
1922 (match_test "TARGET_SSE_TYPELESS_STORES"))
1923 (const_string "V8SF")
1925 (const_string "OI")))])
1927 (define_insn "*movti_internal"
1928 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1929 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1930 "(TARGET_64BIT || TARGET_SSE)
1931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1933 switch (get_attr_type (insn))
1939 return standard_sse_constant_opcode (insn, operands[1]);
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1964 [(set_attr "isa" "x64,x64,*,*,*")
1965 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1966 (set (attr "prefix")
1967 (if_then_else (eq_attr "type" "sselog1,ssemov")
1968 (const_string "maybe_vex")
1969 (const_string "orig")))
1971 (cond [(eq_attr "alternative" "0,1")
1973 (ior (not (match_test "TARGET_SSE2"))
1974 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1975 (const_string "V4SF")
1976 (and (eq_attr "alternative" "4")
1977 (match_test "TARGET_SSE_TYPELESS_STORES"))
1978 (const_string "V4SF")
1979 (match_test "TARGET_AVX")
1981 (match_test "optimize_function_for_size_p (cfun)")
1982 (const_string "V4SF")
1984 (const_string "TI")))])
1987 [(set (match_operand:TI 0 "nonimmediate_operand")
1988 (match_operand:TI 1 "general_operand"))]
1990 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1992 "ix86_split_long_move (operands); DONE;")
1994 (define_insn "*movdi_internal"
1995 [(set (match_operand:DI 0 "nonimmediate_operand"
1996 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1997 (match_operand:DI 1 "general_operand"
1998 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1999 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001 switch (get_attr_type (insn))
2007 return "pxor\t%0, %0";
2010 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2011 /* Handle broken assemblers that require movd instead of movq. */
2012 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013 return "movd\t{%1, %0|%0, %1}";
2015 return "movq\t{%1, %0|%0, %1}";
2018 if (GENERAL_REG_P (operands[0]))
2019 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2021 return standard_sse_constant_opcode (insn, operands[1]);
2024 switch (get_attr_mode (insn))
2027 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2028 /* Handle broken assemblers that require movd instead of movq. */
2029 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2030 return "%vmovd\t{%1, %0|%0, %1}";
2032 return "%vmovq\t{%1, %0|%0, %1}";
2034 return "%vmovdqa\t{%1, %0|%0, %1}";
2036 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2039 gcc_assert (!TARGET_AVX);
2040 return "movlps\t{%1, %0|%0, %1}";
2042 return "%vmovaps\t{%1, %0|%0, %1}";
2049 if (SSE_REG_P (operands[0]))
2050 return "movq2dq\t{%1, %0|%0, %1}";
2052 return "movdq2q\t{%1, %0|%0, %1}";
2055 return "lea{q}\t{%E1, %0|%0, %E1}";
2058 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2059 if (get_attr_mode (insn) == MODE_SI)
2060 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2061 else if (which_alternative == 4)
2062 return "movabs{q}\t{%1, %0|%0, %1}";
2063 else if (ix86_use_lea_for_mov (insn, operands))
2064 return "lea{q}\t{%E1, %0|%0, %E1}";
2066 return "mov{q}\t{%1, %0|%0, %1}";
2073 (cond [(eq_attr "alternative" "0,1")
2074 (const_string "nox64")
2075 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2076 (const_string "x64")
2077 (eq_attr "alternative" "17")
2078 (const_string "x64_sse4")
2080 (const_string "*")))
2082 (cond [(eq_attr "alternative" "0,1")
2083 (const_string "multi")
2084 (eq_attr "alternative" "6")
2085 (const_string "mmx")
2086 (eq_attr "alternative" "7,8,9,10,11")
2087 (const_string "mmxmov")
2088 (eq_attr "alternative" "12,17")
2089 (const_string "sselog1")
2090 (eq_attr "alternative" "13,14,15,16,18")
2091 (const_string "ssemov")
2092 (eq_attr "alternative" "19,20")
2093 (const_string "ssecvt")
2094 (match_operand 1 "pic_32bit_operand")
2095 (const_string "lea")
2097 (const_string "imov")))
2100 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2102 (const_string "*")))
2103 (set (attr "length_immediate")
2104 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2106 (eq_attr "alternative" "17")
2109 (const_string "*")))
2110 (set (attr "prefix_rex")
2111 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2113 (const_string "*")))
2114 (set (attr "prefix_extra")
2115 (if_then_else (eq_attr "alternative" "17")
2117 (const_string "*")))
2118 (set (attr "prefix")
2119 (if_then_else (eq_attr "type" "sselog1,ssemov")
2120 (const_string "maybe_vex")
2121 (const_string "orig")))
2122 (set (attr "prefix_data16")
2123 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2125 (const_string "*")))
2127 (cond [(eq_attr "alternative" "2")
2129 (eq_attr "alternative" "12,13")
2130 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2131 (match_operand 1 "ext_sse_reg_operand"))
2133 (ior (not (match_test "TARGET_SSE2"))
2134 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2135 (const_string "V4SF")
2136 (match_test "TARGET_AVX")
2138 (match_test "optimize_function_for_size_p (cfun)")
2139 (const_string "V4SF")
2141 (const_string "TI"))
2143 (and (eq_attr "alternative" "14,15")
2144 (not (match_test "TARGET_SSE2")))
2145 (const_string "V2SF")
2146 (eq_attr "alternative" "17")
2149 (const_string "DI")))])
2152 [(set (match_operand:DI 0 "nonimmediate_operand")
2153 (match_operand:DI 1 "general_operand"))]
2154 "!TARGET_64BIT && reload_completed
2155 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2156 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2158 "ix86_split_long_move (operands); DONE;")
2160 (define_insn "*movsi_internal"
2161 [(set (match_operand:SI 0 "nonimmediate_operand"
2162 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2163 (match_operand:SI 1 "general_operand"
2164 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2165 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2167 switch (get_attr_type (insn))
2170 if (GENERAL_REG_P (operands[0]))
2171 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2173 return standard_sse_constant_opcode (insn, operands[1]);
2176 switch (get_attr_mode (insn))
2179 return "%vmovd\t{%1, %0|%0, %1}";
2181 return "%vmovdqa\t{%1, %0|%0, %1}";
2183 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2186 return "%vmovaps\t{%1, %0|%0, %1}";
2189 gcc_assert (!TARGET_AVX);
2190 return "movss\t{%1, %0|%0, %1}";
2197 return "pxor\t%0, %0";
2200 switch (get_attr_mode (insn))
2203 return "movq\t{%1, %0|%0, %1}";
2205 return "movd\t{%1, %0|%0, %1}";
2212 return "lea{l}\t{%E1, %0|%0, %E1}";
2215 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2216 if (ix86_use_lea_for_mov (insn, operands))
2217 return "lea{l}\t{%E1, %0|%0, %E1}";
2219 return "mov{l}\t{%1, %0|%0, %1}";
2226 (if_then_else (eq_attr "alternative" "11")
2227 (const_string "sse4")
2228 (const_string "*")))
2230 (cond [(eq_attr "alternative" "2")
2231 (const_string "mmx")
2232 (eq_attr "alternative" "3,4,5")
2233 (const_string "mmxmov")
2234 (eq_attr "alternative" "6,11")
2235 (const_string "sselog1")
2236 (eq_attr "alternative" "7,8,9,10,12")
2237 (const_string "ssemov")
2238 (match_operand 1 "pic_32bit_operand")
2239 (const_string "lea")
2241 (const_string "imov")))
2242 (set (attr "length_immediate")
2243 (if_then_else (eq_attr "alternative" "11")
2245 (const_string "*")))
2246 (set (attr "prefix_extra")
2247 (if_then_else (eq_attr "alternative" "11")
2249 (const_string "*")))
2250 (set (attr "prefix")
2251 (if_then_else (eq_attr "type" "sselog1,ssemov")
2252 (const_string "maybe_vex")
2253 (const_string "orig")))
2254 (set (attr "prefix_data16")
2255 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2257 (const_string "*")))
2259 (cond [(eq_attr "alternative" "2,3")
2261 (eq_attr "alternative" "6,7")
2262 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2263 (match_operand 1 "ext_sse_reg_operand"))
2265 (ior (not (match_test "TARGET_SSE2"))
2266 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2267 (const_string "V4SF")
2268 (match_test "TARGET_AVX")
2270 (match_test "optimize_function_for_size_p (cfun)")
2271 (const_string "V4SF")
2273 (const_string "TI"))
2275 (and (eq_attr "alternative" "8,9")
2276 (not (match_test "TARGET_SSE2")))
2278 (eq_attr "alternative" "11")
2281 (const_string "SI")))])
2283 (define_insn "*movhi_internal"
2284 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2285 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2286 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2288 switch (get_attr_type (insn))
2291 /* movzwl is faster than movw on p2 due to partial word stalls,
2292 though not as fast as an aligned movl. */
2293 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2296 switch (which_alternative)
2298 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2299 case 5: return "kmovw\t{%1, %0|%0, %1}";
2300 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2301 default: gcc_unreachable ();
2305 if (get_attr_mode (insn) == MODE_SI)
2306 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2308 return "mov{w}\t{%1, %0|%0, %1}";
2312 (cond [(match_test "optimize_function_for_size_p (cfun)")
2313 (const_string "imov")
2314 (and (eq_attr "alternative" "0")
2315 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2316 (not (match_test "TARGET_HIMODE_MATH"))))
2317 (const_string "imov")
2318 (and (eq_attr "alternative" "1,2")
2319 (match_operand:HI 1 "aligned_operand"))
2320 (const_string "imov")
2321 (eq_attr "alternative" "4,5,6")
2322 (const_string "mskmov")
2323 (and (match_test "TARGET_MOVX")
2324 (eq_attr "alternative" "0,2"))
2325 (const_string "imovx")
2327 (const_string "imov")))
2328 (set (attr "prefix")
2329 (if_then_else (eq_attr "alternative" "4,5,6")
2330 (const_string "vex")
2331 (const_string "orig")))
2333 (cond [(eq_attr "type" "imovx")
2335 (and (eq_attr "alternative" "1,2")
2336 (match_operand:HI 1 "aligned_operand"))
2338 (and (eq_attr "alternative" "0")
2339 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2340 (not (match_test "TARGET_HIMODE_MATH"))))
2343 (const_string "HI")))])
2345 ;; Situation is quite tricky about when to choose full sized (SImode) move
2346 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2347 ;; partial register dependency machines (such as AMD Athlon), where QImode
2348 ;; moves issue extra dependency and for partial register stalls machines
2349 ;; that don't use QImode patterns (and QImode move cause stall on the next
2352 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2353 ;; register stall machines with, where we use QImode instructions, since
2354 ;; partial register stall can be caused there. Then we use movzx.
2356 (define_insn "*movqi_internal"
2357 [(set (match_operand:QI 0 "nonimmediate_operand"
2358 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2359 (match_operand:QI 1 "general_operand"
2360 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2361 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2363 switch (get_attr_type (insn))
2366 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2367 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2370 switch (which_alternative)
2372 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2373 case 8: return "kmovw\t{%1, %0|%0, %1}";
2374 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2375 default: gcc_unreachable ();
2379 if (get_attr_mode (insn) == MODE_SI)
2380 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2382 return "mov{b}\t{%1, %0|%0, %1}";
2386 (cond [(and (eq_attr "alternative" "5")
2387 (not (match_operand:QI 1 "aligned_operand")))
2388 (const_string "imovx")
2389 (match_test "optimize_function_for_size_p (cfun)")
2390 (const_string "imov")
2391 (and (eq_attr "alternative" "3")
2392 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2393 (not (match_test "TARGET_QIMODE_MATH"))))
2394 (const_string "imov")
2395 (eq_attr "alternative" "3,5")
2396 (const_string "imovx")
2397 (eq_attr "alternative" "7,8,9")
2398 (const_string "mskmov")
2399 (and (match_test "TARGET_MOVX")
2400 (eq_attr "alternative" "2"))
2401 (const_string "imovx")
2403 (const_string "imov")))
2404 (set (attr "prefix")
2405 (if_then_else (eq_attr "alternative" "7,8,9")
2406 (const_string "vex")
2407 (const_string "orig")))
2409 (cond [(eq_attr "alternative" "3,4,5")
2411 (eq_attr "alternative" "6")
2413 (eq_attr "type" "imovx")
2415 (and (eq_attr "type" "imov")
2416 (and (eq_attr "alternative" "0,1")
2417 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2418 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2419 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2421 ;; Avoid partial register stalls when not using QImode arithmetic
2422 (and (eq_attr "type" "imov")
2423 (and (eq_attr "alternative" "0,1")
2424 (and (match_test "TARGET_PARTIAL_REG_STALL")
2425 (not (match_test "TARGET_QIMODE_MATH")))))
2428 (const_string "QI")))])
2430 ;; Stores and loads of ax to arbitrary constant address.
2431 ;; We fake an second form of instruction to force reload to load address
2432 ;; into register when rax is not available
2433 (define_insn "*movabs<mode>_1"
2434 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2435 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2436 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2438 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2439 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2440 [(set_attr "type" "imov")
2441 (set_attr "modrm" "0,*")
2442 (set_attr "length_address" "8,0")
2443 (set_attr "length_immediate" "0,*")
2444 (set_attr "memory" "store")
2445 (set_attr "mode" "<MODE>")])
2447 (define_insn "*movabs<mode>_2"
2448 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2449 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2450 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2452 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2453 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "modrm" "0,*")
2456 (set_attr "length_address" "8,0")
2457 (set_attr "length_immediate" "0")
2458 (set_attr "memory" "load")
2459 (set_attr "mode" "<MODE>")])
2461 (define_insn "swap<mode>"
2462 [(set (match_operand:SWI48 0 "register_operand" "+r")
2463 (match_operand:SWI48 1 "register_operand" "+r"))
2467 "xchg{<imodesuffix>}\t%1, %0"
2468 [(set_attr "type" "imov")
2469 (set_attr "mode" "<MODE>")
2470 (set_attr "pent_pair" "np")
2471 (set_attr "athlon_decode" "vector")
2472 (set_attr "amdfam10_decode" "double")
2473 (set_attr "bdver1_decode" "double")])
2475 (define_insn "*swap<mode>_1"
2476 [(set (match_operand:SWI12 0 "register_operand" "+r")
2477 (match_operand:SWI12 1 "register_operand" "+r"))
2480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2482 [(set_attr "type" "imov")
2483 (set_attr "mode" "SI")
2484 (set_attr "pent_pair" "np")
2485 (set_attr "athlon_decode" "vector")
2486 (set_attr "amdfam10_decode" "double")
2487 (set_attr "bdver1_decode" "double")])
2489 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2490 ;; is disabled for AMDFAM10
2491 (define_insn "*swap<mode>_2"
2492 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2493 (match_operand:SWI12 1 "register_operand" "+<r>"))
2496 "TARGET_PARTIAL_REG_STALL"
2497 "xchg{<imodesuffix>}\t%1, %0"
2498 [(set_attr "type" "imov")
2499 (set_attr "mode" "<MODE>")
2500 (set_attr "pent_pair" "np")
2501 (set_attr "athlon_decode" "vector")])
2503 (define_expand "movstrict<mode>"
2504 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2505 (match_operand:SWI12 1 "general_operand"))]
2508 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2510 if (GET_CODE (operands[0]) == SUBREG
2511 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2513 /* Don't generate memory->memory moves, go through a register */
2514 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2515 operands[1] = force_reg (<MODE>mode, operands[1]);
2518 (define_insn "*movstrict<mode>_1"
2519 [(set (strict_low_part
2520 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2521 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2522 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2523 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2524 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2525 [(set_attr "type" "imov")
2526 (set_attr "mode" "<MODE>")])
2528 (define_insn "*movstrict<mode>_xor"
2529 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2530 (match_operand:SWI12 1 "const0_operand"))
2531 (clobber (reg:CC FLAGS_REG))]
2533 "xor{<imodesuffix>}\t%0, %0"
2534 [(set_attr "type" "alu1")
2535 (set_attr "mode" "<MODE>")
2536 (set_attr "length_immediate" "0")])
2538 (define_insn "*mov<mode>_extv_1"
2539 [(set (match_operand:SWI24 0 "register_operand" "=R")
2540 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2544 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2545 [(set_attr "type" "imovx")
2546 (set_attr "mode" "SI")])
2548 (define_insn "*movqi_extv_1"
2549 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2550 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2555 switch (get_attr_type (insn))
2558 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2560 return "mov{b}\t{%h1, %0|%0, %h1}";
2563 [(set_attr "isa" "*,*,nox64")
2565 (if_then_else (and (match_operand:QI 0 "register_operand")
2566 (ior (not (match_operand:QI 0 "QIreg_operand"))
2567 (match_test "TARGET_MOVX")))
2568 (const_string "imovx")
2569 (const_string "imov")))
2571 (if_then_else (eq_attr "type" "imovx")
2573 (const_string "QI")))])
2575 (define_insn "*mov<mode>_extzv_1"
2576 [(set (match_operand:SWI48 0 "register_operand" "=R")
2577 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2581 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2582 [(set_attr "type" "imovx")
2583 (set_attr "mode" "SI")])
2585 (define_insn "*movqi_extzv_2"
2586 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2588 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2593 switch (get_attr_type (insn))
2596 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2598 return "mov{b}\t{%h1, %0|%0, %h1}";
2601 [(set_attr "isa" "*,*,nox64")
2603 (if_then_else (and (match_operand:QI 0 "register_operand")
2604 (ior (not (match_operand:QI 0 "QIreg_operand"))
2605 (match_test "TARGET_MOVX")))
2606 (const_string "imovx")
2607 (const_string "imov")))
2609 (if_then_else (eq_attr "type" "imovx")
2611 (const_string "QI")))])
2613 (define_insn "mov<mode>_insv_1"
2614 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2617 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2620 if (CONST_INT_P (operands[1]))
2621 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2622 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2624 [(set_attr "isa" "*,nox64")
2625 (set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2628 (define_insn "*movqi_insv_2"
2629 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2632 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2635 "mov{b}\t{%h1, %h0|%h0, %h1}"
2636 [(set_attr "type" "imov")
2637 (set_attr "mode" "QI")])
2639 ;; Floating point push instructions.
2641 (define_insn "*pushtf"
2642 [(set (match_operand:TF 0 "push_operand" "=<,<")
2643 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2644 "TARGET_64BIT || TARGET_SSE"
2646 /* This insn should be already split before reg-stack. */
2649 [(set_attr "isa" "*,x64")
2650 (set_attr "type" "multi")
2651 (set_attr "unit" "sse,*")
2652 (set_attr "mode" "TF,DI")])
2654 ;; %%% Kill this when call knows how to work this out.
2656 [(set (match_operand:TF 0 "push_operand")
2657 (match_operand:TF 1 "sse_reg_operand"))]
2658 "TARGET_SSE && reload_completed"
2659 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2660 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2662 (define_insn "*pushxf"
2663 [(set (match_operand:XF 0 "push_operand" "=<,<")
2664 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2667 /* This insn should be already split before reg-stack. */
2670 [(set_attr "type" "multi")
2671 (set_attr "unit" "i387,*")
2673 (cond [(eq_attr "alternative" "1")
2674 (if_then_else (match_test "TARGET_64BIT")
2676 (const_string "SI"))
2678 (const_string "XF")))])
2680 ;; %%% Kill this when call knows how to work this out.
2682 [(set (match_operand:XF 0 "push_operand")
2683 (match_operand:XF 1 "fp_register_operand"))]
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2689 (define_insn "*pushdf"
2690 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2691 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2694 /* This insn should be already split before reg-stack. */
2697 [(set_attr "isa" "*,nox64,x64,sse2")
2698 (set_attr "type" "multi")
2699 (set_attr "unit" "i387,*,*,sse")
2700 (set_attr "mode" "DF,SI,DI,DF")])
2702 ;; %%% Kill this when call knows how to work this out.
2704 [(set (match_operand:DF 0 "push_operand")
2705 (match_operand:DF 1 "any_fp_register_operand"))]
2707 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2708 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2710 (define_insn "*pushsf_rex64"
2711 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2712 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2715 /* Anything else should be already split before reg-stack. */
2716 gcc_assert (which_alternative == 1);
2717 return "push{q}\t%q1";
2719 [(set_attr "type" "multi,push,multi")
2720 (set_attr "unit" "i387,*,*")
2721 (set_attr "mode" "SF,DI,SF")])
2723 (define_insn "*pushsf"
2724 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2725 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2728 /* Anything else should be already split before reg-stack. */
2729 gcc_assert (which_alternative == 1);
2730 return "push{l}\t%1";
2732 [(set_attr "type" "multi,push,multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "SF,SI,SF")])
2736 ;; %%% Kill this when call knows how to work this out.
2738 [(set (match_operand:SF 0 "push_operand")
2739 (match_operand:SF 1 "any_fp_register_operand"))]
2741 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2742 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2743 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2746 [(set (match_operand:SF 0 "push_operand")
2747 (match_operand:SF 1 "memory_operand"))]
2749 && (operands[2] = find_constant_src (insn))"
2750 [(set (match_dup 0) (match_dup 2))])
2753 [(set (match_operand 0 "push_operand")
2754 (match_operand 1 "general_operand"))]
2756 && (GET_MODE (operands[0]) == TFmode
2757 || GET_MODE (operands[0]) == XFmode
2758 || GET_MODE (operands[0]) == DFmode)
2759 && !ANY_FP_REG_P (operands[1])"
2761 "ix86_split_long_move (operands); DONE;")
2763 ;; Floating point move instructions.
2765 (define_expand "movtf"
2766 [(set (match_operand:TF 0 "nonimmediate_operand")
2767 (match_operand:TF 1 "nonimmediate_operand"))]
2768 "TARGET_64BIT || TARGET_SSE"
2769 "ix86_expand_move (TFmode, operands); DONE;")
2771 (define_expand "mov<mode>"
2772 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2773 (match_operand:X87MODEF 1 "general_operand"))]
2775 "ix86_expand_move (<MODE>mode, operands); DONE;")
2777 (define_insn "*movtf_internal"
2778 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2779 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2780 "(TARGET_64BIT || TARGET_SSE)
2781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2782 && (!can_create_pseudo_p ()
2783 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2784 || GET_CODE (operands[1]) != CONST_DOUBLE
2785 || (optimize_function_for_size_p (cfun)
2786 && standard_sse_constant_p (operands[1])
2787 && !memory_operand (operands[0], TFmode))
2788 || (!TARGET_MEMORY_MISMATCH_STALL
2789 && memory_operand (operands[0], TFmode)))"
2791 switch (get_attr_type (insn))
2794 return standard_sse_constant_opcode (insn, operands[1]);
2797 /* Handle misaligned load/store since we
2798 don't have movmisaligntf pattern. */
2799 if (misaligned_operand (operands[0], TFmode)
2800 || misaligned_operand (operands[1], TFmode))
2802 if (get_attr_mode (insn) == MODE_V4SF)
2803 return "%vmovups\t{%1, %0|%0, %1}";
2805 return "%vmovdqu\t{%1, %0|%0, %1}";
2809 if (get_attr_mode (insn) == MODE_V4SF)
2810 return "%vmovaps\t{%1, %0|%0, %1}";
2812 return "%vmovdqa\t{%1, %0|%0, %1}";
2822 [(set_attr "isa" "*,*,*,x64,x64")
2823 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2824 (set (attr "prefix")
2825 (if_then_else (eq_attr "type" "sselog1,ssemov")
2826 (const_string "maybe_vex")
2827 (const_string "orig")))
2829 (cond [(eq_attr "alternative" "3,4")
2831 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2832 (const_string "V4SF")
2833 (and (eq_attr "alternative" "2")
2834 (match_test "TARGET_SSE_TYPELESS_STORES"))
2835 (const_string "V4SF")
2836 (match_test "TARGET_AVX")
2838 (ior (not (match_test "TARGET_SSE2"))
2839 (match_test "optimize_function_for_size_p (cfun)"))
2840 (const_string "V4SF")
2842 (const_string "TI")))])
2844 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2845 (define_insn "*movxf_internal"
2846 [(set (match_operand:XF 0 "nonimmediate_operand"
2847 "=f,m,f,?Yx*r ,!o ,!o")
2848 (match_operand:XF 1 "general_operand"
2849 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2850 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2851 && (!can_create_pseudo_p ()
2852 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2853 || GET_CODE (operands[1]) != CONST_DOUBLE
2854 || (optimize_function_for_size_p (cfun)
2855 && standard_80387_constant_p (operands[1]) > 0
2856 && !memory_operand (operands[0], XFmode))
2857 || (!TARGET_MEMORY_MISMATCH_STALL
2858 && memory_operand (operands[0], XFmode)))"
2860 switch (get_attr_type (insn))
2863 if (which_alternative == 2)
2864 return standard_80387_constant_opcode (operands[1]);
2865 return output_387_reg_move (insn, operands);
2874 [(set_attr "isa" "*,*,*,*,nox64,x64")
2875 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2877 (cond [(eq_attr "alternative" "3,4,5")
2878 (if_then_else (match_test "TARGET_64BIT")
2880 (const_string "SI"))
2882 (const_string "XF")))])
2884 ;; Possible store forwarding (partial memory) stall in alternative 4.
2885 (define_insn "*movdf_internal"
2886 [(set (match_operand:DF 0 "nonimmediate_operand"
2887 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2888 (match_operand:DF 1 "general_operand"
2889 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2890 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2891 && (!can_create_pseudo_p ()
2892 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || (optimize_function_for_size_p (cfun)
2895 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2896 && standard_80387_constant_p (operands[1]) > 0)
2897 || (TARGET_SSE2 && TARGET_SSE_MATH
2898 && standard_sse_constant_p (operands[1])))
2899 && !memory_operand (operands[0], DFmode))
2900 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2901 && memory_operand (operands[0], DFmode)))"
2903 switch (get_attr_type (insn))
2906 if (which_alternative == 2)
2907 return standard_80387_constant_opcode (operands[1]);
2908 return output_387_reg_move (insn, operands);
2914 if (get_attr_mode (insn) == MODE_SI)
2915 return "mov{l}\t{%1, %k0|%k0, %1}";
2916 else if (which_alternative == 8)
2917 return "movabs{q}\t{%1, %0|%0, %1}";
2919 return "mov{q}\t{%1, %0|%0, %1}";
2922 return standard_sse_constant_opcode (insn, operands[1]);
2925 switch (get_attr_mode (insn))
2928 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2929 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2930 return "%vmovsd\t{%1, %0|%0, %1}";
2933 return "%vmovaps\t{%1, %0|%0, %1}";
2935 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2937 return "%vmovapd\t{%1, %0|%0, %1}";
2940 gcc_assert (!TARGET_AVX);
2941 return "movlps\t{%1, %0|%0, %1}";
2943 gcc_assert (!TARGET_AVX);
2944 return "movlpd\t{%1, %0|%0, %1}";
2947 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2948 /* Handle broken assemblers that require movd instead of movq. */
2949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2950 return "%vmovd\t{%1, %0|%0, %1}";
2952 return "%vmovq\t{%1, %0|%0, %1}";
2963 (cond [(eq_attr "alternative" "3,4")
2964 (const_string "nox64")
2965 (eq_attr "alternative" "5,6,7,8,17,18")
2966 (const_string "x64")
2967 (eq_attr "alternative" "9,10,11,12")
2968 (const_string "sse2")
2970 (const_string "*")))
2972 (cond [(eq_attr "alternative" "0,1,2")
2973 (const_string "fmov")
2974 (eq_attr "alternative" "3,4")
2975 (const_string "multi")
2976 (eq_attr "alternative" "5,6,7,8")
2977 (const_string "imov")
2978 (eq_attr "alternative" "9,13")
2979 (const_string "sselog1")
2981 (const_string "ssemov")))
2983 (if_then_else (eq_attr "alternative" "8")
2985 (const_string "*")))
2986 (set (attr "length_immediate")
2987 (if_then_else (eq_attr "alternative" "8")
2989 (const_string "*")))
2990 (set (attr "prefix")
2991 (if_then_else (eq_attr "type" "sselog1,ssemov")
2992 (const_string "maybe_vex")
2993 (const_string "orig")))
2994 (set (attr "prefix_data16")
2996 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2997 (eq_attr "mode" "V1DF"))
2999 (const_string "*")))
3001 (cond [(eq_attr "alternative" "3,4,7")
3003 (eq_attr "alternative" "5,6,8,17,18")
3006 /* xorps is one byte shorter for non-AVX targets. */
3007 (eq_attr "alternative" "9,13")
3008 (cond [(not (match_test "TARGET_SSE2"))
3009 (const_string "V4SF")
3010 (match_test "TARGET_AVX512F")
3012 (match_test "TARGET_AVX")
3013 (const_string "V2DF")
3014 (match_test "optimize_function_for_size_p (cfun)")
3015 (const_string "V4SF")
3016 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3019 (const_string "V2DF"))
3021 /* For architectures resolving dependencies on
3022 whole SSE registers use movapd to break dependency
3023 chains, otherwise use short move to avoid extra work. */
3025 /* movaps is one byte shorter for non-AVX targets. */
3026 (eq_attr "alternative" "10,14")
3027 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3028 (match_operand 1 "ext_sse_reg_operand"))
3029 (const_string "V8DF")
3030 (ior (not (match_test "TARGET_SSE2"))
3031 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3032 (const_string "V4SF")
3033 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3034 (const_string "V2DF")
3035 (match_test "TARGET_AVX")
3037 (match_test "optimize_function_for_size_p (cfun)")
3038 (const_string "V4SF")
3040 (const_string "DF"))
3042 /* For architectures resolving dependencies on register
3043 parts we may avoid extra work to zero out upper part
3045 (eq_attr "alternative" "11,15")
3046 (cond [(not (match_test "TARGET_SSE2"))
3047 (const_string "V2SF")
3048 (match_test "TARGET_AVX")
3050 (match_test "TARGET_SSE_SPLIT_REGS")
3051 (const_string "V1DF")
3053 (const_string "DF"))
3055 (and (eq_attr "alternative" "12,16")
3056 (not (match_test "TARGET_SSE2")))
3057 (const_string "V2SF")
3059 (const_string "DF")))])
3061 (define_insn "*movsf_internal"
3062 [(set (match_operand:SF 0 "nonimmediate_operand"
3063 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3064 (match_operand:SF 1 "general_operand"
3065 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3066 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3067 && (!can_create_pseudo_p ()
3068 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3069 || GET_CODE (operands[1]) != CONST_DOUBLE
3070 || (optimize_function_for_size_p (cfun)
3071 && ((!TARGET_SSE_MATH
3072 && standard_80387_constant_p (operands[1]) > 0)
3074 && standard_sse_constant_p (operands[1]))))
3075 || memory_operand (operands[0], SFmode))"
3077 switch (get_attr_type (insn))
3080 if (which_alternative == 2)
3081 return standard_80387_constant_opcode (operands[1]);
3082 return output_387_reg_move (insn, operands);
3085 return "mov{l}\t{%1, %0|%0, %1}";
3088 return standard_sse_constant_opcode (insn, operands[1]);
3091 switch (get_attr_mode (insn))
3094 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3095 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3096 return "%vmovss\t{%1, %0|%0, %1}";
3099 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3101 return "%vmovaps\t{%1, %0|%0, %1}";
3104 return "%vmovd\t{%1, %0|%0, %1}";
3111 switch (get_attr_mode (insn))
3114 return "movq\t{%1, %0|%0, %1}";
3116 return "movd\t{%1, %0|%0, %1}";
3127 (cond [(eq_attr "alternative" "0,1,2")
3128 (const_string "fmov")
3129 (eq_attr "alternative" "3,4")
3130 (const_string "imov")
3131 (eq_attr "alternative" "5")
3132 (const_string "sselog1")
3133 (eq_attr "alternative" "11,12,13,14,15")
3134 (const_string "mmxmov")
3136 (const_string "ssemov")))
3137 (set (attr "prefix")
3138 (if_then_else (eq_attr "type" "sselog1,ssemov")
3139 (const_string "maybe_vex")
3140 (const_string "orig")))
3141 (set (attr "prefix_data16")
3142 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3144 (const_string "*")))
3146 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
3148 (eq_attr "alternative" "11")
3150 (eq_attr "alternative" "5")
3151 (cond [(not (match_test "TARGET_SSE2"))
3152 (const_string "V4SF")
3153 (match_test "TARGET_AVX512F")
3154 (const_string "V16SF")
3155 (match_test "TARGET_AVX")
3156 (const_string "V4SF")
3157 (match_test "optimize_function_for_size_p (cfun)")
3158 (const_string "V4SF")
3159 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3162 (const_string "V4SF"))
3164 /* For architectures resolving dependencies on
3165 whole SSE registers use APS move to break dependency
3166 chains, otherwise use short move to avoid extra work.
3168 Do the same for architectures resolving dependencies on
3169 the parts. While in DF mode it is better to always handle
3170 just register parts, the SF mode is different due to lack
3171 of instructions to load just part of the register. It is
3172 better to maintain the whole registers in single format
3173 to avoid problems on using packed logical operations. */
3174 (eq_attr "alternative" "6")
3175 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3176 (match_operand 1 "ext_sse_reg_operand"))
3177 (const_string "V16SF")
3178 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3179 (match_test "TARGET_SSE_SPLIT_REGS"))
3180 (const_string "V4SF")
3182 (const_string "SF"))
3184 (const_string "SF")))])
3187 [(set (match_operand 0 "any_fp_register_operand")
3188 (match_operand 1 "memory_operand"))]
3190 && (GET_MODE (operands[0]) == TFmode
3191 || GET_MODE (operands[0]) == XFmode
3192 || GET_MODE (operands[0]) == DFmode
3193 || GET_MODE (operands[0]) == SFmode)
3194 && (operands[2] = find_constant_src (insn))"
3195 [(set (match_dup 0) (match_dup 2))]
3197 rtx c = operands[2];
3198 int r = REGNO (operands[0]);
3200 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3201 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3206 [(set (match_operand 0 "any_fp_register_operand")
3207 (float_extend (match_operand 1 "memory_operand")))]
3209 && (GET_MODE (operands[0]) == TFmode
3210 || GET_MODE (operands[0]) == XFmode
3211 || GET_MODE (operands[0]) == DFmode)
3212 && (operands[2] = find_constant_src (insn))"
3213 [(set (match_dup 0) (match_dup 2))]
3215 rtx c = operands[2];
3216 int r = REGNO (operands[0]);
3218 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3219 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3223 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3225 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3226 (match_operand:X87MODEF 1 "immediate_operand"))]
3228 && (standard_80387_constant_p (operands[1]) == 8
3229 || standard_80387_constant_p (operands[1]) == 9)"
3230 [(set (match_dup 0)(match_dup 1))
3232 (neg:X87MODEF (match_dup 0)))]
3236 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3237 if (real_isnegzero (&r))
3238 operands[1] = CONST0_RTX (<MODE>mode);
3240 operands[1] = CONST1_RTX (<MODE>mode);
3244 [(set (match_operand 0 "nonimmediate_operand")
3245 (match_operand 1 "general_operand"))]
3247 && (GET_MODE (operands[0]) == TFmode
3248 || GET_MODE (operands[0]) == XFmode
3249 || GET_MODE (operands[0]) == DFmode)
3250 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3252 "ix86_split_long_move (operands); DONE;")
3254 (define_insn "swapxf"
3255 [(set (match_operand:XF 0 "register_operand" "+f")
3256 (match_operand:XF 1 "register_operand" "+f"))
3261 if (STACK_TOP_P (operands[0]))
3266 [(set_attr "type" "fxch")
3267 (set_attr "mode" "XF")])
3269 (define_insn "*swap<mode>"
3270 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3271 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3274 "TARGET_80387 || reload_completed"
3276 if (STACK_TOP_P (operands[0]))
3281 [(set_attr "type" "fxch")
3282 (set_attr "mode" "<MODE>")])
3284 ;; Zero extension instructions
3286 (define_expand "zero_extendsidi2"
3287 [(set (match_operand:DI 0 "nonimmediate_operand")
3288 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3290 (define_insn "*zero_extendsidi2"
3291 [(set (match_operand:DI 0 "nonimmediate_operand"
3292 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3294 (match_operand:SI 1 "x86_64_zext_operand"
3295 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3298 switch (get_attr_type (insn))
3301 if (ix86_use_lea_for_mov (insn, operands))
3302 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3304 return "mov{l}\t{%1, %k0|%k0, %1}";
3310 return "movd\t{%1, %0|%0, %1}";
3313 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3316 if (GENERAL_REG_P (operands[0]))
3317 return "%vmovd\t{%1, %k0|%k0, %1}";
3319 return "%vmovd\t{%1, %0|%0, %1}";
3326 (cond [(eq_attr "alternative" "0,1,2")
3327 (const_string "nox64")
3328 (eq_attr "alternative" "3,7")
3329 (const_string "x64")
3330 (eq_attr "alternative" "8")
3331 (const_string "x64_sse4")
3332 (eq_attr "alternative" "10")
3333 (const_string "sse2")
3335 (const_string "*")))
3337 (cond [(eq_attr "alternative" "0,1,2,4")
3338 (const_string "multi")
3339 (eq_attr "alternative" "5,6")
3340 (const_string "mmxmov")
3341 (eq_attr "alternative" "7,9,10")
3342 (const_string "ssemov")
3343 (eq_attr "alternative" "8")
3344 (const_string "sselog1")
3346 (const_string "imovx")))
3347 (set (attr "prefix_extra")
3348 (if_then_else (eq_attr "alternative" "8")
3350 (const_string "*")))
3351 (set (attr "length_immediate")
3352 (if_then_else (eq_attr "alternative" "8")
3354 (const_string "*")))
3355 (set (attr "prefix")
3356 (if_then_else (eq_attr "type" "ssemov,sselog1")
3357 (const_string "maybe_vex")
3358 (const_string "orig")))
3359 (set (attr "prefix_0f")
3360 (if_then_else (eq_attr "type" "imovx")
3362 (const_string "*")))
3364 (cond [(eq_attr "alternative" "5,6")
3366 (eq_attr "alternative" "7,8,9")
3369 (const_string "SI")))])
3372 [(set (match_operand:DI 0 "memory_operand")
3373 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3375 [(set (match_dup 4) (const_int 0))]
3376 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3379 [(set (match_operand:DI 0 "register_operand")
3380 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3381 "!TARGET_64BIT && reload_completed
3382 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3383 && true_regnum (operands[0]) == true_regnum (operands[1])"
3384 [(set (match_dup 4) (const_int 0))]
3385 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3388 [(set (match_operand:DI 0 "nonimmediate_operand")
3389 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3390 "!TARGET_64BIT && reload_completed
3391 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3392 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3393 [(set (match_dup 3) (match_dup 1))
3394 (set (match_dup 4) (const_int 0))]
3395 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3397 (define_insn "zero_extend<mode>di2"
3398 [(set (match_operand:DI 0 "register_operand" "=r")
3400 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3402 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3403 [(set_attr "type" "imovx")
3404 (set_attr "mode" "SI")])
3406 (define_expand "zero_extend<mode>si2"
3407 [(set (match_operand:SI 0 "register_operand")
3408 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3411 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3413 operands[1] = force_reg (<MODE>mode, operands[1]);
3414 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3419 (define_insn_and_split "zero_extend<mode>si2_and"
3420 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3422 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3423 (clobber (reg:CC FLAGS_REG))]
3424 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3426 "&& reload_completed"
3427 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3428 (clobber (reg:CC FLAGS_REG))])]
3430 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3432 ix86_expand_clear (operands[0]);
3434 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3435 emit_insn (gen_movstrict<mode>
3436 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3440 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3442 [(set_attr "type" "alu1")
3443 (set_attr "mode" "SI")])
3445 (define_insn "*zero_extend<mode>si2"
3446 [(set (match_operand:SI 0 "register_operand" "=r")
3448 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3449 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3450 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3451 [(set_attr "type" "imovx")
3452 (set_attr "mode" "SI")])
3454 (define_expand "zero_extendqihi2"
3455 [(set (match_operand:HI 0 "register_operand")
3456 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3459 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3461 operands[1] = force_reg (QImode, operands[1]);
3462 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3467 (define_insn_and_split "zero_extendqihi2_and"
3468 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3469 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3470 (clobber (reg:CC FLAGS_REG))]
3471 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3473 "&& reload_completed"
3474 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3475 (clobber (reg:CC FLAGS_REG))])]
3477 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3479 ix86_expand_clear (operands[0]);
3481 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3482 emit_insn (gen_movstrictqi
3483 (gen_lowpart (QImode, operands[0]), operands[1]));
3487 operands[0] = gen_lowpart (SImode, operands[0]);
3489 [(set_attr "type" "alu1")
3490 (set_attr "mode" "SI")])
3492 ; zero extend to SImode to avoid partial register stalls
3493 (define_insn "*zero_extendqihi2"
3494 [(set (match_operand:HI 0 "register_operand" "=r")
3495 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3496 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3497 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3498 [(set_attr "type" "imovx")
3499 (set_attr "mode" "SI")])
3501 ;; Sign extension instructions
3503 (define_expand "extendsidi2"
3504 [(set (match_operand:DI 0 "register_operand")
3505 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3510 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3515 (define_insn "*extendsidi2_rex64"
3516 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3517 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3521 movs{lq|x}\t{%1, %0|%0, %1}"
3522 [(set_attr "type" "imovx")
3523 (set_attr "mode" "DI")
3524 (set_attr "prefix_0f" "0")
3525 (set_attr "modrm" "0,1")])
3527 (define_insn "extendsidi2_1"
3528 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3529 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3530 (clobber (reg:CC FLAGS_REG))
3531 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3535 ;; Split the memory case. If the source register doesn't die, it will stay
3536 ;; this way, if it does die, following peephole2s take care of it.
3538 [(set (match_operand:DI 0 "memory_operand")
3539 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3540 (clobber (reg:CC FLAGS_REG))
3541 (clobber (match_operand:SI 2 "register_operand"))]
3545 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3547 emit_move_insn (operands[3], operands[1]);
3549 /* Generate a cltd if possible and doing so it profitable. */
3550 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3551 && true_regnum (operands[1]) == AX_REG
3552 && true_regnum (operands[2]) == DX_REG)
3554 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3558 emit_move_insn (operands[2], operands[1]);
3559 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3561 emit_move_insn (operands[4], operands[2]);
3565 ;; Peepholes for the case where the source register does die, after
3566 ;; being split with the above splitter.
3568 [(set (match_operand:SI 0 "memory_operand")
3569 (match_operand:SI 1 "register_operand"))
3570 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3571 (parallel [(set (match_dup 2)
3572 (ashiftrt:SI (match_dup 2) (const_int 31)))
3573 (clobber (reg:CC FLAGS_REG))])
3574 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3575 "REGNO (operands[1]) != REGNO (operands[2])
3576 && peep2_reg_dead_p (2, operands[1])
3577 && peep2_reg_dead_p (4, operands[2])
3578 && !reg_mentioned_p (operands[2], operands[3])"
3579 [(set (match_dup 0) (match_dup 1))
3580 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3581 (clobber (reg:CC FLAGS_REG))])
3582 (set (match_dup 3) (match_dup 1))])
3585 [(set (match_operand:SI 0 "memory_operand")
3586 (match_operand:SI 1 "register_operand"))
3587 (parallel [(set (match_operand:SI 2 "register_operand")
3588 (ashiftrt:SI (match_dup 1) (const_int 31)))
3589 (clobber (reg:CC FLAGS_REG))])
3590 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3591 "/* cltd is shorter than sarl $31, %eax */
3592 !optimize_function_for_size_p (cfun)
3593 && true_regnum (operands[1]) == AX_REG
3594 && true_regnum (operands[2]) == DX_REG
3595 && peep2_reg_dead_p (2, operands[1])
3596 && peep2_reg_dead_p (3, operands[2])
3597 && !reg_mentioned_p (operands[2], operands[3])"
3598 [(set (match_dup 0) (match_dup 1))
3599 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3600 (clobber (reg:CC FLAGS_REG))])
3601 (set (match_dup 3) (match_dup 1))])
3603 ;; Extend to register case. Optimize case where source and destination
3604 ;; registers match and cases where we can use cltd.
3606 [(set (match_operand:DI 0 "register_operand")
3607 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3608 (clobber (reg:CC FLAGS_REG))
3609 (clobber (match_scratch:SI 2))]
3613 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3615 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3616 emit_move_insn (operands[3], operands[1]);
3618 /* Generate a cltd if possible and doing so it profitable. */
3619 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3620 && true_regnum (operands[3]) == AX_REG
3621 && true_regnum (operands[4]) == DX_REG)
3623 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3627 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3628 emit_move_insn (operands[4], operands[1]);
3630 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3634 (define_insn "extend<mode>di2"
3635 [(set (match_operand:DI 0 "register_operand" "=r")
3637 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3639 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3640 [(set_attr "type" "imovx")
3641 (set_attr "mode" "DI")])
3643 (define_insn "extendhisi2"
3644 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3645 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3648 switch (get_attr_prefix_0f (insn))
3651 return "{cwtl|cwde}";
3653 return "movs{wl|x}\t{%1, %0|%0, %1}";
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "SI")
3658 (set (attr "prefix_0f")
3659 ;; movsx is short decodable while cwtl is vector decoded.
3660 (if_then_else (and (eq_attr "cpu" "!k6")
3661 (eq_attr "alternative" "0"))
3663 (const_string "1")))
3665 (if_then_else (eq_attr "prefix_0f" "0")
3667 (const_string "1")))])
3669 (define_insn "*extendhisi2_zext"
3670 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3673 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3676 switch (get_attr_prefix_0f (insn))
3679 return "{cwtl|cwde}";
3681 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "SI")
3686 (set (attr "prefix_0f")
3687 ;; movsx is short decodable while cwtl is vector decoded.
3688 (if_then_else (and (eq_attr "cpu" "!k6")
3689 (eq_attr "alternative" "0"))
3691 (const_string "1")))
3693 (if_then_else (eq_attr "prefix_0f" "0")
3695 (const_string "1")))])
3697 (define_insn "extendqisi2"
3698 [(set (match_operand:SI 0 "register_operand" "=r")
3699 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3701 "movs{bl|x}\t{%1, %0|%0, %1}"
3702 [(set_attr "type" "imovx")
3703 (set_attr "mode" "SI")])
3705 (define_insn "*extendqisi2_zext"
3706 [(set (match_operand:DI 0 "register_operand" "=r")
3708 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3710 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3711 [(set_attr "type" "imovx")
3712 (set_attr "mode" "SI")])
3714 (define_insn "extendqihi2"
3715 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3716 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3719 switch (get_attr_prefix_0f (insn))
3722 return "{cbtw|cbw}";
3724 return "movs{bw|x}\t{%1, %0|%0, %1}";
3727 [(set_attr "type" "imovx")
3728 (set_attr "mode" "HI")
3729 (set (attr "prefix_0f")
3730 ;; movsx is short decodable while cwtl is vector decoded.
3731 (if_then_else (and (eq_attr "cpu" "!k6")
3732 (eq_attr "alternative" "0"))
3734 (const_string "1")))
3736 (if_then_else (eq_attr "prefix_0f" "0")
3738 (const_string "1")))])
3740 ;; Conversions between float and double.
3742 ;; These are all no-ops in the model used for the 80387.
3743 ;; So just emit moves.
3745 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3747 [(set (match_operand:DF 0 "push_operand")
3748 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3750 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3751 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3754 [(set (match_operand:XF 0 "push_operand")
3755 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3758 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3759 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3761 (define_expand "extendsfdf2"
3762 [(set (match_operand:DF 0 "nonimmediate_operand")
3763 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3764 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3766 /* ??? Needed for compress_float_constant since all fp constants
3767 are TARGET_LEGITIMATE_CONSTANT_P. */
3768 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3770 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3771 && standard_80387_constant_p (operands[1]) > 0)
3773 operands[1] = simplify_const_unary_operation
3774 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3775 emit_move_insn_1 (operands[0], operands[1]);
3778 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3782 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3784 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3786 We do the conversion post reload to avoid producing of 128bit spills
3787 that might lead to ICE on 32bit target. The sequence unlikely combine
3790 [(set (match_operand:DF 0 "register_operand")
3792 (match_operand:SF 1 "nonimmediate_operand")))]
3793 "TARGET_USE_VECTOR_FP_CONVERTS
3794 && optimize_insn_for_speed_p ()
3795 && reload_completed && SSE_REG_P (operands[0])"
3800 (parallel [(const_int 0) (const_int 1)]))))]
3802 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3803 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3804 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3805 Try to avoid move when unpacking can be done in source. */
3806 if (REG_P (operands[1]))
3808 /* If it is unsafe to overwrite upper half of source, we need
3809 to move to destination and unpack there. */
3810 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3811 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3812 && true_regnum (operands[0]) != true_regnum (operands[1]))
3814 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3815 emit_move_insn (tmp, operands[1]);
3818 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3819 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3823 emit_insn (gen_vec_setv4sf_0 (operands[3],
3824 CONST0_RTX (V4SFmode), operands[1]));
3827 ;; It's more profitable to split and then extend in the same register.
3829 [(set (match_operand:DF 0 "register_operand")
3831 (match_operand:SF 1 "memory_operand")))]
3832 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && SSE_REG_P (operands[0])"
3835 [(set (match_dup 2) (match_dup 1))
3836 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3837 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3839 (define_insn "*extendsfdf2_mixed"
3840 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3842 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3843 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3845 switch (which_alternative)
3849 return output_387_reg_move (insn, operands);
3852 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3858 [(set_attr "type" "fmov,fmov,ssecvt")
3859 (set_attr "prefix" "orig,orig,maybe_vex")
3860 (set_attr "mode" "SF,XF,DF")])
3862 (define_insn "*extendsfdf2_sse"
3863 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3864 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3865 "TARGET_SSE2 && TARGET_SSE_MATH"
3866 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3867 [(set_attr "type" "ssecvt")
3868 (set_attr "prefix" "maybe_vex")
3869 (set_attr "mode" "DF")])
3871 (define_insn "*extendsfdf2_i387"
3872 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3873 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3875 "* return output_387_reg_move (insn, operands);"
3876 [(set_attr "type" "fmov")
3877 (set_attr "mode" "SF,XF")])
3879 (define_expand "extend<mode>xf2"
3880 [(set (match_operand:XF 0 "nonimmediate_operand")
3881 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3884 /* ??? Needed for compress_float_constant since all fp constants
3885 are TARGET_LEGITIMATE_CONSTANT_P. */
3886 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3888 if (standard_80387_constant_p (operands[1]) > 0)
3890 operands[1] = simplify_const_unary_operation
3891 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3892 emit_move_insn_1 (operands[0], operands[1]);
3895 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3899 (define_insn "*extend<mode>xf2_i387"
3900 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3902 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3904 "* return output_387_reg_move (insn, operands);"
3905 [(set_attr "type" "fmov")
3906 (set_attr "mode" "<MODE>,XF")])
3908 ;; %%% This seems bad bad news.
3909 ;; This cannot output into an f-reg because there is no way to be sure
3910 ;; of truncating in that case. Otherwise this is just like a simple move
3911 ;; insn. So we pretend we can output to a reg in order to get better
3912 ;; register preferencing, but we really use a stack slot.
3914 ;; Conversion from DFmode to SFmode.
3916 (define_expand "truncdfsf2"
3917 [(set (match_operand:SF 0 "nonimmediate_operand")
3919 (match_operand:DF 1 "nonimmediate_operand")))]
3920 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3922 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3924 else if (flag_unsafe_math_optimizations)
3928 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3929 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3934 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3936 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3938 We do the conversion post reload to avoid producing of 128bit spills
3939 that might lead to ICE on 32bit target. The sequence unlikely combine
3942 [(set (match_operand:SF 0 "register_operand")
3944 (match_operand:DF 1 "nonimmediate_operand")))]
3945 "TARGET_USE_VECTOR_FP_CONVERTS
3946 && optimize_insn_for_speed_p ()
3947 && reload_completed && SSE_REG_P (operands[0])"
3950 (float_truncate:V2SF
3954 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3955 operands[3] = CONST0_RTX (V2SFmode);
3956 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3957 /* Use movsd for loading from memory, unpcklpd for registers.
3958 Try to avoid move when unpacking can be done in source, or SSE3
3959 movddup is available. */
3960 if (REG_P (operands[1]))
3963 && true_regnum (operands[0]) != true_regnum (operands[1])
3964 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3965 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3967 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3968 emit_move_insn (tmp, operands[1]);
3971 else if (!TARGET_SSE3)
3972 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3973 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3976 emit_insn (gen_sse2_loadlpd (operands[4],
3977 CONST0_RTX (V2DFmode), operands[1]));
3980 ;; It's more profitable to split and then extend in the same register.
3982 [(set (match_operand:SF 0 "register_operand")
3984 (match_operand:DF 1 "memory_operand")))]
3985 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3986 && optimize_insn_for_speed_p ()
3987 && SSE_REG_P (operands[0])"
3988 [(set (match_dup 2) (match_dup 1))
3989 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3990 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3992 (define_expand "truncdfsf2_with_temp"
3993 [(parallel [(set (match_operand:SF 0)
3994 (float_truncate:SF (match_operand:DF 1)))
3995 (clobber (match_operand:SF 2))])])
3997 (define_insn "*truncdfsf_fast_mixed"
3998 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4000 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4001 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4003 switch (which_alternative)
4006 return output_387_reg_move (insn, operands);
4008 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4013 [(set_attr "type" "fmov,ssecvt")
4014 (set_attr "prefix" "orig,maybe_vex")
4015 (set_attr "mode" "SF")])
4017 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4018 ;; because nothing we do here is unsafe.
4019 (define_insn "*truncdfsf_fast_sse"
4020 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4022 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4023 "TARGET_SSE2 && TARGET_SSE_MATH"
4024 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4025 [(set_attr "type" "ssecvt")
4026 (set_attr "prefix" "maybe_vex")
4027 (set_attr "mode" "SF")])
4029 (define_insn "*truncdfsf_fast_i387"
4030 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4032 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4033 "TARGET_80387 && flag_unsafe_math_optimizations"
4034 "* return output_387_reg_move (insn, operands);"
4035 [(set_attr "type" "fmov")
4036 (set_attr "mode" "SF")])
4038 (define_insn "*truncdfsf_mixed"
4039 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4041 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4042 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4043 "TARGET_MIX_SSE_I387"
4045 switch (which_alternative)
4048 return output_387_reg_move (insn, operands);
4050 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4056 [(set_attr "isa" "*,sse2,*,*,*")
4057 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4058 (set_attr "unit" "*,*,i387,i387,i387")
4059 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4060 (set_attr "mode" "SF")])
4062 (define_insn "*truncdfsf_i387"
4063 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4065 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4066 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4069 switch (which_alternative)
4072 return output_387_reg_move (insn, operands);
4078 [(set_attr "type" "fmov,multi,multi,multi")
4079 (set_attr "unit" "*,i387,i387,i387")
4080 (set_attr "mode" "SF")])
4082 (define_insn "*truncdfsf2_i387_1"
4083 [(set (match_operand:SF 0 "memory_operand" "=m")
4085 (match_operand:DF 1 "register_operand" "f")))]
4087 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4088 && !TARGET_MIX_SSE_I387"
4089 "* return output_387_reg_move (insn, operands);"
4090 [(set_attr "type" "fmov")
4091 (set_attr "mode" "SF")])
4094 [(set (match_operand:SF 0 "register_operand")
4096 (match_operand:DF 1 "fp_register_operand")))
4097 (clobber (match_operand 2))]
4099 [(set (match_dup 2) (match_dup 1))
4100 (set (match_dup 0) (match_dup 2))]
4101 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4103 ;; Conversion from XFmode to {SF,DF}mode
4105 (define_expand "truncxf<mode>2"
4106 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4107 (float_truncate:MODEF
4108 (match_operand:XF 1 "register_operand")))
4109 (clobber (match_dup 2))])]
4112 if (flag_unsafe_math_optimizations)
4114 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4115 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4116 if (reg != operands[0])
4117 emit_move_insn (operands[0], reg);
4121 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4124 (define_insn "*truncxfsf2_mixed"
4125 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4127 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4128 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4131 gcc_assert (!which_alternative);
4132 return output_387_reg_move (insn, operands);
4134 [(set_attr "type" "fmov,multi,multi,multi")
4135 (set_attr "unit" "*,i387,i387,i387")
4136 (set_attr "mode" "SF")])
4138 (define_insn "*truncxfdf2_mixed"
4139 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4141 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4142 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4145 gcc_assert (!which_alternative);
4146 return output_387_reg_move (insn, operands);
4148 [(set_attr "isa" "*,*,sse2,*")
4149 (set_attr "type" "fmov,multi,multi,multi")
4150 (set_attr "unit" "*,i387,i387,i387")
4151 (set_attr "mode" "DF")])
4153 (define_insn "truncxf<mode>2_i387_noop"
4154 [(set (match_operand:MODEF 0 "register_operand" "=f")
4155 (float_truncate:MODEF
4156 (match_operand:XF 1 "register_operand" "f")))]
4157 "TARGET_80387 && flag_unsafe_math_optimizations"
4158 "* return output_387_reg_move (insn, operands);"
4159 [(set_attr "type" "fmov")
4160 (set_attr "mode" "<MODE>")])
4162 (define_insn "*truncxf<mode>2_i387"
4163 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4164 (float_truncate:MODEF
4165 (match_operand:XF 1 "register_operand" "f")))]
4167 "* return output_387_reg_move (insn, operands);"
4168 [(set_attr "type" "fmov")
4169 (set_attr "mode" "<MODE>")])
4172 [(set (match_operand:MODEF 0 "register_operand")
4173 (float_truncate:MODEF
4174 (match_operand:XF 1 "register_operand")))
4175 (clobber (match_operand:MODEF 2 "memory_operand"))]
4176 "TARGET_80387 && reload_completed"
4177 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4178 (set (match_dup 0) (match_dup 2))])
4181 [(set (match_operand:MODEF 0 "memory_operand")
4182 (float_truncate:MODEF
4183 (match_operand:XF 1 "register_operand")))
4184 (clobber (match_operand:MODEF 2 "memory_operand"))]
4186 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4188 ;; Signed conversion to DImode.
4190 (define_expand "fix_truncxfdi2"
4191 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4192 (fix:DI (match_operand:XF 1 "register_operand")))
4193 (clobber (reg:CC FLAGS_REG))])]
4198 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4203 (define_expand "fix_trunc<mode>di2"
4204 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4205 (fix:DI (match_operand:MODEF 1 "register_operand")))
4206 (clobber (reg:CC FLAGS_REG))])]
4207 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4210 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4212 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4215 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4217 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4218 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4219 if (out != operands[0])
4220 emit_move_insn (operands[0], out);
4225 ;; Signed conversion to SImode.
4227 (define_expand "fix_truncxfsi2"
4228 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4229 (fix:SI (match_operand:XF 1 "register_operand")))
4230 (clobber (reg:CC FLAGS_REG))])]
4235 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4240 (define_expand "fix_trunc<mode>si2"
4241 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4242 (fix:SI (match_operand:MODEF 1 "register_operand")))
4243 (clobber (reg:CC FLAGS_REG))])]
4244 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4247 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4249 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4252 if (SSE_FLOAT_MODE_P (<MODE>mode))
4254 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4255 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4256 if (out != operands[0])
4257 emit_move_insn (operands[0], out);
4262 ;; Signed conversion to HImode.
4264 (define_expand "fix_trunc<mode>hi2"
4265 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4266 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4267 (clobber (reg:CC FLAGS_REG))])]
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4273 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4278 ;; Unsigned conversion to SImode.
4280 (define_expand "fixuns_trunc<mode>si2"
4282 [(set (match_operand:SI 0 "register_operand")
4284 (match_operand:MODEF 1 "nonimmediate_operand")))
4286 (clobber (match_scratch:<ssevecmode> 3))
4287 (clobber (match_scratch:<ssevecmode> 4))])]
4288 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4290 enum machine_mode mode = <MODE>mode;
4291 enum machine_mode vecmode = <ssevecmode>mode;
4292 REAL_VALUE_TYPE TWO31r;
4295 if (optimize_insn_for_size_p ())
4298 real_ldexp (&TWO31r, &dconst1, 31);
4299 two31 = const_double_from_real_value (TWO31r, mode);
4300 two31 = ix86_build_const_vector (vecmode, true, two31);
4301 operands[2] = force_reg (vecmode, two31);
4304 (define_insn_and_split "*fixuns_trunc<mode>_1"
4305 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4307 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4308 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4309 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4310 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4311 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4312 && optimize_function_for_speed_p (cfun)"
4314 "&& reload_completed"
4317 ix86_split_convert_uns_si_sse (operands);
4321 ;; Unsigned conversion to HImode.
4322 ;; Without these patterns, we'll try the unsigned SI conversion which
4323 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4325 (define_expand "fixuns_trunc<mode>hi2"
4327 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4328 (set (match_operand:HI 0 "nonimmediate_operand")
4329 (subreg:HI (match_dup 2) 0))]
4330 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4331 "operands[2] = gen_reg_rtx (SImode);")
4333 ;; When SSE is available, it is always faster to use it!
4334 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4335 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4336 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4337 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4338 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4339 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4340 [(set_attr "type" "sseicvt")
4341 (set_attr "prefix" "maybe_vex")
4342 (set (attr "prefix_rex")
4344 (match_test "<SWI48:MODE>mode == DImode")
4346 (const_string "*")))
4347 (set_attr "mode" "<MODEF:MODE>")
4348 (set_attr "athlon_decode" "double,vector")
4349 (set_attr "amdfam10_decode" "double,double")
4350 (set_attr "bdver1_decode" "double,double")])
4352 ;; Avoid vector decoded forms of the instruction.
4354 [(match_scratch:MODEF 2 "x")
4355 (set (match_operand:SWI48 0 "register_operand")
4356 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4357 "TARGET_AVOID_VECTOR_DECODE
4358 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4359 && optimize_insn_for_speed_p ()"
4360 [(set (match_dup 2) (match_dup 1))
4361 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4363 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4364 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4365 (fix:SWI248x (match_operand 1 "register_operand")))]
4366 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4368 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4369 && (TARGET_64BIT || <MODE>mode != DImode))
4371 && can_create_pseudo_p ()"
4376 if (memory_operand (operands[0], VOIDmode))
4377 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4380 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4381 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4387 [(set_attr "type" "fisttp")
4388 (set_attr "mode" "<MODE>")])
4390 (define_insn "fix_trunc<mode>_i387_fisttp"
4391 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4392 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4393 (clobber (match_scratch:XF 2 "=&1f"))]
4394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4396 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && (TARGET_64BIT || <MODE>mode != DImode))
4398 && TARGET_SSE_MATH)"
4399 "* return output_fix_trunc (insn, operands, true);"
4400 [(set_attr "type" "fisttp")
4401 (set_attr "mode" "<MODE>")])
4403 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4404 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4405 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4406 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4407 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4408 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4410 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4411 && (TARGET_64BIT || <MODE>mode != DImode))
4412 && TARGET_SSE_MATH)"
4414 [(set_attr "type" "fisttp")
4415 (set_attr "mode" "<MODE>")])
4418 [(set (match_operand:SWI248x 0 "register_operand")
4419 (fix:SWI248x (match_operand 1 "register_operand")))
4420 (clobber (match_operand:SWI248x 2 "memory_operand"))
4421 (clobber (match_scratch 3))]
4423 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4424 (clobber (match_dup 3))])
4425 (set (match_dup 0) (match_dup 2))])
4428 [(set (match_operand:SWI248x 0 "memory_operand")
4429 (fix:SWI248x (match_operand 1 "register_operand")))
4430 (clobber (match_operand:SWI248x 2 "memory_operand"))
4431 (clobber (match_scratch 3))]
4433 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4434 (clobber (match_dup 3))])])
4436 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4437 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4438 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4439 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4440 ;; function in i386.c.
4441 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4442 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4443 (fix:SWI248x (match_operand 1 "register_operand")))
4444 (clobber (reg:CC FLAGS_REG))]
4445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4447 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && (TARGET_64BIT || <MODE>mode != DImode))
4449 && can_create_pseudo_p ()"
4454 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4456 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4457 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4458 if (memory_operand (operands[0], VOIDmode))
4459 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4460 operands[2], operands[3]));
4463 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4464 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4465 operands[2], operands[3],
4470 [(set_attr "type" "fistp")
4471 (set_attr "i387_cw" "trunc")
4472 (set_attr "mode" "<MODE>")])
4474 (define_insn "fix_truncdi_i387"
4475 [(set (match_operand:DI 0 "memory_operand" "=m")
4476 (fix:DI (match_operand 1 "register_operand" "f")))
4477 (use (match_operand:HI 2 "memory_operand" "m"))
4478 (use (match_operand:HI 3 "memory_operand" "m"))
4479 (clobber (match_scratch:XF 4 "=&1f"))]
4480 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4482 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4483 "* return output_fix_trunc (insn, operands, false);"
4484 [(set_attr "type" "fistp")
4485 (set_attr "i387_cw" "trunc")
4486 (set_attr "mode" "DI")])
4488 (define_insn "fix_truncdi_i387_with_temp"
4489 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4490 (fix:DI (match_operand 1 "register_operand" "f,f")))
4491 (use (match_operand:HI 2 "memory_operand" "m,m"))
4492 (use (match_operand:HI 3 "memory_operand" "m,m"))
4493 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4494 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4495 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4497 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4499 [(set_attr "type" "fistp")
4500 (set_attr "i387_cw" "trunc")
4501 (set_attr "mode" "DI")])
4504 [(set (match_operand:DI 0 "register_operand")
4505 (fix:DI (match_operand 1 "register_operand")))
4506 (use (match_operand:HI 2 "memory_operand"))
4507 (use (match_operand:HI 3 "memory_operand"))
4508 (clobber (match_operand:DI 4 "memory_operand"))
4509 (clobber (match_scratch 5))]
4511 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4514 (clobber (match_dup 5))])
4515 (set (match_dup 0) (match_dup 4))])
4518 [(set (match_operand:DI 0 "memory_operand")
4519 (fix:DI (match_operand 1 "register_operand")))
4520 (use (match_operand:HI 2 "memory_operand"))
4521 (use (match_operand:HI 3 "memory_operand"))
4522 (clobber (match_operand:DI 4 "memory_operand"))
4523 (clobber (match_scratch 5))]
4525 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4528 (clobber (match_dup 5))])])
4530 (define_insn "fix_trunc<mode>_i387"
4531 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4532 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4533 (use (match_operand:HI 2 "memory_operand" "m"))
4534 (use (match_operand:HI 3 "memory_operand" "m"))]
4535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4538 "* return output_fix_trunc (insn, operands, false);"
4539 [(set_attr "type" "fistp")
4540 (set_attr "i387_cw" "trunc")
4541 (set_attr "mode" "<MODE>")])
4543 (define_insn "fix_trunc<mode>_i387_with_temp"
4544 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4545 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4546 (use (match_operand:HI 2 "memory_operand" "m,m"))
4547 (use (match_operand:HI 3 "memory_operand" "m,m"))
4548 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4549 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4551 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4553 [(set_attr "type" "fistp")
4554 (set_attr "i387_cw" "trunc")
4555 (set_attr "mode" "<MODE>")])
4558 [(set (match_operand:SWI24 0 "register_operand")
4559 (fix:SWI24 (match_operand 1 "register_operand")))
4560 (use (match_operand:HI 2 "memory_operand"))
4561 (use (match_operand:HI 3 "memory_operand"))
4562 (clobber (match_operand:SWI24 4 "memory_operand"))]
4564 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4566 (use (match_dup 3))])
4567 (set (match_dup 0) (match_dup 4))])
4570 [(set (match_operand:SWI24 0 "memory_operand")
4571 (fix:SWI24 (match_operand 1 "register_operand")))
4572 (use (match_operand:HI 2 "memory_operand"))
4573 (use (match_operand:HI 3 "memory_operand"))
4574 (clobber (match_operand:SWI24 4 "memory_operand"))]
4576 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4578 (use (match_dup 3))])])
4580 (define_insn "x86_fnstcw_1"
4581 [(set (match_operand:HI 0 "memory_operand" "=m")
4582 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4585 [(set (attr "length")
4586 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4587 (set_attr "mode" "HI")
4588 (set_attr "unit" "i387")
4589 (set_attr "bdver1_decode" "vector")])
4591 (define_insn "x86_fldcw_1"
4592 [(set (reg:HI FPCR_REG)
4593 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4596 [(set (attr "length")
4597 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4598 (set_attr "mode" "HI")
4599 (set_attr "unit" "i387")
4600 (set_attr "athlon_decode" "vector")
4601 (set_attr "amdfam10_decode" "vector")
4602 (set_attr "bdver1_decode" "vector")])
4604 ;; Conversion between fixed point and floating point.
4606 ;; Even though we only accept memory inputs, the backend _really_
4607 ;; wants to be able to do this between registers.
4609 (define_expand "floathi<mode>2"
4610 [(set (match_operand:X87MODEF 0 "register_operand")
4611 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4614 || TARGET_MIX_SSE_I387)")
4616 ;; Pre-reload splitter to add memory clobber to the pattern.
4617 (define_insn_and_split "*floathi<mode>2_1"
4618 [(set (match_operand:X87MODEF 0 "register_operand")
4619 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4622 || TARGET_MIX_SSE_I387)
4623 && can_create_pseudo_p ()"
4626 [(parallel [(set (match_dup 0)
4627 (float:X87MODEF (match_dup 1)))
4628 (clobber (match_dup 2))])]
4629 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4631 (define_insn "*floathi<mode>2_i387_with_temp"
4632 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4633 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4634 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4637 || TARGET_MIX_SSE_I387)"
4639 [(set_attr "type" "fmov,multi")
4640 (set_attr "mode" "<MODE>")
4641 (set_attr "unit" "*,i387")
4642 (set_attr "fp_int_src" "true")])
4644 (define_insn "*floathi<mode>2_i387"
4645 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4646 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4649 || TARGET_MIX_SSE_I387)"
4651 [(set_attr "type" "fmov")
4652 (set_attr "mode" "<MODE>")
4653 (set_attr "fp_int_src" "true")])
4656 [(set (match_operand:X87MODEF 0 "register_operand")
4657 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4658 (clobber (match_operand:HI 2 "memory_operand"))]
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)
4662 && reload_completed"
4663 [(set (match_dup 2) (match_dup 1))
4664 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4667 [(set (match_operand:X87MODEF 0 "register_operand")
4668 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4669 (clobber (match_operand:HI 2 "memory_operand"))]
4671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4672 || TARGET_MIX_SSE_I387)
4673 && reload_completed"
4674 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4676 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4677 [(set (match_operand:X87MODEF 0 "register_operand")
4679 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4681 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4682 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4684 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4685 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4686 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4688 rtx reg = gen_reg_rtx (XFmode);
4689 rtx (*insn)(rtx, rtx);
4691 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4693 if (<X87MODEF:MODE>mode == SFmode)
4694 insn = gen_truncxfsf2;
4695 else if (<X87MODEF:MODE>mode == DFmode)
4696 insn = gen_truncxfdf2;
4700 emit_insn (insn (operands[0], reg));
4705 ;; Pre-reload splitter to add memory clobber to the pattern.
4706 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4707 [(set (match_operand:X87MODEF 0 "register_operand")
4708 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4710 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4711 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4712 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4713 || TARGET_MIX_SSE_I387))
4714 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4715 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4716 && ((<SWI48x:MODE>mode == SImode
4717 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4718 && optimize_function_for_speed_p (cfun)
4719 && flag_trapping_math)
4720 || !(TARGET_INTER_UNIT_CONVERSIONS
4721 || optimize_function_for_size_p (cfun)))))
4722 && can_create_pseudo_p ()"
4725 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4726 (clobber (match_dup 2))])]
4728 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4730 /* Avoid store forwarding (partial memory) stall penalty
4731 by passing DImode value through XMM registers. */
4732 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4733 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4734 && optimize_function_for_speed_p (cfun))
4736 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4743 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4744 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4746 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4747 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4748 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4749 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4751 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4752 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4753 (set_attr "unit" "*,i387,*,*,*")
4754 (set_attr "athlon_decode" "*,*,double,direct,double")
4755 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4756 (set_attr "bdver1_decode" "*,*,double,direct,double")
4757 (set_attr "fp_int_src" "true")])
4759 (define_insn "*floatsi<mode>2_vector_mixed"
4760 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4761 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4762 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4763 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4767 [(set_attr "type" "fmov,sseicvt")
4768 (set_attr "mode" "<MODE>,<ssevecmode>")
4769 (set_attr "unit" "i387,*")
4770 (set_attr "athlon_decode" "*,direct")
4771 (set_attr "amdfam10_decode" "*,double")
4772 (set_attr "bdver1_decode" "*,direct")
4773 (set_attr "fp_int_src" "true")])
4775 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4776 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4778 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4779 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4780 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4782 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4783 (set_attr "mode" "<MODEF:MODE>")
4784 (set_attr "unit" "*,i387,*,*")
4785 (set_attr "athlon_decode" "*,*,double,direct")
4786 (set_attr "amdfam10_decode" "*,*,vector,double")
4787 (set_attr "bdver1_decode" "*,*,double,direct")
4788 (set_attr "fp_int_src" "true")])
4791 [(set (match_operand:MODEF 0 "register_operand")
4792 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4793 (clobber (match_operand:SWI48 2 "memory_operand"))]
4794 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4795 && TARGET_INTER_UNIT_CONVERSIONS
4796 && reload_completed && SSE_REG_P (operands[0])"
4797 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4800 [(set (match_operand:MODEF 0 "register_operand")
4801 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4802 (clobber (match_operand:SWI48 2 "memory_operand"))]
4803 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4804 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4805 && reload_completed && SSE_REG_P (operands[0])"
4806 [(set (match_dup 2) (match_dup 1))
4807 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4809 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4810 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4812 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4813 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4814 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4817 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4818 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4819 [(set_attr "type" "fmov,sseicvt,sseicvt")
4820 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4821 (set_attr "mode" "<MODEF:MODE>")
4822 (set (attr "prefix_rex")
4824 (and (eq_attr "prefix" "maybe_vex")
4825 (match_test "<SWI48:MODE>mode == DImode"))
4827 (const_string "*")))
4828 (set_attr "unit" "i387,*,*")
4829 (set_attr "athlon_decode" "*,double,direct")
4830 (set_attr "amdfam10_decode" "*,vector,double")
4831 (set_attr "bdver1_decode" "*,double,direct")
4832 (set_attr "fp_int_src" "true")])
4834 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4835 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4837 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4838 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4839 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4842 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4843 [(set_attr "type" "fmov,sseicvt")
4844 (set_attr "prefix" "orig,maybe_vex")
4845 (set_attr "mode" "<MODEF:MODE>")
4846 (set (attr "prefix_rex")
4848 (and (eq_attr "prefix" "maybe_vex")
4849 (match_test "<SWI48:MODE>mode == DImode"))
4851 (const_string "*")))
4852 (set_attr "athlon_decode" "*,direct")
4853 (set_attr "amdfam10_decode" "*,double")
4854 (set_attr "bdver1_decode" "*,direct")
4855 (set_attr "fp_int_src" "true")])
4857 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4858 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4860 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4861 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4862 "TARGET_SSE2 && TARGET_SSE_MATH
4863 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4865 [(set_attr "type" "sseicvt")
4866 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4867 (set_attr "athlon_decode" "double,direct,double")
4868 (set_attr "amdfam10_decode" "vector,double,double")
4869 (set_attr "bdver1_decode" "double,direct,double")
4870 (set_attr "fp_int_src" "true")])
4872 (define_insn "*floatsi<mode>2_vector_sse"
4873 [(set (match_operand:MODEF 0 "register_operand" "=x")
4874 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4875 "TARGET_SSE2 && TARGET_SSE_MATH
4876 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4878 [(set_attr "type" "sseicvt")
4879 (set_attr "mode" "<MODE>")
4880 (set_attr "athlon_decode" "direct")
4881 (set_attr "amdfam10_decode" "double")
4882 (set_attr "bdver1_decode" "direct")
4883 (set_attr "fp_int_src" "true")])
4886 [(set (match_operand:MODEF 0 "register_operand")
4887 (float:MODEF (match_operand:SI 1 "register_operand")))
4888 (clobber (match_operand:SI 2 "memory_operand"))]
4889 "TARGET_SSE2 && TARGET_SSE_MATH
4890 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4891 && reload_completed && SSE_REG_P (operands[0])"
4894 rtx op1 = operands[1];
4896 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4898 if (GET_CODE (op1) == SUBREG)
4899 op1 = SUBREG_REG (op1);
4901 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4903 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4904 emit_insn (gen_sse2_loadld (operands[4],
4905 CONST0_RTX (V4SImode), operands[1]));
4907 /* We can ignore possible trapping value in the
4908 high part of SSE register for non-trapping math. */
4909 else if (SSE_REG_P (op1) && !flag_trapping_math)
4910 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4913 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4914 emit_move_insn (operands[2], operands[1]);
4915 emit_insn (gen_sse2_loadld (operands[4],
4916 CONST0_RTX (V4SImode), operands[2]));
4918 if (<ssevecmode>mode == V4SFmode)
4919 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4921 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4926 [(set (match_operand:MODEF 0 "register_operand")
4927 (float:MODEF (match_operand:SI 1 "memory_operand")))
4928 (clobber (match_operand:SI 2 "memory_operand"))]
4929 "TARGET_SSE2 && TARGET_SSE_MATH
4930 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4931 && reload_completed && SSE_REG_P (operands[0])"
4934 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4936 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4938 emit_insn (gen_sse2_loadld (operands[4],
4939 CONST0_RTX (V4SImode), operands[1]));
4940 if (<ssevecmode>mode == V4SFmode)
4941 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4943 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4948 [(set (match_operand:MODEF 0 "register_operand")
4949 (float:MODEF (match_operand:SI 1 "register_operand")))]
4950 "TARGET_SSE2 && TARGET_SSE_MATH
4951 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4952 && reload_completed && SSE_REG_P (operands[0])"
4955 rtx op1 = operands[1];
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4962 if (GENERAL_REG_P (op1))
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4970 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4972 emit_insn (gen_sse2_loadld (operands[4],
4973 CONST0_RTX (V4SImode), operands[5]));
4974 ix86_free_from_memory (GET_MODE (operands[1]));
4977 /* We can ignore possible trapping value in the
4978 high part of SSE register for non-trapping math. */
4979 else if (SSE_REG_P (op1) && !flag_trapping_math)
4980 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4983 if (<ssevecmode>mode == V4SFmode)
4984 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4986 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4991 [(set (match_operand:MODEF 0 "register_operand")
4992 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4993 "TARGET_SSE2 && TARGET_SSE_MATH
4994 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4995 && reload_completed && SSE_REG_P (operands[0])"
4998 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5000 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5002 emit_insn (gen_sse2_loadld (operands[4],
5003 CONST0_RTX (V4SImode), operands[1]));
5004 if (<ssevecmode>mode == V4SFmode)
5005 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5007 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5011 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5012 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5014 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5015 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5016 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5018 [(set_attr "type" "sseicvt")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "athlon_decode" "double,direct")
5021 (set_attr "amdfam10_decode" "vector,double")
5022 (set_attr "bdver1_decode" "double,direct")
5023 (set_attr "btver2_decode" "double,double")
5024 (set_attr "fp_int_src" "true")])
5026 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5027 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5029 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5030 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5031 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5032 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5033 [(set_attr "type" "sseicvt")
5034 (set_attr "prefix" "maybe_vex")
5035 (set_attr "mode" "<MODEF:MODE>")
5036 (set (attr "prefix_rex")
5038 (and (eq_attr "prefix" "maybe_vex")
5039 (match_test "<SWI48:MODE>mode == DImode"))
5041 (const_string "*")))
5042 (set_attr "athlon_decode" "double,direct")
5043 (set_attr "amdfam10_decode" "vector,double")
5044 (set_attr "bdver1_decode" "double,direct")
5045 (set_attr "btver2_decode" "double,double")
5046 (set_attr "fp_int_src" "true")])
5049 [(set (match_operand:MODEF 0 "register_operand")
5050 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5051 (clobber (match_operand:SWI48 2 "memory_operand"))]
5052 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5053 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5054 && reload_completed && SSE_REG_P (operands[0])"
5055 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5057 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5058 [(set (match_operand:MODEF 0 "register_operand" "=x")
5060 (match_operand:SWI48 1 "memory_operand" "m")))]
5061 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5062 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5063 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5064 [(set_attr "type" "sseicvt")
5065 (set_attr "prefix" "maybe_vex")
5066 (set_attr "mode" "<MODEF:MODE>")
5067 (set (attr "prefix_rex")
5069 (and (eq_attr "prefix" "maybe_vex")
5070 (match_test "<SWI48:MODE>mode == DImode"))
5072 (const_string "*")))
5073 (set_attr "athlon_decode" "direct")
5074 (set_attr "amdfam10_decode" "double")
5075 (set_attr "bdver1_decode" "direct")
5076 (set_attr "fp_int_src" "true")])
5079 [(set (match_operand:MODEF 0 "register_operand")
5080 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5081 (clobber (match_operand:SWI48 2 "memory_operand"))]
5082 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5083 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5084 && reload_completed && SSE_REG_P (operands[0])"
5085 [(set (match_dup 2) (match_dup 1))
5086 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5089 [(set (match_operand:MODEF 0 "register_operand")
5090 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5091 (clobber (match_operand:SWI48 2 "memory_operand"))]
5092 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5093 && reload_completed && SSE_REG_P (operands[0])"
5094 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5096 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5097 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5099 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5100 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5102 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5106 [(set_attr "type" "fmov,multi")
5107 (set_attr "mode" "<X87MODEF:MODE>")
5108 (set_attr "unit" "*,i387")
5109 (set_attr "fp_int_src" "true")])
5111 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5112 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5114 (match_operand:SWI48x 1 "memory_operand" "m")))]
5116 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5118 [(set_attr "type" "fmov")
5119 (set_attr "mode" "<X87MODEF:MODE>")
5120 (set_attr "fp_int_src" "true")])
5123 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5124 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5125 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5127 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5128 && reload_completed"
5129 [(set (match_dup 2) (match_dup 1))
5130 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5133 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5134 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5135 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5137 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5138 && reload_completed"
5139 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5141 ;; Avoid partial SSE register dependency stalls
5144 [(set (match_operand:MODEF 0 "register_operand")
5145 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5146 "TARGET_SSE2 && TARGET_SSE_MATH
5147 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5148 && optimize_function_for_speed_p (cfun)
5149 && reload_completed && SSE_REG_P (operands[0])"
5151 (vec_merge:<ssevecmode>
5152 (vec_duplicate:<ssevecmode>
5153 (float:MODEF (match_dup 1)))
5157 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5159 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5163 [(set (match_operand:MODEF 0 "register_operand")
5164 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5165 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5166 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5167 && optimize_function_for_speed_p (cfun)
5168 && reload_completed && SSE_REG_P (operands[0])"
5170 (vec_merge:<ssevecmode>
5171 (vec_duplicate:<ssevecmode>
5172 (float:MODEF (match_dup 1)))
5176 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5178 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5181 ;; Break partial reg stall for cvtsd2ss.
5184 [(set (match_operand:SF 0 "register_operand")
5186 (match_operand:DF 1 "nonimmediate_operand")))]
5187 "TARGET_SSE2 && TARGET_SSE_MATH
5188 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5189 && optimize_function_for_speed_p (cfun)
5190 && SSE_REG_P (operands[0])
5191 && (!SSE_REG_P (operands[1])
5192 || REGNO (operands[0]) != REGNO (operands[1]))"
5196 (float_truncate:V2SF
5201 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5203 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5205 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5208 ;; Break partial reg stall for cvtss2sd.
5211 [(set (match_operand:DF 0 "register_operand")
5213 (match_operand:SF 1 "nonimmediate_operand")))]
5214 "TARGET_SSE2 && TARGET_SSE_MATH
5215 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5216 && optimize_function_for_speed_p (cfun)
5217 && SSE_REG_P (operands[0])
5218 && (!SSE_REG_P (operands[1])
5219 || REGNO (operands[0]) != REGNO (operands[1]))"
5225 (parallel [(const_int 0) (const_int 1)])))
5229 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5231 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5233 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5236 ;; Avoid store forwarding (partial memory) stall penalty
5237 ;; by passing DImode value through XMM registers. */
5239 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5240 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5242 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5243 (clobber (match_scratch:V4SI 3 "=X,x"))
5244 (clobber (match_scratch:V4SI 4 "=X,x"))
5245 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5246 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5247 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5248 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5250 [(set_attr "type" "multi")
5251 (set_attr "mode" "<X87MODEF:MODE>")
5252 (set_attr "unit" "i387")
5253 (set_attr "fp_int_src" "true")])
5256 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5257 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5258 (clobber (match_scratch:V4SI 3))
5259 (clobber (match_scratch:V4SI 4))
5260 (clobber (match_operand:DI 2 "memory_operand"))]
5261 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5262 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5263 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5264 && reload_completed"
5265 [(set (match_dup 2) (match_dup 3))
5266 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5268 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5269 Assemble the 64-bit DImode value in an xmm register. */
5270 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5271 gen_rtx_SUBREG (SImode, operands[1], 0)));
5272 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5273 gen_rtx_SUBREG (SImode, operands[1], 4)));
5274 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5277 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5282 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5283 (clobber (match_scratch:V4SI 3))
5284 (clobber (match_scratch:V4SI 4))
5285 (clobber (match_operand:DI 2 "memory_operand"))]
5286 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5287 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5288 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5289 && reload_completed"
5290 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5292 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5293 [(set (match_operand:MODEF 0 "register_operand")
5294 (unsigned_float:MODEF
5295 (match_operand:SWI12 1 "nonimmediate_operand")))]
5297 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5299 operands[1] = convert_to_mode (SImode, operands[1], 1);
5300 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5304 ;; Avoid store forwarding (partial memory) stall penalty by extending
5305 ;; SImode value to DImode through XMM register instead of pushing two
5306 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5307 ;; targets benefit from this optimization. Also note that fild
5308 ;; loads from memory only.
5310 (define_insn "*floatunssi<mode>2_1"
5311 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5312 (unsigned_float:X87MODEF
5313 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5314 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5315 (clobber (match_scratch:SI 3 "=X,x"))]
5317 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5320 [(set_attr "type" "multi")
5321 (set_attr "mode" "<MODE>")])
5324 [(set (match_operand:X87MODEF 0 "register_operand")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "register_operand")))
5327 (clobber (match_operand:DI 2 "memory_operand"))
5328 (clobber (match_scratch:SI 3))]
5330 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 && reload_completed"
5333 [(set (match_dup 2) (match_dup 1))
5335 (float:X87MODEF (match_dup 2)))]
5336 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5339 [(set (match_operand:X87MODEF 0 "register_operand")
5340 (unsigned_float:X87MODEF
5341 (match_operand:SI 1 "memory_operand")))
5342 (clobber (match_operand:DI 2 "memory_operand"))
5343 (clobber (match_scratch:SI 3))]
5345 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5347 && reload_completed"
5348 [(set (match_dup 2) (match_dup 3))
5350 (float:X87MODEF (match_dup 2)))]
5352 emit_move_insn (operands[3], operands[1]);
5353 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5356 (define_expand "floatunssi<mode>2"
5358 [(set (match_operand:X87MODEF 0 "register_operand")
5359 (unsigned_float:X87MODEF
5360 (match_operand:SI 1 "nonimmediate_operand")))
5361 (clobber (match_dup 2))
5362 (clobber (match_scratch:SI 3))])]
5364 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5366 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5368 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5370 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5374 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5377 (define_expand "floatunsdisf2"
5378 [(use (match_operand:SF 0 "register_operand"))
5379 (use (match_operand:DI 1 "nonimmediate_operand"))]
5380 "TARGET_64BIT && TARGET_SSE_MATH"
5381 "x86_emit_floatuns (operands); DONE;")
5383 (define_expand "floatunsdidf2"
5384 [(use (match_operand:DF 0 "register_operand"))
5385 (use (match_operand:DI 1 "nonimmediate_operand"))]
5386 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5387 && TARGET_SSE2 && TARGET_SSE_MATH"
5390 x86_emit_floatuns (operands);
5392 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5396 ;; Load effective address instructions
5398 (define_insn_and_split "*lea<mode>"
5399 [(set (match_operand:SWI48 0 "register_operand" "=r")
5400 (match_operand:SWI48 1 "address_no_seg_operand" "p"))]
5403 if (SImode_address_operand (operands[1], VOIDmode))
5405 gcc_assert (TARGET_64BIT);
5406 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5409 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5411 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5414 enum machine_mode mode = <MODE>mode;
5417 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5418 change operands[] array behind our back. */
5419 pat = PATTERN (curr_insn);
5421 operands[0] = SET_DEST (pat);
5422 operands[1] = SET_SRC (pat);
5424 /* Emit all operations in SImode for zero-extended addresses. Recall
5425 that x86_64 inheretly zero-extends SImode operations to DImode. */
5426 if (SImode_address_operand (operands[1], VOIDmode))
5429 ix86_split_lea_for_addr (curr_insn, operands, mode);
5432 [(set_attr "type" "lea")
5435 (match_operand 1 "SImode_address_operand")
5437 (const_string "<MODE>")))])
5441 (define_expand "add<mode>3"
5442 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5443 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5444 (match_operand:SDWIM 2 "<general_operand>")))]
5446 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5448 (define_insn_and_split "*add<dwi>3_doubleword"
5449 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5451 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5452 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5453 (clobber (reg:CC FLAGS_REG))]
5454 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5457 [(parallel [(set (reg:CC FLAGS_REG)
5458 (unspec:CC [(match_dup 1) (match_dup 2)]
5461 (plus:DWIH (match_dup 1) (match_dup 2)))])
5462 (parallel [(set (match_dup 3)
5466 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5468 (clobber (reg:CC FLAGS_REG))])]
5469 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5471 (define_insn "*add<mode>3_cc"
5472 [(set (reg:CC FLAGS_REG)
5474 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5475 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5477 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5478 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5479 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5480 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5481 [(set_attr "type" "alu")
5482 (set_attr "mode" "<MODE>")])
5484 (define_insn "addqi3_cc"
5485 [(set (reg:CC FLAGS_REG)
5487 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5488 (match_operand:QI 2 "general_operand" "qn,qm")]
5490 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5491 (plus:QI (match_dup 1) (match_dup 2)))]
5492 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5493 "add{b}\t{%2, %0|%0, %2}"
5494 [(set_attr "type" "alu")
5495 (set_attr "mode" "QI")])
5497 (define_insn "*add<mode>_1"
5498 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5500 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5501 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5502 (clobber (reg:CC FLAGS_REG))]
5503 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5505 switch (get_attr_type (insn))
5511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5512 if (operands[2] == const1_rtx)
5513 return "inc{<imodesuffix>}\t%0";
5516 gcc_assert (operands[2] == constm1_rtx);
5517 return "dec{<imodesuffix>}\t%0";
5521 /* For most processors, ADD is faster than LEA. This alternative
5522 was added to use ADD as much as possible. */
5523 if (which_alternative == 2)
5526 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5531 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5533 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5537 (cond [(eq_attr "alternative" "3")
5538 (const_string "lea")
5539 (match_operand:SWI48 2 "incdec_operand")
5540 (const_string "incdec")
5542 (const_string "alu")))
5543 (set (attr "length_immediate")
5545 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5547 (const_string "*")))
5548 (set_attr "mode" "<MODE>")])
5550 ;; It may seem that nonimmediate operand is proper one for operand 1.
5551 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5552 ;; we take care in ix86_binary_operator_ok to not allow two memory
5553 ;; operands so proper swapping will be done in reload. This allow
5554 ;; patterns constructed from addsi_1 to match.
5556 (define_insn "addsi_1_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5559 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5560 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5561 (clobber (reg:CC FLAGS_REG))]
5562 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5564 switch (get_attr_type (insn))
5570 if (operands[2] == const1_rtx)
5571 return "inc{l}\t%k0";
5574 gcc_assert (operands[2] == constm1_rtx);
5575 return "dec{l}\t%k0";
5579 /* For most processors, ADD is faster than LEA. This alternative
5580 was added to use ADD as much as possible. */
5581 if (which_alternative == 1)
5584 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5587 if (x86_maybe_negate_const_int (&operands[2], SImode))
5588 return "sub{l}\t{%2, %k0|%k0, %2}";
5590 return "add{l}\t{%2, %k0|%k0, %2}";
5594 (cond [(eq_attr "alternative" "2")
5595 (const_string "lea")
5596 (match_operand:SI 2 "incdec_operand")
5597 (const_string "incdec")
5599 (const_string "alu")))
5600 (set (attr "length_immediate")
5602 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604 (const_string "*")))
5605 (set_attr "mode" "SI")])
5607 (define_insn "*addhi_1"
5608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5609 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5610 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5611 (clobber (reg:CC FLAGS_REG))]
5612 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5614 switch (get_attr_type (insn))
5620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621 if (operands[2] == const1_rtx)
5622 return "inc{w}\t%0";
5625 gcc_assert (operands[2] == constm1_rtx);
5626 return "dec{w}\t%0";
5630 /* For most processors, ADD is faster than LEA. This alternative
5631 was added to use ADD as much as possible. */
5632 if (which_alternative == 2)
5635 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (x86_maybe_negate_const_int (&operands[2], HImode))
5640 return "sub{w}\t{%2, %0|%0, %2}";
5642 return "add{w}\t{%2, %0|%0, %2}";
5646 (cond [(eq_attr "alternative" "3")
5647 (const_string "lea")
5648 (match_operand:HI 2 "incdec_operand")
5649 (const_string "incdec")
5651 (const_string "alu")))
5652 (set (attr "length_immediate")
5654 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5656 (const_string "*")))
5657 (set_attr "mode" "HI,HI,HI,SI")])
5659 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5660 (define_insn "*addqi_1"
5661 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5662 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5663 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5664 (clobber (reg:CC FLAGS_REG))]
5665 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5667 bool widen = (which_alternative == 3 || which_alternative == 4);
5669 switch (get_attr_type (insn))
5675 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676 if (operands[2] == const1_rtx)
5677 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5680 gcc_assert (operands[2] == constm1_rtx);
5681 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5685 /* For most processors, ADD is faster than LEA. These alternatives
5686 were added to use ADD as much as possible. */
5687 if (which_alternative == 2 || which_alternative == 4)
5690 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5693 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5694 if (x86_maybe_negate_const_int (&operands[2], QImode))
5697 return "sub{l}\t{%2, %k0|%k0, %2}";
5699 return "sub{b}\t{%2, %0|%0, %2}";
5702 return "add{l}\t{%k2, %k0|%k0, %k2}";
5704 return "add{b}\t{%2, %0|%0, %2}";
5708 (cond [(eq_attr "alternative" "5")
5709 (const_string "lea")
5710 (match_operand:QI 2 "incdec_operand")
5711 (const_string "incdec")
5713 (const_string "alu")))
5714 (set (attr "length_immediate")
5716 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5718 (const_string "*")))
5719 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5721 (define_insn "*addqi_1_slp"
5722 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5723 (plus:QI (match_dup 0)
5724 (match_operand:QI 1 "general_operand" "qn,qm")))
5725 (clobber (reg:CC FLAGS_REG))]
5726 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5727 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5729 switch (get_attr_type (insn))
5732 if (operands[1] == const1_rtx)
5733 return "inc{b}\t%0";
5736 gcc_assert (operands[1] == constm1_rtx);
5737 return "dec{b}\t%0";
5741 if (x86_maybe_negate_const_int (&operands[1], QImode))
5742 return "sub{b}\t{%1, %0|%0, %1}";
5744 return "add{b}\t{%1, %0|%0, %1}";
5748 (if_then_else (match_operand:QI 1 "incdec_operand")
5749 (const_string "incdec")
5750 (const_string "alu1")))
5751 (set (attr "memory")
5752 (if_then_else (match_operand 1 "memory_operand")
5753 (const_string "load")
5754 (const_string "none")))
5755 (set_attr "mode" "QI")])
5757 ;; Split non destructive adds if we cannot use lea.
5759 [(set (match_operand:SWI48 0 "register_operand")
5760 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5761 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5762 (clobber (reg:CC FLAGS_REG))]
5763 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5764 [(set (match_dup 0) (match_dup 1))
5765 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5766 (clobber (reg:CC FLAGS_REG))])])
5768 ;; Convert add to the lea pattern to avoid flags dependency.
5770 [(set (match_operand:SWI 0 "register_operand")
5771 (plus:SWI (match_operand:SWI 1 "register_operand")
5772 (match_operand:SWI 2 "<nonmemory_operand>")))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5777 enum machine_mode mode = <MODE>mode;
5780 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5783 operands[0] = gen_lowpart (mode, operands[0]);
5784 operands[1] = gen_lowpart (mode, operands[1]);
5785 operands[2] = gen_lowpart (mode, operands[2]);
5788 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5790 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5794 ;; Split non destructive adds if we cannot use lea.
5796 [(set (match_operand:DI 0 "register_operand")
5798 (plus:SI (match_operand:SI 1 "register_operand")
5799 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5800 (clobber (reg:CC FLAGS_REG))]
5802 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5803 [(set (match_dup 3) (match_dup 1))
5804 (parallel [(set (match_dup 0)
5805 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5806 (clobber (reg:CC FLAGS_REG))])]
5807 "operands[3] = gen_lowpart (SImode, operands[0]);")
5809 ;; Convert add to the lea pattern to avoid flags dependency.
5811 [(set (match_operand:DI 0 "register_operand")
5813 (plus:SI (match_operand:SI 1 "register_operand")
5814 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5818 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5820 (define_insn "*add<mode>_2"
5821 [(set (reg FLAGS_REG)
5824 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5825 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5827 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5828 (plus:SWI (match_dup 1) (match_dup 2)))]
5829 "ix86_match_ccmode (insn, CCGOCmode)
5830 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5832 switch (get_attr_type (insn))
5835 if (operands[2] == const1_rtx)
5836 return "inc{<imodesuffix>}\t%0";
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{<imodesuffix>}\t%0";
5844 if (which_alternative == 2)
5847 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5850 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5851 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5852 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5854 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5858 (if_then_else (match_operand:SWI 2 "incdec_operand")
5859 (const_string "incdec")
5860 (const_string "alu")))
5861 (set (attr "length_immediate")
5863 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5865 (const_string "*")))
5866 (set_attr "mode" "<MODE>")])
5868 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5869 (define_insn "*addsi_2_zext"
5870 [(set (reg FLAGS_REG)
5872 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5873 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5875 (set (match_operand:DI 0 "register_operand" "=r,r")
5876 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5877 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5878 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5880 switch (get_attr_type (insn))
5883 if (operands[2] == const1_rtx)
5884 return "inc{l}\t%k0";
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{l}\t%k0";
5892 if (which_alternative == 1)
5895 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5898 if (x86_maybe_negate_const_int (&operands[2], SImode))
5899 return "sub{l}\t{%2, %k0|%k0, %2}";
5901 return "add{l}\t{%2, %k0|%k0, %2}";
5905 (if_then_else (match_operand:SI 2 "incdec_operand")
5906 (const_string "incdec")
5907 (const_string "alu")))
5908 (set (attr "length_immediate")
5910 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5912 (const_string "*")))
5913 (set_attr "mode" "SI")])
5915 (define_insn "*add<mode>_3"
5916 [(set (reg FLAGS_REG)
5918 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5919 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5920 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5921 "ix86_match_ccmode (insn, CCZmode)
5922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5924 switch (get_attr_type (insn))
5927 if (operands[2] == const1_rtx)
5928 return "inc{<imodesuffix>}\t%0";
5931 gcc_assert (operands[2] == constm1_rtx);
5932 return "dec{<imodesuffix>}\t%0";
5936 if (which_alternative == 1)
5939 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5944 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5946 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5950 (if_then_else (match_operand:SWI 2 "incdec_operand")
5951 (const_string "incdec")
5952 (const_string "alu")))
5953 (set (attr "length_immediate")
5955 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5957 (const_string "*")))
5958 (set_attr "mode" "<MODE>")])
5960 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5961 (define_insn "*addsi_3_zext"
5962 [(set (reg FLAGS_REG)
5964 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5965 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5966 (set (match_operand:DI 0 "register_operand" "=r,r")
5967 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5968 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5969 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5971 switch (get_attr_type (insn))
5974 if (operands[2] == const1_rtx)
5975 return "inc{l}\t%k0";
5978 gcc_assert (operands[2] == constm1_rtx);
5979 return "dec{l}\t%k0";
5983 if (which_alternative == 1)
5986 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5989 if (x86_maybe_negate_const_int (&operands[2], SImode))
5990 return "sub{l}\t{%2, %k0|%k0, %2}";
5992 return "add{l}\t{%2, %k0|%k0, %2}";
5996 (if_then_else (match_operand:SI 2 "incdec_operand")
5997 (const_string "incdec")
5998 (const_string "alu")))
5999 (set (attr "length_immediate")
6001 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6003 (const_string "*")))
6004 (set_attr "mode" "SI")])
6006 ; For comparisons against 1, -1 and 128, we may generate better code
6007 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6008 ; is matched then. We can't accept general immediate, because for
6009 ; case of overflows, the result is messed up.
6010 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6011 ; only for comparisons not depending on it.
6013 (define_insn "*adddi_4"
6014 [(set (reg FLAGS_REG)
6016 (match_operand:DI 1 "nonimmediate_operand" "0")
6017 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6018 (clobber (match_scratch:DI 0 "=rm"))]
6020 && ix86_match_ccmode (insn, CCGCmode)"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == constm1_rtx)
6026 return "inc{q}\t%0";
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{q}\t%0";
6034 if (x86_maybe_negate_const_int (&operands[2], DImode))
6035 return "add{q}\t{%2, %0|%0, %2}";
6037 return "sub{q}\t{%2, %0|%0, %2}";
6041 (if_then_else (match_operand:DI 2 "incdec_operand")
6042 (const_string "incdec")
6043 (const_string "alu")))
6044 (set (attr "length_immediate")
6046 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6048 (const_string "*")))
6049 (set_attr "mode" "DI")])
6051 ; For comparisons against 1, -1 and 128, we may generate better code
6052 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6053 ; is matched then. We can't accept general immediate, because for
6054 ; case of overflows, the result is messed up.
6055 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6056 ; only for comparisons not depending on it.
6058 (define_insn "*add<mode>_4"
6059 [(set (reg FLAGS_REG)
6061 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6062 (match_operand:SWI124 2 "const_int_operand" "n")))
6063 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6064 "ix86_match_ccmode (insn, CCGCmode)"
6066 switch (get_attr_type (insn))
6069 if (operands[2] == constm1_rtx)
6070 return "inc{<imodesuffix>}\t%0";
6073 gcc_assert (operands[2] == const1_rtx);
6074 return "dec{<imodesuffix>}\t%0";
6078 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6079 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6081 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6085 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6086 (const_string "incdec")
6087 (const_string "alu")))
6088 (set (attr "length_immediate")
6090 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6092 (const_string "*")))
6093 (set_attr "mode" "<MODE>")])
6095 (define_insn "*add<mode>_5"
6096 [(set (reg FLAGS_REG)
6099 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6100 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6102 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6103 "ix86_match_ccmode (insn, CCGOCmode)
6104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6106 switch (get_attr_type (insn))
6109 if (operands[2] == const1_rtx)
6110 return "inc{<imodesuffix>}\t%0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{<imodesuffix>}\t%0";
6118 if (which_alternative == 1)
6121 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6124 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6125 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6126 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6128 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6132 (if_then_else (match_operand:SWI 2 "incdec_operand")
6133 (const_string "incdec")
6134 (const_string "alu")))
6135 (set (attr "length_immediate")
6137 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6139 (const_string "*")))
6140 (set_attr "mode" "<MODE>")])
6142 (define_insn "addqi_ext_1"
6143 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6148 (match_operand 1 "ext_register_operand" "0,0")
6151 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6152 (clobber (reg:CC FLAGS_REG))]
6155 switch (get_attr_type (insn))
6158 if (operands[2] == const1_rtx)
6159 return "inc{b}\t%h0";
6162 gcc_assert (operands[2] == constm1_rtx);
6163 return "dec{b}\t%h0";
6167 return "add{b}\t{%2, %h0|%h0, %2}";
6170 [(set_attr "isa" "*,nox64")
6172 (if_then_else (match_operand:QI 2 "incdec_operand")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set_attr "modrm" "1")
6176 (set_attr "mode" "QI")])
6178 (define_insn "*addqi_ext_2"
6179 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6184 (match_operand 1 "ext_register_operand" "%0")
6188 (match_operand 2 "ext_register_operand" "Q")
6191 (clobber (reg:CC FLAGS_REG))]
6193 "add{b}\t{%h2, %h0|%h0, %h2}"
6194 [(set_attr "type" "alu")
6195 (set_attr "mode" "QI")])
6197 ;; The lea patterns for modes less than 32 bits need to be matched by
6198 ;; several insns converted to real lea by splitters.
6200 (define_insn_and_split "*lea_general_1"
6201 [(set (match_operand 0 "register_operand" "=r")
6202 (plus (plus (match_operand 1 "index_register_operand" "l")
6203 (match_operand 2 "register_operand" "r"))
6204 (match_operand 3 "immediate_operand" "i")))]
6205 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6206 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6207 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6208 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6209 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6210 || GET_MODE (operands[3]) == VOIDmode)"
6212 "&& reload_completed"
6215 enum machine_mode mode = SImode;
6218 operands[0] = gen_lowpart (mode, operands[0]);
6219 operands[1] = gen_lowpart (mode, operands[1]);
6220 operands[2] = gen_lowpart (mode, operands[2]);
6221 operands[3] = gen_lowpart (mode, operands[3]);
6223 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6226 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6229 [(set_attr "type" "lea")
6230 (set_attr "mode" "SI")])
6232 (define_insn_and_split "*lea_general_2"
6233 [(set (match_operand 0 "register_operand" "=r")
6234 (plus (mult (match_operand 1 "index_register_operand" "l")
6235 (match_operand 2 "const248_operand" "n"))
6236 (match_operand 3 "nonmemory_operand" "ri")))]
6237 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6238 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6239 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6240 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6241 || GET_MODE (operands[3]) == VOIDmode)"
6243 "&& reload_completed"
6246 enum machine_mode mode = SImode;
6249 operands[0] = gen_lowpart (mode, operands[0]);
6250 operands[1] = gen_lowpart (mode, operands[1]);
6251 operands[3] = gen_lowpart (mode, operands[3]);
6253 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6256 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6259 [(set_attr "type" "lea")
6260 (set_attr "mode" "SI")])
6262 (define_insn_and_split "*lea_general_3"
6263 [(set (match_operand 0 "register_operand" "=r")
6264 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6265 (match_operand 2 "const248_operand" "n"))
6266 (match_operand 3 "register_operand" "r"))
6267 (match_operand 4 "immediate_operand" "i")))]
6268 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6269 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6270 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6271 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6273 "&& reload_completed"
6276 enum machine_mode mode = SImode;
6279 operands[0] = gen_lowpart (mode, operands[0]);
6280 operands[1] = gen_lowpart (mode, operands[1]);
6281 operands[3] = gen_lowpart (mode, operands[3]);
6282 operands[4] = gen_lowpart (mode, operands[4]);
6284 pat = gen_rtx_PLUS (mode,
6286 gen_rtx_MULT (mode, operands[1],
6291 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6294 [(set_attr "type" "lea")
6295 (set_attr "mode" "SI")])
6297 (define_insn_and_split "*lea_general_4"
6298 [(set (match_operand 0 "register_operand" "=r")
6300 (match_operand 1 "index_register_operand" "l")
6301 (match_operand 2 "const_int_operand" "n"))
6302 (match_operand 3 "const_int_operand" "n")))]
6303 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6305 || GET_MODE (operands[0]) == SImode
6306 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6307 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6309 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6310 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6312 "&& reload_completed"
6315 enum machine_mode mode = GET_MODE (operands[0]);
6318 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6321 operands[0] = gen_lowpart (mode, operands[0]);
6322 operands[1] = gen_lowpart (mode, operands[1]);
6325 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6327 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6328 INTVAL (operands[3]));
6330 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6333 [(set_attr "type" "lea")
6335 (if_then_else (match_operand:DI 0)
6337 (const_string "SI")))])
6339 ;; Subtract instructions
6341 (define_expand "sub<mode>3"
6342 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6343 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6344 (match_operand:SDWIM 2 "<general_operand>")))]
6346 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6348 (define_insn_and_split "*sub<dwi>3_doubleword"
6349 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6351 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6352 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6353 (clobber (reg:CC FLAGS_REG))]
6354 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6357 [(parallel [(set (reg:CC FLAGS_REG)
6358 (compare:CC (match_dup 1) (match_dup 2)))
6360 (minus:DWIH (match_dup 1) (match_dup 2)))])
6361 (parallel [(set (match_dup 3)
6365 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6367 (clobber (reg:CC FLAGS_REG))])]
6368 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6370 (define_insn "*sub<mode>_1"
6371 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6373 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6374 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6375 (clobber (reg:CC FLAGS_REG))]
6376 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6377 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6378 [(set_attr "type" "alu")
6379 (set_attr "mode" "<MODE>")])
6381 (define_insn "*subsi_1_zext"
6382 [(set (match_operand:DI 0 "register_operand" "=r")
6384 (minus:SI (match_operand:SI 1 "register_operand" "0")
6385 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6386 (clobber (reg:CC FLAGS_REG))]
6387 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6388 "sub{l}\t{%2, %k0|%k0, %2}"
6389 [(set_attr "type" "alu")
6390 (set_attr "mode" "SI")])
6392 (define_insn "*subqi_1_slp"
6393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6394 (minus:QI (match_dup 0)
6395 (match_operand:QI 1 "general_operand" "qn,qm")))
6396 (clobber (reg:CC FLAGS_REG))]
6397 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6399 "sub{b}\t{%1, %0|%0, %1}"
6400 [(set_attr "type" "alu1")
6401 (set_attr "mode" "QI")])
6403 (define_insn "*sub<mode>_2"
6404 [(set (reg FLAGS_REG)
6407 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6408 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6410 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6411 (minus:SWI (match_dup 1) (match_dup 2)))]
6412 "ix86_match_ccmode (insn, CCGOCmode)
6413 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6414 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6415 [(set_attr "type" "alu")
6416 (set_attr "mode" "<MODE>")])
6418 (define_insn "*subsi_2_zext"
6419 [(set (reg FLAGS_REG)
6421 (minus:SI (match_operand:SI 1 "register_operand" "0")
6422 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6424 (set (match_operand:DI 0 "register_operand" "=r")
6426 (minus:SI (match_dup 1)
6428 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6429 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6430 "sub{l}\t{%2, %k0|%k0, %2}"
6431 [(set_attr "type" "alu")
6432 (set_attr "mode" "SI")])
6434 (define_insn "*sub<mode>_3"
6435 [(set (reg FLAGS_REG)
6436 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6437 (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, CCmode)
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_3_zext"
6447 [(set (reg FLAGS_REG)
6448 (compare (match_operand:SI 1 "register_operand" "0")
6449 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6450 (set (match_operand:DI 0 "register_operand" "=r")
6452 (minus:SI (match_dup 1)
6454 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6455 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6456 "sub{l}\t{%2, %1|%1, %2}"
6457 [(set_attr "type" "alu")
6458 (set_attr "mode" "SI")])
6460 ;; Add with carry and subtract with borrow
6462 (define_expand "<plusminus_insn><mode>3_carry"
6464 [(set (match_operand:SWI 0 "nonimmediate_operand")
6466 (match_operand:SWI 1 "nonimmediate_operand")
6467 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6468 [(match_operand 3 "flags_reg_operand")
6470 (match_operand:SWI 2 "<general_operand>"))))
6471 (clobber (reg:CC FLAGS_REG))])]
6472 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6474 (define_insn "*<plusminus_insn><mode>3_carry"
6475 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6477 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6479 (match_operator 3 "ix86_carry_flag_operator"
6480 [(reg FLAGS_REG) (const_int 0)])
6481 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6482 (clobber (reg:CC FLAGS_REG))]
6483 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6484 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6485 [(set_attr "type" "alu")
6486 (set_attr "use_carry" "1")
6487 (set_attr "pent_pair" "pu")
6488 (set_attr "mode" "<MODE>")])
6490 (define_insn "*addsi3_carry_zext"
6491 [(set (match_operand:DI 0 "register_operand" "=r")
6493 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6494 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6495 [(reg FLAGS_REG) (const_int 0)])
6496 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6497 (clobber (reg:CC FLAGS_REG))]
6498 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6499 "adc{l}\t{%2, %k0|%k0, %2}"
6500 [(set_attr "type" "alu")
6501 (set_attr "use_carry" "1")
6502 (set_attr "pent_pair" "pu")
6503 (set_attr "mode" "SI")])
6505 (define_insn "*subsi3_carry_zext"
6506 [(set (match_operand:DI 0 "register_operand" "=r")
6508 (minus:SI (match_operand:SI 1 "register_operand" "0")
6509 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6510 [(reg FLAGS_REG) (const_int 0)])
6511 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6512 (clobber (reg:CC FLAGS_REG))]
6513 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6514 "sbb{l}\t{%2, %k0|%k0, %2}"
6515 [(set_attr "type" "alu")
6516 (set_attr "pent_pair" "pu")
6517 (set_attr "mode" "SI")])
6521 (define_insn "adcx<mode>3"
6522 [(set (reg:CCC FLAGS_REG)
6525 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6527 (match_operator 4 "ix86_carry_flag_operator"
6528 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6529 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6531 (set (match_operand:SWI48 0 "register_operand" "=r")
6532 (plus:SWI48 (match_dup 1)
6533 (plus:SWI48 (match_op_dup 4
6534 [(match_dup 3) (const_int 0)])
6536 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6537 "adcx\t{%2, %0|%0, %2}"
6538 [(set_attr "type" "alu")
6539 (set_attr "use_carry" "1")
6540 (set_attr "mode" "<MODE>")])
6542 ;; Overflow setting add instructions
6544 (define_insn "*add<mode>3_cconly_overflow"
6545 [(set (reg:CCC FLAGS_REG)
6548 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6549 (match_operand:SWI 2 "<general_operand>" "<g>"))
6551 (clobber (match_scratch:SWI 0 "=<r>"))]
6552 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6553 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "mode" "<MODE>")])
6557 (define_insn "*add<mode>3_cc_overflow"
6558 [(set (reg:CCC FLAGS_REG)
6561 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6562 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6564 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6565 (plus:SWI (match_dup 1) (match_dup 2)))]
6566 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6567 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "mode" "<MODE>")])
6571 (define_insn "*addsi3_zext_cc_overflow"
6572 [(set (reg:CCC FLAGS_REG)
6575 (match_operand:SI 1 "nonimmediate_operand" "%0")
6576 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6578 (set (match_operand:DI 0 "register_operand" "=r")
6579 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6580 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6581 "add{l}\t{%2, %k0|%k0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "mode" "SI")])
6585 ;; The patterns that match these are at the end of this file.
6587 (define_expand "<plusminus_insn>xf3"
6588 [(set (match_operand:XF 0 "register_operand")
6590 (match_operand:XF 1 "register_operand")
6591 (match_operand:XF 2 "register_operand")))]
6594 (define_expand "<plusminus_insn><mode>3"
6595 [(set (match_operand:MODEF 0 "register_operand")
6597 (match_operand:MODEF 1 "register_operand")
6598 (match_operand:MODEF 2 "nonimmediate_operand")))]
6599 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6600 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6602 ;; Multiply instructions
6604 (define_expand "mul<mode>3"
6605 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6607 (match_operand:SWIM248 1 "register_operand")
6608 (match_operand:SWIM248 2 "<general_operand>")))
6609 (clobber (reg:CC FLAGS_REG))])])
6611 (define_expand "mulqi3"
6612 [(parallel [(set (match_operand:QI 0 "register_operand")
6614 (match_operand:QI 1 "register_operand")
6615 (match_operand:QI 2 "nonimmediate_operand")))
6616 (clobber (reg:CC FLAGS_REG))])]
6617 "TARGET_QIMODE_MATH")
6620 ;; IMUL reg32/64, reg32/64, imm8 Direct
6621 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6622 ;; IMUL reg32/64, reg32/64, imm32 Direct
6623 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6624 ;; IMUL reg32/64, reg32/64 Direct
6625 ;; IMUL reg32/64, mem32/64 Direct
6627 ;; On BDVER1, all above IMULs use DirectPath
6629 (define_insn "*mul<mode>3_1"
6630 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6632 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6633 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6638 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6639 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6640 [(set_attr "type" "imul")
6641 (set_attr "prefix_0f" "0,0,1")
6642 (set (attr "athlon_decode")
6643 (cond [(eq_attr "cpu" "athlon")
6644 (const_string "vector")
6645 (eq_attr "alternative" "1")
6646 (const_string "vector")
6647 (and (eq_attr "alternative" "2")
6648 (match_operand 1 "memory_operand"))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set (attr "amdfam10_decode")
6652 (cond [(and (eq_attr "alternative" "0,1")
6653 (match_operand 1 "memory_operand"))
6654 (const_string "vector")]
6655 (const_string "direct")))
6656 (set_attr "bdver1_decode" "direct")
6657 (set_attr "mode" "<MODE>")])
6659 (define_insn "*mulsi3_1_zext"
6660 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6662 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6663 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6664 (clobber (reg:CC FLAGS_REG))]
6666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6668 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6669 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6670 imul{l}\t{%2, %k0|%k0, %2}"
6671 [(set_attr "type" "imul")
6672 (set_attr "prefix_0f" "0,0,1")
6673 (set (attr "athlon_decode")
6674 (cond [(eq_attr "cpu" "athlon")
6675 (const_string "vector")
6676 (eq_attr "alternative" "1")
6677 (const_string "vector")
6678 (and (eq_attr "alternative" "2")
6679 (match_operand 1 "memory_operand"))
6680 (const_string "vector")]
6681 (const_string "direct")))
6682 (set (attr "amdfam10_decode")
6683 (cond [(and (eq_attr "alternative" "0,1")
6684 (match_operand 1 "memory_operand"))
6685 (const_string "vector")]
6686 (const_string "direct")))
6687 (set_attr "bdver1_decode" "direct")
6688 (set_attr "mode" "SI")])
6691 ;; IMUL reg16, reg16, imm8 VectorPath
6692 ;; IMUL reg16, mem16, imm8 VectorPath
6693 ;; IMUL reg16, reg16, imm16 VectorPath
6694 ;; IMUL reg16, mem16, imm16 VectorPath
6695 ;; IMUL reg16, reg16 Direct
6696 ;; IMUL reg16, mem16 Direct
6698 ;; On BDVER1, all HI MULs use DoublePath
6700 (define_insn "*mulhi3_1"
6701 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6702 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6703 (match_operand:HI 2 "general_operand" "K,n,mr")))
6704 (clobber (reg:CC FLAGS_REG))]
6706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6708 imul{w}\t{%2, %1, %0|%0, %1, %2}
6709 imul{w}\t{%2, %1, %0|%0, %1, %2}
6710 imul{w}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "imul")
6712 (set_attr "prefix_0f" "0,0,1")
6713 (set (attr "athlon_decode")
6714 (cond [(eq_attr "cpu" "athlon")
6715 (const_string "vector")
6716 (eq_attr "alternative" "1,2")
6717 (const_string "vector")]
6718 (const_string "direct")))
6719 (set (attr "amdfam10_decode")
6720 (cond [(eq_attr "alternative" "0,1")
6721 (const_string "vector")]
6722 (const_string "direct")))
6723 (set_attr "bdver1_decode" "double")
6724 (set_attr "mode" "HI")])
6726 ;;On AMDFAM10 and BDVER1
6730 (define_insn "*mulqi3_1"
6731 [(set (match_operand:QI 0 "register_operand" "=a")
6732 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6733 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6734 (clobber (reg:CC FLAGS_REG))]
6736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6738 [(set_attr "type" "imul")
6739 (set_attr "length_immediate" "0")
6740 (set (attr "athlon_decode")
6741 (if_then_else (eq_attr "cpu" "athlon")
6742 (const_string "vector")
6743 (const_string "direct")))
6744 (set_attr "amdfam10_decode" "direct")
6745 (set_attr "bdver1_decode" "direct")
6746 (set_attr "mode" "QI")])
6748 (define_expand "<u>mul<mode><dwi>3"
6749 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6752 (match_operand:DWIH 1 "nonimmediate_operand"))
6754 (match_operand:DWIH 2 "register_operand"))))
6755 (clobber (reg:CC FLAGS_REG))])])
6757 (define_expand "<u>mulqihi3"
6758 [(parallel [(set (match_operand:HI 0 "register_operand")
6761 (match_operand:QI 1 "nonimmediate_operand"))
6763 (match_operand:QI 2 "register_operand"))))
6764 (clobber (reg:CC FLAGS_REG))])]
6765 "TARGET_QIMODE_MATH")
6767 (define_insn "*bmi2_umulditi3_1"
6768 [(set (match_operand:DI 0 "register_operand" "=r")
6770 (match_operand:DI 2 "nonimmediate_operand" "%d")
6771 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6772 (set (match_operand:DI 1 "register_operand" "=r")
6775 (mult:TI (zero_extend:TI (match_dup 2))
6776 (zero_extend:TI (match_dup 3)))
6778 "TARGET_64BIT && TARGET_BMI2
6779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780 "mulx\t{%3, %0, %1|%1, %0, %3}"
6781 [(set_attr "type" "imulx")
6782 (set_attr "prefix" "vex")
6783 (set_attr "mode" "DI")])
6785 (define_insn "*bmi2_umulsidi3_1"
6786 [(set (match_operand:SI 0 "register_operand" "=r")
6788 (match_operand:SI 2 "nonimmediate_operand" "%d")
6789 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6790 (set (match_operand:SI 1 "register_operand" "=r")
6793 (mult:DI (zero_extend:DI (match_dup 2))
6794 (zero_extend:DI (match_dup 3)))
6796 "!TARGET_64BIT && TARGET_BMI2
6797 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6798 "mulx\t{%3, %0, %1|%1, %0, %3}"
6799 [(set_attr "type" "imulx")
6800 (set_attr "prefix" "vex")
6801 (set_attr "mode" "SI")])
6803 (define_insn "*umul<mode><dwi>3_1"
6804 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6807 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6809 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6810 (clobber (reg:CC FLAGS_REG))]
6811 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814 mul{<imodesuffix>}\t%2"
6815 [(set_attr "isa" "bmi2,*")
6816 (set_attr "type" "imulx,imul")
6817 (set_attr "length_immediate" "*,0")
6818 (set (attr "athlon_decode")
6819 (cond [(eq_attr "alternative" "1")
6820 (if_then_else (eq_attr "cpu" "athlon")
6821 (const_string "vector")
6822 (const_string "double"))]
6823 (const_string "*")))
6824 (set_attr "amdfam10_decode" "*,double")
6825 (set_attr "bdver1_decode" "*,direct")
6826 (set_attr "prefix" "vex,orig")
6827 (set_attr "mode" "<MODE>")])
6829 ;; Convert mul to the mulx pattern to avoid flags dependency.
6831 [(set (match_operand:<DWI> 0 "register_operand")
6834 (match_operand:DWIH 1 "register_operand"))
6836 (match_operand:DWIH 2 "nonimmediate_operand"))))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "TARGET_BMI2 && reload_completed
6839 && true_regnum (operands[1]) == DX_REG"
6840 [(parallel [(set (match_dup 3)
6841 (mult:DWIH (match_dup 1) (match_dup 2)))
6845 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6846 (zero_extend:<DWI> (match_dup 2)))
6849 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6851 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6854 (define_insn "*mul<mode><dwi>3_1"
6855 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6858 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6860 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6863 "imul{<imodesuffix>}\t%2"
6864 [(set_attr "type" "imul")
6865 (set_attr "length_immediate" "0")
6866 (set (attr "athlon_decode")
6867 (if_then_else (eq_attr "cpu" "athlon")
6868 (const_string "vector")
6869 (const_string "double")))
6870 (set_attr "amdfam10_decode" "double")
6871 (set_attr "bdver1_decode" "direct")
6872 (set_attr "mode" "<MODE>")])
6874 (define_insn "*<u>mulqihi3_1"
6875 [(set (match_operand:HI 0 "register_operand" "=a")
6878 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6880 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6881 (clobber (reg:CC FLAGS_REG))]
6883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884 "<sgnprefix>mul{b}\t%2"
6885 [(set_attr "type" "imul")
6886 (set_attr "length_immediate" "0")
6887 (set (attr "athlon_decode")
6888 (if_then_else (eq_attr "cpu" "athlon")
6889 (const_string "vector")
6890 (const_string "direct")))
6891 (set_attr "amdfam10_decode" "direct")
6892 (set_attr "bdver1_decode" "direct")
6893 (set_attr "mode" "QI")])
6895 (define_expand "<s>mul<mode>3_highpart"
6896 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6901 (match_operand:SWI48 1 "nonimmediate_operand"))
6903 (match_operand:SWI48 2 "register_operand")))
6905 (clobber (match_scratch:SWI48 3))
6906 (clobber (reg:CC FLAGS_REG))])]
6908 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6910 (define_insn "*<s>muldi3_highpart_1"
6911 [(set (match_operand:DI 0 "register_operand" "=d")
6916 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6918 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6920 (clobber (match_scratch:DI 3 "=1"))
6921 (clobber (reg:CC FLAGS_REG))]
6923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6924 "<sgnprefix>mul{q}\t%2"
6925 [(set_attr "type" "imul")
6926 (set_attr "length_immediate" "0")
6927 (set (attr "athlon_decode")
6928 (if_then_else (eq_attr "cpu" "athlon")
6929 (const_string "vector")
6930 (const_string "double")))
6931 (set_attr "amdfam10_decode" "double")
6932 (set_attr "bdver1_decode" "direct")
6933 (set_attr "mode" "DI")])
6935 (define_insn "*<s>mulsi3_highpart_1"
6936 [(set (match_operand:SI 0 "register_operand" "=d")
6941 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6943 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6945 (clobber (match_scratch:SI 3 "=1"))
6946 (clobber (reg:CC FLAGS_REG))]
6947 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6948 "<sgnprefix>mul{l}\t%2"
6949 [(set_attr "type" "imul")
6950 (set_attr "length_immediate" "0")
6951 (set (attr "athlon_decode")
6952 (if_then_else (eq_attr "cpu" "athlon")
6953 (const_string "vector")
6954 (const_string "double")))
6955 (set_attr "amdfam10_decode" "double")
6956 (set_attr "bdver1_decode" "direct")
6957 (set_attr "mode" "SI")])
6959 (define_insn "*<s>mulsi3_highpart_zext"
6960 [(set (match_operand:DI 0 "register_operand" "=d")
6961 (zero_extend:DI (truncate:SI
6963 (mult:DI (any_extend:DI
6964 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6968 (clobber (match_scratch:SI 3 "=1"))
6969 (clobber (reg:CC FLAGS_REG))]
6971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6972 "<sgnprefix>mul{l}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "length_immediate" "0")
6975 (set (attr "athlon_decode")
6976 (if_then_else (eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (const_string "double")))
6979 (set_attr "amdfam10_decode" "double")
6980 (set_attr "bdver1_decode" "direct")
6981 (set_attr "mode" "SI")])
6983 ;; The patterns that match these are at the end of this file.
6985 (define_expand "mulxf3"
6986 [(set (match_operand:XF 0 "register_operand")
6987 (mult:XF (match_operand:XF 1 "register_operand")
6988 (match_operand:XF 2 "register_operand")))]
6991 (define_expand "mul<mode>3"
6992 [(set (match_operand:MODEF 0 "register_operand")
6993 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6994 (match_operand:MODEF 2 "nonimmediate_operand")))]
6995 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6996 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6998 ;; Divide instructions
7000 ;; The patterns that match these are at the end of this file.
7002 (define_expand "divxf3"
7003 [(set (match_operand:XF 0 "register_operand")
7004 (div:XF (match_operand:XF 1 "register_operand")
7005 (match_operand:XF 2 "register_operand")))]
7008 (define_expand "divdf3"
7009 [(set (match_operand:DF 0 "register_operand")
7010 (div:DF (match_operand:DF 1 "register_operand")
7011 (match_operand:DF 2 "nonimmediate_operand")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7013 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7015 (define_expand "divsf3"
7016 [(set (match_operand:SF 0 "register_operand")
7017 (div:SF (match_operand:SF 1 "register_operand")
7018 (match_operand:SF 2 "nonimmediate_operand")))]
7019 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7024 && optimize_insn_for_speed_p ()
7025 && flag_finite_math_only && !flag_trapping_math
7026 && flag_unsafe_math_optimizations)
7028 ix86_emit_swdivsf (operands[0], operands[1],
7029 operands[2], SFmode);
7034 ;; Divmod instructions.
7036 (define_expand "divmod<mode>4"
7037 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7039 (match_operand:SWIM248 1 "register_operand")
7040 (match_operand:SWIM248 2 "nonimmediate_operand")))
7041 (set (match_operand:SWIM248 3 "register_operand")
7042 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7043 (clobber (reg:CC FLAGS_REG))])])
7045 ;; Split with 8bit unsigned divide:
7046 ;; if (dividend an divisor are in [0-255])
7047 ;; use 8bit unsigned integer divide
7049 ;; use original integer divide
7051 [(set (match_operand:SWI48 0 "register_operand")
7052 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7053 (match_operand:SWI48 3 "nonimmediate_operand")))
7054 (set (match_operand:SWI48 1 "register_operand")
7055 (mod:SWI48 (match_dup 2) (match_dup 3)))
7056 (clobber (reg:CC FLAGS_REG))]
7057 "TARGET_USE_8BIT_IDIV
7058 && TARGET_QIMODE_MATH
7059 && can_create_pseudo_p ()
7060 && !optimize_insn_for_size_p ()"
7062 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7064 (define_insn_and_split "divmod<mode>4_1"
7065 [(set (match_operand:SWI48 0 "register_operand" "=a")
7066 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7067 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7068 (set (match_operand:SWI48 1 "register_operand" "=&d")
7069 (mod:SWI48 (match_dup 2) (match_dup 3)))
7070 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7071 (clobber (reg:CC FLAGS_REG))]
7075 [(parallel [(set (match_dup 1)
7076 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7077 (clobber (reg:CC FLAGS_REG))])
7078 (parallel [(set (match_dup 0)
7079 (div:SWI48 (match_dup 2) (match_dup 3)))
7081 (mod:SWI48 (match_dup 2) (match_dup 3)))
7083 (clobber (reg:CC FLAGS_REG))])]
7085 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7087 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7088 operands[4] = operands[2];
7091 /* Avoid use of cltd in favor of a mov+shift. */
7092 emit_move_insn (operands[1], operands[2]);
7093 operands[4] = operands[1];
7096 [(set_attr "type" "multi")
7097 (set_attr "mode" "<MODE>")])
7099 (define_insn_and_split "*divmod<mode>4"
7100 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7101 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7102 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7103 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7104 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7105 (clobber (reg:CC FLAGS_REG))]
7109 [(parallel [(set (match_dup 1)
7110 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7111 (clobber (reg:CC FLAGS_REG))])
7112 (parallel [(set (match_dup 0)
7113 (div:SWIM248 (match_dup 2) (match_dup 3)))
7115 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7117 (clobber (reg:CC FLAGS_REG))])]
7119 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7121 if (<MODE>mode != HImode
7122 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7123 operands[4] = operands[2];
7126 /* Avoid use of cltd in favor of a mov+shift. */
7127 emit_move_insn (operands[1], operands[2]);
7128 operands[4] = operands[1];
7131 [(set_attr "type" "multi")
7132 (set_attr "mode" "<MODE>")])
7134 (define_insn "*divmod<mode>4_noext"
7135 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7136 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7137 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7138 (set (match_operand:SWIM248 1 "register_operand" "=d")
7139 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7140 (use (match_operand:SWIM248 4 "register_operand" "1"))
7141 (clobber (reg:CC FLAGS_REG))]
7143 "idiv{<imodesuffix>}\t%3"
7144 [(set_attr "type" "idiv")
7145 (set_attr "mode" "<MODE>")])
7147 (define_expand "divmodqi4"
7148 [(parallel [(set (match_operand:QI 0 "register_operand")
7150 (match_operand:QI 1 "register_operand")
7151 (match_operand:QI 2 "nonimmediate_operand")))
7152 (set (match_operand:QI 3 "register_operand")
7153 (mod:QI (match_dup 1) (match_dup 2)))
7154 (clobber (reg:CC FLAGS_REG))])]
7155 "TARGET_QIMODE_MATH"
7160 tmp0 = gen_reg_rtx (HImode);
7161 tmp1 = gen_reg_rtx (HImode);
7163 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7165 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7166 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7168 /* Extract remainder from AH. */
7169 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7170 insn = emit_move_insn (operands[3], tmp1);
7172 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7173 set_unique_reg_note (insn, REG_EQUAL, mod);
7175 /* Extract quotient from AL. */
7176 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7178 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7179 set_unique_reg_note (insn, REG_EQUAL, div);
7184 ;; Divide AX by r/m8, with result stored in
7187 ;; Change div/mod to HImode and extend the second argument to HImode
7188 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7189 ;; combine may fail.
7190 (define_insn "divmodhiqi3"
7191 [(set (match_operand:HI 0 "register_operand" "=a")
7196 (mod:HI (match_operand:HI 1 "register_operand" "0")
7198 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7202 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7203 (clobber (reg:CC FLAGS_REG))]
7204 "TARGET_QIMODE_MATH"
7206 [(set_attr "type" "idiv")
7207 (set_attr "mode" "QI")])
7209 (define_expand "udivmod<mode>4"
7210 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7212 (match_operand:SWIM248 1 "register_operand")
7213 (match_operand:SWIM248 2 "nonimmediate_operand")))
7214 (set (match_operand:SWIM248 3 "register_operand")
7215 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7216 (clobber (reg:CC FLAGS_REG))])])
7218 ;; Split with 8bit unsigned divide:
7219 ;; if (dividend an divisor are in [0-255])
7220 ;; use 8bit unsigned integer divide
7222 ;; use original integer divide
7224 [(set (match_operand:SWI48 0 "register_operand")
7225 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7226 (match_operand:SWI48 3 "nonimmediate_operand")))
7227 (set (match_operand:SWI48 1 "register_operand")
7228 (umod:SWI48 (match_dup 2) (match_dup 3)))
7229 (clobber (reg:CC FLAGS_REG))]
7230 "TARGET_USE_8BIT_IDIV
7231 && TARGET_QIMODE_MATH
7232 && can_create_pseudo_p ()
7233 && !optimize_insn_for_size_p ()"
7235 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7237 (define_insn_and_split "udivmod<mode>4_1"
7238 [(set (match_operand:SWI48 0 "register_operand" "=a")
7239 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7240 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7241 (set (match_operand:SWI48 1 "register_operand" "=&d")
7242 (umod:SWI48 (match_dup 2) (match_dup 3)))
7243 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7244 (clobber (reg:CC FLAGS_REG))]
7248 [(set (match_dup 1) (const_int 0))
7249 (parallel [(set (match_dup 0)
7250 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7252 (umod:SWI48 (match_dup 2) (match_dup 3)))
7254 (clobber (reg:CC FLAGS_REG))])]
7256 [(set_attr "type" "multi")
7257 (set_attr "mode" "<MODE>")])
7259 (define_insn_and_split "*udivmod<mode>4"
7260 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7261 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7262 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7263 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7264 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))]
7269 [(set (match_dup 1) (const_int 0))
7270 (parallel [(set (match_dup 0)
7271 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7273 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7275 (clobber (reg:CC FLAGS_REG))])]
7277 [(set_attr "type" "multi")
7278 (set_attr "mode" "<MODE>")])
7280 (define_insn "*udivmod<mode>4_noext"
7281 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7282 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7283 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7284 (set (match_operand:SWIM248 1 "register_operand" "=d")
7285 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7286 (use (match_operand:SWIM248 4 "register_operand" "1"))
7287 (clobber (reg:CC FLAGS_REG))]
7289 "div{<imodesuffix>}\t%3"
7290 [(set_attr "type" "idiv")
7291 (set_attr "mode" "<MODE>")])
7293 (define_expand "udivmodqi4"
7294 [(parallel [(set (match_operand:QI 0 "register_operand")
7296 (match_operand:QI 1 "register_operand")
7297 (match_operand:QI 2 "nonimmediate_operand")))
7298 (set (match_operand:QI 3 "register_operand")
7299 (umod:QI (match_dup 1) (match_dup 2)))
7300 (clobber (reg:CC FLAGS_REG))])]
7301 "TARGET_QIMODE_MATH"
7306 tmp0 = gen_reg_rtx (HImode);
7307 tmp1 = gen_reg_rtx (HImode);
7309 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7311 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7312 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7314 /* Extract remainder from AH. */
7315 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7316 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7317 insn = emit_move_insn (operands[3], tmp1);
7319 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7320 set_unique_reg_note (insn, REG_EQUAL, mod);
7322 /* Extract quotient from AL. */
7323 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7325 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7326 set_unique_reg_note (insn, REG_EQUAL, div);
7331 (define_insn "udivmodhiqi3"
7332 [(set (match_operand:HI 0 "register_operand" "=a")
7337 (mod:HI (match_operand:HI 1 "register_operand" "0")
7339 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7343 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7344 (clobber (reg:CC FLAGS_REG))]
7345 "TARGET_QIMODE_MATH"
7347 [(set_attr "type" "idiv")
7348 (set_attr "mode" "QI")])
7350 ;; We cannot use div/idiv for double division, because it causes
7351 ;; "division by zero" on the overflow and that's not what we expect
7352 ;; from truncate. Because true (non truncating) double division is
7353 ;; never generated, we can't create this insn anyway.
7356 ; [(set (match_operand:SI 0 "register_operand" "=a")
7358 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7360 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7361 ; (set (match_operand:SI 3 "register_operand" "=d")
7363 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7364 ; (clobber (reg:CC FLAGS_REG))]
7366 ; "div{l}\t{%2, %0|%0, %2}"
7367 ; [(set_attr "type" "idiv")])
7369 ;;- Logical AND instructions
7371 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7372 ;; Note that this excludes ah.
7374 (define_expand "testsi_ccno_1"
7375 [(set (reg:CCNO FLAGS_REG)
7377 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7378 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7381 (define_expand "testqi_ccz_1"
7382 [(set (reg:CCZ FLAGS_REG)
7383 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7384 (match_operand:QI 1 "nonmemory_operand"))
7387 (define_expand "testdi_ccno_1"
7388 [(set (reg:CCNO FLAGS_REG)
7390 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7391 (match_operand:DI 1 "x86_64_szext_general_operand"))
7393 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7395 (define_insn "*testdi_1"
7396 [(set (reg FLAGS_REG)
7399 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7400 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7402 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7403 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7405 test{l}\t{%k1, %k0|%k0, %k1}
7406 test{l}\t{%k1, %k0|%k0, %k1}
7407 test{q}\t{%1, %0|%0, %1}
7408 test{q}\t{%1, %0|%0, %1}
7409 test{q}\t{%1, %0|%0, %1}"
7410 [(set_attr "type" "test")
7411 (set_attr "modrm" "0,1,0,1,1")
7412 (set_attr "mode" "SI,SI,DI,DI,DI")])
7414 (define_insn "*testqi_1_maybe_si"
7415 [(set (reg FLAGS_REG)
7418 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7419 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7421 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7422 && ix86_match_ccmode (insn,
7423 CONST_INT_P (operands[1])
7424 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7426 if (which_alternative == 3)
7428 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7429 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7430 return "test{l}\t{%1, %k0|%k0, %1}";
7432 return "test{b}\t{%1, %0|%0, %1}";
7434 [(set_attr "type" "test")
7435 (set_attr "modrm" "0,1,1,1")
7436 (set_attr "mode" "QI,QI,QI,SI")
7437 (set_attr "pent_pair" "uv,np,uv,np")])
7439 (define_insn "*test<mode>_1"
7440 [(set (reg FLAGS_REG)
7443 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7444 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7446 "ix86_match_ccmode (insn, CCNOmode)
7447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7448 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7449 [(set_attr "type" "test")
7450 (set_attr "modrm" "0,1,1")
7451 (set_attr "mode" "<MODE>")
7452 (set_attr "pent_pair" "uv,np,uv")])
7454 (define_expand "testqi_ext_ccno_0"
7455 [(set (reg:CCNO FLAGS_REG)
7459 (match_operand 0 "ext_register_operand")
7462 (match_operand 1 "const_int_operand"))
7465 (define_insn "*testqi_ext_0"
7466 [(set (reg FLAGS_REG)
7470 (match_operand 0 "ext_register_operand" "Q")
7473 (match_operand 1 "const_int_operand" "n"))
7475 "ix86_match_ccmode (insn, CCNOmode)"
7476 "test{b}\t{%1, %h0|%h0, %1}"
7477 [(set_attr "type" "test")
7478 (set_attr "mode" "QI")
7479 (set_attr "length_immediate" "1")
7480 (set_attr "modrm" "1")
7481 (set_attr "pent_pair" "np")])
7483 (define_insn "*testqi_ext_1"
7484 [(set (reg FLAGS_REG)
7488 (match_operand 0 "ext_register_operand" "Q,Q")
7492 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7494 "ix86_match_ccmode (insn, CCNOmode)"
7495 "test{b}\t{%1, %h0|%h0, %1}"
7496 [(set_attr "isa" "*,nox64")
7497 (set_attr "type" "test")
7498 (set_attr "mode" "QI")])
7500 (define_insn "*testqi_ext_2"
7501 [(set (reg FLAGS_REG)
7505 (match_operand 0 "ext_register_operand" "Q")
7509 (match_operand 1 "ext_register_operand" "Q")
7513 "ix86_match_ccmode (insn, CCNOmode)"
7514 "test{b}\t{%h1, %h0|%h0, %h1}"
7515 [(set_attr "type" "test")
7516 (set_attr "mode" "QI")])
7518 ;; Combine likes to form bit extractions for some tests. Humor it.
7519 (define_insn "*testqi_ext_3"
7520 [(set (reg FLAGS_REG)
7521 (compare (zero_extract:SWI48
7522 (match_operand 0 "nonimmediate_operand" "rm")
7523 (match_operand:SWI48 1 "const_int_operand")
7524 (match_operand:SWI48 2 "const_int_operand"))
7526 "ix86_match_ccmode (insn, CCNOmode)
7527 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7528 || GET_MODE (operands[0]) == SImode
7529 || GET_MODE (operands[0]) == HImode
7530 || GET_MODE (operands[0]) == QImode)
7531 /* Ensure that resulting mask is zero or sign extended operand. */
7532 && INTVAL (operands[2]) >= 0
7533 && ((INTVAL (operands[1]) > 0
7534 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7535 || (<MODE>mode == DImode
7536 && INTVAL (operands[1]) > 32
7537 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7541 [(set (match_operand 0 "flags_reg_operand")
7542 (match_operator 1 "compare_operator"
7544 (match_operand 2 "nonimmediate_operand")
7545 (match_operand 3 "const_int_operand")
7546 (match_operand 4 "const_int_operand"))
7548 "ix86_match_ccmode (insn, CCNOmode)"
7549 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7551 rtx val = operands[2];
7552 HOST_WIDE_INT len = INTVAL (operands[3]);
7553 HOST_WIDE_INT pos = INTVAL (operands[4]);
7555 enum machine_mode mode, submode;
7557 mode = GET_MODE (val);
7560 /* ??? Combine likes to put non-volatile mem extractions in QImode
7561 no matter the size of the test. So find a mode that works. */
7562 if (! MEM_VOLATILE_P (val))
7564 mode = smallest_mode_for_size (pos + len, MODE_INT);
7565 val = adjust_address (val, mode, 0);
7568 else if (GET_CODE (val) == SUBREG
7569 && (submode = GET_MODE (SUBREG_REG (val)),
7570 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7571 && pos + len <= GET_MODE_BITSIZE (submode)
7572 && GET_MODE_CLASS (submode) == MODE_INT)
7574 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7576 val = SUBREG_REG (val);
7578 else if (mode == HImode && pos + len <= 8)
7580 /* Small HImode tests can be converted to QImode. */
7582 val = gen_lowpart (QImode, val);
7585 if (len == HOST_BITS_PER_WIDE_INT)
7588 mask = ((HOST_WIDE_INT)1 << len) - 1;
7591 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7594 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7595 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7596 ;; this is relatively important trick.
7597 ;; Do the conversion only post-reload to avoid limiting of the register class
7600 [(set (match_operand 0 "flags_reg_operand")
7601 (match_operator 1 "compare_operator"
7602 [(and (match_operand 2 "register_operand")
7603 (match_operand 3 "const_int_operand"))
7606 && QI_REG_P (operands[2])
7607 && GET_MODE (operands[2]) != QImode
7608 && ((ix86_match_ccmode (insn, CCZmode)
7609 && !(INTVAL (operands[3]) & ~(255 << 8)))
7610 || (ix86_match_ccmode (insn, CCNOmode)
7611 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7614 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7618 operands[2] = gen_lowpart (SImode, operands[2]);
7619 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7623 [(set (match_operand 0 "flags_reg_operand")
7624 (match_operator 1 "compare_operator"
7625 [(and (match_operand 2 "nonimmediate_operand")
7626 (match_operand 3 "const_int_operand"))
7629 && GET_MODE (operands[2]) != QImode
7630 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7631 && ((ix86_match_ccmode (insn, CCZmode)
7632 && !(INTVAL (operands[3]) & ~255))
7633 || (ix86_match_ccmode (insn, CCNOmode)
7634 && !(INTVAL (operands[3]) & ~127)))"
7636 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7639 operands[2] = gen_lowpart (QImode, operands[2]);
7640 operands[3] = gen_lowpart (QImode, operands[3]);
7644 [(set (match_operand:SWI12 0 "mask_reg_operand")
7645 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7646 (match_operand:SWI12 2 "mask_reg_operand")))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "TARGET_AVX512F && reload_completed"
7650 (any_logic:SWI12 (match_dup 1)
7653 (define_insn "*k<logic><mode>"
7654 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7655 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7656 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7658 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7659 [(set_attr "mode" "<MODE>")
7660 (set_attr "type" "msklog")
7661 (set_attr "prefix" "vex")])
7663 ;; %%% This used to optimize known byte-wide and operations to memory,
7664 ;; and sometimes to QImode registers. If this is considered useful,
7665 ;; it should be done with splitters.
7667 (define_expand "and<mode>3"
7668 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7669 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7670 (match_operand:SWIM 2 "<general_szext_operand>")))]
7673 enum machine_mode mode = <MODE>mode;
7674 rtx (*insn) (rtx, rtx);
7676 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7678 HOST_WIDE_INT ival = INTVAL (operands[2]);
7680 if (ival == (HOST_WIDE_INT) 0xffffffff)
7682 else if (ival == 0xffff)
7684 else if (ival == 0xff)
7688 if (mode == <MODE>mode)
7690 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7694 if (<MODE>mode == DImode)
7695 insn = (mode == SImode)
7696 ? gen_zero_extendsidi2
7698 ? gen_zero_extendhidi2
7699 : gen_zero_extendqidi2;
7700 else if (<MODE>mode == SImode)
7701 insn = (mode == HImode)
7702 ? gen_zero_extendhisi2
7703 : gen_zero_extendqisi2;
7704 else if (<MODE>mode == HImode)
7705 insn = gen_zero_extendqihi2;
7709 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7713 (define_insn "*anddi_1"
7714 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7716 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7717 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7718 (clobber (reg:CC FLAGS_REG))]
7719 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7721 switch (get_attr_type (insn))
7727 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7728 if (get_attr_mode (insn) == MODE_SI)
7729 return "and{l}\t{%k2, %k0|%k0, %k2}";
7731 return "and{q}\t{%2, %0|%0, %2}";
7734 [(set_attr "type" "alu,alu,alu,imovx")
7735 (set_attr "length_immediate" "*,*,*,0")
7736 (set (attr "prefix_rex")
7738 (and (eq_attr "type" "imovx")
7739 (and (match_test "INTVAL (operands[2]) == 0xff")
7740 (match_operand 1 "ext_QIreg_operand")))
7742 (const_string "*")))
7743 (set_attr "mode" "SI,DI,DI,SI")])
7745 (define_insn "*andsi_1"
7746 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7747 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7748 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7749 (clobber (reg:CC FLAGS_REG))]
7750 "ix86_binary_operator_ok (AND, SImode, operands)"
7752 switch (get_attr_type (insn))
7758 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7759 return "and{l}\t{%2, %0|%0, %2}";
7762 [(set_attr "type" "alu,alu,imovx")
7763 (set (attr "prefix_rex")
7765 (and (eq_attr "type" "imovx")
7766 (and (match_test "INTVAL (operands[2]) == 0xff")
7767 (match_operand 1 "ext_QIreg_operand")))
7769 (const_string "*")))
7770 (set_attr "length_immediate" "*,*,0")
7771 (set_attr "mode" "SI")])
7773 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7774 (define_insn "*andsi_1_zext"
7775 [(set (match_operand:DI 0 "register_operand" "=r")
7777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7778 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7779 (clobber (reg:CC FLAGS_REG))]
7780 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7781 "and{l}\t{%2, %k0|%k0, %2}"
7782 [(set_attr "type" "alu")
7783 (set_attr "mode" "SI")])
7785 (define_insn "*andhi_1"
7786 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7787 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7788 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7789 (clobber (reg:CC FLAGS_REG))]
7790 "ix86_binary_operator_ok (AND, HImode, operands)"
7792 switch (get_attr_type (insn))
7798 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7802 return "and{w}\t{%2, %0|%0, %2}";
7805 [(set_attr "type" "alu,alu,imovx,msklog")
7806 (set_attr "length_immediate" "*,*,0,*")
7807 (set (attr "prefix_rex")
7809 (and (eq_attr "type" "imovx")
7810 (match_operand 1 "ext_QIreg_operand"))
7812 (const_string "*")))
7813 (set_attr "mode" "HI,HI,SI,HI")])
7815 ;; %%% Potential partial reg stall on alternative 2. What to do?
7816 (define_insn "*andqi_1"
7817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7818 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7819 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "ix86_binary_operator_ok (AND, QImode, operands)"
7823 and{b}\t{%2, %0|%0, %2}
7824 and{b}\t{%2, %0|%0, %2}
7825 and{l}\t{%k2, %k0|%k0, %k2}
7826 kandw\t{%2, %1, %0|%0, %1, %2}"
7827 [(set_attr "type" "alu,alu,alu,msklog")
7828 (set_attr "mode" "QI,QI,SI,HI")])
7830 (define_insn "*andqi_1_slp"
7831 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7832 (and:QI (match_dup 0)
7833 (match_operand:QI 1 "general_operand" "qn,qmn")))
7834 (clobber (reg:CC FLAGS_REG))]
7835 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7837 "and{b}\t{%1, %0|%0, %1}"
7838 [(set_attr "type" "alu1")
7839 (set_attr "mode" "QI")])
7841 (define_insn "kandn<mode>"
7842 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7845 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7846 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7847 (clobber (reg:CC FLAGS_REG))]
7850 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7852 kandnw\t{%2, %1, %0|%0, %1, %2}"
7853 [(set_attr "isa" "bmi,*,avx512f")
7854 (set_attr "type" "bitmanip,*,msklog")
7855 (set_attr "prefix" "*,*,vex")
7856 (set_attr "btver2_decode" "direct,*,*")
7857 (set_attr "mode" "<MODE>")])
7860 [(set (match_operand:SWI12 0 "general_reg_operand")
7864 (match_operand:SWI12 1 "general_reg_operand")))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7868 (not:HI (match_dup 0)))
7869 (parallel [(set (match_dup 0)
7870 (and:HI (match_dup 0)
7872 (clobber (reg:CC FLAGS_REG))])])
7874 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7876 [(set (match_operand:DI 0 "register_operand")
7877 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7878 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7879 (clobber (reg:CC FLAGS_REG))]
7881 [(parallel [(set (match_dup 0)
7882 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7883 (clobber (reg:CC FLAGS_REG))])]
7884 "operands[2] = gen_lowpart (SImode, operands[2]);")
7887 [(set (match_operand:SWI248 0 "register_operand")
7888 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7889 (match_operand:SWI248 2 "const_int_operand")))
7890 (clobber (reg:CC FLAGS_REG))]
7892 && true_regnum (operands[0]) != true_regnum (operands[1])"
7895 HOST_WIDE_INT ival = INTVAL (operands[2]);
7896 enum machine_mode mode;
7897 rtx (*insn) (rtx, rtx);
7899 if (ival == (HOST_WIDE_INT) 0xffffffff)
7901 else if (ival == 0xffff)
7905 gcc_assert (ival == 0xff);
7909 if (<MODE>mode == DImode)
7910 insn = (mode == SImode)
7911 ? gen_zero_extendsidi2
7913 ? gen_zero_extendhidi2
7914 : gen_zero_extendqidi2;
7917 if (<MODE>mode != SImode)
7918 /* Zero extend to SImode to avoid partial register stalls. */
7919 operands[0] = gen_lowpart (SImode, operands[0]);
7921 insn = (mode == HImode)
7922 ? gen_zero_extendhisi2
7923 : gen_zero_extendqisi2;
7925 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7930 [(set (match_operand 0 "register_operand")
7932 (const_int -65536)))
7933 (clobber (reg:CC FLAGS_REG))]
7934 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7935 || optimize_function_for_size_p (cfun)"
7936 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7937 "operands[1] = gen_lowpart (HImode, operands[0]);")
7940 [(set (match_operand 0 "ext_register_operand")
7943 (clobber (reg:CC FLAGS_REG))]
7944 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7945 && reload_completed"
7946 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7947 "operands[1] = gen_lowpart (QImode, operands[0]);")
7950 [(set (match_operand 0 "ext_register_operand")
7952 (const_int -65281)))
7953 (clobber (reg:CC FLAGS_REG))]
7954 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7955 && reload_completed"
7956 [(parallel [(set (zero_extract:SI (match_dup 0)
7960 (zero_extract:SI (match_dup 0)
7963 (zero_extract:SI (match_dup 0)
7966 (clobber (reg:CC FLAGS_REG))])]
7967 "operands[0] = gen_lowpart (SImode, operands[0]);")
7969 (define_insn "*anddi_2"
7970 [(set (reg FLAGS_REG)
7973 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7974 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7976 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7977 (and:DI (match_dup 1) (match_dup 2)))]
7978 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7979 && ix86_binary_operator_ok (AND, DImode, operands)"
7981 and{l}\t{%k2, %k0|%k0, %k2}
7982 and{q}\t{%2, %0|%0, %2}
7983 and{q}\t{%2, %0|%0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "mode" "SI,DI,DI")])
7987 (define_insn "*andqi_2_maybe_si"
7988 [(set (reg FLAGS_REG)
7990 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7991 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7993 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7994 (and:QI (match_dup 1) (match_dup 2)))]
7995 "ix86_binary_operator_ok (AND, QImode, operands)
7996 && ix86_match_ccmode (insn,
7997 CONST_INT_P (operands[2])
7998 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8000 if (which_alternative == 2)
8002 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8003 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8004 return "and{l}\t{%2, %k0|%k0, %2}";
8006 return "and{b}\t{%2, %0|%0, %2}";
8008 [(set_attr "type" "alu")
8009 (set_attr "mode" "QI,QI,SI")])
8011 (define_insn "*and<mode>_2"
8012 [(set (reg FLAGS_REG)
8013 (compare (and:SWI124
8014 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8015 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8017 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8018 (and:SWI124 (match_dup 1) (match_dup 2)))]
8019 "ix86_match_ccmode (insn, CCNOmode)
8020 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8021 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "<MODE>")])
8025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8026 (define_insn "*andsi_2_zext"
8027 [(set (reg FLAGS_REG)
8029 (match_operand:SI 1 "nonimmediate_operand" "%0")
8030 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8032 (set (match_operand:DI 0 "register_operand" "=r")
8033 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8034 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8035 && ix86_binary_operator_ok (AND, SImode, operands)"
8036 "and{l}\t{%2, %k0|%k0, %2}"
8037 [(set_attr "type" "alu")
8038 (set_attr "mode" "SI")])
8040 (define_insn "*andqi_2_slp"
8041 [(set (reg FLAGS_REG)
8043 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8044 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8046 (set (strict_low_part (match_dup 0))
8047 (and:QI (match_dup 0) (match_dup 1)))]
8048 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8049 && ix86_match_ccmode (insn, CCNOmode)
8050 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8051 "and{b}\t{%1, %0|%0, %1}"
8052 [(set_attr "type" "alu1")
8053 (set_attr "mode" "QI")])
8055 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8056 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8057 ;; for a QImode operand, which of course failed.
8058 (define_insn "andqi_ext_0"
8059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8064 (match_operand 1 "ext_register_operand" "0")
8067 (match_operand 2 "const_int_operand" "n")))
8068 (clobber (reg:CC FLAGS_REG))]
8070 "and{b}\t{%2, %h0|%h0, %2}"
8071 [(set_attr "type" "alu")
8072 (set_attr "length_immediate" "1")
8073 (set_attr "modrm" "1")
8074 (set_attr "mode" "QI")])
8076 ;; Generated by peephole translating test to and. This shows up
8077 ;; often in fp comparisons.
8078 (define_insn "*andqi_ext_0_cc"
8079 [(set (reg FLAGS_REG)
8083 (match_operand 1 "ext_register_operand" "0")
8086 (match_operand 2 "const_int_operand" "n"))
8088 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8097 "ix86_match_ccmode (insn, CCNOmode)"
8098 "and{b}\t{%2, %h0|%h0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "length_immediate" "1")
8101 (set_attr "modrm" "1")
8102 (set_attr "mode" "QI")])
8104 (define_insn "*andqi_ext_1"
8105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8110 (match_operand 1 "ext_register_operand" "0,0")
8114 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8115 (clobber (reg:CC FLAGS_REG))]
8117 "and{b}\t{%2, %h0|%h0, %2}"
8118 [(set_attr "isa" "*,nox64")
8119 (set_attr "type" "alu")
8120 (set_attr "length_immediate" "0")
8121 (set_attr "mode" "QI")])
8123 (define_insn "*andqi_ext_2"
8124 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8129 (match_operand 1 "ext_register_operand" "%0")
8133 (match_operand 2 "ext_register_operand" "Q")
8136 (clobber (reg:CC FLAGS_REG))]
8138 "and{b}\t{%h2, %h0|%h0, %h2}"
8139 [(set_attr "type" "alu")
8140 (set_attr "length_immediate" "0")
8141 (set_attr "mode" "QI")])
8143 ;; Convert wide AND instructions with immediate operand to shorter QImode
8144 ;; equivalents when possible.
8145 ;; Don't do the splitting with memory operands, since it introduces risk
8146 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8147 ;; for size, but that can (should?) be handled by generic code instead.
8149 [(set (match_operand 0 "register_operand")
8150 (and (match_operand 1 "register_operand")
8151 (match_operand 2 "const_int_operand")))
8152 (clobber (reg:CC FLAGS_REG))]
8154 && QI_REG_P (operands[0])
8155 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8156 && !(~INTVAL (operands[2]) & ~(255 << 8))
8157 && GET_MODE (operands[0]) != QImode"
8158 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8159 (and:SI (zero_extract:SI (match_dup 1)
8160 (const_int 8) (const_int 8))
8162 (clobber (reg:CC FLAGS_REG))])]
8164 operands[0] = gen_lowpart (SImode, operands[0]);
8165 operands[1] = gen_lowpart (SImode, operands[1]);
8166 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8169 ;; Since AND can be encoded with sign extended immediate, this is only
8170 ;; profitable when 7th bit is not set.
8172 [(set (match_operand 0 "register_operand")
8173 (and (match_operand 1 "general_operand")
8174 (match_operand 2 "const_int_operand")))
8175 (clobber (reg:CC FLAGS_REG))]
8177 && ANY_QI_REG_P (operands[0])
8178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8179 && !(~INTVAL (operands[2]) & ~255)
8180 && !(INTVAL (operands[2]) & 128)
8181 && GET_MODE (operands[0]) != QImode"
8182 [(parallel [(set (strict_low_part (match_dup 0))
8183 (and:QI (match_dup 1)
8185 (clobber (reg:CC FLAGS_REG))])]
8187 operands[0] = gen_lowpart (QImode, operands[0]);
8188 operands[1] = gen_lowpart (QImode, operands[1]);
8189 operands[2] = gen_lowpart (QImode, operands[2]);
8192 ;; Logical inclusive and exclusive OR instructions
8194 ;; %%% This used to optimize known byte-wide and operations to memory.
8195 ;; If this is considered useful, it should be done with splitters.
8197 (define_expand "<code><mode>3"
8198 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8199 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8200 (match_operand:SWIM 2 "<general_operand>")))]
8202 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8204 (define_insn "*<code><mode>_1"
8205 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8207 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8208 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8209 (clobber (reg:CC FLAGS_REG))]
8210 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8211 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "<MODE>")])
8215 (define_insn "*<code>hi_1"
8216 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8218 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8219 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8220 (clobber (reg:CC FLAGS_REG))]
8221 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8223 <logic>{w}\t{%2, %0|%0, %2}
8224 <logic>{w}\t{%2, %0|%0, %2}
8225 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8226 [(set_attr "type" "alu,alu,msklog")
8227 (set_attr "mode" "HI")])
8229 ;; %%% Potential partial reg stall on alternative 2. What to do?
8230 (define_insn "*<code>qi_1"
8231 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8232 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8233 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8234 (clobber (reg:CC FLAGS_REG))]
8235 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8237 <logic>{b}\t{%2, %0|%0, %2}
8238 <logic>{b}\t{%2, %0|%0, %2}
8239 <logic>{l}\t{%k2, %k0|%k0, %k2}
8240 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8241 [(set_attr "type" "alu,alu,alu,msklog")
8242 (set_attr "mode" "QI,QI,SI,HI")])
8244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8245 (define_insn "*<code>si_1_zext"
8246 [(set (match_operand:DI 0 "register_operand" "=r")
8248 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8249 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8252 "<logic>{l}\t{%2, %k0|%k0, %2}"
8253 [(set_attr "type" "alu")
8254 (set_attr "mode" "SI")])
8256 (define_insn "*<code>si_1_zext_imm"
8257 [(set (match_operand:DI 0 "register_operand" "=r")
8259 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8260 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8263 "<logic>{l}\t{%2, %k0|%k0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "mode" "SI")])
8267 (define_insn "*<code>qi_1_slp"
8268 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8269 (any_or:QI (match_dup 0)
8270 (match_operand:QI 1 "general_operand" "qmn,qn")))
8271 (clobber (reg:CC FLAGS_REG))]
8272 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8273 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8274 "<logic>{b}\t{%1, %0|%0, %1}"
8275 [(set_attr "type" "alu1")
8276 (set_attr "mode" "QI")])
8278 (define_insn "*<code><mode>_2"
8279 [(set (reg FLAGS_REG)
8280 (compare (any_or:SWI
8281 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8282 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8284 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8285 (any_or:SWI (match_dup 1) (match_dup 2)))]
8286 "ix86_match_ccmode (insn, CCNOmode)
8287 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8288 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8289 [(set_attr "type" "alu")
8290 (set_attr "mode" "<MODE>")])
8292 (define_insn "kxnor<mode>"
8293 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8296 (match_operand:SWI12 1 "register_operand" "0,Yk")
8297 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8298 (clobber (reg:CC FLAGS_REG))]
8302 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8303 [(set_attr "type" "*,msklog")
8304 (set_attr "prefix" "*,vex")
8305 (set_attr "mode" "<MODE>")])
8308 [(set (match_operand:SWI12 0 "general_reg_operand")
8312 (match_operand:SWI12 1 "general_reg_operand"))))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_AVX512F && reload_completed"
8315 [(parallel [(set (match_dup 0)
8316 (xor:HI (match_dup 0)
8318 (clobber (reg:CC FLAGS_REG))])
8320 (not:HI (match_dup 0)))])
8322 (define_insn "kortestzhi"
8323 [(set (reg:CCZ FLAGS_REG)
8326 (match_operand:HI 0 "register_operand" "Yk")
8327 (match_operand:HI 1 "register_operand" "Yk"))
8329 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8330 "kortestw\t{%1, %0|%0, %1}"
8331 [(set_attr "mode" "HI")
8332 (set_attr "type" "msklog")
8333 (set_attr "prefix" "vex")])
8335 (define_insn "kortestchi"
8336 [(set (reg:CCC FLAGS_REG)
8339 (match_operand:HI 0 "register_operand" "Yk")
8340 (match_operand:HI 1 "register_operand" "Yk"))
8342 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8343 "kortestw\t{%1, %0|%0, %1}"
8344 [(set_attr "mode" "HI")
8345 (set_attr "type" "msklog")
8346 (set_attr "prefix" "vex")])
8348 (define_insn "kunpckhi"
8349 [(set (match_operand:HI 0 "register_operand" "=Yk")
8352 (match_operand:HI 1 "register_operand" "Yk")
8354 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8356 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8357 [(set_attr "mode" "HI")
8358 (set_attr "type" "msklog")
8359 (set_attr "prefix" "vex")])
8361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8362 ;; ??? Special case for immediate operand is missing - it is tricky.
8363 (define_insn "*<code>si_2_zext"
8364 [(set (reg FLAGS_REG)
8365 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8366 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8368 (set (match_operand:DI 0 "register_operand" "=r")
8369 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8372 "<logic>{l}\t{%2, %k0|%k0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "SI")])
8376 (define_insn "*<code>si_2_zext_imm"
8377 [(set (reg FLAGS_REG)
8379 (match_operand:SI 1 "nonimmediate_operand" "%0")
8380 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8382 (set (match_operand:DI 0 "register_operand" "=r")
8383 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8384 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8385 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8386 "<logic>{l}\t{%2, %k0|%k0, %2}"
8387 [(set_attr "type" "alu")
8388 (set_attr "mode" "SI")])
8390 (define_insn "*<code>qi_2_slp"
8391 [(set (reg FLAGS_REG)
8392 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8393 (match_operand:QI 1 "general_operand" "qmn,qn"))
8395 (set (strict_low_part (match_dup 0))
8396 (any_or:QI (match_dup 0) (match_dup 1)))]
8397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && ix86_match_ccmode (insn, CCNOmode)
8399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400 "<logic>{b}\t{%1, %0|%0, %1}"
8401 [(set_attr "type" "alu1")
8402 (set_attr "mode" "QI")])
8404 (define_insn "*<code><mode>_3"
8405 [(set (reg FLAGS_REG)
8406 (compare (any_or:SWI
8407 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8408 (match_operand:SWI 2 "<general_operand>" "<g>"))
8410 (clobber (match_scratch:SWI 0 "=<r>"))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8413 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "<MODE>")])
8417 (define_insn "*<code>qi_ext_0"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423 (match_operand 1 "ext_register_operand" "0")
8426 (match_operand 2 "const_int_operand" "n")))
8427 (clobber (reg:CC FLAGS_REG))]
8428 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8429 "<logic>{b}\t{%2, %h0|%h0, %2}"
8430 [(set_attr "type" "alu")
8431 (set_attr "length_immediate" "1")
8432 (set_attr "modrm" "1")
8433 (set_attr "mode" "QI")])
8435 (define_insn "*<code>qi_ext_1"
8436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8441 (match_operand 1 "ext_register_operand" "0,0")
8445 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8446 (clobber (reg:CC FLAGS_REG))]
8447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8448 "<logic>{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "isa" "*,nox64")
8450 (set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8454 (define_insn "*<code>qi_ext_2"
8455 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8462 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8465 (clobber (reg:CC FLAGS_REG))]
8466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8467 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "length_immediate" "0")
8470 (set_attr "mode" "QI")])
8473 [(set (match_operand 0 "register_operand")
8474 (any_or (match_operand 1 "register_operand")
8475 (match_operand 2 "const_int_operand")))
8476 (clobber (reg:CC FLAGS_REG))]
8478 && QI_REG_P (operands[0])
8479 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8480 && !(INTVAL (operands[2]) & ~(255 << 8))
8481 && GET_MODE (operands[0]) != QImode"
8482 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8483 (any_or:SI (zero_extract:SI (match_dup 1)
8484 (const_int 8) (const_int 8))
8486 (clobber (reg:CC FLAGS_REG))])]
8488 operands[0] = gen_lowpart (SImode, operands[0]);
8489 operands[1] = gen_lowpart (SImode, operands[1]);
8490 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8493 ;; Since OR can be encoded with sign extended immediate, this is only
8494 ;; profitable when 7th bit is set.
8496 [(set (match_operand 0 "register_operand")
8497 (any_or (match_operand 1 "general_operand")
8498 (match_operand 2 "const_int_operand")))
8499 (clobber (reg:CC FLAGS_REG))]
8501 && ANY_QI_REG_P (operands[0])
8502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503 && !(INTVAL (operands[2]) & ~255)
8504 && (INTVAL (operands[2]) & 128)
8505 && GET_MODE (operands[0]) != QImode"
8506 [(parallel [(set (strict_low_part (match_dup 0))
8507 (any_or:QI (match_dup 1)
8509 (clobber (reg:CC FLAGS_REG))])]
8511 operands[0] = gen_lowpart (QImode, operands[0]);
8512 operands[1] = gen_lowpart (QImode, operands[1]);
8513 operands[2] = gen_lowpart (QImode, operands[2]);
8516 (define_expand "xorqi_cc_ext_1"
8518 (set (reg:CCNO FLAGS_REG)
8522 (match_operand 1 "ext_register_operand")
8525 (match_operand:QI 2 "const_int_operand"))
8527 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8537 (define_insn "*xorqi_cc_ext_1"
8538 [(set (reg FLAGS_REG)
8542 (match_operand 1 "ext_register_operand" "0,0")
8545 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8547 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8556 "ix86_match_ccmode (insn, CCNOmode)"
8557 "xor{b}\t{%2, %h0|%h0, %2}"
8558 [(set_attr "isa" "*,nox64")
8559 (set_attr "type" "alu")
8560 (set_attr "modrm" "1")
8561 (set_attr "mode" "QI")])
8563 ;; Negation instructions
8565 (define_expand "neg<mode>2"
8566 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8567 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8569 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8571 (define_insn_and_split "*neg<dwi>2_doubleword"
8572 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8573 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8579 [(set (reg:CCZ FLAGS_REG)
8580 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8581 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8584 (plus:DWIH (match_dup 3)
8585 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8587 (clobber (reg:CC FLAGS_REG))])
8590 (neg:DWIH (match_dup 2)))
8591 (clobber (reg:CC FLAGS_REG))])]
8592 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8594 (define_insn "*neg<mode>2_1"
8595 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8596 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8599 "neg{<imodesuffix>}\t%0"
8600 [(set_attr "type" "negnot")
8601 (set_attr "mode" "<MODE>")])
8603 ;; Combine is quite creative about this pattern.
8604 (define_insn "*negsi2_1_zext"
8605 [(set (match_operand:DI 0 "register_operand" "=r")
8607 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8613 [(set_attr "type" "negnot")
8614 (set_attr "mode" "SI")])
8616 ;; The problem with neg is that it does not perform (compare x 0),
8617 ;; it really performs (compare 0 x), which leaves us with the zero
8618 ;; flag being the only useful item.
8620 (define_insn "*neg<mode>2_cmpz"
8621 [(set (reg:CCZ FLAGS_REG)
8623 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8625 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8626 (neg:SWI (match_dup 1)))]
8627 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8628 "neg{<imodesuffix>}\t%0"
8629 [(set_attr "type" "negnot")
8630 (set_attr "mode" "<MODE>")])
8632 (define_insn "*negsi2_cmpz_zext"
8633 [(set (reg:CCZ FLAGS_REG)
8637 (match_operand:DI 1 "register_operand" "0")
8641 (set (match_operand:DI 0 "register_operand" "=r")
8642 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8645 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8647 [(set_attr "type" "negnot")
8648 (set_attr "mode" "SI")])
8650 ;; Changing of sign for FP values is doable using integer unit too.
8652 (define_expand "<code><mode>2"
8653 [(set (match_operand:X87MODEF 0 "register_operand")
8654 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8655 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8656 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8658 (define_insn "*absneg<mode>2_mixed"
8659 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8660 (match_operator:MODEF 3 "absneg_operator"
8661 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8662 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8663 (clobber (reg:CC FLAGS_REG))]
8664 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8667 (define_insn "*absneg<mode>2_sse"
8668 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8669 (match_operator:MODEF 3 "absneg_operator"
8670 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8671 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8672 (clobber (reg:CC FLAGS_REG))]
8673 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8676 (define_insn "*absneg<mode>2_i387"
8677 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8678 (match_operator:X87MODEF 3 "absneg_operator"
8679 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8680 (use (match_operand 2))
8681 (clobber (reg:CC FLAGS_REG))]
8682 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8685 (define_expand "<code>tf2"
8686 [(set (match_operand:TF 0 "register_operand")
8687 (absneg:TF (match_operand:TF 1 "register_operand")))]
8689 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8691 (define_insn "*absnegtf2_sse"
8692 [(set (match_operand:TF 0 "register_operand" "=x,x")
8693 (match_operator:TF 3 "absneg_operator"
8694 [(match_operand:TF 1 "register_operand" "0,x")]))
8695 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8696 (clobber (reg:CC FLAGS_REG))]
8700 ;; Splitters for fp abs and neg.
8703 [(set (match_operand 0 "fp_register_operand")
8704 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8705 (use (match_operand 2))
8706 (clobber (reg:CC FLAGS_REG))]
8708 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8711 [(set (match_operand 0 "register_operand")
8712 (match_operator 3 "absneg_operator"
8713 [(match_operand 1 "register_operand")]))
8714 (use (match_operand 2 "nonimmediate_operand"))
8715 (clobber (reg:CC FLAGS_REG))]
8716 "reload_completed && SSE_REG_P (operands[0])"
8717 [(set (match_dup 0) (match_dup 3))]
8719 enum machine_mode mode = GET_MODE (operands[0]);
8720 enum machine_mode vmode = GET_MODE (operands[2]);
8723 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8724 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8725 if (operands_match_p (operands[0], operands[2]))
8728 operands[1] = operands[2];
8731 if (GET_CODE (operands[3]) == ABS)
8732 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8734 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8739 [(set (match_operand:SF 0 "register_operand")
8740 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8741 (use (match_operand:V4SF 2))
8742 (clobber (reg:CC FLAGS_REG))]
8744 [(parallel [(set (match_dup 0) (match_dup 1))
8745 (clobber (reg:CC FLAGS_REG))])]
8748 operands[0] = gen_lowpart (SImode, operands[0]);
8749 if (GET_CODE (operands[1]) == ABS)
8751 tmp = gen_int_mode (0x7fffffff, SImode);
8752 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8756 tmp = gen_int_mode (0x80000000, SImode);
8757 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8763 [(set (match_operand:DF 0 "register_operand")
8764 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8765 (use (match_operand 2))
8766 (clobber (reg:CC FLAGS_REG))]
8768 [(parallel [(set (match_dup 0) (match_dup 1))
8769 (clobber (reg:CC FLAGS_REG))])]
8774 tmp = gen_lowpart (DImode, operands[0]);
8775 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8778 if (GET_CODE (operands[1]) == ABS)
8781 tmp = gen_rtx_NOT (DImode, tmp);
8785 operands[0] = gen_highpart (SImode, operands[0]);
8786 if (GET_CODE (operands[1]) == ABS)
8788 tmp = gen_int_mode (0x7fffffff, SImode);
8789 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8793 tmp = gen_int_mode (0x80000000, SImode);
8794 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8801 [(set (match_operand:XF 0 "register_operand")
8802 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8803 (use (match_operand 2))
8804 (clobber (reg:CC FLAGS_REG))]
8806 [(parallel [(set (match_dup 0) (match_dup 1))
8807 (clobber (reg:CC FLAGS_REG))])]
8810 operands[0] = gen_rtx_REG (SImode,
8811 true_regnum (operands[0])
8812 + (TARGET_64BIT ? 1 : 2));
8813 if (GET_CODE (operands[1]) == ABS)
8815 tmp = GEN_INT (0x7fff);
8816 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8820 tmp = GEN_INT (0x8000);
8821 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8826 ;; Conditionalize these after reload. If they match before reload, we
8827 ;; lose the clobber and ability to use integer instructions.
8829 (define_insn "*<code><mode>2_1"
8830 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8831 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8833 && (reload_completed
8834 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8835 "f<absneg_mnemonic>"
8836 [(set_attr "type" "fsgn")
8837 (set_attr "mode" "<MODE>")])
8839 (define_insn "*<code>extendsfdf2"
8840 [(set (match_operand:DF 0 "register_operand" "=f")
8841 (absneg:DF (float_extend:DF
8842 (match_operand:SF 1 "register_operand" "0"))))]
8843 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8844 "f<absneg_mnemonic>"
8845 [(set_attr "type" "fsgn")
8846 (set_attr "mode" "DF")])
8848 (define_insn "*<code>extendsfxf2"
8849 [(set (match_operand:XF 0 "register_operand" "=f")
8850 (absneg:XF (float_extend:XF
8851 (match_operand:SF 1 "register_operand" "0"))))]
8853 "f<absneg_mnemonic>"
8854 [(set_attr "type" "fsgn")
8855 (set_attr "mode" "XF")])
8857 (define_insn "*<code>extenddfxf2"
8858 [(set (match_operand:XF 0 "register_operand" "=f")
8859 (absneg:XF (float_extend:XF
8860 (match_operand:DF 1 "register_operand" "0"))))]
8862 "f<absneg_mnemonic>"
8863 [(set_attr "type" "fsgn")
8864 (set_attr "mode" "XF")])
8866 ;; Copysign instructions
8868 (define_mode_iterator CSGNMODE [SF DF TF])
8869 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8871 (define_expand "copysign<mode>3"
8872 [(match_operand:CSGNMODE 0 "register_operand")
8873 (match_operand:CSGNMODE 1 "nonmemory_operand")
8874 (match_operand:CSGNMODE 2 "register_operand")]
8875 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8876 || (TARGET_SSE && (<MODE>mode == TFmode))"
8877 "ix86_expand_copysign (operands); DONE;")
8879 (define_insn_and_split "copysign<mode>3_const"
8880 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8882 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8883 (match_operand:CSGNMODE 2 "register_operand" "0")
8884 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8886 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8887 || (TARGET_SSE && (<MODE>mode == TFmode))"
8889 "&& reload_completed"
8891 "ix86_split_copysign_const (operands); DONE;")
8893 (define_insn "copysign<mode>3_var"
8894 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8896 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8897 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8898 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8899 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8901 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8902 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8903 || (TARGET_SSE && (<MODE>mode == TFmode))"
8907 [(set (match_operand:CSGNMODE 0 "register_operand")
8909 [(match_operand:CSGNMODE 2 "register_operand")
8910 (match_operand:CSGNMODE 3 "register_operand")
8911 (match_operand:<CSGNVMODE> 4)
8912 (match_operand:<CSGNVMODE> 5)]
8914 (clobber (match_scratch:<CSGNVMODE> 1))]
8915 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8916 || (TARGET_SSE && (<MODE>mode == TFmode)))
8917 && reload_completed"
8919 "ix86_split_copysign_var (operands); DONE;")
8921 ;; One complement instructions
8923 (define_expand "one_cmpl<mode>2"
8924 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8925 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8927 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8929 (define_insn "*one_cmpl<mode>2_1"
8930 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8931 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
8932 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8933 "not{<imodesuffix>}\t%0"
8934 [(set_attr "type" "negnot")
8935 (set_attr "mode" "<MODE>")])
8937 (define_insn "*one_cmplhi2_1"
8938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
8939 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
8940 "ix86_unary_operator_ok (NOT, HImode, operands)"
8943 knotw\t{%1, %0|%0, %1}"
8944 [(set_attr "isa" "*,avx512f")
8945 (set_attr "type" "negnot,msklog")
8946 (set_attr "prefix" "*,vex")
8947 (set_attr "mode" "HI")])
8949 ;; %%% Potential partial reg stall on alternative 1. What to do?
8950 (define_insn "*one_cmplqi2_1"
8951 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
8952 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
8953 "ix86_unary_operator_ok (NOT, QImode, operands)"
8957 knotw\t{%1, %0|%0, %1}"
8958 [(set_attr "isa" "*,*,avx512f")
8959 (set_attr "type" "negnot,negnot,msklog")
8960 (set_attr "prefix" "*,*,vex")
8961 (set_attr "mode" "QI,SI,QI")])
8963 ;; ??? Currently never generated - xor is used instead.
8964 (define_insn "*one_cmplsi2_1_zext"
8965 [(set (match_operand:DI 0 "register_operand" "=r")
8967 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8968 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8970 [(set_attr "type" "negnot")
8971 (set_attr "mode" "SI")])
8973 (define_insn "*one_cmpl<mode>2_2"
8974 [(set (reg FLAGS_REG)
8975 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8977 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8978 (not:SWI (match_dup 1)))]
8979 "ix86_match_ccmode (insn, CCNOmode)
8980 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8982 [(set_attr "type" "alu1")
8983 (set_attr "mode" "<MODE>")])
8986 [(set (match_operand 0 "flags_reg_operand")
8987 (match_operator 2 "compare_operator"
8988 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8990 (set (match_operand:SWI 1 "nonimmediate_operand")
8991 (not:SWI (match_dup 3)))]
8992 "ix86_match_ccmode (insn, CCNOmode)"
8993 [(parallel [(set (match_dup 0)
8994 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8997 (xor:SWI (match_dup 3) (const_int -1)))])])
8999 ;; ??? Currently never generated - xor is used instead.
9000 (define_insn "*one_cmplsi2_2_zext"
9001 [(set (reg FLAGS_REG)
9002 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9004 (set (match_operand:DI 0 "register_operand" "=r")
9005 (zero_extend:DI (not:SI (match_dup 1))))]
9006 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007 && ix86_unary_operator_ok (NOT, SImode, operands)"
9009 [(set_attr "type" "alu1")
9010 (set_attr "mode" "SI")])
9013 [(set (match_operand 0 "flags_reg_operand")
9014 (match_operator 2 "compare_operator"
9015 [(not:SI (match_operand:SI 3 "register_operand"))
9017 (set (match_operand:DI 1 "register_operand")
9018 (zero_extend:DI (not:SI (match_dup 3))))]
9019 "ix86_match_ccmode (insn, CCNOmode)"
9020 [(parallel [(set (match_dup 0)
9021 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9024 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9026 ;; Shift instructions
9028 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9029 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9030 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9031 ;; from the assembler input.
9033 ;; This instruction shifts the target reg/mem as usual, but instead of
9034 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9035 ;; is a left shift double, bits are taken from the high order bits of
9036 ;; reg, else if the insn is a shift right double, bits are taken from the
9037 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9038 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9040 ;; Since sh[lr]d does not change the `reg' operand, that is done
9041 ;; separately, making all shifts emit pairs of shift double and normal
9042 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9043 ;; support a 63 bit shift, each shift where the count is in a reg expands
9044 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9046 ;; If the shift count is a constant, we need never emit more than one
9047 ;; shift pair, instead using moves and sign extension for counts greater
9050 (define_expand "ashl<mode>3"
9051 [(set (match_operand:SDWIM 0 "<shift_operand>")
9052 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9053 (match_operand:QI 2 "nonmemory_operand")))]
9055 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9057 (define_insn "*ashl<mode>3_doubleword"
9058 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9059 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9060 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9061 (clobber (reg:CC FLAGS_REG))]
9064 [(set_attr "type" "multi")])
9067 [(set (match_operand:DWI 0 "register_operand")
9068 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9069 (match_operand:QI 2 "nonmemory_operand")))
9070 (clobber (reg:CC FLAGS_REG))]
9071 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9073 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9075 ;; By default we don't ask for a scratch register, because when DWImode
9076 ;; values are manipulated, registers are already at a premium. But if
9077 ;; we have one handy, we won't turn it away.
9080 [(match_scratch:DWIH 3 "r")
9081 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9083 (match_operand:<DWI> 1 "nonmemory_operand")
9084 (match_operand:QI 2 "nonmemory_operand")))
9085 (clobber (reg:CC FLAGS_REG))])
9089 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9091 (define_insn "x86_64_shld"
9092 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9093 (ior:DI (ashift:DI (match_dup 0)
9094 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9095 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9096 (minus:QI (const_int 64) (match_dup 2)))))
9097 (clobber (reg:CC FLAGS_REG))]
9099 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9100 [(set_attr "type" "ishift")
9101 (set_attr "prefix_0f" "1")
9102 (set_attr "mode" "DI")
9103 (set_attr "athlon_decode" "vector")
9104 (set_attr "amdfam10_decode" "vector")
9105 (set_attr "bdver1_decode" "vector")])
9107 (define_insn "x86_shld"
9108 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9109 (ior:SI (ashift:SI (match_dup 0)
9110 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9111 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9112 (minus:QI (const_int 32) (match_dup 2)))))
9113 (clobber (reg:CC FLAGS_REG))]
9115 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9116 [(set_attr "type" "ishift")
9117 (set_attr "prefix_0f" "1")
9118 (set_attr "mode" "SI")
9119 (set_attr "pent_pair" "np")
9120 (set_attr "athlon_decode" "vector")
9121 (set_attr "amdfam10_decode" "vector")
9122 (set_attr "bdver1_decode" "vector")])
9124 (define_expand "x86_shift<mode>_adj_1"
9125 [(set (reg:CCZ FLAGS_REG)
9126 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9129 (set (match_operand:SWI48 0 "register_operand")
9130 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9131 (match_operand:SWI48 1 "register_operand")
9134 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9135 (match_operand:SWI48 3 "register_operand")
9138 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9140 (define_expand "x86_shift<mode>_adj_2"
9141 [(use (match_operand:SWI48 0 "register_operand"))
9142 (use (match_operand:SWI48 1 "register_operand"))
9143 (use (match_operand:QI 2 "register_operand"))]
9146 rtx label = gen_label_rtx ();
9149 emit_insn (gen_testqi_ccz_1 (operands[2],
9150 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9152 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9153 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9154 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9155 gen_rtx_LABEL_REF (VOIDmode, label),
9157 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9158 JUMP_LABEL (tmp) = label;
9160 emit_move_insn (operands[0], operands[1]);
9161 ix86_expand_clear (operands[1]);
9164 LABEL_NUSES (label) = 1;
9169 ;; Avoid useless masking of count operand.
9170 (define_insn "*ashl<mode>3_mask"
9171 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9173 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9176 (match_operand:SI 2 "register_operand" "c")
9177 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9178 (clobber (reg:CC FLAGS_REG))]
9179 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9180 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9181 == GET_MODE_BITSIZE (<MODE>mode)-1"
9183 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9185 [(set_attr "type" "ishift")
9186 (set_attr "mode" "<MODE>")])
9188 (define_insn "*bmi2_ashl<mode>3_1"
9189 [(set (match_operand:SWI48 0 "register_operand" "=r")
9190 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9191 (match_operand:SWI48 2 "register_operand" "r")))]
9193 "shlx\t{%2, %1, %0|%0, %1, %2}"
9194 [(set_attr "type" "ishiftx")
9195 (set_attr "mode" "<MODE>")])
9197 (define_insn "*ashl<mode>3_1"
9198 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9199 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9200 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9204 switch (get_attr_type (insn))
9211 gcc_assert (operands[2] == const1_rtx);
9212 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9213 return "add{<imodesuffix>}\t%0, %0";
9216 if (operands[2] == const1_rtx
9217 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9218 return "sal{<imodesuffix>}\t%0";
9220 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9223 [(set_attr "isa" "*,*,bmi2")
9225 (cond [(eq_attr "alternative" "1")
9226 (const_string "lea")
9227 (eq_attr "alternative" "2")
9228 (const_string "ishiftx")
9229 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9230 (match_operand 0 "register_operand"))
9231 (match_operand 2 "const1_operand"))
9232 (const_string "alu")
9234 (const_string "ishift")))
9235 (set (attr "length_immediate")
9237 (ior (eq_attr "type" "alu")
9238 (and (eq_attr "type" "ishift")
9239 (and (match_operand 2 "const1_operand")
9240 (ior (match_test "TARGET_SHIFT1")
9241 (match_test "optimize_function_for_size_p (cfun)")))))
9243 (const_string "*")))
9244 (set_attr "mode" "<MODE>")])
9246 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9248 [(set (match_operand:SWI48 0 "register_operand")
9249 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9250 (match_operand:QI 2 "register_operand")))
9251 (clobber (reg:CC FLAGS_REG))]
9252 "TARGET_BMI2 && reload_completed"
9254 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9255 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9257 (define_insn "*bmi2_ashlsi3_1_zext"
9258 [(set (match_operand:DI 0 "register_operand" "=r")
9260 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9261 (match_operand:SI 2 "register_operand" "r"))))]
9262 "TARGET_64BIT && TARGET_BMI2"
9263 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9264 [(set_attr "type" "ishiftx")
9265 (set_attr "mode" "SI")])
9267 (define_insn "*ashlsi3_1_zext"
9268 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9270 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9271 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9272 (clobber (reg:CC FLAGS_REG))]
9273 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9275 switch (get_attr_type (insn))
9282 gcc_assert (operands[2] == const1_rtx);
9283 return "add{l}\t%k0, %k0";
9286 if (operands[2] == const1_rtx
9287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9288 return "sal{l}\t%k0";
9290 return "sal{l}\t{%2, %k0|%k0, %2}";
9293 [(set_attr "isa" "*,*,bmi2")
9295 (cond [(eq_attr "alternative" "1")
9296 (const_string "lea")
9297 (eq_attr "alternative" "2")
9298 (const_string "ishiftx")
9299 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9300 (match_operand 2 "const1_operand"))
9301 (const_string "alu")
9303 (const_string "ishift")))
9304 (set (attr "length_immediate")
9306 (ior (eq_attr "type" "alu")
9307 (and (eq_attr "type" "ishift")
9308 (and (match_operand 2 "const1_operand")
9309 (ior (match_test "TARGET_SHIFT1")
9310 (match_test "optimize_function_for_size_p (cfun)")))))
9312 (const_string "*")))
9313 (set_attr "mode" "SI")])
9315 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9317 [(set (match_operand:DI 0 "register_operand")
9319 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9320 (match_operand:QI 2 "register_operand"))))
9321 (clobber (reg:CC FLAGS_REG))]
9322 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9324 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9325 "operands[2] = gen_lowpart (SImode, operands[2]);")
9327 (define_insn "*ashlhi3_1"
9328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9329 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9330 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9334 switch (get_attr_type (insn))
9340 gcc_assert (operands[2] == const1_rtx);
9341 return "add{w}\t%0, %0";
9344 if (operands[2] == const1_rtx
9345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9346 return "sal{w}\t%0";
9348 return "sal{w}\t{%2, %0|%0, %2}";
9352 (cond [(eq_attr "alternative" "1")
9353 (const_string "lea")
9354 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9355 (match_operand 0 "register_operand"))
9356 (match_operand 2 "const1_operand"))
9357 (const_string "alu")
9359 (const_string "ishift")))
9360 (set (attr "length_immediate")
9362 (ior (eq_attr "type" "alu")
9363 (and (eq_attr "type" "ishift")
9364 (and (match_operand 2 "const1_operand")
9365 (ior (match_test "TARGET_SHIFT1")
9366 (match_test "optimize_function_for_size_p (cfun)")))))
9368 (const_string "*")))
9369 (set_attr "mode" "HI,SI")])
9371 ;; %%% Potential partial reg stall on alternative 1. What to do?
9372 (define_insn "*ashlqi3_1"
9373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9374 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9375 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9379 switch (get_attr_type (insn))
9385 gcc_assert (operands[2] == const1_rtx);
9386 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9387 return "add{l}\t%k0, %k0";
9389 return "add{b}\t%0, %0";
9392 if (operands[2] == const1_rtx
9393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9395 if (get_attr_mode (insn) == MODE_SI)
9396 return "sal{l}\t%k0";
9398 return "sal{b}\t%0";
9402 if (get_attr_mode (insn) == MODE_SI)
9403 return "sal{l}\t{%2, %k0|%k0, %2}";
9405 return "sal{b}\t{%2, %0|%0, %2}";
9410 (cond [(eq_attr "alternative" "2")
9411 (const_string "lea")
9412 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9413 (match_operand 0 "register_operand"))
9414 (match_operand 2 "const1_operand"))
9415 (const_string "alu")
9417 (const_string "ishift")))
9418 (set (attr "length_immediate")
9420 (ior (eq_attr "type" "alu")
9421 (and (eq_attr "type" "ishift")
9422 (and (match_operand 2 "const1_operand")
9423 (ior (match_test "TARGET_SHIFT1")
9424 (match_test "optimize_function_for_size_p (cfun)")))))
9426 (const_string "*")))
9427 (set_attr "mode" "QI,SI,SI")])
9429 (define_insn "*ashlqi3_1_slp"
9430 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9431 (ashift:QI (match_dup 0)
9432 (match_operand:QI 1 "nonmemory_operand" "cI")))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "(optimize_function_for_size_p (cfun)
9435 || !TARGET_PARTIAL_FLAG_REG_STALL
9436 || (operands[1] == const1_rtx
9438 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9440 switch (get_attr_type (insn))
9443 gcc_assert (operands[1] == const1_rtx);
9444 return "add{b}\t%0, %0";
9447 if (operands[1] == const1_rtx
9448 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9449 return "sal{b}\t%0";
9451 return "sal{b}\t{%1, %0|%0, %1}";
9455 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9456 (match_operand 0 "register_operand"))
9457 (match_operand 1 "const1_operand"))
9458 (const_string "alu")
9460 (const_string "ishift1")))
9461 (set (attr "length_immediate")
9463 (ior (eq_attr "type" "alu")
9464 (and (eq_attr "type" "ishift1")
9465 (and (match_operand 1 "const1_operand")
9466 (ior (match_test "TARGET_SHIFT1")
9467 (match_test "optimize_function_for_size_p (cfun)")))))
9469 (const_string "*")))
9470 (set_attr "mode" "QI")])
9472 ;; Convert ashift to the lea pattern to avoid flags dependency.
9474 [(set (match_operand 0 "register_operand")
9475 (ashift (match_operand 1 "index_register_operand")
9476 (match_operand:QI 2 "const_int_operand")))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9480 && true_regnum (operands[0]) != true_regnum (operands[1])"
9483 enum machine_mode mode = GET_MODE (operands[0]);
9486 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9489 operands[0] = gen_lowpart (mode, operands[0]);
9490 operands[1] = gen_lowpart (mode, operands[1]);
9493 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9495 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9497 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9501 ;; Convert ashift to the lea pattern to avoid flags dependency.
9503 [(set (match_operand:DI 0 "register_operand")
9505 (ashift:SI (match_operand:SI 1 "index_register_operand")
9506 (match_operand:QI 2 "const_int_operand"))))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "TARGET_64BIT && reload_completed
9509 && true_regnum (operands[0]) != true_regnum (operands[1])"
9511 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9513 operands[1] = gen_lowpart (SImode, operands[1]);
9514 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9517 ;; This pattern can't accept a variable shift count, since shifts by
9518 ;; zero don't affect the flags. We assume that shifts by constant
9519 ;; zero are optimized away.
9520 (define_insn "*ashl<mode>3_cmp"
9521 [(set (reg FLAGS_REG)
9523 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9524 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9526 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9527 (ashift:SWI (match_dup 1) (match_dup 2)))]
9528 "(optimize_function_for_size_p (cfun)
9529 || !TARGET_PARTIAL_FLAG_REG_STALL
9530 || (operands[2] == const1_rtx
9532 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9533 && ix86_match_ccmode (insn, CCGOCmode)
9534 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9536 switch (get_attr_type (insn))
9539 gcc_assert (operands[2] == const1_rtx);
9540 return "add{<imodesuffix>}\t%0, %0";
9543 if (operands[2] == const1_rtx
9544 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9545 return "sal{<imodesuffix>}\t%0";
9547 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9551 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9552 (match_operand 0 "register_operand"))
9553 (match_operand 2 "const1_operand"))
9554 (const_string "alu")
9556 (const_string "ishift")))
9557 (set (attr "length_immediate")
9559 (ior (eq_attr "type" "alu")
9560 (and (eq_attr "type" "ishift")
9561 (and (match_operand 2 "const1_operand")
9562 (ior (match_test "TARGET_SHIFT1")
9563 (match_test "optimize_function_for_size_p (cfun)")))))
9565 (const_string "*")))
9566 (set_attr "mode" "<MODE>")])
9568 (define_insn "*ashlsi3_cmp_zext"
9569 [(set (reg FLAGS_REG)
9571 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9572 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9574 (set (match_operand:DI 0 "register_operand" "=r")
9575 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9577 && (optimize_function_for_size_p (cfun)
9578 || !TARGET_PARTIAL_FLAG_REG_STALL
9579 || (operands[2] == const1_rtx
9581 || TARGET_DOUBLE_WITH_ADD)))
9582 && ix86_match_ccmode (insn, CCGOCmode)
9583 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9585 switch (get_attr_type (insn))
9588 gcc_assert (operands[2] == const1_rtx);
9589 return "add{l}\t%k0, %k0";
9592 if (operands[2] == const1_rtx
9593 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9594 return "sal{l}\t%k0";
9596 return "sal{l}\t{%2, %k0|%k0, %2}";
9600 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9601 (match_operand 2 "const1_operand"))
9602 (const_string "alu")
9604 (const_string "ishift")))
9605 (set (attr "length_immediate")
9607 (ior (eq_attr "type" "alu")
9608 (and (eq_attr "type" "ishift")
9609 (and (match_operand 2 "const1_operand")
9610 (ior (match_test "TARGET_SHIFT1")
9611 (match_test "optimize_function_for_size_p (cfun)")))))
9613 (const_string "*")))
9614 (set_attr "mode" "SI")])
9616 (define_insn "*ashl<mode>3_cconly"
9617 [(set (reg FLAGS_REG)
9619 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9620 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9622 (clobber (match_scratch:SWI 0 "=<r>"))]
9623 "(optimize_function_for_size_p (cfun)
9624 || !TARGET_PARTIAL_FLAG_REG_STALL
9625 || (operands[2] == const1_rtx
9627 || TARGET_DOUBLE_WITH_ADD)))
9628 && ix86_match_ccmode (insn, CCGOCmode)"
9630 switch (get_attr_type (insn))
9633 gcc_assert (operands[2] == const1_rtx);
9634 return "add{<imodesuffix>}\t%0, %0";
9637 if (operands[2] == const1_rtx
9638 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9639 return "sal{<imodesuffix>}\t%0";
9641 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9645 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9646 (match_operand 0 "register_operand"))
9647 (match_operand 2 "const1_operand"))
9648 (const_string "alu")
9650 (const_string "ishift")))
9651 (set (attr "length_immediate")
9653 (ior (eq_attr "type" "alu")
9654 (and (eq_attr "type" "ishift")
9655 (and (match_operand 2 "const1_operand")
9656 (ior (match_test "TARGET_SHIFT1")
9657 (match_test "optimize_function_for_size_p (cfun)")))))
9659 (const_string "*")))
9660 (set_attr "mode" "<MODE>")])
9662 ;; See comment above `ashl<mode>3' about how this works.
9664 (define_expand "<shift_insn><mode>3"
9665 [(set (match_operand:SDWIM 0 "<shift_operand>")
9666 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9667 (match_operand:QI 2 "nonmemory_operand")))]
9669 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9671 ;; Avoid useless masking of count operand.
9672 (define_insn "*<shift_insn><mode>3_mask"
9673 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9675 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9678 (match_operand:SI 2 "register_operand" "c")
9679 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9682 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9683 == GET_MODE_BITSIZE (<MODE>mode)-1"
9685 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9687 [(set_attr "type" "ishift")
9688 (set_attr "mode" "<MODE>")])
9690 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9691 [(set (match_operand:DWI 0 "register_operand" "=r")
9692 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9693 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9694 (clobber (reg:CC FLAGS_REG))]
9697 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9699 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9700 [(set_attr "type" "multi")])
9702 ;; By default we don't ask for a scratch register, because when DWImode
9703 ;; values are manipulated, registers are already at a premium. But if
9704 ;; we have one handy, we won't turn it away.
9707 [(match_scratch:DWIH 3 "r")
9708 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9710 (match_operand:<DWI> 1 "register_operand")
9711 (match_operand:QI 2 "nonmemory_operand")))
9712 (clobber (reg:CC FLAGS_REG))])
9716 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9718 (define_insn "x86_64_shrd"
9719 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9720 (ior:DI (ashiftrt:DI (match_dup 0)
9721 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9722 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9723 (minus:QI (const_int 64) (match_dup 2)))))
9724 (clobber (reg:CC FLAGS_REG))]
9726 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9727 [(set_attr "type" "ishift")
9728 (set_attr "prefix_0f" "1")
9729 (set_attr "mode" "DI")
9730 (set_attr "athlon_decode" "vector")
9731 (set_attr "amdfam10_decode" "vector")
9732 (set_attr "bdver1_decode" "vector")])
9734 (define_insn "x86_shrd"
9735 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9736 (ior:SI (ashiftrt:SI (match_dup 0)
9737 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9738 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9739 (minus:QI (const_int 32) (match_dup 2)))))
9740 (clobber (reg:CC FLAGS_REG))]
9742 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9743 [(set_attr "type" "ishift")
9744 (set_attr "prefix_0f" "1")
9745 (set_attr "mode" "SI")
9746 (set_attr "pent_pair" "np")
9747 (set_attr "athlon_decode" "vector")
9748 (set_attr "amdfam10_decode" "vector")
9749 (set_attr "bdver1_decode" "vector")])
9751 (define_insn "ashrdi3_cvt"
9752 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9753 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9754 (match_operand:QI 2 "const_int_operand")))
9755 (clobber (reg:CC FLAGS_REG))]
9756 "TARGET_64BIT && INTVAL (operands[2]) == 63
9757 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9758 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9761 sar{q}\t{%2, %0|%0, %2}"
9762 [(set_attr "type" "imovx,ishift")
9763 (set_attr "prefix_0f" "0,*")
9764 (set_attr "length_immediate" "0,*")
9765 (set_attr "modrm" "0,1")
9766 (set_attr "mode" "DI")])
9768 (define_insn "ashrsi3_cvt"
9769 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9770 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9771 (match_operand:QI 2 "const_int_operand")))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "INTVAL (operands[2]) == 31
9774 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9775 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9778 sar{l}\t{%2, %0|%0, %2}"
9779 [(set_attr "type" "imovx,ishift")
9780 (set_attr "prefix_0f" "0,*")
9781 (set_attr "length_immediate" "0,*")
9782 (set_attr "modrm" "0,1")
9783 (set_attr "mode" "SI")])
9785 (define_insn "*ashrsi3_cvt_zext"
9786 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9788 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9789 (match_operand:QI 2 "const_int_operand"))))
9790 (clobber (reg:CC FLAGS_REG))]
9791 "TARGET_64BIT && INTVAL (operands[2]) == 31
9792 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9793 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9796 sar{l}\t{%2, %k0|%k0, %2}"
9797 [(set_attr "type" "imovx,ishift")
9798 (set_attr "prefix_0f" "0,*")
9799 (set_attr "length_immediate" "0,*")
9800 (set_attr "modrm" "0,1")
9801 (set_attr "mode" "SI")])
9803 (define_expand "x86_shift<mode>_adj_3"
9804 [(use (match_operand:SWI48 0 "register_operand"))
9805 (use (match_operand:SWI48 1 "register_operand"))
9806 (use (match_operand:QI 2 "register_operand"))]
9809 rtx label = gen_label_rtx ();
9812 emit_insn (gen_testqi_ccz_1 (operands[2],
9813 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9815 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9816 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9817 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9818 gen_rtx_LABEL_REF (VOIDmode, label),
9820 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9821 JUMP_LABEL (tmp) = label;
9823 emit_move_insn (operands[0], operands[1]);
9824 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9825 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9827 LABEL_NUSES (label) = 1;
9832 (define_insn "*bmi2_<shift_insn><mode>3_1"
9833 [(set (match_operand:SWI48 0 "register_operand" "=r")
9834 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9835 (match_operand:SWI48 2 "register_operand" "r")))]
9837 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9838 [(set_attr "type" "ishiftx")
9839 (set_attr "mode" "<MODE>")])
9841 (define_insn "*<shift_insn><mode>3_1"
9842 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9844 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9845 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9846 (clobber (reg:CC FLAGS_REG))]
9847 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9849 switch (get_attr_type (insn))
9855 if (operands[2] == const1_rtx
9856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9857 return "<shift>{<imodesuffix>}\t%0";
9859 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9862 [(set_attr "isa" "*,bmi2")
9863 (set_attr "type" "ishift,ishiftx")
9864 (set (attr "length_immediate")
9866 (and (match_operand 2 "const1_operand")
9867 (ior (match_test "TARGET_SHIFT1")
9868 (match_test "optimize_function_for_size_p (cfun)")))
9870 (const_string "*")))
9871 (set_attr "mode" "<MODE>")])
9873 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9875 [(set (match_operand:SWI48 0 "register_operand")
9876 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9877 (match_operand:QI 2 "register_operand")))
9878 (clobber (reg:CC FLAGS_REG))]
9879 "TARGET_BMI2 && reload_completed"
9881 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9882 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9884 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9885 [(set (match_operand:DI 0 "register_operand" "=r")
9887 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9888 (match_operand:SI 2 "register_operand" "r"))))]
9889 "TARGET_64BIT && TARGET_BMI2"
9890 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9891 [(set_attr "type" "ishiftx")
9892 (set_attr "mode" "SI")])
9894 (define_insn "*<shift_insn>si3_1_zext"
9895 [(set (match_operand:DI 0 "register_operand" "=r,r")
9897 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9898 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9899 (clobber (reg:CC FLAGS_REG))]
9900 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9902 switch (get_attr_type (insn))
9908 if (operands[2] == const1_rtx
9909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9910 return "<shift>{l}\t%k0";
9912 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9915 [(set_attr "isa" "*,bmi2")
9916 (set_attr "type" "ishift,ishiftx")
9917 (set (attr "length_immediate")
9919 (and (match_operand 2 "const1_operand")
9920 (ior (match_test "TARGET_SHIFT1")
9921 (match_test "optimize_function_for_size_p (cfun)")))
9923 (const_string "*")))
9924 (set_attr "mode" "SI")])
9926 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9928 [(set (match_operand:DI 0 "register_operand")
9930 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9931 (match_operand:QI 2 "register_operand"))))
9932 (clobber (reg:CC FLAGS_REG))]
9933 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9935 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9936 "operands[2] = gen_lowpart (SImode, operands[2]);")
9938 (define_insn "*<shift_insn><mode>3_1"
9939 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9941 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9942 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9943 (clobber (reg:CC FLAGS_REG))]
9944 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9946 if (operands[2] == const1_rtx
9947 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9948 return "<shift>{<imodesuffix>}\t%0";
9950 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9952 [(set_attr "type" "ishift")
9953 (set (attr "length_immediate")
9955 (and (match_operand 2 "const1_operand")
9956 (ior (match_test "TARGET_SHIFT1")
9957 (match_test "optimize_function_for_size_p (cfun)")))
9959 (const_string "*")))
9960 (set_attr "mode" "<MODE>")])
9962 (define_insn "*<shift_insn>qi3_1_slp"
9963 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9964 (any_shiftrt:QI (match_dup 0)
9965 (match_operand:QI 1 "nonmemory_operand" "cI")))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "(optimize_function_for_size_p (cfun)
9968 || !TARGET_PARTIAL_REG_STALL
9969 || (operands[1] == const1_rtx
9972 if (operands[1] == const1_rtx
9973 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9974 return "<shift>{b}\t%0";
9976 return "<shift>{b}\t{%1, %0|%0, %1}";
9978 [(set_attr "type" "ishift1")
9979 (set (attr "length_immediate")
9981 (and (match_operand 1 "const1_operand")
9982 (ior (match_test "TARGET_SHIFT1")
9983 (match_test "optimize_function_for_size_p (cfun)")))
9985 (const_string "*")))
9986 (set_attr "mode" "QI")])
9988 ;; This pattern can't accept a variable shift count, since shifts by
9989 ;; zero don't affect the flags. We assume that shifts by constant
9990 ;; zero are optimized away.
9991 (define_insn "*<shift_insn><mode>3_cmp"
9992 [(set (reg FLAGS_REG)
9995 (match_operand:SWI 1 "nonimmediate_operand" "0")
9996 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9998 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9999 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10000 "(optimize_function_for_size_p (cfun)
10001 || !TARGET_PARTIAL_FLAG_REG_STALL
10002 || (operands[2] == const1_rtx
10004 && ix86_match_ccmode (insn, CCGOCmode)
10005 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10007 if (operands[2] == const1_rtx
10008 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10009 return "<shift>{<imodesuffix>}\t%0";
10011 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10013 [(set_attr "type" "ishift")
10014 (set (attr "length_immediate")
10016 (and (match_operand 2 "const1_operand")
10017 (ior (match_test "TARGET_SHIFT1")
10018 (match_test "optimize_function_for_size_p (cfun)")))
10020 (const_string "*")))
10021 (set_attr "mode" "<MODE>")])
10023 (define_insn "*<shift_insn>si3_cmp_zext"
10024 [(set (reg FLAGS_REG)
10026 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10027 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10029 (set (match_operand:DI 0 "register_operand" "=r")
10030 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10032 && (optimize_function_for_size_p (cfun)
10033 || !TARGET_PARTIAL_FLAG_REG_STALL
10034 || (operands[2] == const1_rtx
10036 && ix86_match_ccmode (insn, CCGOCmode)
10037 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10039 if (operands[2] == const1_rtx
10040 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10041 return "<shift>{l}\t%k0";
10043 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10045 [(set_attr "type" "ishift")
10046 (set (attr "length_immediate")
10048 (and (match_operand 2 "const1_operand")
10049 (ior (match_test "TARGET_SHIFT1")
10050 (match_test "optimize_function_for_size_p (cfun)")))
10052 (const_string "*")))
10053 (set_attr "mode" "SI")])
10055 (define_insn "*<shift_insn><mode>3_cconly"
10056 [(set (reg FLAGS_REG)
10059 (match_operand:SWI 1 "register_operand" "0")
10060 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10062 (clobber (match_scratch:SWI 0 "=<r>"))]
10063 "(optimize_function_for_size_p (cfun)
10064 || !TARGET_PARTIAL_FLAG_REG_STALL
10065 || (operands[2] == const1_rtx
10067 && ix86_match_ccmode (insn, CCGOCmode)"
10069 if (operands[2] == const1_rtx
10070 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10071 return "<shift>{<imodesuffix>}\t%0";
10073 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10075 [(set_attr "type" "ishift")
10076 (set (attr "length_immediate")
10078 (and (match_operand 2 "const1_operand")
10079 (ior (match_test "TARGET_SHIFT1")
10080 (match_test "optimize_function_for_size_p (cfun)")))
10082 (const_string "*")))
10083 (set_attr "mode" "<MODE>")])
10085 ;; Rotate instructions
10087 (define_expand "<rotate_insn>ti3"
10088 [(set (match_operand:TI 0 "register_operand")
10089 (any_rotate:TI (match_operand:TI 1 "register_operand")
10090 (match_operand:QI 2 "nonmemory_operand")))]
10093 if (const_1_to_63_operand (operands[2], VOIDmode))
10094 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10095 (operands[0], operands[1], operands[2]));
10102 (define_expand "<rotate_insn>di3"
10103 [(set (match_operand:DI 0 "shiftdi_operand")
10104 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10105 (match_operand:QI 2 "nonmemory_operand")))]
10109 ix86_expand_binary_operator (<CODE>, DImode, operands);
10110 else if (const_1_to_31_operand (operands[2], VOIDmode))
10111 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10112 (operands[0], operands[1], operands[2]));
10119 (define_expand "<rotate_insn><mode>3"
10120 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10121 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10122 (match_operand:QI 2 "nonmemory_operand")))]
10124 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10126 ;; Avoid useless masking of count operand.
10127 (define_insn "*<rotate_insn><mode>3_mask"
10128 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10130 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10133 (match_operand:SI 2 "register_operand" "c")
10134 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10135 (clobber (reg:CC FLAGS_REG))]
10136 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10137 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10138 == GET_MODE_BITSIZE (<MODE>mode)-1"
10140 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10142 [(set_attr "type" "rotate")
10143 (set_attr "mode" "<MODE>")])
10145 ;; Implement rotation using two double-precision
10146 ;; shift instructions and a scratch register.
10148 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10149 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10150 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10151 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10152 (clobber (reg:CC FLAGS_REG))
10153 (clobber (match_scratch:DWIH 3 "=&r"))]
10157 [(set (match_dup 3) (match_dup 4))
10159 [(set (match_dup 4)
10160 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10161 (lshiftrt:DWIH (match_dup 5)
10162 (minus:QI (match_dup 6) (match_dup 2)))))
10163 (clobber (reg:CC FLAGS_REG))])
10165 [(set (match_dup 5)
10166 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10167 (lshiftrt:DWIH (match_dup 3)
10168 (minus:QI (match_dup 6) (match_dup 2)))))
10169 (clobber (reg:CC FLAGS_REG))])]
10171 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10173 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10176 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10177 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10178 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10179 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10180 (clobber (reg:CC FLAGS_REG))
10181 (clobber (match_scratch:DWIH 3 "=&r"))]
10185 [(set (match_dup 3) (match_dup 4))
10187 [(set (match_dup 4)
10188 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10189 (ashift:DWIH (match_dup 5)
10190 (minus:QI (match_dup 6) (match_dup 2)))))
10191 (clobber (reg:CC FLAGS_REG))])
10193 [(set (match_dup 5)
10194 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10195 (ashift:DWIH (match_dup 3)
10196 (minus:QI (match_dup 6) (match_dup 2)))))
10197 (clobber (reg:CC FLAGS_REG))])]
10199 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10201 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10204 (define_insn "*bmi2_rorx<mode>3_1"
10205 [(set (match_operand:SWI48 0 "register_operand" "=r")
10206 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10207 (match_operand:QI 2 "immediate_operand" "<S>")))]
10209 "rorx\t{%2, %1, %0|%0, %1, %2}"
10210 [(set_attr "type" "rotatex")
10211 (set_attr "mode" "<MODE>")])
10213 (define_insn "*<rotate_insn><mode>3_1"
10214 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10216 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10217 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10218 (clobber (reg:CC FLAGS_REG))]
10219 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10221 switch (get_attr_type (insn))
10227 if (operands[2] == const1_rtx
10228 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10229 return "<rotate>{<imodesuffix>}\t%0";
10231 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10234 [(set_attr "isa" "*,bmi2")
10235 (set_attr "type" "rotate,rotatex")
10236 (set (attr "length_immediate")
10238 (and (eq_attr "type" "rotate")
10239 (and (match_operand 2 "const1_operand")
10240 (ior (match_test "TARGET_SHIFT1")
10241 (match_test "optimize_function_for_size_p (cfun)"))))
10243 (const_string "*")))
10244 (set_attr "mode" "<MODE>")])
10246 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10248 [(set (match_operand:SWI48 0 "register_operand")
10249 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10250 (match_operand:QI 2 "immediate_operand")))
10251 (clobber (reg:CC FLAGS_REG))]
10252 "TARGET_BMI2 && reload_completed"
10253 [(set (match_dup 0)
10254 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10257 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10261 [(set (match_operand:SWI48 0 "register_operand")
10262 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10263 (match_operand:QI 2 "immediate_operand")))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_BMI2 && reload_completed"
10266 [(set (match_dup 0)
10267 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10269 (define_insn "*bmi2_rorxsi3_1_zext"
10270 [(set (match_operand:DI 0 "register_operand" "=r")
10272 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10273 (match_operand:QI 2 "immediate_operand" "I"))))]
10274 "TARGET_64BIT && TARGET_BMI2"
10275 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10276 [(set_attr "type" "rotatex")
10277 (set_attr "mode" "SI")])
10279 (define_insn "*<rotate_insn>si3_1_zext"
10280 [(set (match_operand:DI 0 "register_operand" "=r,r")
10282 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10283 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10287 switch (get_attr_type (insn))
10293 if (operands[2] == const1_rtx
10294 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10295 return "<rotate>{l}\t%k0";
10297 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10300 [(set_attr "isa" "*,bmi2")
10301 (set_attr "type" "rotate,rotatex")
10302 (set (attr "length_immediate")
10304 (and (eq_attr "type" "rotate")
10305 (and (match_operand 2 "const1_operand")
10306 (ior (match_test "TARGET_SHIFT1")
10307 (match_test "optimize_function_for_size_p (cfun)"))))
10309 (const_string "*")))
10310 (set_attr "mode" "SI")])
10312 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10314 [(set (match_operand:DI 0 "register_operand")
10316 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10317 (match_operand:QI 2 "immediate_operand"))))
10318 (clobber (reg:CC FLAGS_REG))]
10319 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10320 [(set (match_dup 0)
10321 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10324 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10328 [(set (match_operand:DI 0 "register_operand")
10330 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10331 (match_operand:QI 2 "immediate_operand"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10334 [(set (match_dup 0)
10335 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10337 (define_insn "*<rotate_insn><mode>3_1"
10338 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10339 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10340 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10344 if (operands[2] == const1_rtx
10345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10346 return "<rotate>{<imodesuffix>}\t%0";
10348 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10350 [(set_attr "type" "rotate")
10351 (set (attr "length_immediate")
10353 (and (match_operand 2 "const1_operand")
10354 (ior (match_test "TARGET_SHIFT1")
10355 (match_test "optimize_function_for_size_p (cfun)")))
10357 (const_string "*")))
10358 (set_attr "mode" "<MODE>")])
10360 (define_insn "*<rotate_insn>qi3_1_slp"
10361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10362 (any_rotate:QI (match_dup 0)
10363 (match_operand:QI 1 "nonmemory_operand" "cI")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "(optimize_function_for_size_p (cfun)
10366 || !TARGET_PARTIAL_REG_STALL
10367 || (operands[1] == const1_rtx
10368 && TARGET_SHIFT1))"
10370 if (operands[1] == const1_rtx
10371 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10372 return "<rotate>{b}\t%0";
10374 return "<rotate>{b}\t{%1, %0|%0, %1}";
10376 [(set_attr "type" "rotate1")
10377 (set (attr "length_immediate")
10379 (and (match_operand 1 "const1_operand")
10380 (ior (match_test "TARGET_SHIFT1")
10381 (match_test "optimize_function_for_size_p (cfun)")))
10383 (const_string "*")))
10384 (set_attr "mode" "QI")])
10387 [(set (match_operand:HI 0 "register_operand")
10388 (any_rotate:HI (match_dup 0) (const_int 8)))
10389 (clobber (reg:CC FLAGS_REG))]
10391 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10392 [(parallel [(set (strict_low_part (match_dup 0))
10393 (bswap:HI (match_dup 0)))
10394 (clobber (reg:CC FLAGS_REG))])])
10396 ;; Bit set / bit test instructions
10398 (define_expand "extv"
10399 [(set (match_operand:SI 0 "register_operand")
10400 (sign_extract:SI (match_operand:SI 1 "register_operand")
10401 (match_operand:SI 2 "const8_operand")
10402 (match_operand:SI 3 "const8_operand")))]
10405 /* Handle extractions from %ah et al. */
10406 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10409 /* From mips.md: extract_bit_field doesn't verify that our source
10410 matches the predicate, so check it again here. */
10411 if (! ext_register_operand (operands[1], VOIDmode))
10415 (define_expand "extzv"
10416 [(set (match_operand:SI 0 "register_operand")
10417 (zero_extract:SI (match_operand 1 "ext_register_operand")
10418 (match_operand:SI 2 "const8_operand")
10419 (match_operand:SI 3 "const8_operand")))]
10422 /* Handle extractions from %ah et al. */
10423 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10426 /* From mips.md: extract_bit_field doesn't verify that our source
10427 matches the predicate, so check it again here. */
10428 if (! ext_register_operand (operands[1], VOIDmode))
10432 (define_expand "insv"
10433 [(set (zero_extract (match_operand 0 "register_operand")
10434 (match_operand 1 "const_int_operand")
10435 (match_operand 2 "const_int_operand"))
10436 (match_operand 3 "register_operand"))]
10439 rtx (*gen_mov_insv_1) (rtx, rtx);
10441 if (ix86_expand_pinsr (operands))
10444 /* Handle insertions to %ah et al. */
10445 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10448 /* From mips.md: insert_bit_field doesn't verify that our source
10449 matches the predicate, so check it again here. */
10450 if (! ext_register_operand (operands[0], VOIDmode))
10453 gen_mov_insv_1 = (TARGET_64BIT
10454 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10456 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10460 ;; %%% bts, btr, btc, bt.
10461 ;; In general these instructions are *slow* when applied to memory,
10462 ;; since they enforce atomic operation. When applied to registers,
10463 ;; it depends on the cpu implementation. They're never faster than
10464 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10465 ;; no point. But in 64-bit, we can't hold the relevant immediates
10466 ;; within the instruction itself, so operating on bits in the high
10467 ;; 32-bits of a register becomes easier.
10469 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10470 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10471 ;; negdf respectively, so they can never be disabled entirely.
10473 (define_insn "*btsq"
10474 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10476 (match_operand:DI 1 "const_0_to_63_operand"))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10480 "bts{q}\t{%1, %0|%0, %1}"
10481 [(set_attr "type" "alu1")
10482 (set_attr "prefix_0f" "1")
10483 (set_attr "mode" "DI")])
10485 (define_insn "*btrq"
10486 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10488 (match_operand:DI 1 "const_0_to_63_operand"))
10490 (clobber (reg:CC FLAGS_REG))]
10491 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10492 "btr{q}\t{%1, %0|%0, %1}"
10493 [(set_attr "type" "alu1")
10494 (set_attr "prefix_0f" "1")
10495 (set_attr "mode" "DI")])
10497 (define_insn "*btcq"
10498 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10500 (match_operand:DI 1 "const_0_to_63_operand"))
10501 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10502 (clobber (reg:CC FLAGS_REG))]
10503 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10504 "btc{q}\t{%1, %0|%0, %1}"
10505 [(set_attr "type" "alu1")
10506 (set_attr "prefix_0f" "1")
10507 (set_attr "mode" "DI")])
10509 ;; Allow Nocona to avoid these instructions if a register is available.
10512 [(match_scratch:DI 2 "r")
10513 (parallel [(set (zero_extract:DI
10514 (match_operand:DI 0 "register_operand")
10516 (match_operand:DI 1 "const_0_to_63_operand"))
10518 (clobber (reg:CC FLAGS_REG))])]
10519 "TARGET_64BIT && !TARGET_USE_BT"
10522 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10525 if (HOST_BITS_PER_WIDE_INT >= 64)
10526 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527 else if (i < HOST_BITS_PER_WIDE_INT)
10528 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10530 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10532 op1 = immed_double_const (lo, hi, DImode);
10535 emit_move_insn (operands[2], op1);
10539 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10544 [(match_scratch:DI 2 "r")
10545 (parallel [(set (zero_extract:DI
10546 (match_operand:DI 0 "register_operand")
10548 (match_operand:DI 1 "const_0_to_63_operand"))
10550 (clobber (reg:CC FLAGS_REG))])]
10551 "TARGET_64BIT && !TARGET_USE_BT"
10554 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10557 if (HOST_BITS_PER_WIDE_INT >= 64)
10558 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10559 else if (i < HOST_BITS_PER_WIDE_INT)
10560 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10564 op1 = immed_double_const (~lo, ~hi, DImode);
10567 emit_move_insn (operands[2], op1);
10571 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10576 [(match_scratch:DI 2 "r")
10577 (parallel [(set (zero_extract:DI
10578 (match_operand:DI 0 "register_operand")
10580 (match_operand:DI 1 "const_0_to_63_operand"))
10581 (not:DI (zero_extract:DI
10582 (match_dup 0) (const_int 1) (match_dup 1))))
10583 (clobber (reg:CC FLAGS_REG))])]
10584 "TARGET_64BIT && !TARGET_USE_BT"
10587 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10590 if (HOST_BITS_PER_WIDE_INT >= 64)
10591 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10592 else if (i < HOST_BITS_PER_WIDE_INT)
10593 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10595 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10597 op1 = immed_double_const (lo, hi, DImode);
10600 emit_move_insn (operands[2], op1);
10604 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10608 (define_insn "*bt<mode>"
10609 [(set (reg:CCC FLAGS_REG)
10611 (zero_extract:SWI48
10612 (match_operand:SWI48 0 "register_operand" "r")
10614 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10616 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10617 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10618 [(set_attr "type" "alu1")
10619 (set_attr "prefix_0f" "1")
10620 (set_attr "mode" "<MODE>")])
10622 ;; Store-flag instructions.
10624 ;; For all sCOND expanders, also expand the compare or test insn that
10625 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10627 (define_insn_and_split "*setcc_di_1"
10628 [(set (match_operand:DI 0 "register_operand" "=q")
10629 (match_operator:DI 1 "ix86_comparison_operator"
10630 [(reg FLAGS_REG) (const_int 0)]))]
10631 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10633 "&& reload_completed"
10634 [(set (match_dup 2) (match_dup 1))
10635 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10637 PUT_MODE (operands[1], QImode);
10638 operands[2] = gen_lowpart (QImode, operands[0]);
10641 (define_insn_and_split "*setcc_si_1_and"
10642 [(set (match_operand:SI 0 "register_operand" "=q")
10643 (match_operator:SI 1 "ix86_comparison_operator"
10644 [(reg FLAGS_REG) (const_int 0)]))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "!TARGET_PARTIAL_REG_STALL
10647 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10649 "&& reload_completed"
10650 [(set (match_dup 2) (match_dup 1))
10651 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10652 (clobber (reg:CC FLAGS_REG))])]
10654 PUT_MODE (operands[1], QImode);
10655 operands[2] = gen_lowpart (QImode, operands[0]);
10658 (define_insn_and_split "*setcc_si_1_movzbl"
10659 [(set (match_operand:SI 0 "register_operand" "=q")
10660 (match_operator:SI 1 "ix86_comparison_operator"
10661 [(reg FLAGS_REG) (const_int 0)]))]
10662 "!TARGET_PARTIAL_REG_STALL
10663 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10665 "&& reload_completed"
10666 [(set (match_dup 2) (match_dup 1))
10667 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10669 PUT_MODE (operands[1], QImode);
10670 operands[2] = gen_lowpart (QImode, operands[0]);
10673 (define_insn "*setcc_qi"
10674 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10675 (match_operator:QI 1 "ix86_comparison_operator"
10676 [(reg FLAGS_REG) (const_int 0)]))]
10679 [(set_attr "type" "setcc")
10680 (set_attr "mode" "QI")])
10682 (define_insn "*setcc_qi_slp"
10683 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10684 (match_operator:QI 1 "ix86_comparison_operator"
10685 [(reg FLAGS_REG) (const_int 0)]))]
10688 [(set_attr "type" "setcc")
10689 (set_attr "mode" "QI")])
10691 ;; In general it is not safe to assume too much about CCmode registers,
10692 ;; so simplify-rtx stops when it sees a second one. Under certain
10693 ;; conditions this is safe on x86, so help combine not create
10700 [(set (match_operand:QI 0 "nonimmediate_operand")
10701 (ne:QI (match_operator 1 "ix86_comparison_operator"
10702 [(reg FLAGS_REG) (const_int 0)])
10705 [(set (match_dup 0) (match_dup 1))]
10706 "PUT_MODE (operands[1], QImode);")
10709 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10710 (ne:QI (match_operator 1 "ix86_comparison_operator"
10711 [(reg FLAGS_REG) (const_int 0)])
10714 [(set (match_dup 0) (match_dup 1))]
10715 "PUT_MODE (operands[1], QImode);")
10718 [(set (match_operand:QI 0 "nonimmediate_operand")
10719 (eq:QI (match_operator 1 "ix86_comparison_operator"
10720 [(reg FLAGS_REG) (const_int 0)])
10723 [(set (match_dup 0) (match_dup 1))]
10725 rtx new_op1 = copy_rtx (operands[1]);
10726 operands[1] = new_op1;
10727 PUT_MODE (new_op1, QImode);
10728 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10729 GET_MODE (XEXP (new_op1, 0))));
10731 /* Make sure that (a) the CCmode we have for the flags is strong
10732 enough for the reversed compare or (b) we have a valid FP compare. */
10733 if (! ix86_comparison_operator (new_op1, VOIDmode))
10738 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10739 (eq:QI (match_operator 1 "ix86_comparison_operator"
10740 [(reg FLAGS_REG) (const_int 0)])
10743 [(set (match_dup 0) (match_dup 1))]
10745 rtx new_op1 = copy_rtx (operands[1]);
10746 operands[1] = new_op1;
10747 PUT_MODE (new_op1, QImode);
10748 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10749 GET_MODE (XEXP (new_op1, 0))));
10751 /* Make sure that (a) the CCmode we have for the flags is strong
10752 enough for the reversed compare or (b) we have a valid FP compare. */
10753 if (! ix86_comparison_operator (new_op1, VOIDmode))
10757 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10758 ;; subsequent logical operations are used to imitate conditional moves.
10759 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10762 (define_insn "setcc_<mode>_sse"
10763 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10764 (match_operator:MODEF 3 "sse_comparison_operator"
10765 [(match_operand:MODEF 1 "register_operand" "0,x")
10766 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10767 "SSE_FLOAT_MODE_P (<MODE>mode)"
10769 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10770 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10771 [(set_attr "isa" "noavx,avx")
10772 (set_attr "type" "ssecmp")
10773 (set_attr "length_immediate" "1")
10774 (set_attr "prefix" "orig,vex")
10775 (set_attr "mode" "<MODE>")])
10777 ;; Basic conditional jump instructions.
10778 ;; We ignore the overflow flag for signed branch instructions.
10780 (define_insn "*jcc_1"
10782 (if_then_else (match_operator 1 "ix86_comparison_operator"
10783 [(reg FLAGS_REG) (const_int 0)])
10784 (label_ref (match_operand 0))
10788 [(set_attr "type" "ibr")
10789 (set_attr "modrm" "0")
10790 (set (attr "length_nobnd")
10791 (if_then_else (and (ge (minus (match_dup 0) (pc))
10793 (lt (minus (match_dup 0) (pc))
10798 (define_insn "*jcc_2"
10800 (if_then_else (match_operator 1 "ix86_comparison_operator"
10801 [(reg FLAGS_REG) (const_int 0)])
10803 (label_ref (match_operand 0))))]
10806 [(set_attr "type" "ibr")
10807 (set_attr "modrm" "0")
10808 (set (attr "length_nobnd")
10809 (if_then_else (and (ge (minus (match_dup 0) (pc))
10811 (lt (minus (match_dup 0) (pc))
10816 ;; In general it is not safe to assume too much about CCmode registers,
10817 ;; so simplify-rtx stops when it sees a second one. Under certain
10818 ;; conditions this is safe on x86, so help combine not create
10826 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10827 [(reg FLAGS_REG) (const_int 0)])
10829 (label_ref (match_operand 1))
10833 (if_then_else (match_dup 0)
10834 (label_ref (match_dup 1))
10836 "PUT_MODE (operands[0], VOIDmode);")
10840 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10841 [(reg FLAGS_REG) (const_int 0)])
10843 (label_ref (match_operand 1))
10847 (if_then_else (match_dup 0)
10848 (label_ref (match_dup 1))
10851 rtx new_op0 = copy_rtx (operands[0]);
10852 operands[0] = new_op0;
10853 PUT_MODE (new_op0, VOIDmode);
10854 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10855 GET_MODE (XEXP (new_op0, 0))));
10857 /* Make sure that (a) the CCmode we have for the flags is strong
10858 enough for the reversed compare or (b) we have a valid FP compare. */
10859 if (! ix86_comparison_operator (new_op0, VOIDmode))
10863 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10864 ;; pass generates from shift insn with QImode operand. Actually, the mode
10865 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10866 ;; appropriate modulo of the bit offset value.
10868 (define_insn_and_split "*jcc_bt<mode>"
10870 (if_then_else (match_operator 0 "bt_comparison_operator"
10871 [(zero_extract:SWI48
10872 (match_operand:SWI48 1 "register_operand" "r")
10875 (match_operand:QI 2 "register_operand" "r")))
10877 (label_ref (match_operand 3))
10879 (clobber (reg:CC FLAGS_REG))]
10880 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10883 [(set (reg:CCC FLAGS_REG)
10885 (zero_extract:SWI48
10891 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892 (label_ref (match_dup 3))
10895 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10897 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10900 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10901 ;; zero extended to SImode.
10902 (define_insn_and_split "*jcc_bt<mode>_1"
10904 (if_then_else (match_operator 0 "bt_comparison_operator"
10905 [(zero_extract:SWI48
10906 (match_operand:SWI48 1 "register_operand" "r")
10908 (match_operand:SI 2 "register_operand" "r"))
10910 (label_ref (match_operand 3))
10912 (clobber (reg:CC FLAGS_REG))]
10913 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10916 [(set (reg:CCC FLAGS_REG)
10918 (zero_extract:SWI48
10924 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10925 (label_ref (match_dup 3))
10928 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10930 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10933 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10934 ;; also for DImode, this is what combine produces.
10935 (define_insn_and_split "*jcc_bt<mode>_mask"
10937 (if_then_else (match_operator 0 "bt_comparison_operator"
10938 [(zero_extract:SWI48
10939 (match_operand:SWI48 1 "register_operand" "r")
10942 (match_operand:SI 2 "register_operand" "r")
10943 (match_operand:SI 3 "const_int_operand" "n")))])
10944 (label_ref (match_operand 4))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10948 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10949 == GET_MODE_BITSIZE (<MODE>mode)-1"
10952 [(set (reg:CCC FLAGS_REG)
10954 (zero_extract:SWI48
10960 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10961 (label_ref (match_dup 4))
10964 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10966 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10969 (define_insn_and_split "*jcc_btsi_1"
10971 (if_then_else (match_operator 0 "bt_comparison_operator"
10974 (match_operand:SI 1 "register_operand" "r")
10975 (match_operand:QI 2 "register_operand" "r"))
10978 (label_ref (match_operand 3))
10980 (clobber (reg:CC FLAGS_REG))]
10981 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10984 [(set (reg:CCC FLAGS_REG)
10992 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10993 (label_ref (match_dup 3))
10996 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10998 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11001 ;; avoid useless masking of bit offset operand
11002 (define_insn_and_split "*jcc_btsi_mask_1"
11005 (match_operator 0 "bt_comparison_operator"
11008 (match_operand:SI 1 "register_operand" "r")
11011 (match_operand:SI 2 "register_operand" "r")
11012 (match_operand:SI 3 "const_int_operand" "n")) 0))
11015 (label_ref (match_operand 4))
11017 (clobber (reg:CC FLAGS_REG))]
11018 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11019 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11022 [(set (reg:CCC FLAGS_REG)
11030 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11031 (label_ref (match_dup 4))
11033 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11035 ;; Define combination compare-and-branch fp compare instructions to help
11038 (define_insn "*jcc<mode>_0_i387"
11040 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11041 [(match_operand:X87MODEF 1 "register_operand" "f")
11042 (match_operand:X87MODEF 2 "const0_operand")])
11043 (label_ref (match_operand 3))
11045 (clobber (reg:CCFP FPSR_REG))
11046 (clobber (reg:CCFP FLAGS_REG))
11047 (clobber (match_scratch:HI 4 "=a"))]
11048 "TARGET_80387 && !TARGET_CMOVE"
11051 (define_insn "*jcc<mode>_0_r_i387"
11053 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11054 [(match_operand:X87MODEF 1 "register_operand" "f")
11055 (match_operand:X87MODEF 2 "const0_operand")])
11057 (label_ref (match_operand 3))))
11058 (clobber (reg:CCFP FPSR_REG))
11059 (clobber (reg:CCFP FLAGS_REG))
11060 (clobber (match_scratch:HI 4 "=a"))]
11061 "TARGET_80387 && !TARGET_CMOVE"
11064 (define_insn "*jccxf_i387"
11066 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11067 [(match_operand:XF 1 "register_operand" "f")
11068 (match_operand:XF 2 "register_operand" "f")])
11069 (label_ref (match_operand 3))
11071 (clobber (reg:CCFP FPSR_REG))
11072 (clobber (reg:CCFP FLAGS_REG))
11073 (clobber (match_scratch:HI 4 "=a"))]
11074 "TARGET_80387 && !TARGET_CMOVE"
11077 (define_insn "*jccxf_r_i387"
11079 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11080 [(match_operand:XF 1 "register_operand" "f")
11081 (match_operand:XF 2 "register_operand" "f")])
11083 (label_ref (match_operand 3))))
11084 (clobber (reg:CCFP FPSR_REG))
11085 (clobber (reg:CCFP FLAGS_REG))
11086 (clobber (match_scratch:HI 4 "=a"))]
11087 "TARGET_80387 && !TARGET_CMOVE"
11090 (define_insn "*jcc<mode>_i387"
11092 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11093 [(match_operand:MODEF 1 "register_operand" "f")
11094 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11095 (label_ref (match_operand 3))
11097 (clobber (reg:CCFP FPSR_REG))
11098 (clobber (reg:CCFP FLAGS_REG))
11099 (clobber (match_scratch:HI 4 "=a"))]
11100 "TARGET_80387 && !TARGET_CMOVE"
11103 (define_insn "*jcc<mode>_r_i387"
11105 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11106 [(match_operand:MODEF 1 "register_operand" "f")
11107 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11109 (label_ref (match_operand 3))))
11110 (clobber (reg:CCFP FPSR_REG))
11111 (clobber (reg:CCFP FLAGS_REG))
11112 (clobber (match_scratch:HI 4 "=a"))]
11113 "TARGET_80387 && !TARGET_CMOVE"
11116 (define_insn "*jccu<mode>_i387"
11118 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11119 [(match_operand:X87MODEF 1 "register_operand" "f")
11120 (match_operand:X87MODEF 2 "register_operand" "f")])
11121 (label_ref (match_operand 3))
11123 (clobber (reg:CCFP FPSR_REG))
11124 (clobber (reg:CCFP FLAGS_REG))
11125 (clobber (match_scratch:HI 4 "=a"))]
11126 "TARGET_80387 && !TARGET_CMOVE"
11129 (define_insn "*jccu<mode>_r_i387"
11131 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11132 [(match_operand:X87MODEF 1 "register_operand" "f")
11133 (match_operand:X87MODEF 2 "register_operand" "f")])
11135 (label_ref (match_operand 3))))
11136 (clobber (reg:CCFP FPSR_REG))
11137 (clobber (reg:CCFP FLAGS_REG))
11138 (clobber (match_scratch:HI 4 "=a"))]
11139 "TARGET_80387 && !TARGET_CMOVE"
11144 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11145 [(match_operand:X87MODEF 1 "register_operand")
11146 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11148 (match_operand 4)))
11149 (clobber (reg:CCFP FPSR_REG))
11150 (clobber (reg:CCFP FLAGS_REG))]
11151 "TARGET_80387 && !TARGET_CMOVE
11152 && reload_completed"
11155 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11156 operands[3], operands[4], NULL_RTX, NULL_RTX);
11162 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11163 [(match_operand:X87MODEF 1 "register_operand")
11164 (match_operand:X87MODEF 2 "general_operand")])
11166 (match_operand 4)))
11167 (clobber (reg:CCFP FPSR_REG))
11168 (clobber (reg:CCFP FLAGS_REG))
11169 (clobber (match_scratch:HI 5))]
11170 "TARGET_80387 && !TARGET_CMOVE
11171 && reload_completed"
11174 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11175 operands[3], operands[4], operands[5], NULL_RTX);
11179 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11180 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11181 ;; with a precedence over other operators and is always put in the first
11182 ;; place. Swap condition and operands to match ficom instruction.
11184 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11187 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11188 [(match_operator:X87MODEF 1 "float_operator"
11189 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11190 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11191 (label_ref (match_operand 4))
11193 (clobber (reg:CCFP FPSR_REG))
11194 (clobber (reg:CCFP FLAGS_REG))
11195 (clobber (match_scratch:HI 5 "=a,a"))]
11196 "TARGET_80387 && !TARGET_CMOVE
11197 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11198 || optimize_function_for_size_p (cfun))"
11201 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11204 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11205 [(match_operator:X87MODEF 1 "float_operator"
11206 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11207 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11209 (label_ref (match_operand 4))))
11210 (clobber (reg:CCFP FPSR_REG))
11211 (clobber (reg:CCFP FLAGS_REG))
11212 (clobber (match_scratch:HI 5 "=a,a"))]
11213 "TARGET_80387 && !TARGET_CMOVE
11214 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11215 || optimize_function_for_size_p (cfun))"
11221 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11222 [(match_operator:X87MODEF 1 "float_operator"
11223 [(match_operand:SWI24 2 "memory_operand")])
11224 (match_operand:X87MODEF 3 "register_operand")])
11226 (match_operand 5)))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 6))]
11230 "TARGET_80387 && !TARGET_CMOVE
11231 && reload_completed"
11234 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11235 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11236 operands[4], operands[5], operands[6], NULL_RTX);
11240 ;; %%% Kill this when reload knows how to do it.
11244 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11245 [(match_operator:X87MODEF 1 "float_operator"
11246 [(match_operand:SWI24 2 "register_operand")])
11247 (match_operand:X87MODEF 3 "register_operand")])
11249 (match_operand 5)))
11250 (clobber (reg:CCFP FPSR_REG))
11251 (clobber (reg:CCFP FLAGS_REG))
11252 (clobber (match_scratch:HI 6))]
11253 "TARGET_80387 && !TARGET_CMOVE
11254 && reload_completed"
11257 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11259 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11260 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11261 operands[4], operands[5], operands[6], operands[2]);
11265 ;; Unconditional and other jump instructions
11267 (define_insn "jump"
11269 (label_ref (match_operand 0)))]
11272 [(set_attr "type" "ibr")
11273 (set (attr "length_nobnd")
11274 (if_then_else (and (ge (minus (match_dup 0) (pc))
11276 (lt (minus (match_dup 0) (pc))
11280 (set_attr "modrm" "0")])
11282 (define_expand "indirect_jump"
11283 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11287 operands[0] = convert_memory_address (word_mode, operands[0]);
11290 (define_insn "*indirect_jump"
11291 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11294 [(set_attr "type" "ibr")
11295 (set_attr "length_immediate" "0")])
11297 (define_expand "tablejump"
11298 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11299 (use (label_ref (match_operand 1)))])]
11302 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11303 relative. Convert the relative address to an absolute address. */
11307 enum rtx_code code;
11309 /* We can't use @GOTOFF for text labels on VxWorks;
11310 see gotoff_operand. */
11311 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11315 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11317 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11321 op1 = pic_offset_table_rtx;
11326 op0 = pic_offset_table_rtx;
11330 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11335 operands[0] = convert_memory_address (word_mode, operands[0]);
11338 (define_insn "*tablejump_1"
11339 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11340 (use (label_ref (match_operand 1)))]
11343 [(set_attr "type" "ibr")
11344 (set_attr "length_immediate" "0")])
11346 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11349 [(set (reg FLAGS_REG) (match_operand 0))
11350 (set (match_operand:QI 1 "register_operand")
11351 (match_operator:QI 2 "ix86_comparison_operator"
11352 [(reg FLAGS_REG) (const_int 0)]))
11353 (set (match_operand 3 "q_regs_operand")
11354 (zero_extend (match_dup 1)))]
11355 "(peep2_reg_dead_p (3, operands[1])
11356 || operands_match_p (operands[1], operands[3]))
11357 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11358 [(set (match_dup 4) (match_dup 0))
11359 (set (strict_low_part (match_dup 5))
11362 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11363 operands[5] = gen_lowpart (QImode, operands[3]);
11364 ix86_expand_clear (operands[3]);
11368 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11369 (match_operand 4)])
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (set (match_operand 3 "q_regs_operand")
11374 (zero_extend (match_dup 1)))]
11375 "(peep2_reg_dead_p (3, operands[1])
11376 || operands_match_p (operands[1], operands[3]))
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(parallel [(set (match_dup 5) (match_dup 0))
11380 (set (strict_low_part (match_dup 6))
11383 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11384 operands[6] = gen_lowpart (QImode, operands[3]);
11385 ix86_expand_clear (operands[3]);
11388 ;; Similar, but match zero extend with andsi3.
11391 [(set (reg FLAGS_REG) (match_operand 0))
11392 (set (match_operand:QI 1 "register_operand")
11393 (match_operator:QI 2 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)]))
11395 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11396 (and:SI (match_dup 3) (const_int 255)))
11397 (clobber (reg:CC FLAGS_REG))])]
11398 "REGNO (operands[1]) == REGNO (operands[3])
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(set (match_dup 4) (match_dup 0))
11401 (set (strict_low_part (match_dup 5))
11404 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11405 operands[5] = gen_lowpart (QImode, operands[3]);
11406 ix86_expand_clear (operands[3]);
11410 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11411 (match_operand 4)])
11412 (set (match_operand:QI 1 "register_operand")
11413 (match_operator:QI 2 "ix86_comparison_operator"
11414 [(reg FLAGS_REG) (const_int 0)]))
11415 (parallel [(set (match_operand 3 "q_regs_operand")
11416 (zero_extend (match_dup 1)))
11417 (clobber (reg:CC FLAGS_REG))])]
11418 "(peep2_reg_dead_p (3, operands[1])
11419 || operands_match_p (operands[1], operands[3]))
11420 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11421 [(parallel [(set (match_dup 5) (match_dup 0))
11423 (set (strict_low_part (match_dup 6))
11426 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427 operands[6] = gen_lowpart (QImode, operands[3]);
11428 ix86_expand_clear (operands[3]);
11431 ;; Call instructions.
11433 ;; The predicates normally associated with named expanders are not properly
11434 ;; checked for calls. This is a bug in the generic code, but it isn't that
11435 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11437 ;; P6 processors will jump to the address after the decrement when %esp
11438 ;; is used as a call operand, so they will execute return address as a code.
11439 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11441 ;; Register constraint for call instruction.
11442 (define_mode_attr c [(SI "l") (DI "r")])
11444 ;; Call subroutine returning no value.
11446 (define_expand "call"
11447 [(call (match_operand:QI 0)
11449 (use (match_operand 2))]
11452 ix86_expand_call (NULL, operands[0], operands[1],
11453 operands[2], NULL, false);
11457 (define_expand "sibcall"
11458 [(call (match_operand:QI 0)
11460 (use (match_operand 2))]
11463 ix86_expand_call (NULL, operands[0], operands[1],
11464 operands[2], NULL, true);
11468 (define_insn "*call"
11469 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11470 (match_operand 1))]
11471 "!SIBLING_CALL_P (insn)"
11472 "* return ix86_output_call_insn (insn, operands[0]);"
11473 [(set_attr "type" "call")])
11475 (define_insn "*call_rex64_ms_sysv"
11476 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11477 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11479 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11480 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11481 "* return ix86_output_call_insn (insn, operands[0]);"
11482 [(set_attr "type" "call")])
11484 (define_insn "*sibcall"
11485 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11486 (match_operand 1))]
11487 "SIBLING_CALL_P (insn)"
11488 "* return ix86_output_call_insn (insn, operands[0]);"
11489 [(set_attr "type" "call")])
11491 (define_expand "call_pop"
11492 [(parallel [(call (match_operand:QI 0)
11493 (match_operand:SI 1))
11494 (set (reg:SI SP_REG)
11495 (plus:SI (reg:SI SP_REG)
11496 (match_operand:SI 3)))])]
11499 ix86_expand_call (NULL, operands[0], operands[1],
11500 operands[2], operands[3], false);
11504 (define_insn "*call_pop"
11505 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11507 (set (reg:SI SP_REG)
11508 (plus:SI (reg:SI SP_REG)
11509 (match_operand:SI 2 "immediate_operand" "i")))]
11510 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11511 "* return ix86_output_call_insn (insn, operands[0]);"
11512 [(set_attr "type" "call")])
11514 (define_insn "*sibcall_pop"
11515 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11517 (set (reg:SI SP_REG)
11518 (plus:SI (reg:SI SP_REG)
11519 (match_operand:SI 2 "immediate_operand" "i")))]
11520 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11521 "* return ix86_output_call_insn (insn, operands[0]);"
11522 [(set_attr "type" "call")])
11524 ;; Call subroutine, returning value in operand 0
11526 (define_expand "call_value"
11527 [(set (match_operand 0)
11528 (call (match_operand:QI 1)
11529 (match_operand 2)))
11530 (use (match_operand 3))]
11533 ix86_expand_call (operands[0], operands[1], operands[2],
11534 operands[3], NULL, false);
11538 (define_expand "sibcall_value"
11539 [(set (match_operand 0)
11540 (call (match_operand:QI 1)
11541 (match_operand 2)))
11542 (use (match_operand 3))]
11545 ix86_expand_call (operands[0], operands[1], operands[2],
11546 operands[3], NULL, true);
11550 (define_insn "*call_value"
11551 [(set (match_operand 0)
11552 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11553 (match_operand 2)))]
11554 "!SIBLING_CALL_P (insn)"
11555 "* return ix86_output_call_insn (insn, operands[1]);"
11556 [(set_attr "type" "callv")])
11558 (define_insn "*sibcall_value"
11559 [(set (match_operand 0)
11560 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11561 (match_operand 2)))]
11562 "SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[1]);"
11564 [(set_attr "type" "callv")])
11566 (define_insn "*call_value_rex64_ms_sysv"
11567 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11568 [(set (match_operand 0)
11569 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11570 (match_operand 2)))
11571 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11572 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11573 "* return ix86_output_call_insn (insn, operands[1]);"
11574 [(set_attr "type" "callv")])
11576 (define_expand "call_value_pop"
11577 [(parallel [(set (match_operand 0)
11578 (call (match_operand:QI 1)
11579 (match_operand:SI 2)))
11580 (set (reg:SI SP_REG)
11581 (plus:SI (reg:SI SP_REG)
11582 (match_operand:SI 4)))])]
11585 ix86_expand_call (operands[0], operands[1], operands[2],
11586 operands[3], operands[4], false);
11590 (define_insn "*call_value_pop"
11591 [(set (match_operand 0)
11592 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11593 (match_operand 2)))
11594 (set (reg:SI SP_REG)
11595 (plus:SI (reg:SI SP_REG)
11596 (match_operand:SI 3 "immediate_operand" "i")))]
11597 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11598 "* return ix86_output_call_insn (insn, operands[1]);"
11599 [(set_attr "type" "callv")])
11601 (define_insn "*sibcall_value_pop"
11602 [(set (match_operand 0)
11603 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11604 (match_operand 2)))
11605 (set (reg:SI SP_REG)
11606 (plus:SI (reg:SI SP_REG)
11607 (match_operand:SI 3 "immediate_operand" "i")))]
11608 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11609 "* return ix86_output_call_insn (insn, operands[1]);"
11610 [(set_attr "type" "callv")])
11612 ;; Call subroutine returning any type.
11614 (define_expand "untyped_call"
11615 [(parallel [(call (match_operand 0)
11618 (match_operand 2)])]
11623 /* In order to give reg-stack an easier job in validating two
11624 coprocessor registers as containing a possible return value,
11625 simply pretend the untyped call returns a complex long double
11628 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11629 and should have the default ABI. */
11631 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11632 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11633 operands[0], const0_rtx,
11634 GEN_INT ((TARGET_64BIT
11635 ? (ix86_abi == SYSV_ABI
11636 ? X86_64_SSE_REGPARM_MAX
11637 : X86_64_MS_SSE_REGPARM_MAX)
11638 : X86_32_SSE_REGPARM_MAX)
11642 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11644 rtx set = XVECEXP (operands[2], 0, i);
11645 emit_move_insn (SET_DEST (set), SET_SRC (set));
11648 /* The optimizer does not know that the call sets the function value
11649 registers we stored in the result block. We avoid problems by
11650 claiming that all hard registers are used and clobbered at this
11652 emit_insn (gen_blockage ());
11657 ;; Prologue and epilogue instructions
11659 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11660 ;; all of memory. This blocks insns from being moved across this point.
11662 (define_insn "blockage"
11663 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11666 [(set_attr "length" "0")])
11668 ;; Do not schedule instructions accessing memory across this point.
11670 (define_expand "memory_blockage"
11671 [(set (match_dup 0)
11672 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11675 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11676 MEM_VOLATILE_P (operands[0]) = 1;
11679 (define_insn "*memory_blockage"
11680 [(set (match_operand:BLK 0)
11681 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11684 [(set_attr "length" "0")])
11686 ;; As USE insns aren't meaningful after reload, this is used instead
11687 ;; to prevent deleting instructions setting registers for PIC code
11688 (define_insn "prologue_use"
11689 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11692 [(set_attr "length" "0")])
11694 ;; Insn emitted into the body of a function to return from a function.
11695 ;; This is only done if the function's epilogue is known to be simple.
11696 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11698 (define_expand "return"
11700 "ix86_can_use_return_insn_p ()"
11702 if (crtl->args.pops_args)
11704 rtx popc = GEN_INT (crtl->args.pops_args);
11705 emit_jump_insn (gen_simple_return_pop_internal (popc));
11710 ;; We need to disable this for TARGET_SEH, as otherwise
11711 ;; shrink-wrapped prologue gets enabled too. This might exceed
11712 ;; the maximum size of prologue in unwind information.
11714 (define_expand "simple_return"
11718 if (crtl->args.pops_args)
11720 rtx popc = GEN_INT (crtl->args.pops_args);
11721 emit_jump_insn (gen_simple_return_pop_internal (popc));
11726 (define_insn "simple_return_internal"
11730 [(set_attr "length_nobnd" "1")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "modrm" "0")])
11735 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11736 ;; instruction Athlon and K8 have.
11738 (define_insn "simple_return_internal_long"
11740 (unspec [(const_int 0)] UNSPEC_REP)]
11743 if (ix86_bnd_prefixed_insn_p (insn))
11746 return "rep%; ret";
11748 [(set_attr "length" "2")
11749 (set_attr "atom_unit" "jeu")
11750 (set_attr "length_immediate" "0")
11751 (set_attr "prefix_rep" "1")
11752 (set_attr "modrm" "0")])
11754 (define_insn "simple_return_pop_internal"
11756 (use (match_operand:SI 0 "const_int_operand"))]
11759 [(set_attr "length_nobnd" "3")
11760 (set_attr "atom_unit" "jeu")
11761 (set_attr "length_immediate" "2")
11762 (set_attr "modrm" "0")])
11764 (define_insn "simple_return_indirect_internal"
11766 (use (match_operand:SI 0 "register_operand" "r"))]
11769 [(set_attr "type" "ibr")
11770 (set_attr "length_immediate" "0")])
11776 [(set_attr "length" "1")
11777 (set_attr "length_immediate" "0")
11778 (set_attr "modrm" "0")])
11780 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11781 (define_insn "nops"
11782 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11786 int num = INTVAL (operands[0]);
11788 gcc_assert (IN_RANGE (num, 1, 8));
11791 fputs ("\tnop\n", asm_out_file);
11795 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11796 (set_attr "length_immediate" "0")
11797 (set_attr "modrm" "0")])
11799 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11800 ;; branch prediction penalty for the third jump in a 16-byte
11804 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11807 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11808 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11810 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11811 The align insn is used to avoid 3 jump instructions in the row to improve
11812 branch prediction and the benefits hardly outweigh the cost of extra 8
11813 nops on the average inserted by full alignment pseudo operation. */
11817 [(set_attr "length" "16")])
11819 (define_expand "prologue"
11822 "ix86_expand_prologue (); DONE;")
11824 (define_insn "set_got"
11825 [(set (match_operand:SI 0 "register_operand" "=r")
11826 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11827 (clobber (reg:CC FLAGS_REG))]
11829 "* return output_set_got (operands[0], NULL_RTX);"
11830 [(set_attr "type" "multi")
11831 (set_attr "length" "12")])
11833 (define_insn "set_got_labelled"
11834 [(set (match_operand:SI 0 "register_operand" "=r")
11835 (unspec:SI [(label_ref (match_operand 1))]
11837 (clobber (reg:CC FLAGS_REG))]
11839 "* return output_set_got (operands[0], operands[1]);"
11840 [(set_attr "type" "multi")
11841 (set_attr "length" "12")])
11843 (define_insn "set_got_rex64"
11844 [(set (match_operand:DI 0 "register_operand" "=r")
11845 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11847 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11848 [(set_attr "type" "lea")
11849 (set_attr "length_address" "4")
11850 (set_attr "mode" "DI")])
11852 (define_insn "set_rip_rex64"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11854 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11856 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11857 [(set_attr "type" "lea")
11858 (set_attr "length_address" "4")
11859 (set_attr "mode" "DI")])
11861 (define_insn "set_got_offset_rex64"
11862 [(set (match_operand:DI 0 "register_operand" "=r")
11864 [(label_ref (match_operand 1))]
11865 UNSPEC_SET_GOT_OFFSET))]
11867 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11868 [(set_attr "type" "imov")
11869 (set_attr "length_immediate" "0")
11870 (set_attr "length_address" "8")
11871 (set_attr "mode" "DI")])
11873 (define_expand "epilogue"
11876 "ix86_expand_epilogue (1); DONE;")
11878 (define_expand "sibcall_epilogue"
11881 "ix86_expand_epilogue (0); DONE;")
11883 (define_expand "eh_return"
11884 [(use (match_operand 0 "register_operand"))]
11887 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11889 /* Tricky bit: we write the address of the handler to which we will
11890 be returning into someone else's stack frame, one word below the
11891 stack address we wish to restore. */
11892 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11893 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11894 tmp = gen_rtx_MEM (Pmode, tmp);
11895 emit_move_insn (tmp, ra);
11897 emit_jump_insn (gen_eh_return_internal ());
11902 (define_insn_and_split "eh_return_internal"
11906 "epilogue_completed"
11908 "ix86_expand_epilogue (2); DONE;")
11910 (define_insn "leave"
11911 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11912 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11913 (clobber (mem:BLK (scratch)))]
11916 [(set_attr "type" "leave")])
11918 (define_insn "leave_rex64"
11919 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11920 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11921 (clobber (mem:BLK (scratch)))]
11924 [(set_attr "type" "leave")])
11926 ;; Handle -fsplit-stack.
11928 (define_expand "split_stack_prologue"
11932 ix86_expand_split_stack_prologue ();
11936 ;; In order to support the call/return predictor, we use a return
11937 ;; instruction which the middle-end doesn't see.
11938 (define_insn "split_stack_return"
11939 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11940 UNSPECV_SPLIT_STACK_RETURN)]
11943 if (operands[0] == const0_rtx)
11948 [(set_attr "atom_unit" "jeu")
11949 (set_attr "modrm" "0")
11950 (set (attr "length")
11951 (if_then_else (match_operand:SI 0 "const0_operand")
11954 (set (attr "length_immediate")
11955 (if_then_else (match_operand:SI 0 "const0_operand")
11959 ;; If there are operand 0 bytes available on the stack, jump to
11962 (define_expand "split_stack_space_check"
11963 [(set (pc) (if_then_else
11964 (ltu (minus (reg SP_REG)
11965 (match_operand 0 "register_operand"))
11966 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11967 (label_ref (match_operand 1))
11971 rtx reg, size, limit;
11973 reg = gen_reg_rtx (Pmode);
11974 size = force_reg (Pmode, operands[0]);
11975 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11976 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11977 UNSPEC_STACK_CHECK);
11978 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11979 ix86_expand_branch (GEU, reg, limit, operands[1]);
11984 ;; Bit manipulation instructions.
11986 (define_expand "ffs<mode>2"
11987 [(set (match_dup 2) (const_int -1))
11988 (parallel [(set (match_dup 3) (match_dup 4))
11989 (set (match_operand:SWI48 0 "register_operand")
11991 (match_operand:SWI48 1 "nonimmediate_operand")))])
11992 (set (match_dup 0) (if_then_else:SWI48
11993 (eq (match_dup 3) (const_int 0))
11996 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11997 (clobber (reg:CC FLAGS_REG))])]
12000 enum machine_mode flags_mode;
12002 if (<MODE>mode == SImode && !TARGET_CMOVE)
12004 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12008 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12010 operands[2] = gen_reg_rtx (<MODE>mode);
12011 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12012 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12015 (define_insn_and_split "ffssi2_no_cmove"
12016 [(set (match_operand:SI 0 "register_operand" "=r")
12017 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12018 (clobber (match_scratch:SI 2 "=&q"))
12019 (clobber (reg:CC FLAGS_REG))]
12022 "&& reload_completed"
12023 [(parallel [(set (match_dup 4) (match_dup 5))
12024 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12025 (set (strict_low_part (match_dup 3))
12026 (eq:QI (match_dup 4) (const_int 0)))
12027 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12028 (clobber (reg:CC FLAGS_REG))])
12029 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12030 (clobber (reg:CC FLAGS_REG))])
12031 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12032 (clobber (reg:CC FLAGS_REG))])]
12034 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12036 operands[3] = gen_lowpart (QImode, operands[2]);
12037 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12038 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12040 ix86_expand_clear (operands[2]);
12043 (define_insn "*tzcnt<mode>_1"
12044 [(set (reg:CCC FLAGS_REG)
12045 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12047 (set (match_operand:SWI48 0 "register_operand" "=r")
12048 (ctz:SWI48 (match_dup 1)))]
12050 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set_attr "prefix_rep" "1")
12054 (set_attr "btver2_decode" "double")
12055 (set_attr "mode" "<MODE>")])
12057 (define_insn "*bsf<mode>_1"
12058 [(set (reg:CCZ FLAGS_REG)
12059 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12061 (set (match_operand:SWI48 0 "register_operand" "=r")
12062 (ctz:SWI48 (match_dup 1)))]
12064 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12065 [(set_attr "type" "alu1")
12066 (set_attr "prefix_0f" "1")
12067 (set_attr "btver2_decode" "double")
12068 (set_attr "mode" "<MODE>")])
12070 (define_insn "ctz<mode>2"
12071 [(set (match_operand:SWI248 0 "register_operand" "=r")
12072 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12073 (clobber (reg:CC FLAGS_REG))]
12077 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12078 else if (optimize_function_for_size_p (cfun))
12080 else if (TARGET_GENERIC)
12081 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12082 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12084 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12086 [(set_attr "type" "alu1")
12087 (set_attr "prefix_0f" "1")
12088 (set (attr "prefix_rep")
12090 (ior (match_test "TARGET_BMI")
12091 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12092 (match_test "TARGET_GENERIC")))
12094 (const_string "0")))
12095 (set_attr "mode" "<MODE>")])
12097 (define_expand "clz<mode>2"
12099 [(set (match_operand:SWI248 0 "register_operand")
12102 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12103 (clobber (reg:CC FLAGS_REG))])
12105 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12106 (clobber (reg:CC FLAGS_REG))])]
12111 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12114 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12117 (define_insn "clz<mode>2_lzcnt"
12118 [(set (match_operand:SWI248 0 "register_operand" "=r")
12119 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12120 (clobber (reg:CC FLAGS_REG))]
12122 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12123 [(set_attr "prefix_rep" "1")
12124 (set_attr "type" "bitmanip")
12125 (set_attr "mode" "<MODE>")])
12127 ;; BMI instructions.
12128 (define_insn "*bmi_andn_<mode>"
12129 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12132 (match_operand:SWI48 1 "register_operand" "r,r"))
12133 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12134 (clobber (reg:CC FLAGS_REG))]
12136 "andn\t{%2, %1, %0|%0, %1, %2}"
12137 [(set_attr "type" "bitmanip")
12138 (set_attr "btver2_decode" "direct, double")
12139 (set_attr "mode" "<MODE>")])
12141 (define_insn "bmi_bextr_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12143 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12144 (match_operand:SWI48 2 "register_operand" "r,r")]
12146 (clobber (reg:CC FLAGS_REG))]
12148 "bextr\t{%2, %1, %0|%0, %1, %2}"
12149 [(set_attr "type" "bitmanip")
12150 (set_attr "btver2_decode" "direct, double")
12151 (set_attr "mode" "<MODE>")])
12153 (define_insn "*bmi_blsi_<mode>"
12154 [(set (match_operand:SWI48 0 "register_operand" "=r")
12157 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12159 (clobber (reg:CC FLAGS_REG))]
12161 "blsi\t{%1, %0|%0, %1}"
12162 [(set_attr "type" "bitmanip")
12163 (set_attr "btver2_decode" "double")
12164 (set_attr "mode" "<MODE>")])
12166 (define_insn "*bmi_blsmsk_<mode>"
12167 [(set (match_operand:SWI48 0 "register_operand" "=r")
12170 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12173 (clobber (reg:CC FLAGS_REG))]
12175 "blsmsk\t{%1, %0|%0, %1}"
12176 [(set_attr "type" "bitmanip")
12177 (set_attr "btver2_decode" "double")
12178 (set_attr "mode" "<MODE>")])
12180 (define_insn "*bmi_blsr_<mode>"
12181 [(set (match_operand:SWI48 0 "register_operand" "=r")
12184 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12187 (clobber (reg:CC FLAGS_REG))]
12189 "blsr\t{%1, %0|%0, %1}"
12190 [(set_attr "type" "bitmanip")
12191 (set_attr "btver2_decode" "double")
12192 (set_attr "mode" "<MODE>")])
12194 ;; BMI2 instructions.
12195 (define_insn "bmi2_bzhi_<mode>3"
12196 [(set (match_operand:SWI48 0 "register_operand" "=r")
12197 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12198 (match_operand:SWI48 2 "register_operand" "r"))
12199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12200 (clobber (reg:CC FLAGS_REG))]
12202 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12203 [(set_attr "type" "bitmanip")
12204 (set_attr "prefix" "vex")
12205 (set_attr "mode" "<MODE>")])
12207 (define_insn "bmi2_pdep_<mode>3"
12208 [(set (match_operand:SWI48 0 "register_operand" "=r")
12209 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12210 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12213 "pdep\t{%2, %1, %0|%0, %1, %2}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "prefix" "vex")
12216 (set_attr "mode" "<MODE>")])
12218 (define_insn "bmi2_pext_<mode>3"
12219 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12221 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12224 "pext\t{%2, %1, %0|%0, %1, %2}"
12225 [(set_attr "type" "bitmanip")
12226 (set_attr "prefix" "vex")
12227 (set_attr "mode" "<MODE>")])
12229 ;; TBM instructions.
12230 (define_insn "tbm_bextri_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12232 (zero_extract:SWI48
12233 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12235 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12236 (clobber (reg:CC FLAGS_REG))]
12239 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12240 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12242 [(set_attr "type" "bitmanip")
12243 (set_attr "mode" "<MODE>")])
12245 (define_insn "*tbm_blcfill_<mode>"
12246 [(set (match_operand:SWI48 0 "register_operand" "=r")
12249 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12252 (clobber (reg:CC FLAGS_REG))]
12254 "blcfill\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12258 (define_insn "*tbm_blci_<mode>"
12259 [(set (match_operand:SWI48 0 "register_operand" "=r")
12263 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12266 (clobber (reg:CC FLAGS_REG))]
12268 "blci\t{%1, %0|%0, %1}"
12269 [(set_attr "type" "bitmanip")
12270 (set_attr "mode" "<MODE>")])
12272 (define_insn "*tbm_blcic_<mode>"
12273 [(set (match_operand:SWI48 0 "register_operand" "=r")
12276 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12280 (clobber (reg:CC FLAGS_REG))]
12282 "blcic\t{%1, %0|%0, %1}"
12283 [(set_attr "type" "bitmanip")
12284 (set_attr "mode" "<MODE>")])
12286 (define_insn "*tbm_blcmsk_<mode>"
12287 [(set (match_operand:SWI48 0 "register_operand" "=r")
12290 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12293 (clobber (reg:CC FLAGS_REG))]
12295 "blcmsk\t{%1, %0|%0, %1}"
12296 [(set_attr "type" "bitmanip")
12297 (set_attr "mode" "<MODE>")])
12299 (define_insn "*tbm_blcs_<mode>"
12300 [(set (match_operand:SWI48 0 "register_operand" "=r")
12303 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12306 (clobber (reg:CC FLAGS_REG))]
12308 "blcs\t{%1, %0|%0, %1}"
12309 [(set_attr "type" "bitmanip")
12310 (set_attr "mode" "<MODE>")])
12312 (define_insn "*tbm_blsfill_<mode>"
12313 [(set (match_operand:SWI48 0 "register_operand" "=r")
12316 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12319 (clobber (reg:CC FLAGS_REG))]
12321 "blsfill\t{%1, %0|%0, %1}"
12322 [(set_attr "type" "bitmanip")
12323 (set_attr "mode" "<MODE>")])
12325 (define_insn "*tbm_blsic_<mode>"
12326 [(set (match_operand:SWI48 0 "register_operand" "=r")
12329 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12333 (clobber (reg:CC FLAGS_REG))]
12335 "blsic\t{%1, %0|%0, %1}"
12336 [(set_attr "type" "bitmanip")
12337 (set_attr "mode" "<MODE>")])
12339 (define_insn "*tbm_t1mskc_<mode>"
12340 [(set (match_operand:SWI48 0 "register_operand" "=r")
12343 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12347 (clobber (reg:CC FLAGS_REG))]
12349 "t1mskc\t{%1, %0|%0, %1}"
12350 [(set_attr "type" "bitmanip")
12351 (set_attr "mode" "<MODE>")])
12353 (define_insn "*tbm_tzmsk_<mode>"
12354 [(set (match_operand:SWI48 0 "register_operand" "=r")
12357 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12361 (clobber (reg:CC FLAGS_REG))]
12363 "tzmsk\t{%1, %0|%0, %1}"
12364 [(set_attr "type" "bitmanip")
12365 (set_attr "mode" "<MODE>")])
12367 (define_insn "bsr_rex64"
12368 [(set (match_operand:DI 0 "register_operand" "=r")
12369 (minus:DI (const_int 63)
12370 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12371 (clobber (reg:CC FLAGS_REG))]
12373 "bsr{q}\t{%1, %0|%0, %1}"
12374 [(set_attr "type" "alu1")
12375 (set_attr "prefix_0f" "1")
12376 (set_attr "mode" "DI")])
12379 [(set (match_operand:SI 0 "register_operand" "=r")
12380 (minus:SI (const_int 31)
12381 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12382 (clobber (reg:CC FLAGS_REG))]
12384 "bsr{l}\t{%1, %0|%0, %1}"
12385 [(set_attr "type" "alu1")
12386 (set_attr "prefix_0f" "1")
12387 (set_attr "mode" "SI")])
12389 (define_insn "*bsrhi"
12390 [(set (match_operand:HI 0 "register_operand" "=r")
12391 (minus:HI (const_int 15)
12392 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12393 (clobber (reg:CC FLAGS_REG))]
12395 "bsr{w}\t{%1, %0|%0, %1}"
12396 [(set_attr "type" "alu1")
12397 (set_attr "prefix_0f" "1")
12398 (set_attr "mode" "HI")])
12400 (define_insn "popcount<mode>2"
12401 [(set (match_operand:SWI248 0 "register_operand" "=r")
12403 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12404 (clobber (reg:CC FLAGS_REG))]
12408 return "popcnt\t{%1, %0|%0, %1}";
12410 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12413 [(set_attr "prefix_rep" "1")
12414 (set_attr "type" "bitmanip")
12415 (set_attr "mode" "<MODE>")])
12417 (define_insn "*popcount<mode>2_cmp"
12418 [(set (reg FLAGS_REG)
12421 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12423 (set (match_operand:SWI248 0 "register_operand" "=r")
12424 (popcount:SWI248 (match_dup 1)))]
12425 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12428 return "popcnt\t{%1, %0|%0, %1}";
12430 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12433 [(set_attr "prefix_rep" "1")
12434 (set_attr "type" "bitmanip")
12435 (set_attr "mode" "<MODE>")])
12437 (define_insn "*popcountsi2_cmp_zext"
12438 [(set (reg FLAGS_REG)
12440 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12442 (set (match_operand:DI 0 "register_operand" "=r")
12443 (zero_extend:DI(popcount:SI (match_dup 1))))]
12444 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12447 return "popcnt\t{%1, %0|%0, %1}";
12449 return "popcnt{l}\t{%1, %0|%0, %1}";
12452 [(set_attr "prefix_rep" "1")
12453 (set_attr "type" "bitmanip")
12454 (set_attr "mode" "SI")])
12456 (define_expand "bswapdi2"
12457 [(set (match_operand:DI 0 "register_operand")
12458 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12462 operands[1] = force_reg (DImode, operands[1]);
12465 (define_expand "bswapsi2"
12466 [(set (match_operand:SI 0 "register_operand")
12467 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12472 else if (TARGET_BSWAP)
12473 operands[1] = force_reg (SImode, operands[1]);
12476 rtx x = operands[0];
12478 emit_move_insn (x, operands[1]);
12479 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12480 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12481 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12486 (define_insn "*bswap<mode>2_movbe"
12487 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12488 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12493 movbe\t{%1, %0|%0, %1}
12494 movbe\t{%1, %0|%0, %1}"
12495 [(set_attr "type" "bitmanip,imov,imov")
12496 (set_attr "modrm" "0,1,1")
12497 (set_attr "prefix_0f" "*,1,1")
12498 (set_attr "prefix_extra" "*,1,1")
12499 (set_attr "mode" "<MODE>")])
12501 (define_insn "*bswap<mode>2"
12502 [(set (match_operand:SWI48 0 "register_operand" "=r")
12503 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12506 [(set_attr "type" "bitmanip")
12507 (set_attr "modrm" "0")
12508 (set_attr "mode" "<MODE>")])
12510 (define_insn "*bswaphi_lowpart_1"
12511 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12512 (bswap:HI (match_dup 0)))
12513 (clobber (reg:CC FLAGS_REG))]
12514 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12516 xchg{b}\t{%h0, %b0|%b0, %h0}
12517 rol{w}\t{$8, %0|%0, 8}"
12518 [(set_attr "length" "2,4")
12519 (set_attr "mode" "QI,HI")])
12521 (define_insn "bswaphi_lowpart"
12522 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12523 (bswap:HI (match_dup 0)))
12524 (clobber (reg:CC FLAGS_REG))]
12526 "rol{w}\t{$8, %0|%0, 8}"
12527 [(set_attr "length" "4")
12528 (set_attr "mode" "HI")])
12530 (define_expand "paritydi2"
12531 [(set (match_operand:DI 0 "register_operand")
12532 (parity:DI (match_operand:DI 1 "register_operand")))]
12535 rtx scratch = gen_reg_rtx (QImode);
12538 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12539 NULL_RTX, operands[1]));
12541 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12542 gen_rtx_REG (CCmode, FLAGS_REG),
12544 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12547 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12550 rtx tmp = gen_reg_rtx (SImode);
12552 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12553 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12558 (define_expand "paritysi2"
12559 [(set (match_operand:SI 0 "register_operand")
12560 (parity:SI (match_operand:SI 1 "register_operand")))]
12563 rtx scratch = gen_reg_rtx (QImode);
12566 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12568 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12569 gen_rtx_REG (CCmode, FLAGS_REG),
12571 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12573 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12577 (define_insn_and_split "paritydi2_cmp"
12578 [(set (reg:CC FLAGS_REG)
12579 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12581 (clobber (match_scratch:DI 0 "=r"))
12582 (clobber (match_scratch:SI 1 "=&r"))
12583 (clobber (match_scratch:HI 2 "=Q"))]
12586 "&& reload_completed"
12588 [(set (match_dup 1)
12589 (xor:SI (match_dup 1) (match_dup 4)))
12590 (clobber (reg:CC FLAGS_REG))])
12592 [(set (reg:CC FLAGS_REG)
12593 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12594 (clobber (match_dup 1))
12595 (clobber (match_dup 2))])]
12597 operands[4] = gen_lowpart (SImode, operands[3]);
12601 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12602 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12605 operands[1] = gen_highpart (SImode, operands[3]);
12608 (define_insn_and_split "paritysi2_cmp"
12609 [(set (reg:CC FLAGS_REG)
12610 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12612 (clobber (match_scratch:SI 0 "=r"))
12613 (clobber (match_scratch:HI 1 "=&Q"))]
12616 "&& reload_completed"
12618 [(set (match_dup 1)
12619 (xor:HI (match_dup 1) (match_dup 3)))
12620 (clobber (reg:CC FLAGS_REG))])
12622 [(set (reg:CC FLAGS_REG)
12623 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12624 (clobber (match_dup 1))])]
12626 operands[3] = gen_lowpart (HImode, operands[2]);
12628 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12629 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12632 (define_insn "*parityhi2_cmp"
12633 [(set (reg:CC FLAGS_REG)
12634 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12636 (clobber (match_scratch:HI 0 "=Q"))]
12638 "xor{b}\t{%h0, %b0|%b0, %h0}"
12639 [(set_attr "length" "2")
12640 (set_attr "mode" "HI")])
12643 ;; Thread-local storage patterns for ELF.
12645 ;; Note that these code sequences must appear exactly as shown
12646 ;; in order to allow linker relaxation.
12648 (define_insn "*tls_global_dynamic_32_gnu"
12649 [(set (match_operand:SI 0 "register_operand" "=a")
12651 [(match_operand:SI 1 "register_operand" "b")
12652 (match_operand 2 "tls_symbolic_operand")
12653 (match_operand 3 "constant_call_address_operand" "z")]
12655 (clobber (match_scratch:SI 4 "=d"))
12656 (clobber (match_scratch:SI 5 "=c"))
12657 (clobber (reg:CC FLAGS_REG))]
12658 "!TARGET_64BIT && TARGET_GNU_TLS"
12661 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12662 if (TARGET_SUN_TLS)
12663 #ifdef HAVE_AS_IX86_TLSGDPLT
12664 return "call\t%a2@tlsgdplt";
12666 return "call\t%p3@plt";
12668 return "call\t%P3";
12670 [(set_attr "type" "multi")
12671 (set_attr "length" "12")])
12673 (define_expand "tls_global_dynamic_32"
12675 [(set (match_operand:SI 0 "register_operand")
12676 (unspec:SI [(match_operand:SI 2 "register_operand")
12677 (match_operand 1 "tls_symbolic_operand")
12678 (match_operand 3 "constant_call_address_operand")]
12680 (clobber (match_scratch:SI 4))
12681 (clobber (match_scratch:SI 5))
12682 (clobber (reg:CC FLAGS_REG))])])
12684 (define_insn "*tls_global_dynamic_64_<mode>"
12685 [(set (match_operand:P 0 "register_operand" "=a")
12687 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12688 (match_operand 3)))
12689 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12694 fputs (ASM_BYTE "0x66\n", asm_out_file);
12696 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12697 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12698 fputs ("\trex64\n", asm_out_file);
12699 if (TARGET_SUN_TLS)
12700 return "call\t%p2@plt";
12701 return "call\t%P2";
12703 [(set_attr "type" "multi")
12704 (set (attr "length")
12705 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12707 (define_insn "*tls_global_dynamic_64_largepic"
12708 [(set (match_operand:DI 0 "register_operand" "=a")
12710 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12711 (match_operand:DI 3 "immediate_operand" "i")))
12712 (match_operand 4)))
12713 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12715 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12716 && GET_CODE (operands[3]) == CONST
12717 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12718 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12721 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12722 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12723 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12724 return "call\t{*%%rax|rax}";
12726 [(set_attr "type" "multi")
12727 (set_attr "length" "22")])
12729 (define_expand "tls_global_dynamic_64_<mode>"
12731 [(set (match_operand:P 0 "register_operand")
12733 (mem:QI (match_operand 2))
12735 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12739 (define_insn "*tls_local_dynamic_base_32_gnu"
12740 [(set (match_operand:SI 0 "register_operand" "=a")
12742 [(match_operand:SI 1 "register_operand" "b")
12743 (match_operand 2 "constant_call_address_operand" "z")]
12744 UNSPEC_TLS_LD_BASE))
12745 (clobber (match_scratch:SI 3 "=d"))
12746 (clobber (match_scratch:SI 4 "=c"))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "!TARGET_64BIT && TARGET_GNU_TLS"
12751 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12752 if (TARGET_SUN_TLS)
12753 #ifdef HAVE_AS_IX86_TLSLDMPLT
12754 return "call\t%&@tlsldmplt";
12756 return "call\t%p2@plt";
12758 return "call\t%P2";
12760 [(set_attr "type" "multi")
12761 (set_attr "length" "11")])
12763 (define_expand "tls_local_dynamic_base_32"
12765 [(set (match_operand:SI 0 "register_operand")
12767 [(match_operand:SI 1 "register_operand")
12768 (match_operand 2 "constant_call_address_operand")]
12769 UNSPEC_TLS_LD_BASE))
12770 (clobber (match_scratch:SI 3))
12771 (clobber (match_scratch:SI 4))
12772 (clobber (reg:CC FLAGS_REG))])])
12774 (define_insn "*tls_local_dynamic_base_64_<mode>"
12775 [(set (match_operand:P 0 "register_operand" "=a")
12777 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12778 (match_operand 2)))
12779 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12783 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12784 if (TARGET_SUN_TLS)
12785 return "call\t%p1@plt";
12786 return "call\t%P1";
12788 [(set_attr "type" "multi")
12789 (set_attr "length" "12")])
12791 (define_insn "*tls_local_dynamic_base_64_largepic"
12792 [(set (match_operand:DI 0 "register_operand" "=a")
12794 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12795 (match_operand:DI 2 "immediate_operand" "i")))
12796 (match_operand 3)))
12797 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12798 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12799 && GET_CODE (operands[2]) == CONST
12800 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12801 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12804 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12805 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12806 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12807 return "call\t{*%%rax|rax}";
12809 [(set_attr "type" "multi")
12810 (set_attr "length" "22")])
12812 (define_expand "tls_local_dynamic_base_64_<mode>"
12814 [(set (match_operand:P 0 "register_operand")
12816 (mem:QI (match_operand 1))
12818 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12821 ;; Local dynamic of a single variable is a lose. Show combine how
12822 ;; to convert that back to global dynamic.
12824 (define_insn_and_split "*tls_local_dynamic_32_once"
12825 [(set (match_operand:SI 0 "register_operand" "=a")
12827 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12828 (match_operand 2 "constant_call_address_operand" "z")]
12829 UNSPEC_TLS_LD_BASE)
12830 (const:SI (unspec:SI
12831 [(match_operand 3 "tls_symbolic_operand")]
12833 (clobber (match_scratch:SI 4 "=d"))
12834 (clobber (match_scratch:SI 5 "=c"))
12835 (clobber (reg:CC FLAGS_REG))]
12840 [(set (match_dup 0)
12841 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12843 (clobber (match_dup 4))
12844 (clobber (match_dup 5))
12845 (clobber (reg:CC FLAGS_REG))])])
12847 ;; Segment register for the thread base ptr load
12848 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12850 ;; Load and add the thread base pointer from %<tp_seg>:0.
12851 (define_insn "*load_tp_x32"
12852 [(set (match_operand:SI 0 "register_operand" "=r")
12853 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12855 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12856 [(set_attr "type" "imov")
12857 (set_attr "modrm" "0")
12858 (set_attr "length" "7")
12859 (set_attr "memory" "load")
12860 (set_attr "imm_disp" "false")])
12862 (define_insn "*load_tp_x32_zext"
12863 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12866 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12867 [(set_attr "type" "imov")
12868 (set_attr "modrm" "0")
12869 (set_attr "length" "7")
12870 (set_attr "memory" "load")
12871 (set_attr "imm_disp" "false")])
12873 (define_insn "*load_tp_<mode>"
12874 [(set (match_operand:P 0 "register_operand" "=r")
12875 (unspec:P [(const_int 0)] UNSPEC_TP))]
12877 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12878 [(set_attr "type" "imov")
12879 (set_attr "modrm" "0")
12880 (set_attr "length" "7")
12881 (set_attr "memory" "load")
12882 (set_attr "imm_disp" "false")])
12884 (define_insn "*add_tp_x32"
12885 [(set (match_operand:SI 0 "register_operand" "=r")
12886 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12887 (match_operand:SI 1 "register_operand" "0")))
12888 (clobber (reg:CC FLAGS_REG))]
12890 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12891 [(set_attr "type" "alu")
12892 (set_attr "modrm" "0")
12893 (set_attr "length" "7")
12894 (set_attr "memory" "load")
12895 (set_attr "imm_disp" "false")])
12897 (define_insn "*add_tp_x32_zext"
12898 [(set (match_operand:DI 0 "register_operand" "=r")
12900 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12901 (match_operand:SI 1 "register_operand" "0"))))
12902 (clobber (reg:CC FLAGS_REG))]
12904 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12905 [(set_attr "type" "alu")
12906 (set_attr "modrm" "0")
12907 (set_attr "length" "7")
12908 (set_attr "memory" "load")
12909 (set_attr "imm_disp" "false")])
12911 (define_insn "*add_tp_<mode>"
12912 [(set (match_operand:P 0 "register_operand" "=r")
12913 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12914 (match_operand:P 1 "register_operand" "0")))
12915 (clobber (reg:CC FLAGS_REG))]
12917 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12918 [(set_attr "type" "alu")
12919 (set_attr "modrm" "0")
12920 (set_attr "length" "7")
12921 (set_attr "memory" "load")
12922 (set_attr "imm_disp" "false")])
12924 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12925 ;; %rax as destination of the initial executable code sequence.
12926 (define_insn "tls_initial_exec_64_sun"
12927 [(set (match_operand:DI 0 "register_operand" "=a")
12929 [(match_operand 1 "tls_symbolic_operand")]
12930 UNSPEC_TLS_IE_SUN))
12931 (clobber (reg:CC FLAGS_REG))]
12932 "TARGET_64BIT && TARGET_SUN_TLS"
12935 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12936 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12938 [(set_attr "type" "multi")])
12940 ;; GNU2 TLS patterns can be split.
12942 (define_expand "tls_dynamic_gnu2_32"
12943 [(set (match_dup 3)
12944 (plus:SI (match_operand:SI 2 "register_operand")
12946 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12949 [(set (match_operand:SI 0 "register_operand")
12950 (unspec:SI [(match_dup 1) (match_dup 3)
12951 (match_dup 2) (reg:SI SP_REG)]
12953 (clobber (reg:CC FLAGS_REG))])]
12954 "!TARGET_64BIT && TARGET_GNU2_TLS"
12956 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12957 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12960 (define_insn "*tls_dynamic_gnu2_lea_32"
12961 [(set (match_operand:SI 0 "register_operand" "=r")
12962 (plus:SI (match_operand:SI 1 "register_operand" "b")
12964 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12965 UNSPEC_TLSDESC))))]
12966 "!TARGET_64BIT && TARGET_GNU2_TLS"
12967 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12968 [(set_attr "type" "lea")
12969 (set_attr "mode" "SI")
12970 (set_attr "length" "6")
12971 (set_attr "length_address" "4")])
12973 (define_insn "*tls_dynamic_gnu2_call_32"
12974 [(set (match_operand:SI 0 "register_operand" "=a")
12975 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12976 (match_operand:SI 2 "register_operand" "0")
12977 ;; we have to make sure %ebx still points to the GOT
12978 (match_operand:SI 3 "register_operand" "b")
12981 (clobber (reg:CC FLAGS_REG))]
12982 "!TARGET_64BIT && TARGET_GNU2_TLS"
12983 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12984 [(set_attr "type" "call")
12985 (set_attr "length" "2")
12986 (set_attr "length_address" "0")])
12988 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12989 [(set (match_operand:SI 0 "register_operand" "=&a")
12991 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12992 (match_operand:SI 4)
12993 (match_operand:SI 2 "register_operand" "b")
12996 (const:SI (unspec:SI
12997 [(match_operand 1 "tls_symbolic_operand")]
12999 (clobber (reg:CC FLAGS_REG))]
13000 "!TARGET_64BIT && TARGET_GNU2_TLS"
13003 [(set (match_dup 0) (match_dup 5))]
13005 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13006 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13009 (define_expand "tls_dynamic_gnu2_64"
13010 [(set (match_dup 2)
13011 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13014 [(set (match_operand:DI 0 "register_operand")
13015 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13017 (clobber (reg:CC FLAGS_REG))])]
13018 "TARGET_64BIT && TARGET_GNU2_TLS"
13020 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13021 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13024 (define_insn "*tls_dynamic_gnu2_lea_64"
13025 [(set (match_operand:DI 0 "register_operand" "=r")
13026 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13028 "TARGET_64BIT && TARGET_GNU2_TLS"
13029 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13030 [(set_attr "type" "lea")
13031 (set_attr "mode" "DI")
13032 (set_attr "length" "7")
13033 (set_attr "length_address" "4")])
13035 (define_insn "*tls_dynamic_gnu2_call_64"
13036 [(set (match_operand:DI 0 "register_operand" "=a")
13037 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13038 (match_operand:DI 2 "register_operand" "0")
13041 (clobber (reg:CC FLAGS_REG))]
13042 "TARGET_64BIT && TARGET_GNU2_TLS"
13043 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13044 [(set_attr "type" "call")
13045 (set_attr "length" "2")
13046 (set_attr "length_address" "0")])
13048 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13049 [(set (match_operand:DI 0 "register_operand" "=&a")
13051 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13052 (match_operand:DI 3)
13055 (const:DI (unspec:DI
13056 [(match_operand 1 "tls_symbolic_operand")]
13058 (clobber (reg:CC FLAGS_REG))]
13059 "TARGET_64BIT && TARGET_GNU2_TLS"
13062 [(set (match_dup 0) (match_dup 4))]
13064 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13065 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13068 ;; These patterns match the binary 387 instructions for addM3, subM3,
13069 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13070 ;; SFmode. The first is the normal insn, the second the same insn but
13071 ;; with one operand a conversion, and the third the same insn but with
13072 ;; the other operand a conversion. The conversion may be SFmode or
13073 ;; SImode if the target mode DFmode, but only SImode if the target mode
13076 ;; Gcc is slightly more smart about handling normal two address instructions
13077 ;; so use special patterns for add and mull.
13079 (define_insn "*fop_<mode>_comm_mixed"
13080 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13081 (match_operator:MODEF 3 "binary_fp_operator"
13082 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13083 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13084 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13085 && COMMUTATIVE_ARITH_P (operands[3])
13086 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13087 "* return output_387_binary_op (insn, operands);"
13088 [(set (attr "type")
13089 (if_then_else (eq_attr "alternative" "1,2")
13090 (if_then_else (match_operand:MODEF 3 "mult_operator")
13091 (const_string "ssemul")
13092 (const_string "sseadd"))
13093 (if_then_else (match_operand:MODEF 3 "mult_operator")
13094 (const_string "fmul")
13095 (const_string "fop"))))
13096 (set_attr "isa" "*,noavx,avx")
13097 (set_attr "prefix" "orig,orig,vex")
13098 (set_attr "mode" "<MODE>")])
13100 (define_insn "*fop_<mode>_comm_sse"
13101 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13102 (match_operator:MODEF 3 "binary_fp_operator"
13103 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13104 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13105 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13106 && COMMUTATIVE_ARITH_P (operands[3])
13107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13108 "* return output_387_binary_op (insn, operands);"
13109 [(set (attr "type")
13110 (if_then_else (match_operand:MODEF 3 "mult_operator")
13111 (const_string "ssemul")
13112 (const_string "sseadd")))
13113 (set_attr "isa" "noavx,avx")
13114 (set_attr "prefix" "orig,vex")
13115 (set_attr "mode" "<MODE>")])
13117 (define_insn "*fop_<mode>_comm_i387"
13118 [(set (match_operand:MODEF 0 "register_operand" "=f")
13119 (match_operator:MODEF 3 "binary_fp_operator"
13120 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13121 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13122 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13123 && COMMUTATIVE_ARITH_P (operands[3])
13124 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13125 "* return output_387_binary_op (insn, operands);"
13126 [(set (attr "type")
13127 (if_then_else (match_operand:MODEF 3 "mult_operator")
13128 (const_string "fmul")
13129 (const_string "fop")))
13130 (set_attr "mode" "<MODE>")])
13132 (define_insn "*fop_<mode>_1_mixed"
13133 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13134 (match_operator:MODEF 3 "binary_fp_operator"
13135 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13136 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13137 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13138 && !COMMUTATIVE_ARITH_P (operands[3])
13139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13140 "* return output_387_binary_op (insn, operands);"
13141 [(set (attr "type")
13142 (cond [(and (eq_attr "alternative" "2,3")
13143 (match_operand:MODEF 3 "mult_operator"))
13144 (const_string "ssemul")
13145 (and (eq_attr "alternative" "2,3")
13146 (match_operand:MODEF 3 "div_operator"))
13147 (const_string "ssediv")
13148 (eq_attr "alternative" "2,3")
13149 (const_string "sseadd")
13150 (match_operand:MODEF 3 "mult_operator")
13151 (const_string "fmul")
13152 (match_operand:MODEF 3 "div_operator")
13153 (const_string "fdiv")
13155 (const_string "fop")))
13156 (set_attr "isa" "*,*,noavx,avx")
13157 (set_attr "prefix" "orig,orig,orig,vex")
13158 (set_attr "mode" "<MODE>")])
13160 (define_insn "*rcpsf2_sse"
13161 [(set (match_operand:SF 0 "register_operand" "=x")
13162 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13165 "%vrcpss\t{%1, %d0|%d0, %1}"
13166 [(set_attr "type" "sse")
13167 (set_attr "atom_sse_attr" "rcp")
13168 (set_attr "btver2_sse_attr" "rcp")
13169 (set_attr "prefix" "maybe_vex")
13170 (set_attr "mode" "SF")])
13172 (define_insn "*fop_<mode>_1_sse"
13173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13174 (match_operator:MODEF 3 "binary_fp_operator"
13175 [(match_operand:MODEF 1 "register_operand" "0,x")
13176 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13177 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13178 && !COMMUTATIVE_ARITH_P (operands[3])"
13179 "* return output_387_binary_op (insn, operands);"
13180 [(set (attr "type")
13181 (cond [(match_operand:MODEF 3 "mult_operator")
13182 (const_string "ssemul")
13183 (match_operand:MODEF 3 "div_operator")
13184 (const_string "ssediv")
13186 (const_string "sseadd")))
13187 (set_attr "isa" "noavx,avx")
13188 (set_attr "prefix" "orig,vex")
13189 (set_attr "mode" "<MODE>")])
13191 ;; This pattern is not fully shadowed by the pattern above.
13192 (define_insn "*fop_<mode>_1_i387"
13193 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13194 (match_operator:MODEF 3 "binary_fp_operator"
13195 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13196 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13197 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13198 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13199 && !COMMUTATIVE_ARITH_P (operands[3])
13200 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13201 "* return output_387_binary_op (insn, operands);"
13202 [(set (attr "type")
13203 (cond [(match_operand:MODEF 3 "mult_operator")
13204 (const_string "fmul")
13205 (match_operand:MODEF 3 "div_operator")
13206 (const_string "fdiv")
13208 (const_string "fop")))
13209 (set_attr "mode" "<MODE>")])
13211 ;; ??? Add SSE splitters for these!
13212 (define_insn "*fop_<MODEF:mode>_2_i387"
13213 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13214 (match_operator:MODEF 3 "binary_fp_operator"
13216 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13217 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13218 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13219 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13220 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13221 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13222 [(set (attr "type")
13223 (cond [(match_operand:MODEF 3 "mult_operator")
13224 (const_string "fmul")
13225 (match_operand:MODEF 3 "div_operator")
13226 (const_string "fdiv")
13228 (const_string "fop")))
13229 (set_attr "fp_int_src" "true")
13230 (set_attr "mode" "<SWI24:MODE>")])
13232 (define_insn "*fop_<MODEF:mode>_3_i387"
13233 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13234 (match_operator:MODEF 3 "binary_fp_operator"
13235 [(match_operand:MODEF 1 "register_operand" "0,0")
13237 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13238 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13239 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13240 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13241 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13242 [(set (attr "type")
13243 (cond [(match_operand:MODEF 3 "mult_operator")
13244 (const_string "fmul")
13245 (match_operand:MODEF 3 "div_operator")
13246 (const_string "fdiv")
13248 (const_string "fop")))
13249 (set_attr "fp_int_src" "true")
13250 (set_attr "mode" "<MODE>")])
13252 (define_insn "*fop_df_4_i387"
13253 [(set (match_operand:DF 0 "register_operand" "=f,f")
13254 (match_operator:DF 3 "binary_fp_operator"
13256 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13257 (match_operand:DF 2 "register_operand" "0,f")]))]
13258 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13259 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13260 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13261 "* return output_387_binary_op (insn, operands);"
13262 [(set (attr "type")
13263 (cond [(match_operand:DF 3 "mult_operator")
13264 (const_string "fmul")
13265 (match_operand:DF 3 "div_operator")
13266 (const_string "fdiv")
13268 (const_string "fop")))
13269 (set_attr "mode" "SF")])
13271 (define_insn "*fop_df_5_i387"
13272 [(set (match_operand:DF 0 "register_operand" "=f,f")
13273 (match_operator:DF 3 "binary_fp_operator"
13274 [(match_operand:DF 1 "register_operand" "0,f")
13276 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13277 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13278 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (cond [(match_operand:DF 3 "mult_operator")
13282 (const_string "fmul")
13283 (match_operand:DF 3 "div_operator")
13284 (const_string "fdiv")
13286 (const_string "fop")))
13287 (set_attr "mode" "SF")])
13289 (define_insn "*fop_df_6_i387"
13290 [(set (match_operand:DF 0 "register_operand" "=f,f")
13291 (match_operator:DF 3 "binary_fp_operator"
13293 (match_operand:SF 1 "register_operand" "0,f"))
13295 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13296 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13297 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13298 "* return output_387_binary_op (insn, operands);"
13299 [(set (attr "type")
13300 (cond [(match_operand:DF 3 "mult_operator")
13301 (const_string "fmul")
13302 (match_operand:DF 3 "div_operator")
13303 (const_string "fdiv")
13305 (const_string "fop")))
13306 (set_attr "mode" "SF")])
13308 (define_insn "*fop_xf_comm_i387"
13309 [(set (match_operand:XF 0 "register_operand" "=f")
13310 (match_operator:XF 3 "binary_fp_operator"
13311 [(match_operand:XF 1 "register_operand" "%0")
13312 (match_operand:XF 2 "register_operand" "f")]))]
13314 && COMMUTATIVE_ARITH_P (operands[3])"
13315 "* return output_387_binary_op (insn, operands);"
13316 [(set (attr "type")
13317 (if_then_else (match_operand:XF 3 "mult_operator")
13318 (const_string "fmul")
13319 (const_string "fop")))
13320 (set_attr "mode" "XF")])
13322 (define_insn "*fop_xf_1_i387"
13323 [(set (match_operand:XF 0 "register_operand" "=f,f")
13324 (match_operator:XF 3 "binary_fp_operator"
13325 [(match_operand:XF 1 "register_operand" "0,f")
13326 (match_operand:XF 2 "register_operand" "f,0")]))]
13328 && !COMMUTATIVE_ARITH_P (operands[3])"
13329 "* return output_387_binary_op (insn, operands);"
13330 [(set (attr "type")
13331 (cond [(match_operand:XF 3 "mult_operator")
13332 (const_string "fmul")
13333 (match_operand:XF 3 "div_operator")
13334 (const_string "fdiv")
13336 (const_string "fop")))
13337 (set_attr "mode" "XF")])
13339 (define_insn "*fop_xf_2_i387"
13340 [(set (match_operand:XF 0 "register_operand" "=f,f")
13341 (match_operator:XF 3 "binary_fp_operator"
13343 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13344 (match_operand:XF 2 "register_operand" "0,0")]))]
13345 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13346 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13347 [(set (attr "type")
13348 (cond [(match_operand:XF 3 "mult_operator")
13349 (const_string "fmul")
13350 (match_operand:XF 3 "div_operator")
13351 (const_string "fdiv")
13353 (const_string "fop")))
13354 (set_attr "fp_int_src" "true")
13355 (set_attr "mode" "<MODE>")])
13357 (define_insn "*fop_xf_3_i387"
13358 [(set (match_operand:XF 0 "register_operand" "=f,f")
13359 (match_operator:XF 3 "binary_fp_operator"
13360 [(match_operand:XF 1 "register_operand" "0,0")
13362 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13363 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13364 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13365 [(set (attr "type")
13366 (cond [(match_operand:XF 3 "mult_operator")
13367 (const_string "fmul")
13368 (match_operand:XF 3 "div_operator")
13369 (const_string "fdiv")
13371 (const_string "fop")))
13372 (set_attr "fp_int_src" "true")
13373 (set_attr "mode" "<MODE>")])
13375 (define_insn "*fop_xf_4_i387"
13376 [(set (match_operand:XF 0 "register_operand" "=f,f")
13377 (match_operator:XF 3 "binary_fp_operator"
13379 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13380 (match_operand:XF 2 "register_operand" "0,f")]))]
13382 "* return output_387_binary_op (insn, operands);"
13383 [(set (attr "type")
13384 (cond [(match_operand:XF 3 "mult_operator")
13385 (const_string "fmul")
13386 (match_operand:XF 3 "div_operator")
13387 (const_string "fdiv")
13389 (const_string "fop")))
13390 (set_attr "mode" "<MODE>")])
13392 (define_insn "*fop_xf_5_i387"
13393 [(set (match_operand:XF 0 "register_operand" "=f,f")
13394 (match_operator:XF 3 "binary_fp_operator"
13395 [(match_operand:XF 1 "register_operand" "0,f")
13397 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13399 "* return output_387_binary_op (insn, operands);"
13400 [(set (attr "type")
13401 (cond [(match_operand:XF 3 "mult_operator")
13402 (const_string "fmul")
13403 (match_operand:XF 3 "div_operator")
13404 (const_string "fdiv")
13406 (const_string "fop")))
13407 (set_attr "mode" "<MODE>")])
13409 (define_insn "*fop_xf_6_i387"
13410 [(set (match_operand:XF 0 "register_operand" "=f,f")
13411 (match_operator:XF 3 "binary_fp_operator"
13413 (match_operand:MODEF 1 "register_operand" "0,f"))
13415 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13417 "* return output_387_binary_op (insn, operands);"
13418 [(set (attr "type")
13419 (cond [(match_operand:XF 3 "mult_operator")
13420 (const_string "fmul")
13421 (match_operand:XF 3 "div_operator")
13422 (const_string "fdiv")
13424 (const_string "fop")))
13425 (set_attr "mode" "<MODE>")])
13428 [(set (match_operand 0 "register_operand")
13429 (match_operator 3 "binary_fp_operator"
13430 [(float (match_operand:SWI24 1 "register_operand"))
13431 (match_operand 2 "register_operand")]))]
13433 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13434 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13437 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13438 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13439 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13440 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13441 GET_MODE (operands[3]),
13444 ix86_free_from_memory (GET_MODE (operands[1]));
13449 [(set (match_operand 0 "register_operand")
13450 (match_operator 3 "binary_fp_operator"
13451 [(match_operand 1 "register_operand")
13452 (float (match_operand:SWI24 2 "register_operand"))]))]
13454 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13455 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13458 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13459 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13460 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13461 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13462 GET_MODE (operands[3]),
13465 ix86_free_from_memory (GET_MODE (operands[2]));
13469 ;; FPU special functions.
13471 ;; This pattern implements a no-op XFmode truncation for
13472 ;; all fancy i386 XFmode math functions.
13474 (define_insn "truncxf<mode>2_i387_noop_unspec"
13475 [(set (match_operand:MODEF 0 "register_operand" "=f")
13476 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13477 UNSPEC_TRUNC_NOOP))]
13478 "TARGET_USE_FANCY_MATH_387"
13479 "* return output_387_reg_move (insn, operands);"
13480 [(set_attr "type" "fmov")
13481 (set_attr "mode" "<MODE>")])
13483 (define_insn "sqrtxf2"
13484 [(set (match_operand:XF 0 "register_operand" "=f")
13485 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13486 "TARGET_USE_FANCY_MATH_387"
13488 [(set_attr "type" "fpspc")
13489 (set_attr "mode" "XF")
13490 (set_attr "athlon_decode" "direct")
13491 (set_attr "amdfam10_decode" "direct")
13492 (set_attr "bdver1_decode" "direct")])
13494 (define_insn "sqrt_extend<mode>xf2_i387"
13495 [(set (match_operand:XF 0 "register_operand" "=f")
13498 (match_operand:MODEF 1 "register_operand" "0"))))]
13499 "TARGET_USE_FANCY_MATH_387"
13501 [(set_attr "type" "fpspc")
13502 (set_attr "mode" "XF")
13503 (set_attr "athlon_decode" "direct")
13504 (set_attr "amdfam10_decode" "direct")
13505 (set_attr "bdver1_decode" "direct")])
13507 (define_insn "*rsqrtsf2_sse"
13508 [(set (match_operand:SF 0 "register_operand" "=x")
13509 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13512 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13513 [(set_attr "type" "sse")
13514 (set_attr "atom_sse_attr" "rcp")
13515 (set_attr "btver2_sse_attr" "rcp")
13516 (set_attr "prefix" "maybe_vex")
13517 (set_attr "mode" "SF")])
13519 (define_expand "rsqrtsf2"
13520 [(set (match_operand:SF 0 "register_operand")
13521 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13525 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13529 (define_insn "*sqrt<mode>2_sse"
13530 [(set (match_operand:MODEF 0 "register_operand" "=x")
13532 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13534 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13535 [(set_attr "type" "sse")
13536 (set_attr "atom_sse_attr" "sqrt")
13537 (set_attr "btver2_sse_attr" "sqrt")
13538 (set_attr "prefix" "maybe_vex")
13539 (set_attr "mode" "<MODE>")
13540 (set_attr "athlon_decode" "*")
13541 (set_attr "amdfam10_decode" "*")
13542 (set_attr "bdver1_decode" "*")])
13544 (define_expand "sqrt<mode>2"
13545 [(set (match_operand:MODEF 0 "register_operand")
13547 (match_operand:MODEF 1 "nonimmediate_operand")))]
13548 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13549 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13551 if (<MODE>mode == SFmode
13553 && TARGET_RECIP_SQRT
13554 && !optimize_function_for_size_p (cfun)
13555 && flag_finite_math_only && !flag_trapping_math
13556 && flag_unsafe_math_optimizations)
13558 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13562 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13564 rtx op0 = gen_reg_rtx (XFmode);
13565 rtx op1 = force_reg (<MODE>mode, operands[1]);
13567 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13568 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13573 (define_insn "fpremxf4_i387"
13574 [(set (match_operand:XF 0 "register_operand" "=f")
13575 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13576 (match_operand:XF 3 "register_operand" "1")]
13578 (set (match_operand:XF 1 "register_operand" "=u")
13579 (unspec:XF [(match_dup 2) (match_dup 3)]
13581 (set (reg:CCFP FPSR_REG)
13582 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13584 "TARGET_USE_FANCY_MATH_387"
13586 [(set_attr "type" "fpspc")
13587 (set_attr "mode" "XF")])
13589 (define_expand "fmodxf3"
13590 [(use (match_operand:XF 0 "register_operand"))
13591 (use (match_operand:XF 1 "general_operand"))
13592 (use (match_operand:XF 2 "general_operand"))]
13593 "TARGET_USE_FANCY_MATH_387"
13595 rtx label = gen_label_rtx ();
13597 rtx op1 = gen_reg_rtx (XFmode);
13598 rtx op2 = gen_reg_rtx (XFmode);
13600 emit_move_insn (op2, operands[2]);
13601 emit_move_insn (op1, operands[1]);
13603 emit_label (label);
13604 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13605 ix86_emit_fp_unordered_jump (label);
13606 LABEL_NUSES (label) = 1;
13608 emit_move_insn (operands[0], op1);
13612 (define_expand "fmod<mode>3"
13613 [(use (match_operand:MODEF 0 "register_operand"))
13614 (use (match_operand:MODEF 1 "general_operand"))
13615 (use (match_operand:MODEF 2 "general_operand"))]
13616 "TARGET_USE_FANCY_MATH_387"
13618 rtx (*gen_truncxf) (rtx, rtx);
13620 rtx label = gen_label_rtx ();
13622 rtx op1 = gen_reg_rtx (XFmode);
13623 rtx op2 = gen_reg_rtx (XFmode);
13625 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13626 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13628 emit_label (label);
13629 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13630 ix86_emit_fp_unordered_jump (label);
13631 LABEL_NUSES (label) = 1;
13633 /* Truncate the result properly for strict SSE math. */
13634 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13635 && !TARGET_MIX_SSE_I387)
13636 gen_truncxf = gen_truncxf<mode>2;
13638 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13640 emit_insn (gen_truncxf (operands[0], op1));
13644 (define_insn "fprem1xf4_i387"
13645 [(set (match_operand:XF 0 "register_operand" "=f")
13646 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13647 (match_operand:XF 3 "register_operand" "1")]
13649 (set (match_operand:XF 1 "register_operand" "=u")
13650 (unspec:XF [(match_dup 2) (match_dup 3)]
13652 (set (reg:CCFP FPSR_REG)
13653 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13655 "TARGET_USE_FANCY_MATH_387"
13657 [(set_attr "type" "fpspc")
13658 (set_attr "mode" "XF")])
13660 (define_expand "remainderxf3"
13661 [(use (match_operand:XF 0 "register_operand"))
13662 (use (match_operand:XF 1 "general_operand"))
13663 (use (match_operand:XF 2 "general_operand"))]
13664 "TARGET_USE_FANCY_MATH_387"
13666 rtx label = gen_label_rtx ();
13668 rtx op1 = gen_reg_rtx (XFmode);
13669 rtx op2 = gen_reg_rtx (XFmode);
13671 emit_move_insn (op2, operands[2]);
13672 emit_move_insn (op1, operands[1]);
13674 emit_label (label);
13675 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13676 ix86_emit_fp_unordered_jump (label);
13677 LABEL_NUSES (label) = 1;
13679 emit_move_insn (operands[0], op1);
13683 (define_expand "remainder<mode>3"
13684 [(use (match_operand:MODEF 0 "register_operand"))
13685 (use (match_operand:MODEF 1 "general_operand"))
13686 (use (match_operand:MODEF 2 "general_operand"))]
13687 "TARGET_USE_FANCY_MATH_387"
13689 rtx (*gen_truncxf) (rtx, rtx);
13691 rtx label = gen_label_rtx ();
13693 rtx op1 = gen_reg_rtx (XFmode);
13694 rtx op2 = gen_reg_rtx (XFmode);
13696 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13697 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13699 emit_label (label);
13701 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13702 ix86_emit_fp_unordered_jump (label);
13703 LABEL_NUSES (label) = 1;
13705 /* Truncate the result properly for strict SSE math. */
13706 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13707 && !TARGET_MIX_SSE_I387)
13708 gen_truncxf = gen_truncxf<mode>2;
13710 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13712 emit_insn (gen_truncxf (operands[0], op1));
13716 (define_int_iterator SINCOS
13720 (define_int_attr sincos
13721 [(UNSPEC_SIN "sin")
13722 (UNSPEC_COS "cos")])
13724 (define_insn "*<sincos>xf2_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13728 "TARGET_USE_FANCY_MATH_387
13729 && flag_unsafe_math_optimizations"
13731 [(set_attr "type" "fpspc")
13732 (set_attr "mode" "XF")])
13734 (define_insn "*<sincos>_extend<mode>xf2_i387"
13735 [(set (match_operand:XF 0 "register_operand" "=f")
13736 (unspec:XF [(float_extend:XF
13737 (match_operand:MODEF 1 "register_operand" "0"))]
13739 "TARGET_USE_FANCY_MATH_387
13740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13741 || TARGET_MIX_SSE_I387)
13742 && flag_unsafe_math_optimizations"
13744 [(set_attr "type" "fpspc")
13745 (set_attr "mode" "XF")])
13747 ;; When sincos pattern is defined, sin and cos builtin functions will be
13748 ;; expanded to sincos pattern with one of its outputs left unused.
13749 ;; CSE pass will figure out if two sincos patterns can be combined,
13750 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13751 ;; depending on the unused output.
13753 (define_insn "sincosxf3"
13754 [(set (match_operand:XF 0 "register_operand" "=f")
13755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13756 UNSPEC_SINCOS_COS))
13757 (set (match_operand:XF 1 "register_operand" "=u")
13758 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13759 "TARGET_USE_FANCY_MATH_387
13760 && flag_unsafe_math_optimizations"
13762 [(set_attr "type" "fpspc")
13763 (set_attr "mode" "XF")])
13766 [(set (match_operand:XF 0 "register_operand")
13767 (unspec:XF [(match_operand:XF 2 "register_operand")]
13768 UNSPEC_SINCOS_COS))
13769 (set (match_operand:XF 1 "register_operand")
13770 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13771 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13772 && can_create_pseudo_p ()"
13773 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13776 [(set (match_operand:XF 0 "register_operand")
13777 (unspec:XF [(match_operand:XF 2 "register_operand")]
13778 UNSPEC_SINCOS_COS))
13779 (set (match_operand:XF 1 "register_operand")
13780 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13781 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13782 && can_create_pseudo_p ()"
13783 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13785 (define_insn "sincos_extend<mode>xf3_i387"
13786 [(set (match_operand:XF 0 "register_operand" "=f")
13787 (unspec:XF [(float_extend:XF
13788 (match_operand:MODEF 2 "register_operand" "0"))]
13789 UNSPEC_SINCOS_COS))
13790 (set (match_operand:XF 1 "register_operand" "=u")
13791 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13792 "TARGET_USE_FANCY_MATH_387
13793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794 || TARGET_MIX_SSE_I387)
13795 && flag_unsafe_math_optimizations"
13797 [(set_attr "type" "fpspc")
13798 (set_attr "mode" "XF")])
13801 [(set (match_operand:XF 0 "register_operand")
13802 (unspec:XF [(float_extend:XF
13803 (match_operand:MODEF 2 "register_operand"))]
13804 UNSPEC_SINCOS_COS))
13805 (set (match_operand:XF 1 "register_operand")
13806 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13807 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13808 && can_create_pseudo_p ()"
13809 [(set (match_dup 1)
13810 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13813 [(set (match_operand:XF 0 "register_operand")
13814 (unspec:XF [(float_extend:XF
13815 (match_operand:MODEF 2 "register_operand"))]
13816 UNSPEC_SINCOS_COS))
13817 (set (match_operand:XF 1 "register_operand")
13818 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13819 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13820 && can_create_pseudo_p ()"
13821 [(set (match_dup 0)
13822 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13824 (define_expand "sincos<mode>3"
13825 [(use (match_operand:MODEF 0 "register_operand"))
13826 (use (match_operand:MODEF 1 "register_operand"))
13827 (use (match_operand:MODEF 2 "register_operand"))]
13828 "TARGET_USE_FANCY_MATH_387
13829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13830 || TARGET_MIX_SSE_I387)
13831 && flag_unsafe_math_optimizations"
13833 rtx op0 = gen_reg_rtx (XFmode);
13834 rtx op1 = gen_reg_rtx (XFmode);
13836 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13842 (define_insn "fptanxf4_i387"
13843 [(set (match_operand:XF 0 "register_operand" "=f")
13844 (match_operand:XF 3 "const_double_operand" "F"))
13845 (set (match_operand:XF 1 "register_operand" "=u")
13846 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations
13850 && standard_80387_constant_p (operands[3]) == 2"
13852 [(set_attr "type" "fpspc")
13853 (set_attr "mode" "XF")])
13855 (define_insn "fptan_extend<mode>xf4_i387"
13856 [(set (match_operand:MODEF 0 "register_operand" "=f")
13857 (match_operand:MODEF 3 "const_double_operand" "F"))
13858 (set (match_operand:XF 1 "register_operand" "=u")
13859 (unspec:XF [(float_extend:XF
13860 (match_operand:MODEF 2 "register_operand" "0"))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864 || TARGET_MIX_SSE_I387)
13865 && flag_unsafe_math_optimizations
13866 && standard_80387_constant_p (operands[3]) == 2"
13868 [(set_attr "type" "fpspc")
13869 (set_attr "mode" "XF")])
13871 (define_expand "tanxf2"
13872 [(use (match_operand:XF 0 "register_operand"))
13873 (use (match_operand:XF 1 "register_operand"))]
13874 "TARGET_USE_FANCY_MATH_387
13875 && flag_unsafe_math_optimizations"
13877 rtx one = gen_reg_rtx (XFmode);
13878 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13880 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13884 (define_expand "tan<mode>2"
13885 [(use (match_operand:MODEF 0 "register_operand"))
13886 (use (match_operand:MODEF 1 "register_operand"))]
13887 "TARGET_USE_FANCY_MATH_387
13888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13889 || TARGET_MIX_SSE_I387)
13890 && flag_unsafe_math_optimizations"
13892 rtx op0 = gen_reg_rtx (XFmode);
13894 rtx one = gen_reg_rtx (<MODE>mode);
13895 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13897 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13898 operands[1], op2));
13899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13903 (define_insn "*fpatanxf3_i387"
13904 [(set (match_operand:XF 0 "register_operand" "=f")
13905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13906 (match_operand:XF 2 "register_operand" "u")]
13908 (clobber (match_scratch:XF 3 "=2"))]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_unsafe_math_optimizations"
13912 [(set_attr "type" "fpspc")
13913 (set_attr "mode" "XF")])
13915 (define_insn "fpatan_extend<mode>xf3_i387"
13916 [(set (match_operand:XF 0 "register_operand" "=f")
13917 (unspec:XF [(float_extend:XF
13918 (match_operand:MODEF 1 "register_operand" "0"))
13920 (match_operand:MODEF 2 "register_operand" "u"))]
13922 (clobber (match_scratch:XF 3 "=2"))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13925 || TARGET_MIX_SSE_I387)
13926 && flag_unsafe_math_optimizations"
13928 [(set_attr "type" "fpspc")
13929 (set_attr "mode" "XF")])
13931 (define_expand "atan2xf3"
13932 [(parallel [(set (match_operand:XF 0 "register_operand")
13933 (unspec:XF [(match_operand:XF 2 "register_operand")
13934 (match_operand:XF 1 "register_operand")]
13936 (clobber (match_scratch:XF 3))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations")
13940 (define_expand "atan2<mode>3"
13941 [(use (match_operand:MODEF 0 "register_operand"))
13942 (use (match_operand:MODEF 1 "register_operand"))
13943 (use (match_operand:MODEF 2 "register_operand"))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946 || TARGET_MIX_SSE_I387)
13947 && flag_unsafe_math_optimizations"
13949 rtx op0 = gen_reg_rtx (XFmode);
13951 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13952 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13956 (define_expand "atanxf2"
13957 [(parallel [(set (match_operand:XF 0 "register_operand")
13958 (unspec:XF [(match_dup 2)
13959 (match_operand:XF 1 "register_operand")]
13961 (clobber (match_scratch:XF 3))])]
13962 "TARGET_USE_FANCY_MATH_387
13963 && flag_unsafe_math_optimizations"
13965 operands[2] = gen_reg_rtx (XFmode);
13966 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13969 (define_expand "atan<mode>2"
13970 [(use (match_operand:MODEF 0 "register_operand"))
13971 (use (match_operand:MODEF 1 "register_operand"))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13974 || TARGET_MIX_SSE_I387)
13975 && flag_unsafe_math_optimizations"
13977 rtx op0 = gen_reg_rtx (XFmode);
13979 rtx op2 = gen_reg_rtx (<MODE>mode);
13980 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13982 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13987 (define_expand "asinxf2"
13988 [(set (match_dup 2)
13989 (mult:XF (match_operand:XF 1 "register_operand")
13991 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13992 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13993 (parallel [(set (match_operand:XF 0 "register_operand")
13994 (unspec:XF [(match_dup 5) (match_dup 1)]
13996 (clobber (match_scratch:XF 6))])]
13997 "TARGET_USE_FANCY_MATH_387
13998 && flag_unsafe_math_optimizations"
14002 if (optimize_insn_for_size_p ())
14005 for (i = 2; i < 6; i++)
14006 operands[i] = gen_reg_rtx (XFmode);
14008 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14011 (define_expand "asin<mode>2"
14012 [(use (match_operand:MODEF 0 "register_operand"))
14013 (use (match_operand:MODEF 1 "general_operand"))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016 || TARGET_MIX_SSE_I387)
14017 && flag_unsafe_math_optimizations"
14019 rtx op0 = gen_reg_rtx (XFmode);
14020 rtx op1 = gen_reg_rtx (XFmode);
14022 if (optimize_insn_for_size_p ())
14025 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14026 emit_insn (gen_asinxf2 (op0, op1));
14027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14031 (define_expand "acosxf2"
14032 [(set (match_dup 2)
14033 (mult:XF (match_operand:XF 1 "register_operand")
14035 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14036 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14037 (parallel [(set (match_operand:XF 0 "register_operand")
14038 (unspec:XF [(match_dup 1) (match_dup 5)]
14040 (clobber (match_scratch:XF 6))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14046 if (optimize_insn_for_size_p ())
14049 for (i = 2; i < 6; i++)
14050 operands[i] = gen_reg_rtx (XFmode);
14052 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14055 (define_expand "acos<mode>2"
14056 [(use (match_operand:MODEF 0 "register_operand"))
14057 (use (match_operand:MODEF 1 "general_operand"))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14060 || TARGET_MIX_SSE_I387)
14061 && flag_unsafe_math_optimizations"
14063 rtx op0 = gen_reg_rtx (XFmode);
14064 rtx op1 = gen_reg_rtx (XFmode);
14066 if (optimize_insn_for_size_p ())
14069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14070 emit_insn (gen_acosxf2 (op0, op1));
14071 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14075 (define_insn "fyl2xxf3_i387"
14076 [(set (match_operand:XF 0 "register_operand" "=f")
14077 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14078 (match_operand:XF 2 "register_operand" "u")]
14080 (clobber (match_scratch:XF 3 "=2"))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && flag_unsafe_math_optimizations"
14084 [(set_attr "type" "fpspc")
14085 (set_attr "mode" "XF")])
14087 (define_insn "fyl2x_extend<mode>xf3_i387"
14088 [(set (match_operand:XF 0 "register_operand" "=f")
14089 (unspec:XF [(float_extend:XF
14090 (match_operand:MODEF 1 "register_operand" "0"))
14091 (match_operand:XF 2 "register_operand" "u")]
14093 (clobber (match_scratch:XF 3 "=2"))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096 || TARGET_MIX_SSE_I387)
14097 && flag_unsafe_math_optimizations"
14099 [(set_attr "type" "fpspc")
14100 (set_attr "mode" "XF")])
14102 (define_expand "logxf2"
14103 [(parallel [(set (match_operand:XF 0 "register_operand")
14104 (unspec:XF [(match_operand:XF 1 "register_operand")
14105 (match_dup 2)] UNSPEC_FYL2X))
14106 (clobber (match_scratch:XF 3))])]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14110 operands[2] = gen_reg_rtx (XFmode);
14111 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14114 (define_expand "log<mode>2"
14115 [(use (match_operand:MODEF 0 "register_operand"))
14116 (use (match_operand:MODEF 1 "register_operand"))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119 || TARGET_MIX_SSE_I387)
14120 && flag_unsafe_math_optimizations"
14122 rtx op0 = gen_reg_rtx (XFmode);
14124 rtx op2 = gen_reg_rtx (XFmode);
14125 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14127 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14132 (define_expand "log10xf2"
14133 [(parallel [(set (match_operand:XF 0 "register_operand")
14134 (unspec:XF [(match_operand:XF 1 "register_operand")
14135 (match_dup 2)] UNSPEC_FYL2X))
14136 (clobber (match_scratch:XF 3))])]
14137 "TARGET_USE_FANCY_MATH_387
14138 && flag_unsafe_math_optimizations"
14140 operands[2] = gen_reg_rtx (XFmode);
14141 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14144 (define_expand "log10<mode>2"
14145 [(use (match_operand:MODEF 0 "register_operand"))
14146 (use (match_operand:MODEF 1 "register_operand"))]
14147 "TARGET_USE_FANCY_MATH_387
14148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14149 || TARGET_MIX_SSE_I387)
14150 && flag_unsafe_math_optimizations"
14152 rtx op0 = gen_reg_rtx (XFmode);
14154 rtx op2 = gen_reg_rtx (XFmode);
14155 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14157 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14158 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14162 (define_expand "log2xf2"
14163 [(parallel [(set (match_operand:XF 0 "register_operand")
14164 (unspec:XF [(match_operand:XF 1 "register_operand")
14165 (match_dup 2)] UNSPEC_FYL2X))
14166 (clobber (match_scratch:XF 3))])]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14170 operands[2] = gen_reg_rtx (XFmode);
14171 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14174 (define_expand "log2<mode>2"
14175 [(use (match_operand:MODEF 0 "register_operand"))
14176 (use (match_operand:MODEF 1 "register_operand"))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14182 rtx op0 = gen_reg_rtx (XFmode);
14184 rtx op2 = gen_reg_rtx (XFmode);
14185 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14187 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14188 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14192 (define_insn "fyl2xp1xf3_i387"
14193 [(set (match_operand:XF 0 "register_operand" "=f")
14194 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14195 (match_operand:XF 2 "register_operand" "u")]
14197 (clobber (match_scratch:XF 3 "=2"))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations"
14201 [(set_attr "type" "fpspc")
14202 (set_attr "mode" "XF")])
14204 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14205 [(set (match_operand:XF 0 "register_operand" "=f")
14206 (unspec:XF [(float_extend:XF
14207 (match_operand:MODEF 1 "register_operand" "0"))
14208 (match_operand:XF 2 "register_operand" "u")]
14210 (clobber (match_scratch:XF 3 "=2"))]
14211 "TARGET_USE_FANCY_MATH_387
14212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213 || TARGET_MIX_SSE_I387)
14214 && flag_unsafe_math_optimizations"
14216 [(set_attr "type" "fpspc")
14217 (set_attr "mode" "XF")])
14219 (define_expand "log1pxf2"
14220 [(use (match_operand:XF 0 "register_operand"))
14221 (use (match_operand:XF 1 "register_operand"))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && flag_unsafe_math_optimizations"
14225 if (optimize_insn_for_size_p ())
14228 ix86_emit_i387_log1p (operands[0], operands[1]);
14232 (define_expand "log1p<mode>2"
14233 [(use (match_operand:MODEF 0 "register_operand"))
14234 (use (match_operand:MODEF 1 "register_operand"))]
14235 "TARGET_USE_FANCY_MATH_387
14236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237 || TARGET_MIX_SSE_I387)
14238 && flag_unsafe_math_optimizations"
14242 if (optimize_insn_for_size_p ())
14245 op0 = gen_reg_rtx (XFmode);
14247 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14249 ix86_emit_i387_log1p (op0, operands[1]);
14250 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14254 (define_insn "fxtractxf3_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14257 UNSPEC_XTRACT_FRACT))
14258 (set (match_operand:XF 1 "register_operand" "=u")
14259 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14263 [(set_attr "type" "fpspc")
14264 (set_attr "mode" "XF")])
14266 (define_insn "fxtract_extend<mode>xf3_i387"
14267 [(set (match_operand:XF 0 "register_operand" "=f")
14268 (unspec:XF [(float_extend:XF
14269 (match_operand:MODEF 2 "register_operand" "0"))]
14270 UNSPEC_XTRACT_FRACT))
14271 (set (match_operand:XF 1 "register_operand" "=u")
14272 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14273 "TARGET_USE_FANCY_MATH_387
14274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14275 || TARGET_MIX_SSE_I387)
14276 && flag_unsafe_math_optimizations"
14278 [(set_attr "type" "fpspc")
14279 (set_attr "mode" "XF")])
14281 (define_expand "logbxf2"
14282 [(parallel [(set (match_dup 2)
14283 (unspec:XF [(match_operand:XF 1 "register_operand")]
14284 UNSPEC_XTRACT_FRACT))
14285 (set (match_operand:XF 0 "register_operand")
14286 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14287 "TARGET_USE_FANCY_MATH_387
14288 && flag_unsafe_math_optimizations"
14289 "operands[2] = gen_reg_rtx (XFmode);")
14291 (define_expand "logb<mode>2"
14292 [(use (match_operand:MODEF 0 "register_operand"))
14293 (use (match_operand:MODEF 1 "register_operand"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14299 rtx op0 = gen_reg_rtx (XFmode);
14300 rtx op1 = gen_reg_rtx (XFmode);
14302 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14303 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14307 (define_expand "ilogbxf2"
14308 [(use (match_operand:SI 0 "register_operand"))
14309 (use (match_operand:XF 1 "register_operand"))]
14310 "TARGET_USE_FANCY_MATH_387
14311 && flag_unsafe_math_optimizations"
14315 if (optimize_insn_for_size_p ())
14318 op0 = gen_reg_rtx (XFmode);
14319 op1 = gen_reg_rtx (XFmode);
14321 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14322 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14326 (define_expand "ilogb<mode>2"
14327 [(use (match_operand:SI 0 "register_operand"))
14328 (use (match_operand:MODEF 1 "register_operand"))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14331 || TARGET_MIX_SSE_I387)
14332 && flag_unsafe_math_optimizations"
14336 if (optimize_insn_for_size_p ())
14339 op0 = gen_reg_rtx (XFmode);
14340 op1 = gen_reg_rtx (XFmode);
14342 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14343 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14347 (define_insn "*f2xm1xf2_i387"
14348 [(set (match_operand:XF 0 "register_operand" "=f")
14349 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14351 "TARGET_USE_FANCY_MATH_387
14352 && flag_unsafe_math_optimizations"
14354 [(set_attr "type" "fpspc")
14355 (set_attr "mode" "XF")])
14357 (define_insn "*fscalexf4_i387"
14358 [(set (match_operand:XF 0 "register_operand" "=f")
14359 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14360 (match_operand:XF 3 "register_operand" "1")]
14361 UNSPEC_FSCALE_FRACT))
14362 (set (match_operand:XF 1 "register_operand" "=u")
14363 (unspec:XF [(match_dup 2) (match_dup 3)]
14364 UNSPEC_FSCALE_EXP))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14371 (define_expand "expNcorexf3"
14372 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14373 (match_operand:XF 2 "register_operand")))
14374 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14375 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14376 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14377 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14378 (parallel [(set (match_operand:XF 0 "register_operand")
14379 (unspec:XF [(match_dup 8) (match_dup 4)]
14380 UNSPEC_FSCALE_FRACT))
14382 (unspec:XF [(match_dup 8) (match_dup 4)]
14383 UNSPEC_FSCALE_EXP))])]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 for (i = 3; i < 10; i++)
14393 operands[i] = gen_reg_rtx (XFmode);
14395 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14398 (define_expand "expxf2"
14399 [(use (match_operand:XF 0 "register_operand"))
14400 (use (match_operand:XF 1 "register_operand"))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14406 if (optimize_insn_for_size_p ())
14409 op2 = gen_reg_rtx (XFmode);
14410 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14412 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14416 (define_expand "exp<mode>2"
14417 [(use (match_operand:MODEF 0 "register_operand"))
14418 (use (match_operand:MODEF 1 "general_operand"))]
14419 "TARGET_USE_FANCY_MATH_387
14420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14421 || TARGET_MIX_SSE_I387)
14422 && flag_unsafe_math_optimizations"
14426 if (optimize_insn_for_size_p ())
14429 op0 = gen_reg_rtx (XFmode);
14430 op1 = gen_reg_rtx (XFmode);
14432 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14433 emit_insn (gen_expxf2 (op0, op1));
14434 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14438 (define_expand "exp10xf2"
14439 [(use (match_operand:XF 0 "register_operand"))
14440 (use (match_operand:XF 1 "register_operand"))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && flag_unsafe_math_optimizations"
14446 if (optimize_insn_for_size_p ())
14449 op2 = gen_reg_rtx (XFmode);
14450 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14452 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14456 (define_expand "exp10<mode>2"
14457 [(use (match_operand:MODEF 0 "register_operand"))
14458 (use (match_operand:MODEF 1 "general_operand"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14461 || TARGET_MIX_SSE_I387)
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_extend<mode>xf2 (op1, operands[1]));
14473 emit_insn (gen_exp10xf2 (op0, op1));
14474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14478 (define_expand "exp2xf2"
14479 [(use (match_operand:XF 0 "register_operand"))
14480 (use (match_operand:XF 1 "register_operand"))]
14481 "TARGET_USE_FANCY_MATH_387
14482 && flag_unsafe_math_optimizations"
14486 if (optimize_insn_for_size_p ())
14489 op2 = gen_reg_rtx (XFmode);
14490 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14492 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14496 (define_expand "exp2<mode>2"
14497 [(use (match_operand:MODEF 0 "register_operand"))
14498 (use (match_operand:MODEF 1 "general_operand"))]
14499 "TARGET_USE_FANCY_MATH_387
14500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14501 || TARGET_MIX_SSE_I387)
14502 && flag_unsafe_math_optimizations"
14506 if (optimize_insn_for_size_p ())
14509 op0 = gen_reg_rtx (XFmode);
14510 op1 = gen_reg_rtx (XFmode);
14512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513 emit_insn (gen_exp2xf2 (op0, op1));
14514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14518 (define_expand "expm1xf2"
14519 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14521 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14522 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14523 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14524 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14525 (parallel [(set (match_dup 7)
14526 (unspec:XF [(match_dup 6) (match_dup 4)]
14527 UNSPEC_FSCALE_FRACT))
14529 (unspec:XF [(match_dup 6) (match_dup 4)]
14530 UNSPEC_FSCALE_EXP))])
14531 (parallel [(set (match_dup 10)
14532 (unspec:XF [(match_dup 9) (match_dup 8)]
14533 UNSPEC_FSCALE_FRACT))
14534 (set (match_dup 11)
14535 (unspec:XF [(match_dup 9) (match_dup 8)]
14536 UNSPEC_FSCALE_EXP))])
14537 (set (match_dup 12) (minus:XF (match_dup 10)
14538 (float_extend:XF (match_dup 13))))
14539 (set (match_operand:XF 0 "register_operand")
14540 (plus:XF (match_dup 12) (match_dup 7)))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && flag_unsafe_math_optimizations"
14546 if (optimize_insn_for_size_p ())
14549 for (i = 2; i < 13; i++)
14550 operands[i] = gen_reg_rtx (XFmode);
14553 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14555 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14558 (define_expand "expm1<mode>2"
14559 [(use (match_operand:MODEF 0 "register_operand"))
14560 (use (match_operand:MODEF 1 "general_operand"))]
14561 "TARGET_USE_FANCY_MATH_387
14562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14563 || TARGET_MIX_SSE_I387)
14564 && flag_unsafe_math_optimizations"
14568 if (optimize_insn_for_size_p ())
14571 op0 = gen_reg_rtx (XFmode);
14572 op1 = gen_reg_rtx (XFmode);
14574 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14575 emit_insn (gen_expm1xf2 (op0, op1));
14576 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14580 (define_expand "ldexpxf3"
14581 [(set (match_dup 3)
14582 (float:XF (match_operand:SI 2 "register_operand")))
14583 (parallel [(set (match_operand:XF 0 " register_operand")
14584 (unspec:XF [(match_operand:XF 1 "register_operand")
14586 UNSPEC_FSCALE_FRACT))
14588 (unspec:XF [(match_dup 1) (match_dup 3)]
14589 UNSPEC_FSCALE_EXP))])]
14590 "TARGET_USE_FANCY_MATH_387
14591 && flag_unsafe_math_optimizations"
14593 if (optimize_insn_for_size_p ())
14596 operands[3] = gen_reg_rtx (XFmode);
14597 operands[4] = gen_reg_rtx (XFmode);
14600 (define_expand "ldexp<mode>3"
14601 [(use (match_operand:MODEF 0 "register_operand"))
14602 (use (match_operand:MODEF 1 "general_operand"))
14603 (use (match_operand:SI 2 "register_operand"))]
14604 "TARGET_USE_FANCY_MATH_387
14605 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14606 || TARGET_MIX_SSE_I387)
14607 && flag_unsafe_math_optimizations"
14611 if (optimize_insn_for_size_p ())
14614 op0 = gen_reg_rtx (XFmode);
14615 op1 = gen_reg_rtx (XFmode);
14617 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14618 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14619 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14623 (define_expand "scalbxf3"
14624 [(parallel [(set (match_operand:XF 0 " register_operand")
14625 (unspec:XF [(match_operand:XF 1 "register_operand")
14626 (match_operand:XF 2 "register_operand")]
14627 UNSPEC_FSCALE_FRACT))
14629 (unspec:XF [(match_dup 1) (match_dup 2)]
14630 UNSPEC_FSCALE_EXP))])]
14631 "TARGET_USE_FANCY_MATH_387
14632 && flag_unsafe_math_optimizations"
14634 if (optimize_insn_for_size_p ())
14637 operands[3] = gen_reg_rtx (XFmode);
14640 (define_expand "scalb<mode>3"
14641 [(use (match_operand:MODEF 0 "register_operand"))
14642 (use (match_operand:MODEF 1 "general_operand"))
14643 (use (match_operand:MODEF 2 "general_operand"))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14646 || TARGET_MIX_SSE_I387)
14647 && flag_unsafe_math_optimizations"
14651 if (optimize_insn_for_size_p ())
14654 op0 = gen_reg_rtx (XFmode);
14655 op1 = gen_reg_rtx (XFmode);
14656 op2 = gen_reg_rtx (XFmode);
14658 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14659 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14660 emit_insn (gen_scalbxf3 (op0, op1, op2));
14661 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14665 (define_expand "significandxf2"
14666 [(parallel [(set (match_operand:XF 0 "register_operand")
14667 (unspec:XF [(match_operand:XF 1 "register_operand")]
14668 UNSPEC_XTRACT_FRACT))
14670 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14671 "TARGET_USE_FANCY_MATH_387
14672 && flag_unsafe_math_optimizations"
14673 "operands[2] = gen_reg_rtx (XFmode);")
14675 (define_expand "significand<mode>2"
14676 [(use (match_operand:MODEF 0 "register_operand"))
14677 (use (match_operand:MODEF 1 "register_operand"))]
14678 "TARGET_USE_FANCY_MATH_387
14679 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14680 || TARGET_MIX_SSE_I387)
14681 && flag_unsafe_math_optimizations"
14683 rtx op0 = gen_reg_rtx (XFmode);
14684 rtx op1 = gen_reg_rtx (XFmode);
14686 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14687 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14692 (define_insn "sse4_1_round<mode>2"
14693 [(set (match_operand:MODEF 0 "register_operand" "=x")
14694 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14695 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14698 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14699 [(set_attr "type" "ssecvt")
14700 (set_attr "prefix_extra" "1")
14701 (set_attr "prefix" "maybe_vex")
14702 (set_attr "mode" "<MODE>")])
14704 (define_insn "rintxf2"
14705 [(set (match_operand:XF 0 "register_operand" "=f")
14706 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14708 "TARGET_USE_FANCY_MATH_387
14709 && flag_unsafe_math_optimizations"
14711 [(set_attr "type" "fpspc")
14712 (set_attr "mode" "XF")])
14714 (define_expand "rint<mode>2"
14715 [(use (match_operand:MODEF 0 "register_operand"))
14716 (use (match_operand:MODEF 1 "register_operand"))]
14717 "(TARGET_USE_FANCY_MATH_387
14718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14719 || TARGET_MIX_SSE_I387)
14720 && flag_unsafe_math_optimizations)
14721 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14722 && !flag_trapping_math)"
14724 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14725 && !flag_trapping_math)
14728 emit_insn (gen_sse4_1_round<mode>2
14729 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14730 else if (optimize_insn_for_size_p ())
14733 ix86_expand_rint (operands[0], operands[1]);
14737 rtx op0 = gen_reg_rtx (XFmode);
14738 rtx op1 = gen_reg_rtx (XFmode);
14740 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14741 emit_insn (gen_rintxf2 (op0, op1));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14748 (define_expand "round<mode>2"
14749 [(match_operand:X87MODEF 0 "register_operand")
14750 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14751 "(TARGET_USE_FANCY_MATH_387
14752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14753 || TARGET_MIX_SSE_I387)
14754 && flag_unsafe_math_optimizations)
14755 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14756 && !flag_trapping_math && !flag_rounding_math)"
14758 if (optimize_insn_for_size_p ())
14761 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14762 && !flag_trapping_math && !flag_rounding_math)
14766 operands[1] = force_reg (<MODE>mode, operands[1]);
14767 ix86_expand_round_sse4 (operands[0], operands[1]);
14769 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14770 ix86_expand_round (operands[0], operands[1]);
14772 ix86_expand_rounddf_32 (operands[0], operands[1]);
14776 operands[1] = force_reg (<MODE>mode, operands[1]);
14777 ix86_emit_i387_round (operands[0], operands[1]);
14782 (define_insn_and_split "*fistdi2_1"
14783 [(set (match_operand:DI 0 "nonimmediate_operand")
14784 (unspec:DI [(match_operand:XF 1 "register_operand")]
14786 "TARGET_USE_FANCY_MATH_387
14787 && can_create_pseudo_p ()"
14792 if (memory_operand (operands[0], VOIDmode))
14793 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14796 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14797 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14802 [(set_attr "type" "fpspc")
14803 (set_attr "mode" "DI")])
14805 (define_insn "fistdi2"
14806 [(set (match_operand:DI 0 "memory_operand" "=m")
14807 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14809 (clobber (match_scratch:XF 2 "=&1f"))]
14810 "TARGET_USE_FANCY_MATH_387"
14811 "* return output_fix_trunc (insn, operands, false);"
14812 [(set_attr "type" "fpspc")
14813 (set_attr "mode" "DI")])
14815 (define_insn "fistdi2_with_temp"
14816 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14817 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14819 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14820 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14821 "TARGET_USE_FANCY_MATH_387"
14823 [(set_attr "type" "fpspc")
14824 (set_attr "mode" "DI")])
14827 [(set (match_operand:DI 0 "register_operand")
14828 (unspec:DI [(match_operand:XF 1 "register_operand")]
14830 (clobber (match_operand:DI 2 "memory_operand"))
14831 (clobber (match_scratch 3))]
14833 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14834 (clobber (match_dup 3))])
14835 (set (match_dup 0) (match_dup 2))])
14838 [(set (match_operand:DI 0 "memory_operand")
14839 (unspec:DI [(match_operand:XF 1 "register_operand")]
14841 (clobber (match_operand:DI 2 "memory_operand"))
14842 (clobber (match_scratch 3))]
14844 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14845 (clobber (match_dup 3))])])
14847 (define_insn_and_split "*fist<mode>2_1"
14848 [(set (match_operand:SWI24 0 "register_operand")
14849 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14851 "TARGET_USE_FANCY_MATH_387
14852 && can_create_pseudo_p ()"
14857 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14858 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "<MODE>")])
14865 (define_insn "fist<mode>2"
14866 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14867 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14869 "TARGET_USE_FANCY_MATH_387"
14870 "* return output_fix_trunc (insn, operands, false);"
14871 [(set_attr "type" "fpspc")
14872 (set_attr "mode" "<MODE>")])
14874 (define_insn "fist<mode>2_with_temp"
14875 [(set (match_operand:SWI24 0 "register_operand" "=r")
14876 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14878 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14879 "TARGET_USE_FANCY_MATH_387"
14881 [(set_attr "type" "fpspc")
14882 (set_attr "mode" "<MODE>")])
14885 [(set (match_operand:SWI24 0 "register_operand")
14886 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14888 (clobber (match_operand:SWI24 2 "memory_operand"))]
14890 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14891 (set (match_dup 0) (match_dup 2))])
14894 [(set (match_operand:SWI24 0 "memory_operand")
14895 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14897 (clobber (match_operand:SWI24 2 "memory_operand"))]
14899 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14901 (define_expand "lrintxf<mode>2"
14902 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14903 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14905 "TARGET_USE_FANCY_MATH_387")
14907 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14908 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14909 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14910 UNSPEC_FIX_NOTRUNC))]
14911 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14913 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14914 [(match_operand:SWI248x 0 "nonimmediate_operand")
14915 (match_operand:X87MODEF 1 "register_operand")]
14916 "(TARGET_USE_FANCY_MATH_387
14917 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14918 || TARGET_MIX_SSE_I387)
14919 && flag_unsafe_math_optimizations)
14920 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14921 && <SWI248x:MODE>mode != HImode
14922 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14923 && !flag_trapping_math && !flag_rounding_math)"
14925 if (optimize_insn_for_size_p ())
14928 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14929 && <SWI248x:MODE>mode != HImode
14930 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14931 && !flag_trapping_math && !flag_rounding_math)
14932 ix86_expand_lround (operands[0], operands[1]);
14934 ix86_emit_i387_round (operands[0], operands[1]);
14938 (define_int_iterator FRNDINT_ROUNDING
14939 [UNSPEC_FRNDINT_FLOOR
14940 UNSPEC_FRNDINT_CEIL
14941 UNSPEC_FRNDINT_TRUNC])
14943 (define_int_iterator FIST_ROUNDING
14947 ;; Base name for define_insn
14948 (define_int_attr rounding_insn
14949 [(UNSPEC_FRNDINT_FLOOR "floor")
14950 (UNSPEC_FRNDINT_CEIL "ceil")
14951 (UNSPEC_FRNDINT_TRUNC "btrunc")
14952 (UNSPEC_FIST_FLOOR "floor")
14953 (UNSPEC_FIST_CEIL "ceil")])
14955 (define_int_attr rounding
14956 [(UNSPEC_FRNDINT_FLOOR "floor")
14957 (UNSPEC_FRNDINT_CEIL "ceil")
14958 (UNSPEC_FRNDINT_TRUNC "trunc")
14959 (UNSPEC_FIST_FLOOR "floor")
14960 (UNSPEC_FIST_CEIL "ceil")])
14962 (define_int_attr ROUNDING
14963 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14964 (UNSPEC_FRNDINT_CEIL "CEIL")
14965 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14966 (UNSPEC_FIST_FLOOR "FLOOR")
14967 (UNSPEC_FIST_CEIL "CEIL")])
14969 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14970 (define_insn_and_split "frndintxf2_<rounding>"
14971 [(set (match_operand:XF 0 "register_operand")
14972 (unspec:XF [(match_operand:XF 1 "register_operand")]
14974 (clobber (reg:CC FLAGS_REG))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && flag_unsafe_math_optimizations
14977 && can_create_pseudo_p ()"
14982 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14984 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14985 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14987 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14988 operands[2], operands[3]));
14991 [(set_attr "type" "frndint")
14992 (set_attr "i387_cw" "<rounding>")
14993 (set_attr "mode" "XF")])
14995 (define_insn "frndintxf2_<rounding>_i387"
14996 [(set (match_operand:XF 0 "register_operand" "=f")
14997 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14999 (use (match_operand:HI 2 "memory_operand" "m"))
15000 (use (match_operand:HI 3 "memory_operand" "m"))]
15001 "TARGET_USE_FANCY_MATH_387
15002 && flag_unsafe_math_optimizations"
15003 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15004 [(set_attr "type" "frndint")
15005 (set_attr "i387_cw" "<rounding>")
15006 (set_attr "mode" "XF")])
15008 (define_expand "<rounding_insn>xf2"
15009 [(parallel [(set (match_operand:XF 0 "register_operand")
15010 (unspec:XF [(match_operand:XF 1 "register_operand")]
15012 (clobber (reg:CC FLAGS_REG))])]
15013 "TARGET_USE_FANCY_MATH_387
15014 && flag_unsafe_math_optimizations
15015 && !optimize_insn_for_size_p ()")
15017 (define_expand "<rounding_insn><mode>2"
15018 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15019 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15021 (clobber (reg:CC FLAGS_REG))])]
15022 "(TARGET_USE_FANCY_MATH_387
15023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15024 || TARGET_MIX_SSE_I387)
15025 && flag_unsafe_math_optimizations)
15026 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15027 && !flag_trapping_math)"
15029 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15030 && !flag_trapping_math)
15033 emit_insn (gen_sse4_1_round<mode>2
15034 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15035 else if (optimize_insn_for_size_p ())
15037 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15039 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15040 ix86_expand_floorceil (operands[0], operands[1], true);
15041 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15042 ix86_expand_floorceil (operands[0], operands[1], false);
15043 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15044 ix86_expand_trunc (operands[0], operands[1]);
15046 gcc_unreachable ();
15050 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15051 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15052 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15053 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15054 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15055 ix86_expand_truncdf_32 (operands[0], operands[1]);
15057 gcc_unreachable ();
15064 if (optimize_insn_for_size_p ())
15067 op0 = gen_reg_rtx (XFmode);
15068 op1 = gen_reg_rtx (XFmode);
15069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15070 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15077 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15078 (define_insn_and_split "frndintxf2_mask_pm"
15079 [(set (match_operand:XF 0 "register_operand")
15080 (unspec:XF [(match_operand:XF 1 "register_operand")]
15081 UNSPEC_FRNDINT_MASK_PM))
15082 (clobber (reg:CC FLAGS_REG))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && flag_unsafe_math_optimizations
15085 && can_create_pseudo_p ()"
15090 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15095 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15096 operands[2], operands[3]));
15099 [(set_attr "type" "frndint")
15100 (set_attr "i387_cw" "mask_pm")
15101 (set_attr "mode" "XF")])
15103 (define_insn "frndintxf2_mask_pm_i387"
15104 [(set (match_operand:XF 0 "register_operand" "=f")
15105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15106 UNSPEC_FRNDINT_MASK_PM))
15107 (use (match_operand:HI 2 "memory_operand" "m"))
15108 (use (match_operand:HI 3 "memory_operand" "m"))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations"
15111 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15112 [(set_attr "type" "frndint")
15113 (set_attr "i387_cw" "mask_pm")
15114 (set_attr "mode" "XF")])
15116 (define_expand "nearbyintxf2"
15117 [(parallel [(set (match_operand:XF 0 "register_operand")
15118 (unspec:XF [(match_operand:XF 1 "register_operand")]
15119 UNSPEC_FRNDINT_MASK_PM))
15120 (clobber (reg:CC FLAGS_REG))])]
15121 "TARGET_USE_FANCY_MATH_387
15122 && flag_unsafe_math_optimizations")
15124 (define_expand "nearbyint<mode>2"
15125 [(use (match_operand:MODEF 0 "register_operand"))
15126 (use (match_operand:MODEF 1 "register_operand"))]
15127 "TARGET_USE_FANCY_MATH_387
15128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15129 || TARGET_MIX_SSE_I387)
15130 && flag_unsafe_math_optimizations"
15132 rtx op0 = gen_reg_rtx (XFmode);
15133 rtx op1 = gen_reg_rtx (XFmode);
15135 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15136 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15138 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15142 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15143 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15144 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15145 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15147 (clobber (reg:CC FLAGS_REG))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations
15150 && can_create_pseudo_p ()"
15155 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15157 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15158 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15159 if (memory_operand (operands[0], VOIDmode))
15160 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15161 operands[2], operands[3]));
15164 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15165 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15166 (operands[0], operands[1], operands[2],
15167 operands[3], operands[4]));
15171 [(set_attr "type" "fistp")
15172 (set_attr "i387_cw" "<rounding>")
15173 (set_attr "mode" "<MODE>")])
15175 (define_insn "fistdi2_<rounding>"
15176 [(set (match_operand:DI 0 "memory_operand" "=m")
15177 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15179 (use (match_operand:HI 2 "memory_operand" "m"))
15180 (use (match_operand:HI 3 "memory_operand" "m"))
15181 (clobber (match_scratch:XF 4 "=&1f"))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations"
15184 "* return output_fix_trunc (insn, operands, false);"
15185 [(set_attr "type" "fistp")
15186 (set_attr "i387_cw" "<rounding>")
15187 (set_attr "mode" "DI")])
15189 (define_insn "fistdi2_<rounding>_with_temp"
15190 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15191 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15193 (use (match_operand:HI 2 "memory_operand" "m,m"))
15194 (use (match_operand:HI 3 "memory_operand" "m,m"))
15195 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15196 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && flag_unsafe_math_optimizations"
15200 [(set_attr "type" "fistp")
15201 (set_attr "i387_cw" "<rounding>")
15202 (set_attr "mode" "DI")])
15205 [(set (match_operand:DI 0 "register_operand")
15206 (unspec:DI [(match_operand:XF 1 "register_operand")]
15208 (use (match_operand:HI 2 "memory_operand"))
15209 (use (match_operand:HI 3 "memory_operand"))
15210 (clobber (match_operand:DI 4 "memory_operand"))
15211 (clobber (match_scratch 5))]
15213 [(parallel [(set (match_dup 4)
15214 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15215 (use (match_dup 2))
15216 (use (match_dup 3))
15217 (clobber (match_dup 5))])
15218 (set (match_dup 0) (match_dup 4))])
15221 [(set (match_operand:DI 0 "memory_operand")
15222 (unspec:DI [(match_operand:XF 1 "register_operand")]
15224 (use (match_operand:HI 2 "memory_operand"))
15225 (use (match_operand:HI 3 "memory_operand"))
15226 (clobber (match_operand:DI 4 "memory_operand"))
15227 (clobber (match_scratch 5))]
15229 [(parallel [(set (match_dup 0)
15230 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15231 (use (match_dup 2))
15232 (use (match_dup 3))
15233 (clobber (match_dup 5))])])
15235 (define_insn "fist<mode>2_<rounding>"
15236 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15237 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15239 (use (match_operand:HI 2 "memory_operand" "m"))
15240 (use (match_operand:HI 3 "memory_operand" "m"))]
15241 "TARGET_USE_FANCY_MATH_387
15242 && flag_unsafe_math_optimizations"
15243 "* return output_fix_trunc (insn, operands, false);"
15244 [(set_attr "type" "fistp")
15245 (set_attr "i387_cw" "<rounding>")
15246 (set_attr "mode" "<MODE>")])
15248 (define_insn "fist<mode>2_<rounding>_with_temp"
15249 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15250 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15252 (use (match_operand:HI 2 "memory_operand" "m,m"))
15253 (use (match_operand:HI 3 "memory_operand" "m,m"))
15254 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15255 "TARGET_USE_FANCY_MATH_387
15256 && flag_unsafe_math_optimizations"
15258 [(set_attr "type" "fistp")
15259 (set_attr "i387_cw" "<rounding>")
15260 (set_attr "mode" "<MODE>")])
15263 [(set (match_operand:SWI24 0 "register_operand")
15264 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15266 (use (match_operand:HI 2 "memory_operand"))
15267 (use (match_operand:HI 3 "memory_operand"))
15268 (clobber (match_operand:SWI24 4 "memory_operand"))]
15270 [(parallel [(set (match_dup 4)
15271 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15272 (use (match_dup 2))
15273 (use (match_dup 3))])
15274 (set (match_dup 0) (match_dup 4))])
15277 [(set (match_operand:SWI24 0 "memory_operand")
15278 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15280 (use (match_operand:HI 2 "memory_operand"))
15281 (use (match_operand:HI 3 "memory_operand"))
15282 (clobber (match_operand:SWI24 4 "memory_operand"))]
15284 [(parallel [(set (match_dup 0)
15285 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15286 (use (match_dup 2))
15287 (use (match_dup 3))])])
15289 (define_expand "l<rounding_insn>xf<mode>2"
15290 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15291 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15293 (clobber (reg:CC FLAGS_REG))])]
15294 "TARGET_USE_FANCY_MATH_387
15295 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15296 && flag_unsafe_math_optimizations")
15298 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15299 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15300 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15302 (clobber (reg:CC FLAGS_REG))])]
15303 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15304 && !flag_trapping_math"
15306 if (TARGET_64BIT && optimize_insn_for_size_p ())
15309 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15310 ix86_expand_lfloorceil (operands[0], operands[1], true);
15311 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15312 ix86_expand_lfloorceil (operands[0], operands[1], false);
15314 gcc_unreachable ();
15319 (define_insn "fxam<mode>2_i387"
15320 [(set (match_operand:HI 0 "register_operand" "=a")
15322 [(match_operand:X87MODEF 1 "register_operand" "f")]
15324 "TARGET_USE_FANCY_MATH_387"
15325 "fxam\n\tfnstsw\t%0"
15326 [(set_attr "type" "multi")
15327 (set_attr "length" "4")
15328 (set_attr "unit" "i387")
15329 (set_attr "mode" "<MODE>")])
15331 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15332 [(set (match_operand:HI 0 "register_operand")
15334 [(match_operand:MODEF 1 "memory_operand")]
15336 "TARGET_USE_FANCY_MATH_387
15337 && can_create_pseudo_p ()"
15340 [(set (match_dup 2)(match_dup 1))
15342 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15344 operands[2] = gen_reg_rtx (<MODE>mode);
15346 MEM_VOLATILE_P (operands[1]) = 1;
15348 [(set_attr "type" "multi")
15349 (set_attr "unit" "i387")
15350 (set_attr "mode" "<MODE>")])
15352 (define_expand "isinfxf2"
15353 [(use (match_operand:SI 0 "register_operand"))
15354 (use (match_operand:XF 1 "register_operand"))]
15355 "TARGET_USE_FANCY_MATH_387
15356 && ix86_libc_has_function (function_c99_misc)"
15358 rtx mask = GEN_INT (0x45);
15359 rtx val = GEN_INT (0x05);
15363 rtx scratch = gen_reg_rtx (HImode);
15364 rtx res = gen_reg_rtx (QImode);
15366 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15368 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15369 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15370 cond = gen_rtx_fmt_ee (EQ, QImode,
15371 gen_rtx_REG (CCmode, FLAGS_REG),
15373 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15374 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15378 (define_expand "isinf<mode>2"
15379 [(use (match_operand:SI 0 "register_operand"))
15380 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15381 "TARGET_USE_FANCY_MATH_387
15382 && ix86_libc_has_function (function_c99_misc)
15383 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15385 rtx mask = GEN_INT (0x45);
15386 rtx val = GEN_INT (0x05);
15390 rtx scratch = gen_reg_rtx (HImode);
15391 rtx res = gen_reg_rtx (QImode);
15393 /* Remove excess precision by forcing value through memory. */
15394 if (memory_operand (operands[1], VOIDmode))
15395 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15398 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15400 emit_move_insn (temp, operands[1]);
15401 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15404 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15405 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15406 cond = gen_rtx_fmt_ee (EQ, QImode,
15407 gen_rtx_REG (CCmode, FLAGS_REG),
15409 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15410 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15414 (define_expand "signbitxf2"
15415 [(use (match_operand:SI 0 "register_operand"))
15416 (use (match_operand:XF 1 "register_operand"))]
15417 "TARGET_USE_FANCY_MATH_387"
15419 rtx scratch = gen_reg_rtx (HImode);
15421 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15422 emit_insn (gen_andsi3 (operands[0],
15423 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15427 (define_insn "movmsk_df"
15428 [(set (match_operand:SI 0 "register_operand" "=r")
15430 [(match_operand:DF 1 "register_operand" "x")]
15432 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15433 "%vmovmskpd\t{%1, %0|%0, %1}"
15434 [(set_attr "type" "ssemov")
15435 (set_attr "prefix" "maybe_vex")
15436 (set_attr "mode" "DF")])
15438 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15439 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15440 (define_expand "signbitdf2"
15441 [(use (match_operand:SI 0 "register_operand"))
15442 (use (match_operand:DF 1 "register_operand"))]
15443 "TARGET_USE_FANCY_MATH_387
15444 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15446 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15448 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15449 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15453 rtx scratch = gen_reg_rtx (HImode);
15455 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15456 emit_insn (gen_andsi3 (operands[0],
15457 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15462 (define_expand "signbitsf2"
15463 [(use (match_operand:SI 0 "register_operand"))
15464 (use (match_operand:SF 1 "register_operand"))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15468 rtx scratch = gen_reg_rtx (HImode);
15470 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15471 emit_insn (gen_andsi3 (operands[0],
15472 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15476 ;; Block operation instructions
15479 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15482 [(set_attr "length" "1")
15483 (set_attr "length_immediate" "0")
15484 (set_attr "modrm" "0")])
15486 (define_expand "movmem<mode>"
15487 [(use (match_operand:BLK 0 "memory_operand"))
15488 (use (match_operand:BLK 1 "memory_operand"))
15489 (use (match_operand:SWI48 2 "nonmemory_operand"))
15490 (use (match_operand:SWI48 3 "const_int_operand"))
15491 (use (match_operand:SI 4 "const_int_operand"))
15492 (use (match_operand:SI 5 "const_int_operand"))]
15495 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15496 operands[4], operands[5]))
15502 ;; Most CPUs don't like single string operations
15503 ;; Handle this case here to simplify previous expander.
15505 (define_expand "strmov"
15506 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15507 (set (match_operand 1 "memory_operand") (match_dup 4))
15508 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15509 (clobber (reg:CC FLAGS_REG))])
15510 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15511 (clobber (reg:CC FLAGS_REG))])]
15514 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15516 /* If .md ever supports :P for Pmode, these can be directly
15517 in the pattern above. */
15518 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15519 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15521 /* Can't use this if the user has appropriated esi or edi. */
15522 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15523 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15525 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15526 operands[2], operands[3],
15527 operands[5], operands[6]));
15531 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15534 (define_expand "strmov_singleop"
15535 [(parallel [(set (match_operand 1 "memory_operand")
15536 (match_operand 3 "memory_operand"))
15537 (set (match_operand 0 "register_operand")
15539 (set (match_operand 2 "register_operand")
15540 (match_operand 5))])]
15542 "ix86_current_function_needs_cld = 1;")
15544 (define_insn "*strmovdi_rex_1"
15545 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15546 (mem:DI (match_operand:P 3 "register_operand" "1")))
15547 (set (match_operand:P 0 "register_operand" "=D")
15548 (plus:P (match_dup 2)
15550 (set (match_operand:P 1 "register_operand" "=S")
15551 (plus:P (match_dup 3)
15554 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15556 [(set_attr "type" "str")
15557 (set_attr "memory" "both")
15558 (set_attr "mode" "DI")])
15560 (define_insn "*strmovsi_1"
15561 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15562 (mem:SI (match_operand:P 3 "register_operand" "1")))
15563 (set (match_operand:P 0 "register_operand" "=D")
15564 (plus:P (match_dup 2)
15566 (set (match_operand:P 1 "register_operand" "=S")
15567 (plus:P (match_dup 3)
15569 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15571 [(set_attr "type" "str")
15572 (set_attr "memory" "both")
15573 (set_attr "mode" "SI")])
15575 (define_insn "*strmovhi_1"
15576 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15577 (mem:HI (match_operand:P 3 "register_operand" "1")))
15578 (set (match_operand:P 0 "register_operand" "=D")
15579 (plus:P (match_dup 2)
15581 (set (match_operand:P 1 "register_operand" "=S")
15582 (plus:P (match_dup 3)
15584 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15586 [(set_attr "type" "str")
15587 (set_attr "memory" "both")
15588 (set_attr "mode" "HI")])
15590 (define_insn "*strmovqi_1"
15591 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15592 (mem:QI (match_operand:P 3 "register_operand" "1")))
15593 (set (match_operand:P 0 "register_operand" "=D")
15594 (plus:P (match_dup 2)
15596 (set (match_operand:P 1 "register_operand" "=S")
15597 (plus:P (match_dup 3)
15599 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15601 [(set_attr "type" "str")
15602 (set_attr "memory" "both")
15603 (set (attr "prefix_rex")
15605 (match_test "<P:MODE>mode == DImode")
15607 (const_string "*")))
15608 (set_attr "mode" "QI")])
15610 (define_expand "rep_mov"
15611 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15612 (set (match_operand 0 "register_operand")
15614 (set (match_operand 2 "register_operand")
15616 (set (match_operand 1 "memory_operand")
15617 (match_operand 3 "memory_operand"))
15618 (use (match_dup 4))])]
15620 "ix86_current_function_needs_cld = 1;")
15622 (define_insn "*rep_movdi_rex64"
15623 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15624 (set (match_operand:P 0 "register_operand" "=D")
15625 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15627 (match_operand:P 3 "register_operand" "0")))
15628 (set (match_operand:P 1 "register_operand" "=S")
15629 (plus:P (ashift:P (match_dup 5) (const_int 3))
15630 (match_operand:P 4 "register_operand" "1")))
15631 (set (mem:BLK (match_dup 3))
15632 (mem:BLK (match_dup 4)))
15633 (use (match_dup 5))]
15635 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15637 [(set_attr "type" "str")
15638 (set_attr "prefix_rep" "1")
15639 (set_attr "memory" "both")
15640 (set_attr "mode" "DI")])
15642 (define_insn "*rep_movsi"
15643 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15644 (set (match_operand:P 0 "register_operand" "=D")
15645 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15647 (match_operand:P 3 "register_operand" "0")))
15648 (set (match_operand:P 1 "register_operand" "=S")
15649 (plus:P (ashift:P (match_dup 5) (const_int 2))
15650 (match_operand:P 4 "register_operand" "1")))
15651 (set (mem:BLK (match_dup 3))
15652 (mem:BLK (match_dup 4)))
15653 (use (match_dup 5))]
15654 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15655 "%^rep{%;} movs{l|d}"
15656 [(set_attr "type" "str")
15657 (set_attr "prefix_rep" "1")
15658 (set_attr "memory" "both")
15659 (set_attr "mode" "SI")])
15661 (define_insn "*rep_movqi"
15662 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15663 (set (match_operand:P 0 "register_operand" "=D")
15664 (plus:P (match_operand:P 3 "register_operand" "0")
15665 (match_operand:P 5 "register_operand" "2")))
15666 (set (match_operand:P 1 "register_operand" "=S")
15667 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15668 (set (mem:BLK (match_dup 3))
15669 (mem:BLK (match_dup 4)))
15670 (use (match_dup 5))]
15671 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15673 [(set_attr "type" "str")
15674 (set_attr "prefix_rep" "1")
15675 (set_attr "memory" "both")
15676 (set_attr "mode" "QI")])
15678 (define_expand "setmem<mode>"
15679 [(use (match_operand:BLK 0 "memory_operand"))
15680 (use (match_operand:SWI48 1 "nonmemory_operand"))
15681 (use (match_operand:QI 2 "nonmemory_operand"))
15682 (use (match_operand 3 "const_int_operand"))
15683 (use (match_operand:SI 4 "const_int_operand"))
15684 (use (match_operand:SI 5 "const_int_operand"))]
15687 if (ix86_expand_setmem (operands[0], operands[1],
15688 operands[2], operands[3],
15689 operands[4], operands[5]))
15695 ;; Most CPUs don't like single string operations
15696 ;; Handle this case here to simplify previous expander.
15698 (define_expand "strset"
15699 [(set (match_operand 1 "memory_operand")
15700 (match_operand 2 "register_operand"))
15701 (parallel [(set (match_operand 0 "register_operand")
15703 (clobber (reg:CC FLAGS_REG))])]
15706 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15707 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15709 /* If .md ever supports :P for Pmode, this can be directly
15710 in the pattern above. */
15711 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15712 GEN_INT (GET_MODE_SIZE (GET_MODE
15714 /* Can't use this if the user has appropriated eax or edi. */
15715 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15716 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15718 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15724 (define_expand "strset_singleop"
15725 [(parallel [(set (match_operand 1 "memory_operand")
15726 (match_operand 2 "register_operand"))
15727 (set (match_operand 0 "register_operand")
15729 (unspec [(const_int 0)] UNSPEC_STOS)])]
15731 "ix86_current_function_needs_cld = 1;")
15733 (define_insn "*strsetdi_rex_1"
15734 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15735 (match_operand:DI 2 "register_operand" "a"))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 1)
15739 (unspec [(const_int 0)] UNSPEC_STOS)]
15741 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "store")
15745 (set_attr "mode" "DI")])
15747 (define_insn "*strsetsi_1"
15748 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15749 (match_operand:SI 2 "register_operand" "a"))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 1)
15753 (unspec [(const_int 0)] UNSPEC_STOS)]
15754 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15756 [(set_attr "type" "str")
15757 (set_attr "memory" "store")
15758 (set_attr "mode" "SI")])
15760 (define_insn "*strsethi_1"
15761 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15762 (match_operand:HI 2 "register_operand" "a"))
15763 (set (match_operand:P 0 "register_operand" "=D")
15764 (plus:P (match_dup 1)
15766 (unspec [(const_int 0)] UNSPEC_STOS)]
15767 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15769 [(set_attr "type" "str")
15770 (set_attr "memory" "store")
15771 (set_attr "mode" "HI")])
15773 (define_insn "*strsetqi_1"
15774 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15775 (match_operand:QI 2 "register_operand" "a"))
15776 (set (match_operand:P 0 "register_operand" "=D")
15777 (plus:P (match_dup 1)
15779 (unspec [(const_int 0)] UNSPEC_STOS)]
15780 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15782 [(set_attr "type" "str")
15783 (set_attr "memory" "store")
15784 (set (attr "prefix_rex")
15786 (match_test "<P:MODE>mode == DImode")
15788 (const_string "*")))
15789 (set_attr "mode" "QI")])
15791 (define_expand "rep_stos"
15792 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15793 (set (match_operand 0 "register_operand")
15795 (set (match_operand 2 "memory_operand") (const_int 0))
15796 (use (match_operand 3 "register_operand"))
15797 (use (match_dup 1))])]
15799 "ix86_current_function_needs_cld = 1;")
15801 (define_insn "*rep_stosdi_rex64"
15802 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15803 (set (match_operand:P 0 "register_operand" "=D")
15804 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15806 (match_operand:P 3 "register_operand" "0")))
15807 (set (mem:BLK (match_dup 3))
15809 (use (match_operand:DI 2 "register_operand" "a"))
15810 (use (match_dup 4))]
15812 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15814 [(set_attr "type" "str")
15815 (set_attr "prefix_rep" "1")
15816 (set_attr "memory" "store")
15817 (set_attr "mode" "DI")])
15819 (define_insn "*rep_stossi"
15820 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15821 (set (match_operand:P 0 "register_operand" "=D")
15822 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15824 (match_operand:P 3 "register_operand" "0")))
15825 (set (mem:BLK (match_dup 3))
15827 (use (match_operand:SI 2 "register_operand" "a"))
15828 (use (match_dup 4))]
15829 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15830 "%^rep{%;} stos{l|d}"
15831 [(set_attr "type" "str")
15832 (set_attr "prefix_rep" "1")
15833 (set_attr "memory" "store")
15834 (set_attr "mode" "SI")])
15836 (define_insn "*rep_stosqi"
15837 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15838 (set (match_operand:P 0 "register_operand" "=D")
15839 (plus:P (match_operand:P 3 "register_operand" "0")
15840 (match_operand:P 4 "register_operand" "1")))
15841 (set (mem:BLK (match_dup 3))
15843 (use (match_operand:QI 2 "register_operand" "a"))
15844 (use (match_dup 4))]
15845 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15847 [(set_attr "type" "str")
15848 (set_attr "prefix_rep" "1")
15849 (set_attr "memory" "store")
15850 (set (attr "prefix_rex")
15852 (match_test "<P:MODE>mode == DImode")
15854 (const_string "*")))
15855 (set_attr "mode" "QI")])
15857 (define_expand "cmpstrnsi"
15858 [(set (match_operand:SI 0 "register_operand")
15859 (compare:SI (match_operand:BLK 1 "general_operand")
15860 (match_operand:BLK 2 "general_operand")))
15861 (use (match_operand 3 "general_operand"))
15862 (use (match_operand 4 "immediate_operand"))]
15865 rtx addr1, addr2, out, outlow, count, countreg, align;
15867 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15870 /* Can't use this if the user has appropriated ecx, esi or edi. */
15871 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15876 out = gen_reg_rtx (SImode);
15878 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15879 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15880 if (addr1 != XEXP (operands[1], 0))
15881 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15882 if (addr2 != XEXP (operands[2], 0))
15883 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15885 count = operands[3];
15886 countreg = ix86_zero_extend_to_Pmode (count);
15888 /* %%% Iff we are testing strict equality, we can use known alignment
15889 to good advantage. This may be possible with combine, particularly
15890 once cc0 is dead. */
15891 align = operands[4];
15893 if (CONST_INT_P (count))
15895 if (INTVAL (count) == 0)
15897 emit_move_insn (operands[0], const0_rtx);
15900 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15901 operands[1], operands[2]));
15905 rtx (*gen_cmp) (rtx, rtx);
15907 gen_cmp = (TARGET_64BIT
15908 ? gen_cmpdi_1 : gen_cmpsi_1);
15910 emit_insn (gen_cmp (countreg, countreg));
15911 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15912 operands[1], operands[2]));
15915 outlow = gen_lowpart (QImode, out);
15916 emit_insn (gen_cmpintqi (outlow));
15917 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15919 if (operands[0] != out)
15920 emit_move_insn (operands[0], out);
15925 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15927 (define_expand "cmpintqi"
15928 [(set (match_dup 1)
15929 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15931 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15932 (parallel [(set (match_operand:QI 0 "register_operand")
15933 (minus:QI (match_dup 1)
15935 (clobber (reg:CC FLAGS_REG))])]
15938 operands[1] = gen_reg_rtx (QImode);
15939 operands[2] = gen_reg_rtx (QImode);
15942 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15943 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15945 (define_expand "cmpstrnqi_nz_1"
15946 [(parallel [(set (reg:CC FLAGS_REG)
15947 (compare:CC (match_operand 4 "memory_operand")
15948 (match_operand 5 "memory_operand")))
15949 (use (match_operand 2 "register_operand"))
15950 (use (match_operand:SI 3 "immediate_operand"))
15951 (clobber (match_operand 0 "register_operand"))
15952 (clobber (match_operand 1 "register_operand"))
15953 (clobber (match_dup 2))])]
15955 "ix86_current_function_needs_cld = 1;")
15957 (define_insn "*cmpstrnqi_nz_1"
15958 [(set (reg:CC FLAGS_REG)
15959 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15960 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15961 (use (match_operand:P 6 "register_operand" "2"))
15962 (use (match_operand:SI 3 "immediate_operand" "i"))
15963 (clobber (match_operand:P 0 "register_operand" "=S"))
15964 (clobber (match_operand:P 1 "register_operand" "=D"))
15965 (clobber (match_operand:P 2 "register_operand" "=c"))]
15966 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15968 [(set_attr "type" "str")
15969 (set_attr "mode" "QI")
15970 (set (attr "prefix_rex")
15972 (match_test "<P:MODE>mode == DImode")
15974 (const_string "*")))
15975 (set_attr "prefix_rep" "1")])
15977 ;; The same, but the count is not known to not be zero.
15979 (define_expand "cmpstrnqi_1"
15980 [(parallel [(set (reg:CC FLAGS_REG)
15981 (if_then_else:CC (ne (match_operand 2 "register_operand")
15983 (compare:CC (match_operand 4 "memory_operand")
15984 (match_operand 5 "memory_operand"))
15986 (use (match_operand:SI 3 "immediate_operand"))
15987 (use (reg:CC FLAGS_REG))
15988 (clobber (match_operand 0 "register_operand"))
15989 (clobber (match_operand 1 "register_operand"))
15990 (clobber (match_dup 2))])]
15992 "ix86_current_function_needs_cld = 1;")
15994 (define_insn "*cmpstrnqi_1"
15995 [(set (reg:CC FLAGS_REG)
15996 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15998 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15999 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16001 (use (match_operand:SI 3 "immediate_operand" "i"))
16002 (use (reg:CC FLAGS_REG))
16003 (clobber (match_operand:P 0 "register_operand" "=S"))
16004 (clobber (match_operand:P 1 "register_operand" "=D"))
16005 (clobber (match_operand:P 2 "register_operand" "=c"))]
16006 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16008 [(set_attr "type" "str")
16009 (set_attr "mode" "QI")
16010 (set (attr "prefix_rex")
16012 (match_test "<P:MODE>mode == DImode")
16014 (const_string "*")))
16015 (set_attr "prefix_rep" "1")])
16017 (define_expand "strlen<mode>"
16018 [(set (match_operand:P 0 "register_operand")
16019 (unspec:P [(match_operand:BLK 1 "general_operand")
16020 (match_operand:QI 2 "immediate_operand")
16021 (match_operand 3 "immediate_operand")]
16025 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16031 (define_expand "strlenqi_1"
16032 [(parallel [(set (match_operand 0 "register_operand")
16034 (clobber (match_operand 1 "register_operand"))
16035 (clobber (reg:CC FLAGS_REG))])]
16037 "ix86_current_function_needs_cld = 1;")
16039 (define_insn "*strlenqi_1"
16040 [(set (match_operand:P 0 "register_operand" "=&c")
16041 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16042 (match_operand:QI 2 "register_operand" "a")
16043 (match_operand:P 3 "immediate_operand" "i")
16044 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16045 (clobber (match_operand:P 1 "register_operand" "=D"))
16046 (clobber (reg:CC FLAGS_REG))]
16047 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16048 "%^repnz{%;} scasb"
16049 [(set_attr "type" "str")
16050 (set_attr "mode" "QI")
16051 (set (attr "prefix_rex")
16053 (match_test "<P:MODE>mode == DImode")
16055 (const_string "*")))
16056 (set_attr "prefix_rep" "1")])
16058 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16059 ;; handled in combine, but it is not currently up to the task.
16060 ;; When used for their truth value, the cmpstrn* expanders generate
16069 ;; The intermediate three instructions are unnecessary.
16071 ;; This one handles cmpstrn*_nz_1...
16074 (set (reg:CC FLAGS_REG)
16075 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16076 (mem:BLK (match_operand 5 "register_operand"))))
16077 (use (match_operand 6 "register_operand"))
16078 (use (match_operand:SI 3 "immediate_operand"))
16079 (clobber (match_operand 0 "register_operand"))
16080 (clobber (match_operand 1 "register_operand"))
16081 (clobber (match_operand 2 "register_operand"))])
16082 (set (match_operand:QI 7 "register_operand")
16083 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16084 (set (match_operand:QI 8 "register_operand")
16085 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16086 (set (reg FLAGS_REG)
16087 (compare (match_dup 7) (match_dup 8)))
16089 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16091 (set (reg:CC FLAGS_REG)
16092 (compare:CC (mem:BLK (match_dup 4))
16093 (mem:BLK (match_dup 5))))
16094 (use (match_dup 6))
16095 (use (match_dup 3))
16096 (clobber (match_dup 0))
16097 (clobber (match_dup 1))
16098 (clobber (match_dup 2))])])
16100 ;; ...and this one handles cmpstrn*_1.
16103 (set (reg:CC FLAGS_REG)
16104 (if_then_else:CC (ne (match_operand 6 "register_operand")
16106 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16107 (mem:BLK (match_operand 5 "register_operand")))
16109 (use (match_operand:SI 3 "immediate_operand"))
16110 (use (reg:CC FLAGS_REG))
16111 (clobber (match_operand 0 "register_operand"))
16112 (clobber (match_operand 1 "register_operand"))
16113 (clobber (match_operand 2 "register_operand"))])
16114 (set (match_operand:QI 7 "register_operand")
16115 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16116 (set (match_operand:QI 8 "register_operand")
16117 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16118 (set (reg FLAGS_REG)
16119 (compare (match_dup 7) (match_dup 8)))
16121 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16123 (set (reg:CC FLAGS_REG)
16124 (if_then_else:CC (ne (match_dup 6)
16126 (compare:CC (mem:BLK (match_dup 4))
16127 (mem:BLK (match_dup 5)))
16129 (use (match_dup 3))
16130 (use (reg:CC FLAGS_REG))
16131 (clobber (match_dup 0))
16132 (clobber (match_dup 1))
16133 (clobber (match_dup 2))])])
16135 ;; Conditional move instructions.
16137 (define_expand "mov<mode>cc"
16138 [(set (match_operand:SWIM 0 "register_operand")
16139 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16140 (match_operand:SWIM 2 "<general_operand>")
16141 (match_operand:SWIM 3 "<general_operand>")))]
16143 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16145 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16146 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16147 ;; So just document what we're doing explicitly.
16149 (define_expand "x86_mov<mode>cc_0_m1"
16151 [(set (match_operand:SWI48 0 "register_operand")
16152 (if_then_else:SWI48
16153 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16154 [(match_operand 1 "flags_reg_operand")
16158 (clobber (reg:CC FLAGS_REG))])])
16160 (define_insn "*x86_mov<mode>cc_0_m1"
16161 [(set (match_operand:SWI48 0 "register_operand" "=r")
16162 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16163 [(reg FLAGS_REG) (const_int 0)])
16166 (clobber (reg:CC FLAGS_REG))]
16168 "sbb{<imodesuffix>}\t%0, %0"
16169 ; Since we don't have the proper number of operands for an alu insn,
16170 ; fill in all the blanks.
16171 [(set_attr "type" "alu")
16172 (set_attr "use_carry" "1")
16173 (set_attr "pent_pair" "pu")
16174 (set_attr "memory" "none")
16175 (set_attr "imm_disp" "false")
16176 (set_attr "mode" "<MODE>")
16177 (set_attr "length_immediate" "0")])
16179 (define_insn "*x86_mov<mode>cc_0_m1_se"
16180 [(set (match_operand:SWI48 0 "register_operand" "=r")
16181 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16182 [(reg FLAGS_REG) (const_int 0)])
16185 (clobber (reg:CC FLAGS_REG))]
16187 "sbb{<imodesuffix>}\t%0, %0"
16188 [(set_attr "type" "alu")
16189 (set_attr "use_carry" "1")
16190 (set_attr "pent_pair" "pu")
16191 (set_attr "memory" "none")
16192 (set_attr "imm_disp" "false")
16193 (set_attr "mode" "<MODE>")
16194 (set_attr "length_immediate" "0")])
16196 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16197 [(set (match_operand:SWI48 0 "register_operand" "=r")
16198 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16199 [(reg FLAGS_REG) (const_int 0)])))
16200 (clobber (reg:CC FLAGS_REG))]
16202 "sbb{<imodesuffix>}\t%0, %0"
16203 [(set_attr "type" "alu")
16204 (set_attr "use_carry" "1")
16205 (set_attr "pent_pair" "pu")
16206 (set_attr "memory" "none")
16207 (set_attr "imm_disp" "false")
16208 (set_attr "mode" "<MODE>")
16209 (set_attr "length_immediate" "0")])
16211 (define_insn "*mov<mode>cc_noc"
16212 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16213 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16214 [(reg FLAGS_REG) (const_int 0)])
16215 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16216 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16217 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16219 cmov%O2%C1\t{%2, %0|%0, %2}
16220 cmov%O2%c1\t{%3, %0|%0, %3}"
16221 [(set_attr "type" "icmov")
16222 (set_attr "mode" "<MODE>")])
16224 ;; Don't do conditional moves with memory inputs. This splitter helps
16225 ;; register starved x86_32 by forcing inputs into registers before reload.
16227 [(set (match_operand:SWI248 0 "register_operand")
16228 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16229 [(reg FLAGS_REG) (const_int 0)])
16230 (match_operand:SWI248 2 "nonimmediate_operand")
16231 (match_operand:SWI248 3 "nonimmediate_operand")))]
16232 "!TARGET_64BIT && TARGET_CMOVE
16233 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16234 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16235 && can_create_pseudo_p ()
16236 && optimize_insn_for_speed_p ()"
16237 [(set (match_dup 0)
16238 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16240 if (MEM_P (operands[2]))
16241 operands[2] = force_reg (<MODE>mode, operands[2]);
16242 if (MEM_P (operands[3]))
16243 operands[3] = force_reg (<MODE>mode, operands[3]);
16246 (define_insn "*movqicc_noc"
16247 [(set (match_operand:QI 0 "register_operand" "=r,r")
16248 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16249 [(reg FLAGS_REG) (const_int 0)])
16250 (match_operand:QI 2 "register_operand" "r,0")
16251 (match_operand:QI 3 "register_operand" "0,r")))]
16252 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16254 [(set_attr "type" "icmov")
16255 (set_attr "mode" "QI")])
16258 [(set (match_operand:SWI12 0 "register_operand")
16259 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16260 [(reg FLAGS_REG) (const_int 0)])
16261 (match_operand:SWI12 2 "register_operand")
16262 (match_operand:SWI12 3 "register_operand")))]
16263 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16264 && reload_completed"
16265 [(set (match_dup 0)
16266 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16268 operands[0] = gen_lowpart (SImode, operands[0]);
16269 operands[2] = gen_lowpart (SImode, operands[2]);
16270 operands[3] = gen_lowpart (SImode, operands[3]);
16273 ;; Don't do conditional moves with memory inputs
16275 [(match_scratch:SWI248 2 "r")
16276 (set (match_operand:SWI248 0 "register_operand")
16277 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16278 [(reg FLAGS_REG) (const_int 0)])
16280 (match_operand:SWI248 3 "memory_operand")))]
16281 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16282 && optimize_insn_for_speed_p ()"
16283 [(set (match_dup 2) (match_dup 3))
16285 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16288 [(match_scratch:SWI248 2 "r")
16289 (set (match_operand:SWI248 0 "register_operand")
16290 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16291 [(reg FLAGS_REG) (const_int 0)])
16292 (match_operand:SWI248 3 "memory_operand")
16294 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16295 && optimize_insn_for_speed_p ()"
16296 [(set (match_dup 2) (match_dup 3))
16298 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16300 (define_expand "mov<mode>cc"
16301 [(set (match_operand:X87MODEF 0 "register_operand")
16302 (if_then_else:X87MODEF
16303 (match_operand 1 "comparison_operator")
16304 (match_operand:X87MODEF 2 "register_operand")
16305 (match_operand:X87MODEF 3 "register_operand")))]
16306 "(TARGET_80387 && TARGET_CMOVE)
16307 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16308 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16310 (define_insn "*movxfcc_1"
16311 [(set (match_operand:XF 0 "register_operand" "=f,f")
16312 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16313 [(reg FLAGS_REG) (const_int 0)])
16314 (match_operand:XF 2 "register_operand" "f,0")
16315 (match_operand:XF 3 "register_operand" "0,f")))]
16316 "TARGET_80387 && TARGET_CMOVE"
16318 fcmov%F1\t{%2, %0|%0, %2}
16319 fcmov%f1\t{%3, %0|%0, %3}"
16320 [(set_attr "type" "fcmov")
16321 (set_attr "mode" "XF")])
16323 (define_insn "*movdfcc_1"
16324 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16325 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16326 [(reg FLAGS_REG) (const_int 0)])
16327 (match_operand:DF 2 "nonimmediate_operand"
16329 (match_operand:DF 3 "nonimmediate_operand"
16330 "0 ,f,0 ,rm,0, rm")))]
16331 "TARGET_80387 && TARGET_CMOVE
16332 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16334 fcmov%F1\t{%2, %0|%0, %2}
16335 fcmov%f1\t{%3, %0|%0, %3}
16338 cmov%O2%C1\t{%2, %0|%0, %2}
16339 cmov%O2%c1\t{%3, %0|%0, %3}"
16340 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16341 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16342 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16345 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16346 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16347 [(reg FLAGS_REG) (const_int 0)])
16348 (match_operand:DF 2 "nonimmediate_operand")
16349 (match_operand:DF 3 "nonimmediate_operand")))]
16350 "!TARGET_64BIT && reload_completed"
16351 [(set (match_dup 2)
16352 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16354 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16356 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16357 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16360 (define_insn "*movsfcc_1_387"
16361 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16362 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16363 [(reg FLAGS_REG) (const_int 0)])
16364 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16365 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16366 "TARGET_80387 && TARGET_CMOVE
16367 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16369 fcmov%F1\t{%2, %0|%0, %2}
16370 fcmov%f1\t{%3, %0|%0, %3}
16371 cmov%O2%C1\t{%2, %0|%0, %2}
16372 cmov%O2%c1\t{%3, %0|%0, %3}"
16373 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16374 (set_attr "mode" "SF,SF,SI,SI")])
16376 ;; Don't do conditional moves with memory inputs. This splitter helps
16377 ;; register starved x86_32 by forcing inputs into registers before reload.
16379 [(set (match_operand:MODEF 0 "register_operand")
16380 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16381 [(reg FLAGS_REG) (const_int 0)])
16382 (match_operand:MODEF 2 "nonimmediate_operand")
16383 (match_operand:MODEF 3 "nonimmediate_operand")))]
16384 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16385 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16386 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16387 && can_create_pseudo_p ()
16388 && optimize_insn_for_speed_p ()"
16389 [(set (match_dup 0)
16390 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16392 if (MEM_P (operands[2]))
16393 operands[2] = force_reg (<MODE>mode, operands[2]);
16394 if (MEM_P (operands[3]))
16395 operands[3] = force_reg (<MODE>mode, operands[3]);
16398 ;; Don't do conditional moves with memory inputs
16400 [(match_scratch:MODEF 2 "r")
16401 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16402 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16403 [(reg FLAGS_REG) (const_int 0)])
16405 (match_operand:MODEF 3 "memory_operand")))]
16406 "(<MODE>mode != DFmode || TARGET_64BIT)
16407 && TARGET_80387 && TARGET_CMOVE
16408 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16409 && optimize_insn_for_speed_p ()"
16410 [(set (match_dup 2) (match_dup 3))
16412 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16415 [(match_scratch:MODEF 2 "r")
16416 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16417 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16419 (match_operand:MODEF 3 "memory_operand")
16421 "(<MODE>mode != DFmode || TARGET_64BIT)
16422 && TARGET_80387 && TARGET_CMOVE
16423 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16424 && optimize_insn_for_speed_p ()"
16425 [(set (match_dup 2) (match_dup 3))
16427 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16429 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16430 ;; the scalar versions to have only XMM registers as operands.
16432 ;; XOP conditional move
16433 (define_insn "*xop_pcmov_<mode>"
16434 [(set (match_operand:MODEF 0 "register_operand" "=x")
16435 (if_then_else:MODEF
16436 (match_operand:MODEF 1 "register_operand" "x")
16437 (match_operand:MODEF 2 "register_operand" "x")
16438 (match_operand:MODEF 3 "register_operand" "x")))]
16440 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16441 [(set_attr "type" "sse4arg")])
16443 ;; These versions of the min/max patterns are intentionally ignorant of
16444 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16445 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16446 ;; are undefined in this condition, we're certain this is correct.
16448 (define_insn "<code><mode>3"
16449 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16451 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16452 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16453 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16455 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16456 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16457 [(set_attr "isa" "noavx,avx")
16458 (set_attr "prefix" "orig,vex")
16459 (set_attr "type" "sseadd")
16460 (set_attr "mode" "<MODE>")])
16462 ;; These versions of the min/max patterns implement exactly the operations
16463 ;; min = (op1 < op2 ? op1 : op2)
16464 ;; max = (!(op1 < op2) ? op1 : op2)
16465 ;; Their operands are not commutative, and thus they may be used in the
16466 ;; presence of -0.0 and NaN.
16468 (define_int_iterator IEEE_MAXMIN
16472 (define_int_attr ieee_maxmin
16473 [(UNSPEC_IEEE_MAX "max")
16474 (UNSPEC_IEEE_MIN "min")])
16476 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16477 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16479 [(match_operand:MODEF 1 "register_operand" "0,x")
16480 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16482 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16484 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16485 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16486 [(set_attr "isa" "noavx,avx")
16487 (set_attr "prefix" "orig,vex")
16488 (set_attr "type" "sseadd")
16489 (set_attr "mode" "<MODE>")])
16491 ;; Make two stack loads independent:
16493 ;; fld %st(0) -> fld bb
16494 ;; fmul bb fmul %st(1), %st
16496 ;; Actually we only match the last two instructions for simplicity.
16498 [(set (match_operand 0 "fp_register_operand")
16499 (match_operand 1 "fp_register_operand"))
16501 (match_operator 2 "binary_fp_operator"
16503 (match_operand 3 "memory_operand")]))]
16504 "REGNO (operands[0]) != REGNO (operands[1])"
16505 [(set (match_dup 0) (match_dup 3))
16506 (set (match_dup 0) (match_dup 4))]
16508 ;; The % modifier is not operational anymore in peephole2's, so we have to
16509 ;; swap the operands manually in the case of addition and multiplication.
16513 if (COMMUTATIVE_ARITH_P (operands[2]))
16514 op0 = operands[0], op1 = operands[1];
16516 op0 = operands[1], op1 = operands[0];
16518 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16519 GET_MODE (operands[2]),
16523 ;; Conditional addition patterns
16524 (define_expand "add<mode>cc"
16525 [(match_operand:SWI 0 "register_operand")
16526 (match_operand 1 "ordered_comparison_operator")
16527 (match_operand:SWI 2 "register_operand")
16528 (match_operand:SWI 3 "const_int_operand")]
16530 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16532 ;; Misc patterns (?)
16534 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16535 ;; Otherwise there will be nothing to keep
16537 ;; [(set (reg ebp) (reg esp))]
16538 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16539 ;; (clobber (eflags)]
16540 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16542 ;; in proper program order.
16544 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16545 [(set (match_operand:P 0 "register_operand" "=r,r")
16546 (plus:P (match_operand:P 1 "register_operand" "0,r")
16547 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16548 (clobber (reg:CC FLAGS_REG))
16549 (clobber (mem:BLK (scratch)))]
16552 switch (get_attr_type (insn))
16555 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16558 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16559 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16560 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16562 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16565 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16566 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16569 [(set (attr "type")
16570 (cond [(and (eq_attr "alternative" "0")
16571 (not (match_test "TARGET_OPT_AGU")))
16572 (const_string "alu")
16573 (match_operand:<MODE> 2 "const0_operand")
16574 (const_string "imov")
16576 (const_string "lea")))
16577 (set (attr "length_immediate")
16578 (cond [(eq_attr "type" "imov")
16580 (and (eq_attr "type" "alu")
16581 (match_operand 2 "const128_operand"))
16584 (const_string "*")))
16585 (set_attr "mode" "<MODE>")])
16587 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16588 [(set (match_operand:P 0 "register_operand" "=r")
16589 (minus:P (match_operand:P 1 "register_operand" "0")
16590 (match_operand:P 2 "register_operand" "r")))
16591 (clobber (reg:CC FLAGS_REG))
16592 (clobber (mem:BLK (scratch)))]
16594 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16595 [(set_attr "type" "alu")
16596 (set_attr "mode" "<MODE>")])
16598 (define_insn "allocate_stack_worker_probe_<mode>"
16599 [(set (match_operand:P 0 "register_operand" "=a")
16600 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16601 UNSPECV_STACK_PROBE))
16602 (clobber (reg:CC FLAGS_REG))]
16603 "ix86_target_stack_probe ()"
16604 "call\t___chkstk_ms"
16605 [(set_attr "type" "multi")
16606 (set_attr "length" "5")])
16608 (define_expand "allocate_stack"
16609 [(match_operand 0 "register_operand")
16610 (match_operand 1 "general_operand")]
16611 "ix86_target_stack_probe ()"
16615 #ifndef CHECK_STACK_LIMIT
16616 #define CHECK_STACK_LIMIT 0
16619 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16620 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16624 rtx (*insn) (rtx, rtx);
16626 x = copy_to_mode_reg (Pmode, operands[1]);
16628 insn = (TARGET_64BIT
16629 ? gen_allocate_stack_worker_probe_di
16630 : gen_allocate_stack_worker_probe_si);
16632 emit_insn (insn (x, x));
16635 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16636 stack_pointer_rtx, 0, OPTAB_DIRECT);
16638 if (x != stack_pointer_rtx)
16639 emit_move_insn (stack_pointer_rtx, x);
16641 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16645 ;; Use IOR for stack probes, this is shorter.
16646 (define_expand "probe_stack"
16647 [(match_operand 0 "memory_operand")]
16650 rtx (*gen_ior3) (rtx, rtx, rtx);
16652 gen_ior3 = (GET_MODE (operands[0]) == DImode
16653 ? gen_iordi3 : gen_iorsi3);
16655 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16659 (define_insn "adjust_stack_and_probe<mode>"
16660 [(set (match_operand:P 0 "register_operand" "=r")
16661 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16662 UNSPECV_PROBE_STACK_RANGE))
16663 (set (reg:P SP_REG)
16664 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16665 (clobber (reg:CC FLAGS_REG))
16666 (clobber (mem:BLK (scratch)))]
16668 "* return output_adjust_stack_and_probe (operands[0]);"
16669 [(set_attr "type" "multi")])
16671 (define_insn "probe_stack_range<mode>"
16672 [(set (match_operand:P 0 "register_operand" "=r")
16673 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16674 (match_operand:P 2 "const_int_operand" "n")]
16675 UNSPECV_PROBE_STACK_RANGE))
16676 (clobber (reg:CC FLAGS_REG))]
16678 "* return output_probe_stack_range (operands[0], operands[2]);"
16679 [(set_attr "type" "multi")])
16681 (define_expand "builtin_setjmp_receiver"
16682 [(label_ref (match_operand 0))]
16683 "!TARGET_64BIT && flag_pic"
16689 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16690 rtx label_rtx = gen_label_rtx ();
16691 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16692 xops[0] = xops[1] = picreg;
16693 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16694 ix86_expand_binary_operator (MINUS, SImode, xops);
16698 emit_insn (gen_set_got (pic_offset_table_rtx));
16702 (define_insn_and_split "nonlocal_goto_receiver"
16703 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16704 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16706 "&& reload_completed"
16709 if (crtl->uses_pic_offset_table)
16712 rtx label_rtx = gen_label_rtx ();
16715 /* Get a new pic base. */
16716 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16717 /* Correct this with the offset from the new to the old. */
16718 xops[0] = xops[1] = pic_offset_table_rtx;
16719 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16720 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16721 UNSPEC_MACHOPIC_OFFSET);
16722 xops[2] = gen_rtx_CONST (Pmode, tmp);
16723 ix86_expand_binary_operator (MINUS, SImode, xops);
16726 /* No pic reg restore needed. */
16727 emit_note (NOTE_INSN_DELETED);
16732 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16733 ;; Do not split instructions with mask registers.
16735 [(set (match_operand 0 "general_reg_operand")
16736 (match_operator 3 "promotable_binary_operator"
16737 [(match_operand 1 "general_reg_operand")
16738 (match_operand 2 "aligned_operand")]))
16739 (clobber (reg:CC FLAGS_REG))]
16740 "! TARGET_PARTIAL_REG_STALL && reload_completed
16741 && ((GET_MODE (operands[0]) == HImode
16742 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16743 /* ??? next two lines just !satisfies_constraint_K (...) */
16744 || !CONST_INT_P (operands[2])
16745 || satisfies_constraint_K (operands[2])))
16746 || (GET_MODE (operands[0]) == QImode
16747 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16748 [(parallel [(set (match_dup 0)
16749 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16750 (clobber (reg:CC FLAGS_REG))])]
16752 operands[0] = gen_lowpart (SImode, operands[0]);
16753 operands[1] = gen_lowpart (SImode, operands[1]);
16754 if (GET_CODE (operands[3]) != ASHIFT)
16755 operands[2] = gen_lowpart (SImode, operands[2]);
16756 PUT_MODE (operands[3], SImode);
16759 ; Promote the QImode tests, as i386 has encoding of the AND
16760 ; instruction with 32-bit sign-extended immediate and thus the
16761 ; instruction size is unchanged, except in the %eax case for
16762 ; which it is increased by one byte, hence the ! optimize_size.
16764 [(set (match_operand 0 "flags_reg_operand")
16765 (match_operator 2 "compare_operator"
16766 [(and (match_operand 3 "aligned_operand")
16767 (match_operand 4 "const_int_operand"))
16769 (set (match_operand 1 "register_operand")
16770 (and (match_dup 3) (match_dup 4)))]
16771 "! TARGET_PARTIAL_REG_STALL && reload_completed
16772 && optimize_insn_for_speed_p ()
16773 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16774 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16775 /* Ensure that the operand will remain sign-extended immediate. */
16776 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16777 [(parallel [(set (match_dup 0)
16778 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16781 (and:SI (match_dup 3) (match_dup 4)))])]
16784 = gen_int_mode (INTVAL (operands[4])
16785 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16786 operands[1] = gen_lowpart (SImode, operands[1]);
16787 operands[3] = gen_lowpart (SImode, operands[3]);
16790 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16791 ; the TEST instruction with 32-bit sign-extended immediate and thus
16792 ; the instruction size would at least double, which is not what we
16793 ; want even with ! optimize_size.
16795 [(set (match_operand 0 "flags_reg_operand")
16796 (match_operator 1 "compare_operator"
16797 [(and (match_operand:HI 2 "aligned_operand")
16798 (match_operand:HI 3 "const_int_operand"))
16800 "! TARGET_PARTIAL_REG_STALL && reload_completed
16801 && ! TARGET_FAST_PREFIX
16802 && optimize_insn_for_speed_p ()
16803 /* Ensure that the operand will remain sign-extended immediate. */
16804 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16805 [(set (match_dup 0)
16806 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16810 = gen_int_mode (INTVAL (operands[3])
16811 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16812 operands[2] = gen_lowpart (SImode, operands[2]);
16816 [(set (match_operand 0 "register_operand")
16817 (neg (match_operand 1 "register_operand")))
16818 (clobber (reg:CC FLAGS_REG))]
16819 "! TARGET_PARTIAL_REG_STALL && reload_completed
16820 && (GET_MODE (operands[0]) == HImode
16821 || (GET_MODE (operands[0]) == QImode
16822 && (TARGET_PROMOTE_QImode
16823 || optimize_insn_for_size_p ())))"
16824 [(parallel [(set (match_dup 0)
16825 (neg:SI (match_dup 1)))
16826 (clobber (reg:CC FLAGS_REG))])]
16828 operands[0] = gen_lowpart (SImode, operands[0]);
16829 operands[1] = gen_lowpart (SImode, operands[1]);
16832 ;; Do not split instructions with mask regs.
16834 [(set (match_operand 0 "general_reg_operand")
16835 (not (match_operand 1 "general_reg_operand")))]
16836 "! TARGET_PARTIAL_REG_STALL && reload_completed
16837 && (GET_MODE (operands[0]) == HImode
16838 || (GET_MODE (operands[0]) == QImode
16839 && (TARGET_PROMOTE_QImode
16840 || optimize_insn_for_size_p ())))"
16841 [(set (match_dup 0)
16842 (not:SI (match_dup 1)))]
16844 operands[0] = gen_lowpart (SImode, operands[0]);
16845 operands[1] = gen_lowpart (SImode, operands[1]);
16848 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16849 ;; transform a complex memory operation into two memory to register operations.
16851 ;; Don't push memory operands
16853 [(set (match_operand:SWI 0 "push_operand")
16854 (match_operand:SWI 1 "memory_operand"))
16855 (match_scratch:SWI 2 "<r>")]
16856 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16857 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16858 [(set (match_dup 2) (match_dup 1))
16859 (set (match_dup 0) (match_dup 2))])
16861 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16864 [(set (match_operand:SF 0 "push_operand")
16865 (match_operand:SF 1 "memory_operand"))
16866 (match_scratch:SF 2 "r")]
16867 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16868 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16869 [(set (match_dup 2) (match_dup 1))
16870 (set (match_dup 0) (match_dup 2))])
16872 ;; Don't move an immediate directly to memory when the instruction
16873 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16875 [(match_scratch:SWI124 1 "<r>")
16876 (set (match_operand:SWI124 0 "memory_operand")
16878 "optimize_insn_for_speed_p ()
16879 && ((<MODE>mode == HImode
16880 && TARGET_LCP_STALL)
16881 || (!TARGET_USE_MOV0
16882 && TARGET_SPLIT_LONG_MOVES
16883 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16884 && peep2_regno_dead_p (0, FLAGS_REG)"
16885 [(parallel [(set (match_dup 2) (const_int 0))
16886 (clobber (reg:CC FLAGS_REG))])
16887 (set (match_dup 0) (match_dup 1))]
16888 "operands[2] = gen_lowpart (SImode, operands[1]);")
16891 [(match_scratch:SWI124 2 "<r>")
16892 (set (match_operand:SWI124 0 "memory_operand")
16893 (match_operand:SWI124 1 "immediate_operand"))]
16894 "optimize_insn_for_speed_p ()
16895 && ((<MODE>mode == HImode
16896 && TARGET_LCP_STALL)
16897 || (TARGET_SPLIT_LONG_MOVES
16898 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16899 [(set (match_dup 2) (match_dup 1))
16900 (set (match_dup 0) (match_dup 2))])
16902 ;; Don't compare memory with zero, load and use a test instead.
16904 [(set (match_operand 0 "flags_reg_operand")
16905 (match_operator 1 "compare_operator"
16906 [(match_operand:SI 2 "memory_operand")
16908 (match_scratch:SI 3 "r")]
16909 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16910 [(set (match_dup 3) (match_dup 2))
16911 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16913 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16914 ;; Don't split NOTs with a displacement operand, because resulting XOR
16915 ;; will not be pairable anyway.
16917 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16918 ;; represented using a modRM byte. The XOR replacement is long decoded,
16919 ;; so this split helps here as well.
16921 ;; Note: Can't do this as a regular split because we can't get proper
16922 ;; lifetime information then.
16925 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16926 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16927 "optimize_insn_for_speed_p ()
16928 && ((TARGET_NOT_UNPAIRABLE
16929 && (!MEM_P (operands[0])
16930 || !memory_displacement_operand (operands[0], <MODE>mode)))
16931 || (TARGET_NOT_VECTORMODE
16932 && long_memory_operand (operands[0], <MODE>mode)))
16933 && peep2_regno_dead_p (0, FLAGS_REG)"
16934 [(parallel [(set (match_dup 0)
16935 (xor:SWI124 (match_dup 1) (const_int -1)))
16936 (clobber (reg:CC FLAGS_REG))])])
16938 ;; Non pairable "test imm, reg" instructions can be translated to
16939 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16940 ;; byte opcode instead of two, have a short form for byte operands),
16941 ;; so do it for other CPUs as well. Given that the value was dead,
16942 ;; this should not create any new dependencies. Pass on the sub-word
16943 ;; versions if we're concerned about partial register stalls.
16946 [(set (match_operand 0 "flags_reg_operand")
16947 (match_operator 1 "compare_operator"
16948 [(and:SI (match_operand:SI 2 "register_operand")
16949 (match_operand:SI 3 "immediate_operand"))
16951 "ix86_match_ccmode (insn, CCNOmode)
16952 && (true_regnum (operands[2]) != AX_REG
16953 || satisfies_constraint_K (operands[3]))
16954 && peep2_reg_dead_p (1, operands[2])"
16956 [(set (match_dup 0)
16957 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16960 (and:SI (match_dup 2) (match_dup 3)))])])
16962 ;; We don't need to handle HImode case, because it will be promoted to SImode
16963 ;; on ! TARGET_PARTIAL_REG_STALL
16966 [(set (match_operand 0 "flags_reg_operand")
16967 (match_operator 1 "compare_operator"
16968 [(and:QI (match_operand:QI 2 "register_operand")
16969 (match_operand:QI 3 "immediate_operand"))
16971 "! TARGET_PARTIAL_REG_STALL
16972 && ix86_match_ccmode (insn, CCNOmode)
16973 && true_regnum (operands[2]) != AX_REG
16974 && peep2_reg_dead_p (1, operands[2])"
16976 [(set (match_dup 0)
16977 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16980 (and:QI (match_dup 2) (match_dup 3)))])])
16983 [(set (match_operand 0 "flags_reg_operand")
16984 (match_operator 1 "compare_operator"
16987 (match_operand 2 "ext_register_operand")
16990 (match_operand 3 "const_int_operand"))
16992 "! TARGET_PARTIAL_REG_STALL
16993 && ix86_match_ccmode (insn, CCNOmode)
16994 && true_regnum (operands[2]) != AX_REG
16995 && peep2_reg_dead_p (1, operands[2])"
16996 [(parallel [(set (match_dup 0)
17005 (set (zero_extract:SI (match_dup 2)
17013 (match_dup 3)))])])
17015 ;; Don't do logical operations with memory inputs.
17017 [(match_scratch:SI 2 "r")
17018 (parallel [(set (match_operand:SI 0 "register_operand")
17019 (match_operator:SI 3 "arith_or_logical_operator"
17021 (match_operand:SI 1 "memory_operand")]))
17022 (clobber (reg:CC FLAGS_REG))])]
17023 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17024 [(set (match_dup 2) (match_dup 1))
17025 (parallel [(set (match_dup 0)
17026 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17027 (clobber (reg:CC FLAGS_REG))])])
17030 [(match_scratch:SI 2 "r")
17031 (parallel [(set (match_operand:SI 0 "register_operand")
17032 (match_operator:SI 3 "arith_or_logical_operator"
17033 [(match_operand:SI 1 "memory_operand")
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17037 [(set (match_dup 2) (match_dup 1))
17038 (parallel [(set (match_dup 0)
17039 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17040 (clobber (reg:CC FLAGS_REG))])])
17042 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17043 ;; refers to the destination of the load!
17046 [(set (match_operand:SI 0 "register_operand")
17047 (match_operand:SI 1 "register_operand"))
17048 (parallel [(set (match_dup 0)
17049 (match_operator:SI 3 "commutative_operator"
17051 (match_operand:SI 2 "memory_operand")]))
17052 (clobber (reg:CC FLAGS_REG))])]
17053 "REGNO (operands[0]) != REGNO (operands[1])
17054 && GENERAL_REGNO_P (REGNO (operands[0]))
17055 && GENERAL_REGNO_P (REGNO (operands[1]))"
17056 [(set (match_dup 0) (match_dup 4))
17057 (parallel [(set (match_dup 0)
17058 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17059 (clobber (reg:CC FLAGS_REG))])]
17060 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17063 [(set (match_operand 0 "register_operand")
17064 (match_operand 1 "register_operand"))
17066 (match_operator 3 "commutative_operator"
17068 (match_operand 2 "memory_operand")]))]
17069 "REGNO (operands[0]) != REGNO (operands[1])
17070 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17071 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17072 [(set (match_dup 0) (match_dup 2))
17074 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17076 ; Don't do logical operations with memory outputs
17078 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17079 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17080 ; the same decoder scheduling characteristics as the original.
17083 [(match_scratch:SI 2 "r")
17084 (parallel [(set (match_operand:SI 0 "memory_operand")
17085 (match_operator:SI 3 "arith_or_logical_operator"
17087 (match_operand:SI 1 "nonmemory_operand")]))
17088 (clobber (reg:CC FLAGS_REG))])]
17089 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17090 /* Do not split stack checking probes. */
17091 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17092 [(set (match_dup 2) (match_dup 0))
17093 (parallel [(set (match_dup 2)
17094 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17095 (clobber (reg:CC FLAGS_REG))])
17096 (set (match_dup 0) (match_dup 2))])
17099 [(match_scratch:SI 2 "r")
17100 (parallel [(set (match_operand:SI 0 "memory_operand")
17101 (match_operator:SI 3 "arith_or_logical_operator"
17102 [(match_operand:SI 1 "nonmemory_operand")
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17106 /* Do not split stack checking probes. */
17107 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17108 [(set (match_dup 2) (match_dup 0))
17109 (parallel [(set (match_dup 2)
17110 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17111 (clobber (reg:CC FLAGS_REG))])
17112 (set (match_dup 0) (match_dup 2))])
17114 ;; Attempt to use arith or logical operations with memory outputs with
17115 ;; setting of flags.
17117 [(set (match_operand:SWI 0 "register_operand")
17118 (match_operand:SWI 1 "memory_operand"))
17119 (parallel [(set (match_dup 0)
17120 (match_operator:SWI 3 "plusminuslogic_operator"
17122 (match_operand:SWI 2 "<nonmemory_operand>")]))
17123 (clobber (reg:CC FLAGS_REG))])
17124 (set (match_dup 1) (match_dup 0))
17125 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17126 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17127 && peep2_reg_dead_p (4, operands[0])
17128 && !reg_overlap_mentioned_p (operands[0], operands[1])
17129 && !reg_overlap_mentioned_p (operands[0], operands[2])
17130 && (<MODE>mode != QImode
17131 || immediate_operand (operands[2], QImode)
17132 || q_regs_operand (operands[2], QImode))
17133 && ix86_match_ccmode (peep2_next_insn (3),
17134 (GET_CODE (operands[3]) == PLUS
17135 || GET_CODE (operands[3]) == MINUS)
17136 ? CCGOCmode : CCNOmode)"
17137 [(parallel [(set (match_dup 4) (match_dup 5))
17138 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17139 (match_dup 2)]))])]
17141 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17142 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17143 copy_rtx (operands[1]),
17144 copy_rtx (operands[2]));
17145 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17146 operands[5], const0_rtx);
17150 [(parallel [(set (match_operand:SWI 0 "register_operand")
17151 (match_operator:SWI 2 "plusminuslogic_operator"
17153 (match_operand:SWI 1 "memory_operand")]))
17154 (clobber (reg:CC FLAGS_REG))])
17155 (set (match_dup 1) (match_dup 0))
17156 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17157 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17158 && GET_CODE (operands[2]) != MINUS
17159 && peep2_reg_dead_p (3, operands[0])
17160 && !reg_overlap_mentioned_p (operands[0], operands[1])
17161 && ix86_match_ccmode (peep2_next_insn (2),
17162 GET_CODE (operands[2]) == PLUS
17163 ? CCGOCmode : CCNOmode)"
17164 [(parallel [(set (match_dup 3) (match_dup 4))
17165 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17166 (match_dup 0)]))])]
17168 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17169 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17170 copy_rtx (operands[1]),
17171 copy_rtx (operands[0]));
17172 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17173 operands[4], const0_rtx);
17177 [(set (match_operand:SWI12 0 "register_operand")
17178 (match_operand:SWI12 1 "memory_operand"))
17179 (parallel [(set (match_operand:SI 4 "register_operand")
17180 (match_operator:SI 3 "plusminuslogic_operator"
17182 (match_operand:SI 2 "nonmemory_operand")]))
17183 (clobber (reg:CC FLAGS_REG))])
17184 (set (match_dup 1) (match_dup 0))
17185 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17186 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17187 && REG_P (operands[0]) && REG_P (operands[4])
17188 && REGNO (operands[0]) == REGNO (operands[4])
17189 && peep2_reg_dead_p (4, operands[0])
17190 && (<MODE>mode != QImode
17191 || immediate_operand (operands[2], SImode)
17192 || q_regs_operand (operands[2], SImode))
17193 && !reg_overlap_mentioned_p (operands[0], operands[1])
17194 && !reg_overlap_mentioned_p (operands[0], operands[2])
17195 && ix86_match_ccmode (peep2_next_insn (3),
17196 (GET_CODE (operands[3]) == PLUS
17197 || GET_CODE (operands[3]) == MINUS)
17198 ? CCGOCmode : CCNOmode)"
17199 [(parallel [(set (match_dup 4) (match_dup 5))
17200 (set (match_dup 1) (match_dup 6))])]
17202 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17203 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17204 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17205 copy_rtx (operands[1]), operands[2]);
17206 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17207 operands[5], const0_rtx);
17208 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17209 copy_rtx (operands[1]),
17210 copy_rtx (operands[2]));
17213 ;; Attempt to always use XOR for zeroing registers.
17215 [(set (match_operand 0 "register_operand")
17216 (match_operand 1 "const0_operand"))]
17217 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17218 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17219 && GENERAL_REG_P (operands[0])
17220 && peep2_regno_dead_p (0, FLAGS_REG)"
17221 [(parallel [(set (match_dup 0) (const_int 0))
17222 (clobber (reg:CC FLAGS_REG))])]
17223 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17226 [(set (strict_low_part (match_operand 0 "register_operand"))
17228 "(GET_MODE (operands[0]) == QImode
17229 || GET_MODE (operands[0]) == HImode)
17230 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17231 && peep2_regno_dead_p (0, FLAGS_REG)"
17232 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17233 (clobber (reg:CC FLAGS_REG))])])
17235 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17237 [(set (match_operand:SWI248 0 "register_operand")
17239 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17240 && peep2_regno_dead_p (0, FLAGS_REG)"
17241 [(parallel [(set (match_dup 0) (const_int -1))
17242 (clobber (reg:CC FLAGS_REG))])]
17244 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17245 operands[0] = gen_lowpart (SImode, operands[0]);
17248 ;; Attempt to convert simple lea to add/shift.
17249 ;; These can be created by move expanders.
17250 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17251 ;; relevant lea instructions were already split.
17254 [(set (match_operand:SWI48 0 "register_operand")
17255 (plus:SWI48 (match_dup 0)
17256 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17258 && peep2_regno_dead_p (0, FLAGS_REG)"
17259 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17260 (clobber (reg:CC FLAGS_REG))])])
17263 [(set (match_operand:SWI48 0 "register_operand")
17264 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17267 && peep2_regno_dead_p (0, FLAGS_REG)"
17268 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17269 (clobber (reg:CC FLAGS_REG))])])
17272 [(set (match_operand:DI 0 "register_operand")
17274 (plus:SI (match_operand:SI 1 "register_operand")
17275 (match_operand:SI 2 "nonmemory_operand"))))]
17276 "TARGET_64BIT && !TARGET_OPT_AGU
17277 && REGNO (operands[0]) == REGNO (operands[1])
17278 && peep2_regno_dead_p (0, FLAGS_REG)"
17279 [(parallel [(set (match_dup 0)
17280 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17281 (clobber (reg:CC FLAGS_REG))])])
17284 [(set (match_operand:DI 0 "register_operand")
17286 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17287 (match_operand:SI 2 "register_operand"))))]
17288 "TARGET_64BIT && !TARGET_OPT_AGU
17289 && REGNO (operands[0]) == REGNO (operands[2])
17290 && peep2_regno_dead_p (0, FLAGS_REG)"
17291 [(parallel [(set (match_dup 0)
17292 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17293 (clobber (reg:CC FLAGS_REG))])])
17296 [(set (match_operand:SWI48 0 "register_operand")
17297 (mult:SWI48 (match_dup 0)
17298 (match_operand:SWI48 1 "const_int_operand")))]
17299 "exact_log2 (INTVAL (operands[1])) >= 0
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17306 [(set (match_operand:DI 0 "register_operand")
17308 (mult:SI (match_operand:SI 1 "register_operand")
17309 (match_operand:SI 2 "const_int_operand"))))]
17311 && exact_log2 (INTVAL (operands[2])) >= 0
17312 && REGNO (operands[0]) == REGNO (operands[1])
17313 && peep2_regno_dead_p (0, FLAGS_REG)"
17314 [(parallel [(set (match_dup 0)
17315 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17316 (clobber (reg:CC FLAGS_REG))])]
17317 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17319 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17320 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17321 ;; On many CPUs it is also faster, since special hardware to avoid esp
17322 ;; dependencies is present.
17324 ;; While some of these conversions may be done using splitters, we use
17325 ;; peepholes in order to allow combine_stack_adjustments pass to see
17326 ;; nonobfuscated RTL.
17328 ;; Convert prologue esp subtractions to push.
17329 ;; We need register to push. In order to keep verify_flow_info happy we have
17331 ;; - use scratch and clobber it in order to avoid dependencies
17332 ;; - use already live register
17333 ;; We can't use the second way right now, since there is no reliable way how to
17334 ;; verify that given register is live. First choice will also most likely in
17335 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17336 ;; call clobbered registers are dead. We may want to use base pointer as an
17337 ;; alternative when no register is available later.
17340 [(match_scratch:W 1 "r")
17341 (parallel [(set (reg:P SP_REG)
17342 (plus:P (reg:P SP_REG)
17343 (match_operand:P 0 "const_int_operand")))
17344 (clobber (reg:CC FLAGS_REG))
17345 (clobber (mem:BLK (scratch)))])]
17346 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17347 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17348 [(clobber (match_dup 1))
17349 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17350 (clobber (mem:BLK (scratch)))])])
17353 [(match_scratch:W 1 "r")
17354 (parallel [(set (reg:P SP_REG)
17355 (plus:P (reg:P SP_REG)
17356 (match_operand:P 0 "const_int_operand")))
17357 (clobber (reg:CC FLAGS_REG))
17358 (clobber (mem:BLK (scratch)))])]
17359 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17360 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17361 [(clobber (match_dup 1))
17362 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17363 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17364 (clobber (mem:BLK (scratch)))])])
17366 ;; Convert esp subtractions to push.
17368 [(match_scratch:W 1 "r")
17369 (parallel [(set (reg:P SP_REG)
17370 (plus:P (reg:P SP_REG)
17371 (match_operand:P 0 "const_int_operand")))
17372 (clobber (reg:CC FLAGS_REG))])]
17373 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17374 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17375 [(clobber (match_dup 1))
17376 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17379 [(match_scratch:W 1 "r")
17380 (parallel [(set (reg:P SP_REG)
17381 (plus:P (reg:P SP_REG)
17382 (match_operand:P 0 "const_int_operand")))
17383 (clobber (reg:CC FLAGS_REG))])]
17384 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17385 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17386 [(clobber (match_dup 1))
17387 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17388 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17390 ;; Convert epilogue deallocator to pop.
17392 [(match_scratch:W 1 "r")
17393 (parallel [(set (reg:P SP_REG)
17394 (plus:P (reg:P SP_REG)
17395 (match_operand:P 0 "const_int_operand")))
17396 (clobber (reg:CC FLAGS_REG))
17397 (clobber (mem:BLK (scratch)))])]
17398 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17399 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17400 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17401 (clobber (mem:BLK (scratch)))])])
17403 ;; Two pops case is tricky, since pop causes dependency
17404 ;; on destination register. We use two registers if available.
17406 [(match_scratch:W 1 "r")
17407 (match_scratch:W 2 "r")
17408 (parallel [(set (reg:P SP_REG)
17409 (plus:P (reg:P SP_REG)
17410 (match_operand:P 0 "const_int_operand")))
17411 (clobber (reg:CC FLAGS_REG))
17412 (clobber (mem:BLK (scratch)))])]
17413 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17414 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17415 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17416 (clobber (mem:BLK (scratch)))])
17417 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17420 [(match_scratch:W 1 "r")
17421 (parallel [(set (reg:P SP_REG)
17422 (plus:P (reg:P SP_REG)
17423 (match_operand:P 0 "const_int_operand")))
17424 (clobber (reg:CC FLAGS_REG))
17425 (clobber (mem:BLK (scratch)))])]
17426 "optimize_insn_for_size_p ()
17427 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17428 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17429 (clobber (mem:BLK (scratch)))])
17430 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17432 ;; Convert esp additions to pop.
17434 [(match_scratch:W 1 "r")
17435 (parallel [(set (reg:P SP_REG)
17436 (plus:P (reg:P SP_REG)
17437 (match_operand:P 0 "const_int_operand")))
17438 (clobber (reg:CC FLAGS_REG))])]
17439 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17440 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17442 ;; Two pops case is tricky, since pop causes dependency
17443 ;; on destination register. We use two registers if available.
17445 [(match_scratch:W 1 "r")
17446 (match_scratch:W 2 "r")
17447 (parallel [(set (reg:P SP_REG)
17448 (plus:P (reg:P SP_REG)
17449 (match_operand:P 0 "const_int_operand")))
17450 (clobber (reg:CC FLAGS_REG))])]
17451 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17452 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17453 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17456 [(match_scratch:W 1 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand")))
17460 (clobber (reg:CC FLAGS_REG))])]
17461 "optimize_insn_for_size_p ()
17462 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17463 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17464 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17466 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17467 ;; required and register dies. Similarly for 128 to -128.
17469 [(set (match_operand 0 "flags_reg_operand")
17470 (match_operator 1 "compare_operator"
17471 [(match_operand 2 "register_operand")
17472 (match_operand 3 "const_int_operand")]))]
17473 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17474 && incdec_operand (operands[3], GET_MODE (operands[3])))
17475 || (!TARGET_FUSE_CMP_AND_BRANCH
17476 && INTVAL (operands[3]) == 128))
17477 && ix86_match_ccmode (insn, CCGCmode)
17478 && peep2_reg_dead_p (1, operands[2])"
17479 [(parallel [(set (match_dup 0)
17480 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17481 (clobber (match_dup 2))])])
17483 ;; Convert imul by three, five and nine into lea
17486 [(set (match_operand:SWI48 0 "register_operand")
17487 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17488 (match_operand:SWI48 2 "const359_operand")))
17489 (clobber (reg:CC FLAGS_REG))])]
17490 "!TARGET_PARTIAL_REG_STALL
17491 || <MODE>mode == SImode
17492 || optimize_function_for_size_p (cfun)"
17493 [(set (match_dup 0)
17494 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17496 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17500 [(set (match_operand:SWI48 0 "register_operand")
17501 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17502 (match_operand:SWI48 2 "const359_operand")))
17503 (clobber (reg:CC FLAGS_REG))])]
17504 "optimize_insn_for_speed_p ()
17505 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17506 [(set (match_dup 0) (match_dup 1))
17508 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17510 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17512 ;; imul $32bit_imm, mem, reg is vector decoded, while
17513 ;; imul $32bit_imm, reg, reg is direct decoded.
17515 [(match_scratch:SWI48 3 "r")
17516 (parallel [(set (match_operand:SWI48 0 "register_operand")
17517 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17518 (match_operand:SWI48 2 "immediate_operand")))
17519 (clobber (reg:CC FLAGS_REG))])]
17520 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17521 && !satisfies_constraint_K (operands[2])"
17522 [(set (match_dup 3) (match_dup 1))
17523 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17524 (clobber (reg:CC FLAGS_REG))])])
17527 [(match_scratch:SI 3 "r")
17528 (parallel [(set (match_operand:DI 0 "register_operand")
17530 (mult:SI (match_operand:SI 1 "memory_operand")
17531 (match_operand:SI 2 "immediate_operand"))))
17532 (clobber (reg:CC FLAGS_REG))])]
17534 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17535 && !satisfies_constraint_K (operands[2])"
17536 [(set (match_dup 3) (match_dup 1))
17537 (parallel [(set (match_dup 0)
17538 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17539 (clobber (reg:CC FLAGS_REG))])])
17541 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17542 ;; Convert it into imul reg, reg
17543 ;; It would be better to force assembler to encode instruction using long
17544 ;; immediate, but there is apparently no way to do so.
17546 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17548 (match_operand:SWI248 1 "nonimmediate_operand")
17549 (match_operand:SWI248 2 "const_int_operand")))
17550 (clobber (reg:CC FLAGS_REG))])
17551 (match_scratch:SWI248 3 "r")]
17552 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17553 && satisfies_constraint_K (operands[2])"
17554 [(set (match_dup 3) (match_dup 2))
17555 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17556 (clobber (reg:CC FLAGS_REG))])]
17558 if (!rtx_equal_p (operands[0], operands[1]))
17559 emit_move_insn (operands[0], operands[1]);
17562 ;; After splitting up read-modify operations, array accesses with memory
17563 ;; operands might end up in form:
17565 ;; movl 4(%esp), %edx
17567 ;; instead of pre-splitting:
17569 ;; addl 4(%esp), %eax
17571 ;; movl 4(%esp), %edx
17572 ;; leal (%edx,%eax,4), %eax
17575 [(match_scratch:W 5 "r")
17576 (parallel [(set (match_operand 0 "register_operand")
17577 (ashift (match_operand 1 "register_operand")
17578 (match_operand 2 "const_int_operand")))
17579 (clobber (reg:CC FLAGS_REG))])
17580 (parallel [(set (match_operand 3 "register_operand")
17581 (plus (match_dup 0)
17582 (match_operand 4 "x86_64_general_operand")))
17583 (clobber (reg:CC FLAGS_REG))])]
17584 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17585 /* Validate MODE for lea. */
17586 && ((!TARGET_PARTIAL_REG_STALL
17587 && (GET_MODE (operands[0]) == QImode
17588 || GET_MODE (operands[0]) == HImode))
17589 || GET_MODE (operands[0]) == SImode
17590 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17591 && (rtx_equal_p (operands[0], operands[3])
17592 || peep2_reg_dead_p (2, operands[0]))
17593 /* We reorder load and the shift. */
17594 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17595 [(set (match_dup 5) (match_dup 4))
17596 (set (match_dup 0) (match_dup 1))]
17598 enum machine_mode op1mode = GET_MODE (operands[1]);
17599 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17600 int scale = 1 << INTVAL (operands[2]);
17601 rtx index = gen_lowpart (word_mode, operands[1]);
17602 rtx base = gen_lowpart (word_mode, operands[5]);
17603 rtx dest = gen_lowpart (mode, operands[3]);
17605 operands[1] = gen_rtx_PLUS (word_mode, base,
17606 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17607 operands[5] = base;
17608 if (mode != word_mode)
17609 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17610 if (op1mode != word_mode)
17611 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17612 operands[0] = dest;
17615 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17616 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17617 ;; caught for use by garbage collectors and the like. Using an insn that
17618 ;; maps to SIGILL makes it more likely the program will rightfully die.
17619 ;; Keeping with tradition, "6" is in honor of #UD.
17620 (define_insn "trap"
17621 [(trap_if (const_int 1) (const_int 6))]
17623 { return ASM_SHORT "0x0b0f"; }
17624 [(set_attr "length" "2")])
17626 (define_expand "prefetch"
17627 [(prefetch (match_operand 0 "address_operand")
17628 (match_operand:SI 1 "const_int_operand")
17629 (match_operand:SI 2 "const_int_operand"))]
17630 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_AVX512PF"
17632 bool write = INTVAL (operands[1]) != 0;
17633 int locality = INTVAL (operands[2]);
17635 gcc_assert (IN_RANGE (locality, 0, 3));
17637 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17638 supported by SSE counterpart or the SSE prefetch is not available
17639 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17641 if (TARGET_AVX512PF && write)
17642 operands[2] = const1_rtx;
17643 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17644 operands[2] = GEN_INT (3);
17646 operands[1] = const0_rtx;
17649 (define_insn "*prefetch_sse"
17650 [(prefetch (match_operand 0 "address_operand" "p")
17652 (match_operand:SI 1 "const_int_operand"))]
17653 "TARGET_PREFETCH_SSE"
17655 static const char * const patterns[4] = {
17656 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17659 int locality = INTVAL (operands[1]);
17660 gcc_assert (IN_RANGE (locality, 0, 3));
17662 return patterns[locality];
17664 [(set_attr "type" "sse")
17665 (set_attr "atom_sse_attr" "prefetch")
17666 (set (attr "length_address")
17667 (symbol_ref "memory_address_length (operands[0], false)"))
17668 (set_attr "memory" "none")])
17670 (define_insn "*prefetch_3dnow"
17671 [(prefetch (match_operand 0 "address_operand" "p")
17672 (match_operand:SI 1 "const_int_operand" "n")
17676 if (INTVAL (operands[1]) == 0)
17677 return "prefetch\t%a0";
17679 return "prefetchw\t%a0";
17681 [(set_attr "type" "mmx")
17682 (set (attr "length_address")
17683 (symbol_ref "memory_address_length (operands[0], false)"))
17684 (set_attr "memory" "none")])
17686 (define_insn "*prefetch_avx512pf_<mode>"
17687 [(prefetch (match_operand:P 0 "address_operand" "p")
17691 "prefetchwt1\t%a0";
17692 [(set_attr "type" "sse")
17693 (set_attr "prefix" "evex")
17694 (set (attr "length_address")
17695 (symbol_ref "memory_address_length (operands[0], false)"))
17696 (set_attr "memory" "none")])
17698 (define_expand "stack_protect_set"
17699 [(match_operand 0 "memory_operand")
17700 (match_operand 1 "memory_operand")]
17701 "TARGET_SSP_TLS_GUARD"
17703 rtx (*insn)(rtx, rtx);
17705 #ifdef TARGET_THREAD_SSP_OFFSET
17706 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17707 insn = (TARGET_LP64
17708 ? gen_stack_tls_protect_set_di
17709 : gen_stack_tls_protect_set_si);
17711 insn = (TARGET_LP64
17712 ? gen_stack_protect_set_di
17713 : gen_stack_protect_set_si);
17716 emit_insn (insn (operands[0], operands[1]));
17720 (define_insn "stack_protect_set_<mode>"
17721 [(set (match_operand:PTR 0 "memory_operand" "=m")
17722 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17724 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17725 (clobber (reg:CC FLAGS_REG))]
17726 "TARGET_SSP_TLS_GUARD"
17727 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17728 [(set_attr "type" "multi")])
17730 (define_insn "stack_tls_protect_set_<mode>"
17731 [(set (match_operand:PTR 0 "memory_operand" "=m")
17732 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17733 UNSPEC_SP_TLS_SET))
17734 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17735 (clobber (reg:CC FLAGS_REG))]
17737 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17738 [(set_attr "type" "multi")])
17740 (define_expand "stack_protect_test"
17741 [(match_operand 0 "memory_operand")
17742 (match_operand 1 "memory_operand")
17744 "TARGET_SSP_TLS_GUARD"
17746 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17748 rtx (*insn)(rtx, rtx, rtx);
17750 #ifdef TARGET_THREAD_SSP_OFFSET
17751 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17752 insn = (TARGET_LP64
17753 ? gen_stack_tls_protect_test_di
17754 : gen_stack_tls_protect_test_si);
17756 insn = (TARGET_LP64
17757 ? gen_stack_protect_test_di
17758 : gen_stack_protect_test_si);
17761 emit_insn (insn (flags, operands[0], operands[1]));
17763 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17764 flags, const0_rtx, operands[2]));
17768 (define_insn "stack_protect_test_<mode>"
17769 [(set (match_operand:CCZ 0 "flags_reg_operand")
17770 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17771 (match_operand:PTR 2 "memory_operand" "m")]
17773 (clobber (match_scratch:PTR 3 "=&r"))]
17774 "TARGET_SSP_TLS_GUARD"
17775 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17776 [(set_attr "type" "multi")])
17778 (define_insn "stack_tls_protect_test_<mode>"
17779 [(set (match_operand:CCZ 0 "flags_reg_operand")
17780 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17781 (match_operand:PTR 2 "const_int_operand" "i")]
17782 UNSPEC_SP_TLS_TEST))
17783 (clobber (match_scratch:PTR 3 "=r"))]
17785 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17786 [(set_attr "type" "multi")])
17788 (define_insn "sse4_2_crc32<mode>"
17789 [(set (match_operand:SI 0 "register_operand" "=r")
17791 [(match_operand:SI 1 "register_operand" "0")
17792 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17794 "TARGET_SSE4_2 || TARGET_CRC32"
17795 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17796 [(set_attr "type" "sselog1")
17797 (set_attr "prefix_rep" "1")
17798 (set_attr "prefix_extra" "1")
17799 (set (attr "prefix_data16")
17800 (if_then_else (match_operand:HI 2)
17802 (const_string "*")))
17803 (set (attr "prefix_rex")
17804 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17806 (const_string "*")))
17807 (set_attr "mode" "SI")])
17809 (define_insn "sse4_2_crc32di"
17810 [(set (match_operand:DI 0 "register_operand" "=r")
17812 [(match_operand:DI 1 "register_operand" "0")
17813 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17815 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17816 "crc32{q}\t{%2, %0|%0, %2}"
17817 [(set_attr "type" "sselog1")
17818 (set_attr "prefix_rep" "1")
17819 (set_attr "prefix_extra" "1")
17820 (set_attr "mode" "DI")])
17822 (define_insn "rdpmc"
17823 [(set (match_operand:DI 0 "register_operand" "=A")
17824 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17828 [(set_attr "type" "other")
17829 (set_attr "length" "2")])
17831 (define_insn "rdpmc_rex64"
17832 [(set (match_operand:DI 0 "register_operand" "=a")
17833 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17835 (set (match_operand:DI 1 "register_operand" "=d")
17836 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17839 [(set_attr "type" "other")
17840 (set_attr "length" "2")])
17842 (define_insn "rdtsc"
17843 [(set (match_operand:DI 0 "register_operand" "=A")
17844 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17847 [(set_attr "type" "other")
17848 (set_attr "length" "2")])
17850 (define_insn "rdtsc_rex64"
17851 [(set (match_operand:DI 0 "register_operand" "=a")
17852 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17853 (set (match_operand:DI 1 "register_operand" "=d")
17854 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17857 [(set_attr "type" "other")
17858 (set_attr "length" "2")])
17860 (define_insn "rdtscp"
17861 [(set (match_operand:DI 0 "register_operand" "=A")
17862 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17863 (set (match_operand:SI 1 "register_operand" "=c")
17864 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17867 [(set_attr "type" "other")
17868 (set_attr "length" "3")])
17870 (define_insn "rdtscp_rex64"
17871 [(set (match_operand:DI 0 "register_operand" "=a")
17872 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17873 (set (match_operand:DI 1 "register_operand" "=d")
17874 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17875 (set (match_operand:SI 2 "register_operand" "=c")
17876 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17879 [(set_attr "type" "other")
17880 (set_attr "length" "3")])
17882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17884 ;; FXSR, XSAVE and XSAVEOPT instructions
17886 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17888 (define_insn "fxsave"
17889 [(set (match_operand:BLK 0 "memory_operand" "=m")
17890 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17893 [(set_attr "type" "other")
17894 (set_attr "memory" "store")
17895 (set (attr "length")
17896 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17898 (define_insn "fxsave64"
17899 [(set (match_operand:BLK 0 "memory_operand" "=m")
17900 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17901 "TARGET_64BIT && TARGET_FXSR"
17903 [(set_attr "type" "other")
17904 (set_attr "memory" "store")
17905 (set (attr "length")
17906 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17908 (define_insn "fxrstor"
17909 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17913 [(set_attr "type" "other")
17914 (set_attr "memory" "load")
17915 (set (attr "length")
17916 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17918 (define_insn "fxrstor64"
17919 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17920 UNSPECV_FXRSTOR64)]
17921 "TARGET_64BIT && TARGET_FXSR"
17923 [(set_attr "type" "other")
17924 (set_attr "memory" "load")
17925 (set (attr "length")
17926 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17928 (define_int_iterator ANY_XSAVE
17930 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17932 (define_int_iterator ANY_XSAVE64
17934 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17936 (define_int_attr xsave
17937 [(UNSPECV_XSAVE "xsave")
17938 (UNSPECV_XSAVE64 "xsave64")
17939 (UNSPECV_XSAVEOPT "xsaveopt")
17940 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17942 (define_insn "<xsave>"
17943 [(set (match_operand:BLK 0 "memory_operand" "=m")
17944 (unspec_volatile:BLK
17945 [(match_operand:DI 1 "register_operand" "A")]
17947 "!TARGET_64BIT && TARGET_XSAVE"
17949 [(set_attr "type" "other")
17950 (set_attr "memory" "store")
17951 (set (attr "length")
17952 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17954 (define_insn "<xsave>_rex64"
17955 [(set (match_operand:BLK 0 "memory_operand" "=m")
17956 (unspec_volatile:BLK
17957 [(match_operand:SI 1 "register_operand" "a")
17958 (match_operand:SI 2 "register_operand" "d")]
17960 "TARGET_64BIT && TARGET_XSAVE"
17962 [(set_attr "type" "other")
17963 (set_attr "memory" "store")
17964 (set (attr "length")
17965 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17967 (define_insn "<xsave>"
17968 [(set (match_operand:BLK 0 "memory_operand" "=m")
17969 (unspec_volatile:BLK
17970 [(match_operand:SI 1 "register_operand" "a")
17971 (match_operand:SI 2 "register_operand" "d")]
17973 "TARGET_64BIT && TARGET_XSAVE"
17975 [(set_attr "type" "other")
17976 (set_attr "memory" "store")
17977 (set (attr "length")
17978 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17980 (define_insn "xrstor"
17981 [(unspec_volatile:BLK
17982 [(match_operand:BLK 0 "memory_operand" "m")
17983 (match_operand:DI 1 "register_operand" "A")]
17985 "!TARGET_64BIT && TARGET_XSAVE"
17987 [(set_attr "type" "other")
17988 (set_attr "memory" "load")
17989 (set (attr "length")
17990 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17992 (define_insn "xrstor_rex64"
17993 [(unspec_volatile:BLK
17994 [(match_operand:BLK 0 "memory_operand" "m")
17995 (match_operand:SI 1 "register_operand" "a")
17996 (match_operand:SI 2 "register_operand" "d")]
17998 "TARGET_64BIT && TARGET_XSAVE"
18000 [(set_attr "type" "other")
18001 (set_attr "memory" "load")
18002 (set (attr "length")
18003 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18005 (define_insn "xrstor64"
18006 [(unspec_volatile:BLK
18007 [(match_operand:BLK 0 "memory_operand" "m")
18008 (match_operand:SI 1 "register_operand" "a")
18009 (match_operand:SI 2 "register_operand" "d")]
18011 "TARGET_64BIT && TARGET_XSAVE"
18013 [(set_attr "type" "other")
18014 (set_attr "memory" "load")
18015 (set (attr "length")
18016 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18020 ;; LWP instructions
18022 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18024 (define_expand "lwp_llwpcb"
18025 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18026 UNSPECV_LLWP_INTRINSIC)]
18029 (define_insn "*lwp_llwpcb<mode>1"
18030 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18031 UNSPECV_LLWP_INTRINSIC)]
18034 [(set_attr "type" "lwp")
18035 (set_attr "mode" "<MODE>")
18036 (set_attr "length" "5")])
18038 (define_expand "lwp_slwpcb"
18039 [(set (match_operand 0 "register_operand" "=r")
18040 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18045 insn = (Pmode == DImode
18047 : gen_lwp_slwpcbsi);
18049 emit_insn (insn (operands[0]));
18053 (define_insn "lwp_slwpcb<mode>"
18054 [(set (match_operand:P 0 "register_operand" "=r")
18055 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18058 [(set_attr "type" "lwp")
18059 (set_attr "mode" "<MODE>")
18060 (set_attr "length" "5")])
18062 (define_expand "lwp_lwpval<mode>3"
18063 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18064 (match_operand:SI 2 "nonimmediate_operand" "rm")
18065 (match_operand:SI 3 "const_int_operand" "i")]
18066 UNSPECV_LWPVAL_INTRINSIC)]
18068 ;; Avoid unused variable warning.
18069 "(void) operands[0];")
18071 (define_insn "*lwp_lwpval<mode>3_1"
18072 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18073 (match_operand:SI 1 "nonimmediate_operand" "rm")
18074 (match_operand:SI 2 "const_int_operand" "i")]
18075 UNSPECV_LWPVAL_INTRINSIC)]
18077 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18078 [(set_attr "type" "lwp")
18079 (set_attr "mode" "<MODE>")
18080 (set (attr "length")
18081 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18083 (define_expand "lwp_lwpins<mode>3"
18084 [(set (reg:CCC FLAGS_REG)
18085 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18086 (match_operand:SI 2 "nonimmediate_operand" "rm")
18087 (match_operand:SI 3 "const_int_operand" "i")]
18088 UNSPECV_LWPINS_INTRINSIC))
18089 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18090 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18093 (define_insn "*lwp_lwpins<mode>3_1"
18094 [(set (reg:CCC FLAGS_REG)
18095 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18096 (match_operand:SI 1 "nonimmediate_operand" "rm")
18097 (match_operand:SI 2 "const_int_operand" "i")]
18098 UNSPECV_LWPINS_INTRINSIC))]
18100 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18101 [(set_attr "type" "lwp")
18102 (set_attr "mode" "<MODE>")
18103 (set (attr "length")
18104 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18106 (define_int_iterator RDFSGSBASE
18110 (define_int_iterator WRFSGSBASE
18114 (define_int_attr fsgs
18115 [(UNSPECV_RDFSBASE "fs")
18116 (UNSPECV_RDGSBASE "gs")
18117 (UNSPECV_WRFSBASE "fs")
18118 (UNSPECV_WRGSBASE "gs")])
18120 (define_insn "rd<fsgs>base<mode>"
18121 [(set (match_operand:SWI48 0 "register_operand" "=r")
18122 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18123 "TARGET_64BIT && TARGET_FSGSBASE"
18125 [(set_attr "type" "other")
18126 (set_attr "prefix_extra" "2")])
18128 (define_insn "wr<fsgs>base<mode>"
18129 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18131 "TARGET_64BIT && TARGET_FSGSBASE"
18133 [(set_attr "type" "other")
18134 (set_attr "prefix_extra" "2")])
18136 (define_insn "rdrand<mode>_1"
18137 [(set (match_operand:SWI248 0 "register_operand" "=r")
18138 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18139 (set (reg:CCC FLAGS_REG)
18140 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18143 [(set_attr "type" "other")
18144 (set_attr "prefix_extra" "1")])
18146 (define_insn "rdseed<mode>_1"
18147 [(set (match_operand:SWI248 0 "register_operand" "=r")
18148 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18149 (set (reg:CCC FLAGS_REG)
18150 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18153 [(set_attr "type" "other")
18154 (set_attr "prefix_extra" "1")])
18156 (define_expand "pause"
18157 [(set (match_dup 0)
18158 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18161 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18162 MEM_VOLATILE_P (operands[0]) = 1;
18165 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18166 ;; They have the same encoding.
18167 (define_insn "*pause"
18168 [(set (match_operand:BLK 0)
18169 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18172 [(set_attr "length" "2")
18173 (set_attr "memory" "unknown")])
18175 (define_expand "xbegin"
18176 [(set (match_operand:SI 0 "register_operand")
18177 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18180 rtx label = gen_label_rtx ();
18182 /* xbegin is emitted as jump_insn, so reload won't be able
18183 to reload its operand. Force the value into AX hard register. */
18184 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18185 emit_move_insn (ax_reg, constm1_rtx);
18187 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18189 emit_label (label);
18190 LABEL_NUSES (label) = 1;
18192 emit_move_insn (operands[0], ax_reg);
18197 (define_insn "xbegin_1"
18199 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18201 (label_ref (match_operand 1))
18203 (set (match_operand:SI 0 "register_operand" "+a")
18204 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18207 [(set_attr "type" "other")
18208 (set_attr "length" "6")])
18210 (define_insn "xend"
18211 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18214 [(set_attr "type" "other")
18215 (set_attr "length" "3")])
18217 (define_insn "xabort"
18218 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18222 [(set_attr "type" "other")
18223 (set_attr "length" "3")])
18225 (define_expand "xtest"
18226 [(set (match_operand:QI 0 "register_operand")
18227 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18230 emit_insn (gen_xtest_1 ());
18232 ix86_expand_setcc (operands[0], NE,
18233 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18237 (define_insn "xtest_1"
18238 [(set (reg:CCZ FLAGS_REG)
18239 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18242 [(set_attr "type" "other")
18243 (set_attr "length" "3")])
18245 ;; MPX instructions
18247 (define_expand "<mode>_mk"
18248 [(set (match_operand:BND 0 "register_operand")
18252 [(match_operand:<bnd_ptr> 1 "register_operand")
18253 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18257 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18259 UNSPEC_BNDMK_ADDR);
18262 (define_insn "*<mode>_mk"
18263 [(set (match_operand:BND 0 "register_operand" "=B")
18265 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18267 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18268 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18269 UNSPEC_BNDMK_ADDR)])]
18272 "bndmk\t{%3, %0|%0, %3}"
18273 [(set_attr "type" "mpxmk")])
18275 (define_expand "mov<mode>"
18276 [(set (match_operand:BND 0 "general_operand")
18277 (match_operand:BND 1 "general_operand"))]
18280 ix86_expand_move (<MODE>mode, operands);DONE;
18283 (define_insn "*mov<mode>_internal_mpx"
18284 [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m")
18285 (match_operand:BND 1 "general_operand" "Bm,B"))]
18287 "bndmov\t{%1, %0|%0, %1}"
18288 [(set_attr "type" "mpxmov")])
18290 (define_expand "<mode>_<bndcheck>"
18291 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18292 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18294 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18297 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18298 MEM_VOLATILE_P (operands[2]) = 1;
18301 (define_insn "*<mode>_<bndcheck>"
18302 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
18303 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "p")] BNDCHECK)
18304 (set (match_operand:BLK 2 "bnd_mem_operator")
18305 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18307 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18308 [(set_attr "type" "mpxchk")])
18310 (define_expand "<mode>_ldx"
18311 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18315 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18316 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18318 (use (mem:BLK (match_dup 1)))])]
18321 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18323 UNSPEC_BNDLDX_ADDR);
18326 (define_insn "*<mode>_ldx"
18327 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
18329 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18331 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18332 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18333 UNSPEC_BNDLDX_ADDR)])]
18335 (use (mem:BLK (match_dup 1)))])]
18337 "bndldx\t{%3, %0|%0, %3}"
18338 [(set_attr "type" "mpxld")])
18340 (define_expand "<mode>_stx"
18341 [(parallel [(unspec [(mem:<bnd_ptr>
18343 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18344 (match_operand:<bnd_ptr> 1 "register_operand")]))
18345 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18347 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18350 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18352 UNSPEC_BNDLDX_ADDR);
18353 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18354 MEM_VOLATILE_P (operands[4]) = 1;
18357 (define_insn "*<mode>_stx"
18358 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18360 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18361 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18362 UNSPEC_BNDLDX_ADDR)])
18363 (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
18364 (set (match_operand:BLK 4 "bnd_mem_operator")
18365 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18367 "bndstx\t{%2, %3|%3, %2}"
18368 [(set_attr "type" "mpxst")])
18372 (include "sync.md")