1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
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 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
108 UNSPEC_CALL_NEEDS_VZEROUPPER
110 ;; For SSE/MMX support:
128 UNSPEC_MS_TO_SYSV_CALL
130 ;; Generic math support
132 UNSPEC_IEEE_MIN ; not commutative
133 UNSPEC_IEEE_MAX ; not commutative
135 ;; x87 Floating point
151 UNSPEC_FRNDINT_MASK_PM
155 ;; x87 Double output FP
187 ;; For SSE4.1 support
197 ;; For SSE4.2 support
204 UNSPEC_XOP_UNSIGNED_CMP
215 UNSPEC_AESKEYGENASSIST
217 ;; For PCLMUL support
233 (define_c_enum "unspecv" [
236 UNSPECV_PROBE_STACK_RANGE
256 UNSPECV_LLWP_INTRINSIC
257 UNSPECV_SLWP_INTRINSIC
258 UNSPECV_LWPVAL_INTRINSIC
259 UNSPECV_LWPINS_INTRINSIC
265 UNSPECV_SPLIT_STACK_RETURN
268 ;; Constants to represent pcomtrue/pcomfalse variants
278 ;; Constants used in the XOP pperm instruction
280 [(PPERM_SRC 0x00) /* copy source */
281 (PPERM_INVERT 0x20) /* invert source */
282 (PPERM_REVERSE 0x40) /* bit reverse source */
283 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
284 (PPERM_ZERO 0x80) /* all 0's */
285 (PPERM_ONES 0xa0) /* all 1's */
286 (PPERM_SIGN 0xc0) /* propagate sign bit */
287 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
288 (PPERM_SRC1 0x00) /* use first source byte */
289 (PPERM_SRC2 0x10) /* use second source byte */
292 ;; Registers by name.
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first. This allows for better optimization. For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356 generic64,amdfam10,bdver1"
357 (const (symbol_ref "ix86_schedule")))
359 ;; A basic instruction type. Refinements due to arguments to be
360 ;; provided in other attributes.
363 alu,alu1,negnot,imov,imovx,lea,
364 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365 icmp,test,ibr,setcc,icmov,
366 push,pop,call,callv,leave,
368 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371 ssemuladd,sse4arg,lwp,
372 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373 (const_string "other"))
375 ;; Main data type used by the insn
377 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378 (const_string "unknown"))
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383 (const_string "i387")
384 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
388 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
390 (eq_attr "type" "other")
391 (const_string "unknown")]
392 (const_string "integer")))
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
399 (eq_attr "unit" "i387,sse,mmx")
401 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
403 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404 (eq_attr "type" "imov,test")
405 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406 (eq_attr "type" "call")
407 (if_then_else (match_operand 0 "constant_call_address_operand" "")
410 (eq_attr "type" "callv")
411 (if_then_else (match_operand 1 "constant_call_address_operand" "")
414 ;; We don't know the size before shorten_branches. Expect
415 ;; the instruction to fit for better scheduling.
416 (eq_attr "type" "ibr")
419 (symbol_ref "/* Update immediate_length and other attributes! */
420 gcc_unreachable (),1")))
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424 (cond [(eq_attr "type" "str,other,multi,fxch")
426 (and (eq_attr "type" "call")
427 (match_operand 0 "constant_call_address_operand" ""))
429 (and (eq_attr "type" "callv")
430 (match_operand 1 "constant_call_address_operand" ""))
433 (symbol_ref "ix86_attr_length_address_default (insn)")))
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (eq_attr "mode" "HI")
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
450 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
458 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459 (eq_attr "unit" "sse,mmx"))
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
467 (and (eq_attr "mode" "DI")
468 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469 (eq_attr "unit" "!mmx")))
471 (and (eq_attr "mode" "QI")
472 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
475 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
478 (and (eq_attr "type" "imovx")
479 (match_operand:QI 1 "ext_QIreg_operand" ""))
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg")
491 (eq_attr "type" "sseiadd1,ssecvt1")
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
500 (const_string "orig")))
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510 (if_then_else (and (eq_attr "prefix_0f" "1")
511 (eq_attr "prefix_extra" "0"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515 (if_then_else (eq_attr "prefix_vex_w" "1")
516 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521 (cond [(eq_attr "type" "str,leave")
523 (eq_attr "unit" "i387")
525 (and (eq_attr "type" "incdec")
526 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527 (ior (match_operand:SI 1 "register_operand" "")
528 (match_operand:HI 1 "register_operand" ""))))
530 (and (eq_attr "type" "push")
531 (not (match_operand 1 "memory_operand" "")))
533 (and (eq_attr "type" "pop")
534 (not (match_operand 0 "memory_operand" "")))
536 (and (eq_attr "type" "imov")
537 (and (not (eq_attr "mode" "DI"))
538 (ior (and (match_operand 0 "register_operand" "")
539 (match_operand 1 "immediate_operand" ""))
540 (ior (and (match_operand 0 "ax_reg_operand" "")
541 (match_operand 1 "memory_displacement_only_operand" ""))
542 (and (match_operand 0 "memory_displacement_only_operand" "")
543 (match_operand 1 "ax_reg_operand" ""))))))
545 (and (eq_attr "type" "call")
546 (match_operand 0 "constant_call_address_operand" ""))
548 (and (eq_attr "type" "callv")
549 (match_operand 1 "constant_call_address_operand" ""))
551 (and (eq_attr "type" "alu,alu1,icmp,test")
552 (match_operand 0 "ax_reg_operand" ""))
553 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
561 (define_attr "length" ""
562 (cond [(eq_attr "type" "other,multi,fistp,frndint")
564 (eq_attr "type" "fcmp")
566 (eq_attr "unit" "i387")
568 (plus (attr "prefix_data16")
569 (attr "length_address")))
570 (ior (eq_attr "prefix" "vex")
571 (and (eq_attr "prefix" "maybe_vex")
572 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573 (plus (attr "length_vex")
574 (plus (attr "length_immediate")
576 (attr "length_address"))))]
577 (plus (plus (attr "modrm")
578 (plus (attr "prefix_0f")
579 (plus (attr "prefix_rex")
580 (plus (attr "prefix_extra")
582 (plus (attr "prefix_rep")
583 (plus (attr "prefix_data16")
584 (plus (attr "length_immediate")
585 (attr "length_address")))))))
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
591 (define_attr "memory" "none,load,store,both,unknown"
592 (cond [(eq_attr "type" "other,multi,str,lwp")
593 (const_string "unknown")
594 (eq_attr "type" "lea,fcmov,fpspc")
595 (const_string "none")
596 (eq_attr "type" "fistp,leave")
597 (const_string "both")
598 (eq_attr "type" "frndint")
599 (const_string "load")
600 (eq_attr "type" "push")
601 (if_then_else (match_operand 1 "memory_operand" "")
602 (const_string "both")
603 (const_string "store"))
604 (eq_attr "type" "pop")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "both")
607 (const_string "load"))
608 (eq_attr "type" "setcc")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "store")
611 (const_string "none"))
612 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613 (if_then_else (ior (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "ibr")
618 (if_then_else (match_operand 0 "memory_operand" "")
619 (const_string "load")
620 (const_string "none"))
621 (eq_attr "type" "call")
622 (if_then_else (match_operand 0 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (eq_attr "type" "callv")
626 (if_then_else (match_operand 1 "constant_call_address_operand" "")
627 (const_string "none")
628 (const_string "load"))
629 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (and (match_operand 0 "memory_operand" "")
633 (match_operand 1 "memory_operand" ""))
634 (const_string "both")
635 (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (match_operand 1 "memory_operand" "")
638 (const_string "load")
640 "!alu1,negnot,ishift1,
641 imov,imovx,icmp,test,bitmanip,
643 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645 (match_operand 2 "memory_operand" ""))
646 (const_string "load")
647 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648 (match_operand 3 "memory_operand" ""))
649 (const_string "load")
651 (const_string "none")))
653 ;; Indicates if an instruction has both an immediate and a displacement.
655 (define_attr "imm_disp" "false,true,unknown"
656 (cond [(eq_attr "type" "other,multi")
657 (const_string "unknown")
658 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 1 "immediate_operand" "")))
661 (const_string "true")
662 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663 (and (match_operand 0 "memory_displacement_operand" "")
664 (match_operand 2 "immediate_operand" "")))
665 (const_string "true")
667 (const_string "false")))
669 ;; Indicates if an FP operation has an integer source.
671 (define_attr "fp_int_src" "false,true"
672 (const_string "false"))
674 ;; Defines rounding mode of an FP operation.
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677 (const_string "any"))
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
690 (define_code_iterator plusminus [plus minus])
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701 [(plus "add") (ss_plus "adds") (us_plus "addus")
702 (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757 (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765 (div "i") (udiv "")])
767 ;; 64bit single word integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
770 ;; 64bit single word integer modes without QImode and HImode.
771 (define_mode_iterator SWI48x [SI DI])
773 ;; Single word integer modes.
774 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
776 ;; Single word integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
779 ;; Single word integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
782 ;; Single word integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
785 ;; Single word integer modes without QImode.
786 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
788 ;; Single word integer modes without QImode and HImode.
789 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
791 ;; All math-dependant single and double word integer modes.
792 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
793 (HI "TARGET_HIMODE_MATH")
794 SI DI (TI "TARGET_64BIT")])
796 ;; Math-dependant single word integer modes.
797 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
798 (HI "TARGET_HIMODE_MATH")
799 SI (DI "TARGET_64BIT")])
801 ;; Math-dependant single word integer modes without DImode.
802 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
803 (HI "TARGET_HIMODE_MATH")
806 ;; Math-dependant single word integer modes without QImode.
807 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
808 SI (DI "TARGET_64BIT")])
810 ;; Double word integer modes.
811 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
812 (TI "TARGET_64BIT")])
814 ;; Double word integer modes as mode attribute.
815 (define_mode_attr DWI [(SI "DI") (DI "TI")])
816 (define_mode_attr dwi [(SI "di") (DI "ti")])
818 ;; Half mode for double word integer modes.
819 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
820 (DI "TARGET_64BIT")])
822 ;; Instruction suffix for integer modes.
823 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
825 ;; Pointer size prefix for integer modes (Intel asm dialect)
826 (define_mode_attr iptrsize [(QI "BYTE")
831 ;; Register class for integer modes.
832 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
834 ;; Immediate operand constraint for integer modes.
835 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
837 ;; General operand constraint for word modes.
838 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
840 ;; Immediate operand constraint for double integer modes.
841 (define_mode_attr di [(SI "iF") (DI "e")])
843 ;; Immediate operand constraint for shifts.
844 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
846 ;; General operand predicate for integer modes.
847 (define_mode_attr general_operand
848 [(QI "general_operand")
849 (HI "general_operand")
850 (SI "general_operand")
851 (DI "x86_64_general_operand")
852 (TI "x86_64_general_operand")])
854 ;; General sign/zero extend operand predicate for integer modes.
855 (define_mode_attr general_szext_operand
856 [(QI "general_operand")
857 (HI "general_operand")
858 (SI "general_operand")
859 (DI "x86_64_szext_general_operand")])
861 ;; Immediate operand predicate for integer modes.
862 (define_mode_attr immediate_operand
863 [(QI "immediate_operand")
864 (HI "immediate_operand")
865 (SI "immediate_operand")
866 (DI "x86_64_immediate_operand")])
868 ;; Nonmemory operand predicate for integer modes.
869 (define_mode_attr nonmemory_operand
870 [(QI "nonmemory_operand")
871 (HI "nonmemory_operand")
872 (SI "nonmemory_operand")
873 (DI "x86_64_nonmemory_operand")])
875 ;; Operand predicate for shifts.
876 (define_mode_attr shift_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "shiftdi_operand")
881 (TI "register_operand")])
883 ;; Operand predicate for shift argument.
884 (define_mode_attr shift_immediate_operand
885 [(QI "const_1_to_31_operand")
886 (HI "const_1_to_31_operand")
887 (SI "const_1_to_31_operand")
888 (DI "const_1_to_63_operand")])
890 ;; Input operand predicate for arithmetic left shifts.
891 (define_mode_attr ashl_input_operand
892 [(QI "nonimmediate_operand")
893 (HI "nonimmediate_operand")
894 (SI "nonimmediate_operand")
895 (DI "ashldi_input_operand")
896 (TI "reg_or_pm1_operand")])
898 ;; SSE and x87 SFmode and DFmode floating point modes
899 (define_mode_iterator MODEF [SF DF])
901 ;; All x87 floating point modes
902 (define_mode_iterator X87MODEF [SF DF XF])
904 ;; All integer modes handled by x87 fisttp operator.
905 (define_mode_iterator X87MODEI [HI SI DI])
907 ;; All integer modes handled by integer x87 operators.
908 (define_mode_iterator X87MODEI12 [HI SI])
910 ;; All integer modes handled by SSE cvtts?2si* operators.
911 (define_mode_iterator SSEMODEI24 [SI DI])
913 ;; SSE asm suffix for floating point modes
914 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
916 ;; SSE vector mode corresponding to a scalar mode
917 (define_mode_attr ssevecmode
918 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
920 ;; Instruction suffix for REX 64bit operators.
921 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
923 ;; This mode iterator allows :P to be used for patterns that operate on
924 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
925 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
927 ;; Scheduling descriptions
929 (include "pentium.md")
932 (include "athlon.md")
933 (include "bdver1.md")
938 ;; Operand and operator predicates and constraints
940 (include "predicates.md")
941 (include "constraints.md")
944 ;; Compare and branch/compare and store instructions.
946 (define_expand "cbranch<mode>4"
947 [(set (reg:CC FLAGS_REG)
948 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
949 (match_operand:SDWIM 2 "<general_operand>" "")))
950 (set (pc) (if_then_else
951 (match_operator 0 "ordered_comparison_operator"
952 [(reg:CC FLAGS_REG) (const_int 0)])
953 (label_ref (match_operand 3 "" ""))
957 if (MEM_P (operands[1]) && MEM_P (operands[2]))
958 operands[1] = force_reg (<MODE>mode, operands[1]);
959 ix86_expand_branch (GET_CODE (operands[0]),
960 operands[1], operands[2], operands[3]);
964 (define_expand "cstore<mode>4"
965 [(set (reg:CC FLAGS_REG)
966 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
967 (match_operand:SWIM 3 "<general_operand>" "")))
968 (set (match_operand:QI 0 "register_operand" "")
969 (match_operator 1 "ordered_comparison_operator"
970 [(reg:CC FLAGS_REG) (const_int 0)]))]
973 if (MEM_P (operands[2]) && MEM_P (operands[3]))
974 operands[2] = force_reg (<MODE>mode, operands[2]);
975 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
976 operands[2], operands[3]);
980 (define_expand "cmp<mode>_1"
981 [(set (reg:CC FLAGS_REG)
982 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
983 (match_operand:SWI48 1 "<general_operand>" "")))])
985 (define_insn "*cmp<mode>_ccno_1"
986 [(set (reg FLAGS_REG)
987 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
988 (match_operand:SWI 1 "const0_operand" "")))]
989 "ix86_match_ccmode (insn, CCNOmode)"
991 test{<imodesuffix>}\t%0, %0
992 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
993 [(set_attr "type" "test,icmp")
994 (set_attr "length_immediate" "0,1")
995 (set_attr "mode" "<MODE>")])
997 (define_insn "*cmp<mode>_1"
998 [(set (reg FLAGS_REG)
999 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1000 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1001 "ix86_match_ccmode (insn, CCmode)"
1002 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1003 [(set_attr "type" "icmp")
1004 (set_attr "mode" "<MODE>")])
1006 (define_insn "*cmp<mode>_minus_1"
1007 [(set (reg FLAGS_REG)
1009 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1010 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1012 "ix86_match_ccmode (insn, CCGOCmode)"
1013 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1014 [(set_attr "type" "icmp")
1015 (set_attr "mode" "<MODE>")])
1017 (define_insn "*cmpqi_ext_1"
1018 [(set (reg FLAGS_REG)
1020 (match_operand:QI 0 "general_operand" "Qm")
1023 (match_operand 1 "ext_register_operand" "Q")
1025 (const_int 8)) 0)))]
1026 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1027 "cmp{b}\t{%h1, %0|%0, %h1}"
1028 [(set_attr "type" "icmp")
1029 (set_attr "mode" "QI")])
1031 (define_insn "*cmpqi_ext_1_rex64"
1032 [(set (reg FLAGS_REG)
1034 (match_operand:QI 0 "register_operand" "Q")
1037 (match_operand 1 "ext_register_operand" "Q")
1039 (const_int 8)) 0)))]
1040 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1041 "cmp{b}\t{%h1, %0|%0, %h1}"
1042 [(set_attr "type" "icmp")
1043 (set_attr "mode" "QI")])
1045 (define_insn "*cmpqi_ext_2"
1046 [(set (reg FLAGS_REG)
1050 (match_operand 0 "ext_register_operand" "Q")
1053 (match_operand:QI 1 "const0_operand" "")))]
1054 "ix86_match_ccmode (insn, CCNOmode)"
1056 [(set_attr "type" "test")
1057 (set_attr "length_immediate" "0")
1058 (set_attr "mode" "QI")])
1060 (define_expand "cmpqi_ext_3"
1061 [(set (reg:CC FLAGS_REG)
1065 (match_operand 0 "ext_register_operand" "")
1068 (match_operand:QI 1 "immediate_operand" "")))])
1070 (define_insn "*cmpqi_ext_3_insn"
1071 [(set (reg FLAGS_REG)
1075 (match_operand 0 "ext_register_operand" "Q")
1078 (match_operand:QI 1 "general_operand" "Qmn")))]
1079 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1080 "cmp{b}\t{%1, %h0|%h0, %1}"
1081 [(set_attr "type" "icmp")
1082 (set_attr "modrm" "1")
1083 (set_attr "mode" "QI")])
1085 (define_insn "*cmpqi_ext_3_insn_rex64"
1086 [(set (reg FLAGS_REG)
1090 (match_operand 0 "ext_register_operand" "Q")
1093 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1094 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1095 "cmp{b}\t{%1, %h0|%h0, %1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "modrm" "1")
1098 (set_attr "mode" "QI")])
1100 (define_insn "*cmpqi_ext_4"
1101 [(set (reg FLAGS_REG)
1105 (match_operand 0 "ext_register_operand" "Q")
1110 (match_operand 1 "ext_register_operand" "Q")
1112 (const_int 8)) 0)))]
1113 "ix86_match_ccmode (insn, CCmode)"
1114 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1115 [(set_attr "type" "icmp")
1116 (set_attr "mode" "QI")])
1118 ;; These implement float point compares.
1119 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1120 ;; which would allow mix and match FP modes on the compares. Which is what
1121 ;; the old patterns did, but with many more of them.
1123 (define_expand "cbranchxf4"
1124 [(set (reg:CC FLAGS_REG)
1125 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1126 (match_operand:XF 2 "nonmemory_operand" "")))
1127 (set (pc) (if_then_else
1128 (match_operator 0 "ix86_fp_comparison_operator"
1131 (label_ref (match_operand 3 "" ""))
1135 ix86_expand_branch (GET_CODE (operands[0]),
1136 operands[1], operands[2], operands[3]);
1140 (define_expand "cstorexf4"
1141 [(set (reg:CC FLAGS_REG)
1142 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1143 (match_operand:XF 3 "nonmemory_operand" "")))
1144 (set (match_operand:QI 0 "register_operand" "")
1145 (match_operator 1 "ix86_fp_comparison_operator"
1150 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1151 operands[2], operands[3]);
1155 (define_expand "cbranch<mode>4"
1156 [(set (reg:CC FLAGS_REG)
1157 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1158 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1159 (set (pc) (if_then_else
1160 (match_operator 0 "ix86_fp_comparison_operator"
1163 (label_ref (match_operand 3 "" ""))
1165 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1167 ix86_expand_branch (GET_CODE (operands[0]),
1168 operands[1], operands[2], operands[3]);
1172 (define_expand "cstore<mode>4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1175 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1176 (set (match_operand:QI 0 "register_operand" "")
1177 (match_operator 1 "ix86_fp_comparison_operator"
1180 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1182 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183 operands[2], operands[3]);
1187 (define_expand "cbranchcc4"
1188 [(set (pc) (if_then_else
1189 (match_operator 0 "comparison_operator"
1190 [(match_operand 1 "flags_reg_operand" "")
1191 (match_operand 2 "const0_operand" "")])
1192 (label_ref (match_operand 3 "" ""))
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstorecc4"
1202 [(set (match_operand:QI 0 "register_operand" "")
1203 (match_operator 1 "comparison_operator"
1204 [(match_operand 2 "flags_reg_operand" "")
1205 (match_operand 3 "const0_operand" "")]))]
1208 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1209 operands[2], operands[3]);
1214 ;; FP compares, step 1:
1215 ;; Set the FP condition codes.
1217 ;; CCFPmode compare with exceptions
1218 ;; CCFPUmode compare with no exceptions
1220 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1221 ;; used to manage the reg stack popping would not be preserved.
1223 (define_insn "*cmpfp_0"
1224 [(set (match_operand:HI 0 "register_operand" "=a")
1227 (match_operand 1 "register_operand" "f")
1228 (match_operand 2 "const0_operand" ""))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1232 "* return output_fp_compare (insn, operands, 0, 0);"
1233 [(set_attr "type" "multi")
1234 (set_attr "unit" "i387")
1236 (cond [(match_operand:SF 1 "" "")
1238 (match_operand:DF 1 "" "")
1241 (const_string "XF")))])
1243 (define_insn_and_split "*cmpfp_0_cc"
1244 [(set (reg:CCFP FLAGS_REG)
1246 (match_operand 1 "register_operand" "f")
1247 (match_operand 2 "const0_operand" "")))
1248 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1249 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1250 && TARGET_SAHF && !TARGET_CMOVE
1251 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1253 "&& reload_completed"
1256 [(compare:CCFP (match_dup 1)(match_dup 2))]
1258 (set (reg:CC FLAGS_REG)
1259 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1261 [(set_attr "type" "multi")
1262 (set_attr "unit" "i387")
1264 (cond [(match_operand:SF 1 "" "")
1266 (match_operand:DF 1 "" "")
1269 (const_string "XF")))])
1271 (define_insn "*cmpfp_xf"
1272 [(set (match_operand:HI 0 "register_operand" "=a")
1275 (match_operand:XF 1 "register_operand" "f")
1276 (match_operand:XF 2 "register_operand" "f"))]
1279 "* return output_fp_compare (insn, operands, 0, 0);"
1280 [(set_attr "type" "multi")
1281 (set_attr "unit" "i387")
1282 (set_attr "mode" "XF")])
1284 (define_insn_and_split "*cmpfp_xf_cc"
1285 [(set (reg:CCFP FLAGS_REG)
1287 (match_operand:XF 1 "register_operand" "f")
1288 (match_operand:XF 2 "register_operand" "f")))
1289 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1291 && TARGET_SAHF && !TARGET_CMOVE"
1293 "&& reload_completed"
1296 [(compare:CCFP (match_dup 1)(match_dup 2))]
1298 (set (reg:CC FLAGS_REG)
1299 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1301 [(set_attr "type" "multi")
1302 (set_attr "unit" "i387")
1303 (set_attr "mode" "XF")])
1305 (define_insn "*cmpfp_<mode>"
1306 [(set (match_operand:HI 0 "register_operand" "=a")
1309 (match_operand:MODEF 1 "register_operand" "f")
1310 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1313 "* return output_fp_compare (insn, operands, 0, 0);"
1314 [(set_attr "type" "multi")
1315 (set_attr "unit" "i387")
1316 (set_attr "mode" "<MODE>")])
1318 (define_insn_and_split "*cmpfp_<mode>_cc"
1319 [(set (reg:CCFP FLAGS_REG)
1321 (match_operand:MODEF 1 "register_operand" "f")
1322 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1323 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325 && TARGET_SAHF && !TARGET_CMOVE"
1327 "&& reload_completed"
1330 [(compare:CCFP (match_dup 1)(match_dup 2))]
1332 (set (reg:CC FLAGS_REG)
1333 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "<MODE>")])
1339 (define_insn "*cmpfp_u"
1340 [(set (match_operand:HI 0 "register_operand" "=a")
1343 (match_operand 1 "register_operand" "f")
1344 (match_operand 2 "register_operand" "f"))]
1346 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1348 "* return output_fp_compare (insn, operands, 0, 1);"
1349 [(set_attr "type" "multi")
1350 (set_attr "unit" "i387")
1352 (cond [(match_operand:SF 1 "" "")
1354 (match_operand:DF 1 "" "")
1357 (const_string "XF")))])
1359 (define_insn_and_split "*cmpfp_u_cc"
1360 [(set (reg:CCFPU FLAGS_REG)
1362 (match_operand 1 "register_operand" "f")
1363 (match_operand 2 "register_operand" "f")))
1364 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1365 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1366 && TARGET_SAHF && !TARGET_CMOVE
1367 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1369 "&& reload_completed"
1372 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1374 (set (reg:CC FLAGS_REG)
1375 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1377 [(set_attr "type" "multi")
1378 (set_attr "unit" "i387")
1380 (cond [(match_operand:SF 1 "" "")
1382 (match_operand:DF 1 "" "")
1385 (const_string "XF")))])
1387 (define_insn "*cmpfp_<mode>"
1388 [(set (match_operand:HI 0 "register_operand" "=a")
1391 (match_operand 1 "register_operand" "f")
1392 (match_operator 3 "float_operator"
1393 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1396 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1397 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1398 "* return output_fp_compare (insn, operands, 0, 0);"
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "fp_int_src" "true")
1402 (set_attr "mode" "<MODE>")])
1404 (define_insn_and_split "*cmpfp_<mode>_cc"
1405 [(set (reg:CCFP FLAGS_REG)
1407 (match_operand 1 "register_operand" "f")
1408 (match_operator 3 "float_operator"
1409 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1410 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1411 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1412 && TARGET_SAHF && !TARGET_CMOVE
1413 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1414 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1416 "&& reload_completed"
1421 (match_op_dup 3 [(match_dup 2)]))]
1423 (set (reg:CC FLAGS_REG)
1424 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1426 [(set_attr "type" "multi")
1427 (set_attr "unit" "i387")
1428 (set_attr "fp_int_src" "true")
1429 (set_attr "mode" "<MODE>")])
1431 ;; FP compares, step 2
1432 ;; Move the fpsw to ax.
1434 (define_insn "x86_fnstsw_1"
1435 [(set (match_operand:HI 0 "register_operand" "=a")
1436 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1439 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1440 (set_attr "mode" "SI")
1441 (set_attr "unit" "i387")])
1443 ;; FP compares, step 3
1444 ;; Get ax into flags, general case.
1446 (define_insn "x86_sahf_1"
1447 [(set (reg:CC FLAGS_REG)
1448 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1452 #ifndef HAVE_AS_IX86_SAHF
1454 return ASM_BYTE "0x9e";
1459 [(set_attr "length" "1")
1460 (set_attr "athlon_decode" "vector")
1461 (set_attr "amdfam10_decode" "direct")
1462 (set_attr "bdver1_decode" "direct")
1463 (set_attr "mode" "SI")])
1465 ;; Pentium Pro can do steps 1 through 3 in one go.
1466 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1467 (define_insn "*cmpfp_i_mixed"
1468 [(set (reg:CCFP FLAGS_REG)
1469 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1470 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1471 "TARGET_MIX_SSE_I387
1472 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1473 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1474 "* return output_fp_compare (insn, operands, 1, 0);"
1475 [(set_attr "type" "fcmp,ssecomi")
1476 (set_attr "prefix" "orig,maybe_vex")
1478 (if_then_else (match_operand:SF 1 "" "")
1480 (const_string "DF")))
1481 (set (attr "prefix_rep")
1482 (if_then_else (eq_attr "type" "ssecomi")
1484 (const_string "*")))
1485 (set (attr "prefix_data16")
1486 (cond [(eq_attr "type" "fcmp")
1488 (eq_attr "mode" "DF")
1491 (const_string "0")))
1492 (set_attr "athlon_decode" "vector")
1493 (set_attr "amdfam10_decode" "direct")
1494 (set_attr "bdver1_decode" "double")])
1496 (define_insn "*cmpfp_i_sse"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "x")
1499 (match_operand 1 "nonimmediate_operand" "xm")))]
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, 1, 0);"
1504 [(set_attr "type" "ssecomi")
1505 (set_attr "prefix" "maybe_vex")
1507 (if_then_else (match_operand:SF 1 "" "")
1509 (const_string "DF")))
1510 (set_attr "prefix_rep" "0")
1511 (set (attr "prefix_data16")
1512 (if_then_else (eq_attr "mode" "DF")
1514 (const_string "0")))
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")
1517 (set_attr "bdver1_decode" "double")])
1519 (define_insn "*cmpfp_i_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1521 (compare:CCFP (match_operand 0 "register_operand" "f")
1522 (match_operand 1 "register_operand" "f")))]
1523 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1526 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527 "* return output_fp_compare (insn, operands, 1, 0);"
1528 [(set_attr "type" "fcmp")
1530 (cond [(match_operand:SF 1 "" "")
1532 (match_operand:DF 1 "" "")
1535 (const_string "XF")))
1536 (set_attr "athlon_decode" "vector")
1537 (set_attr "amdfam10_decode" "direct")
1538 (set_attr "bdver1_decode" "double")])
1540 (define_insn "*cmpfp_iu_mixed"
1541 [(set (reg:CCFPU FLAGS_REG)
1542 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1543 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1544 "TARGET_MIX_SSE_I387
1545 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1546 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1547 "* return output_fp_compare (insn, operands, 1, 1);"
1548 [(set_attr "type" "fcmp,ssecomi")
1549 (set_attr "prefix" "orig,maybe_vex")
1551 (if_then_else (match_operand:SF 1 "" "")
1553 (const_string "DF")))
1554 (set (attr "prefix_rep")
1555 (if_then_else (eq_attr "type" "ssecomi")
1557 (const_string "*")))
1558 (set (attr "prefix_data16")
1559 (cond [(eq_attr "type" "fcmp")
1561 (eq_attr "mode" "DF")
1564 (const_string "0")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1569 (define_insn "*cmpfp_iu_sse"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "x")
1572 (match_operand 1 "nonimmediate_operand" "xm")))]
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, 1, 1);"
1577 [(set_attr "type" "ssecomi")
1578 (set_attr "prefix" "maybe_vex")
1580 (if_then_else (match_operand:SF 1 "" "")
1582 (const_string "DF")))
1583 (set_attr "prefix_rep" "0")
1584 (set (attr "prefix_data16")
1585 (if_then_else (eq_attr "mode" "DF")
1587 (const_string "0")))
1588 (set_attr "athlon_decode" "vector")
1589 (set_attr "amdfam10_decode" "direct")
1590 (set_attr "bdver1_decode" "double")])
1592 (define_insn "*cmpfp_iu_387"
1593 [(set (reg:CCFPU FLAGS_REG)
1594 (compare:CCFPU (match_operand 0 "register_operand" "f")
1595 (match_operand 1 "register_operand" "f")))]
1596 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1598 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1599 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1600 "* return output_fp_compare (insn, operands, 1, 1);"
1601 [(set_attr "type" "fcmp")
1603 (cond [(match_operand:SF 1 "" "")
1605 (match_operand:DF 1 "" "")
1608 (const_string "XF")))
1609 (set_attr "athlon_decode" "vector")
1610 (set_attr "amdfam10_decode" "direct")
1611 (set_attr "bdver1_decode" "direct")])
1613 ;; Push/pop instructions.
1615 (define_insn "*push<mode>2"
1616 [(set (match_operand:DWI 0 "push_operand" "=<")
1617 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1622 [(set (match_operand:TI 0 "push_operand" "")
1623 (match_operand:TI 1 "general_operand" ""))]
1624 "TARGET_64BIT && reload_completed
1625 && !SSE_REG_P (operands[1])"
1627 "ix86_split_long_move (operands); DONE;")
1629 (define_insn "*pushdi2_rex64"
1630 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1631 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1636 [(set_attr "type" "push,multi")
1637 (set_attr "mode" "DI")])
1639 ;; Convert impossible pushes of immediate to existing instructions.
1640 ;; First try to get scratch register and go through it. In case this
1641 ;; fails, push sign extended lower part first and then overwrite
1642 ;; upper part by 32bit move.
1644 [(match_scratch:DI 2 "r")
1645 (set (match_operand:DI 0 "push_operand" "")
1646 (match_operand:DI 1 "immediate_operand" ""))]
1647 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1648 && !x86_64_immediate_operand (operands[1], DImode)"
1649 [(set (match_dup 2) (match_dup 1))
1650 (set (match_dup 0) (match_dup 2))])
1652 ;; We need to define this as both peepholer and splitter for case
1653 ;; peephole2 pass is not run.
1654 ;; "&& 1" is needed to keep it from matching the previous pattern.
1656 [(set (match_operand:DI 0 "push_operand" "")
1657 (match_operand:DI 1 "immediate_operand" ""))]
1658 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1659 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1660 [(set (match_dup 0) (match_dup 1))
1661 (set (match_dup 2) (match_dup 3))]
1663 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1665 operands[1] = gen_lowpart (DImode, operands[2]);
1666 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1671 [(set (match_operand:DI 0 "push_operand" "")
1672 (match_operand:DI 1 "immediate_operand" ""))]
1673 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1674 ? epilogue_completed : reload_completed)
1675 && !symbolic_operand (operands[1], DImode)
1676 && !x86_64_immediate_operand (operands[1], DImode)"
1677 [(set (match_dup 0) (match_dup 1))
1678 (set (match_dup 2) (match_dup 3))]
1680 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1682 operands[1] = gen_lowpart (DImode, operands[2]);
1683 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1688 [(set (match_operand:DI 0 "push_operand" "")
1689 (match_operand:DI 1 "general_operand" ""))]
1690 "!TARGET_64BIT && reload_completed
1691 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1693 "ix86_split_long_move (operands); DONE;")
1695 (define_insn "*pushsi2"
1696 [(set (match_operand:SI 0 "push_operand" "=<")
1697 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1700 [(set_attr "type" "push")
1701 (set_attr "mode" "SI")])
1703 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1704 ;; "push a byte/word". But actually we use pushl, which has the effect
1705 ;; of rounding the amount pushed up to a word.
1707 ;; For TARGET_64BIT we always round up to 8 bytes.
1708 (define_insn "*push<mode>2_rex64"
1709 [(set (match_operand:SWI124 0 "push_operand" "=X")
1710 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1713 [(set_attr "type" "push")
1714 (set_attr "mode" "DI")])
1716 (define_insn "*push<mode>2"
1717 [(set (match_operand:SWI12 0 "push_operand" "=X")
1718 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "SI")])
1724 (define_insn "*push<mode>2_prologue"
1725 [(set (match_operand:P 0 "push_operand" "=<")
1726 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1727 (clobber (mem:BLK (scratch)))]
1729 "push{<imodesuffix>}\t%1"
1730 [(set_attr "type" "push")
1731 (set_attr "mode" "<MODE>")])
1733 (define_insn "*pop<mode>1"
1734 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1735 (match_operand:P 1 "pop_operand" ">"))]
1737 "pop{<imodesuffix>}\t%0"
1738 [(set_attr "type" "pop")
1739 (set_attr "mode" "<MODE>")])
1741 (define_insn "*pop<mode>1_epilogue"
1742 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1743 (match_operand:P 1 "pop_operand" ">"))
1744 (clobber (mem:BLK (scratch)))]
1746 "pop{<imodesuffix>}\t%0"
1747 [(set_attr "type" "pop")
1748 (set_attr "mode" "<MODE>")])
1750 ;; Move instructions.
1752 (define_expand "movoi"
1753 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1754 (match_operand:OI 1 "general_operand" ""))]
1756 "ix86_expand_move (OImode, operands); DONE;")
1758 (define_expand "movti"
1759 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1760 (match_operand:TI 1 "nonimmediate_operand" ""))]
1761 "TARGET_64BIT || TARGET_SSE"
1764 ix86_expand_move (TImode, operands);
1765 else if (push_operand (operands[0], TImode))
1766 ix86_expand_push (TImode, operands[1]);
1768 ix86_expand_vector_move (TImode, operands);
1772 ;; This expands to what emit_move_complex would generate if we didn't
1773 ;; have a movti pattern. Having this avoids problems with reload on
1774 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1775 ;; to have around all the time.
1776 (define_expand "movcdi"
1777 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1778 (match_operand:CDI 1 "general_operand" ""))]
1781 if (push_operand (operands[0], CDImode))
1782 emit_move_complex_push (CDImode, operands[0], operands[1]);
1784 emit_move_complex_parts (operands[0], operands[1]);
1788 (define_expand "mov<mode>"
1789 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1790 (match_operand:SWI1248x 1 "general_operand" ""))]
1792 "ix86_expand_move (<MODE>mode, operands); DONE;")
1794 (define_insn "*mov<mode>_xor"
1795 [(set (match_operand:SWI48 0 "register_operand" "=r")
1796 (match_operand:SWI48 1 "const0_operand" ""))
1797 (clobber (reg:CC FLAGS_REG))]
1800 [(set_attr "type" "alu1")
1801 (set_attr "mode" "SI")
1802 (set_attr "length_immediate" "0")])
1804 (define_insn "*mov<mode>_or"
1805 [(set (match_operand:SWI48 0 "register_operand" "=r")
1806 (match_operand:SWI48 1 "const_int_operand" ""))
1807 (clobber (reg:CC FLAGS_REG))]
1809 && operands[1] == constm1_rtx"
1810 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1811 [(set_attr "type" "alu1")
1812 (set_attr "mode" "<MODE>")
1813 (set_attr "length_immediate" "1")])
1815 (define_insn "*movoi_internal_avx"
1816 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1817 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1818 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1820 switch (which_alternative)
1823 return "vxorps\t%0, %0, %0";
1826 if (misaligned_operand (operands[0], OImode)
1827 || misaligned_operand (operands[1], OImode))
1828 return "vmovdqu\t{%1, %0|%0, %1}";
1830 return "vmovdqa\t{%1, %0|%0, %1}";
1835 [(set_attr "type" "sselog1,ssemov,ssemov")
1836 (set_attr "prefix" "vex")
1837 (set_attr "mode" "OI")])
1839 (define_insn "*movti_internal_rex64"
1840 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1841 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1842 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1844 switch (which_alternative)
1850 if (get_attr_mode (insn) == MODE_V4SF)
1851 return "%vxorps\t%0, %d0";
1853 return "%vpxor\t%0, %d0";
1856 /* TDmode values are passed as TImode on the stack. Moving them
1857 to stack may result in unaligned memory access. */
1858 if (misaligned_operand (operands[0], TImode)
1859 || misaligned_operand (operands[1], TImode))
1861 if (get_attr_mode (insn) == MODE_V4SF)
1862 return "%vmovups\t{%1, %0|%0, %1}";
1864 return "%vmovdqu\t{%1, %0|%0, %1}";
1868 if (get_attr_mode (insn) == MODE_V4SF)
1869 return "%vmovaps\t{%1, %0|%0, %1}";
1871 return "%vmovdqa\t{%1, %0|%0, %1}";
1877 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1878 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1880 (cond [(eq_attr "alternative" "2,3")
1882 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1884 (const_string "V4SF")
1885 (const_string "TI"))
1886 (eq_attr "alternative" "4")
1888 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1890 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1892 (const_string "V4SF")
1893 (const_string "TI"))]
1894 (const_string "DI")))])
1897 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1898 (match_operand:TI 1 "general_operand" ""))]
1900 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1902 "ix86_split_long_move (operands); DONE;")
1904 (define_insn "*movti_internal_sse"
1905 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1906 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1907 "TARGET_SSE && !TARGET_64BIT
1908 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1910 switch (which_alternative)
1913 if (get_attr_mode (insn) == MODE_V4SF)
1914 return "%vxorps\t%0, %d0";
1916 return "%vpxor\t%0, %d0";
1919 /* TDmode values are passed as TImode on the stack. Moving them
1920 to stack may result in unaligned memory access. */
1921 if (misaligned_operand (operands[0], TImode)
1922 || misaligned_operand (operands[1], TImode))
1924 if (get_attr_mode (insn) == MODE_V4SF)
1925 return "%vmovups\t{%1, %0|%0, %1}";
1927 return "%vmovdqu\t{%1, %0|%0, %1}";
1931 if (get_attr_mode (insn) == MODE_V4SF)
1932 return "%vmovaps\t{%1, %0|%0, %1}";
1934 return "%vmovdqa\t{%1, %0|%0, %1}";
1940 [(set_attr "type" "sselog1,ssemov,ssemov")
1941 (set_attr "prefix" "maybe_vex")
1943 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1944 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1946 (const_string "V4SF")
1947 (and (eq_attr "alternative" "2")
1948 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1950 (const_string "V4SF")]
1951 (const_string "TI")))])
1953 (define_insn "*movdi_internal_rex64"
1954 [(set (match_operand:DI 0 "nonimmediate_operand"
1955 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1956 (match_operand:DI 1 "general_operand"
1957 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1958 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1960 switch (get_attr_type (insn))
1963 if (SSE_REG_P (operands[0]))
1964 return "movq2dq\t{%1, %0|%0, %1}";
1966 return "movdq2q\t{%1, %0|%0, %1}";
1971 if (get_attr_mode (insn) == MODE_TI)
1972 return "vmovdqa\t{%1, %0|%0, %1}";
1974 return "vmovq\t{%1, %0|%0, %1}";
1977 if (get_attr_mode (insn) == MODE_TI)
1978 return "movdqa\t{%1, %0|%0, %1}";
1982 /* Moves from and into integer register is done using movd
1983 opcode with REX prefix. */
1984 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1985 return "movd\t{%1, %0|%0, %1}";
1986 return "movq\t{%1, %0|%0, %1}";
1989 return "%vpxor\t%0, %d0";
1992 return "pxor\t%0, %0";
1998 return "lea{q}\t{%a1, %0|%0, %a1}";
2001 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2002 if (get_attr_mode (insn) == MODE_SI)
2003 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2004 else if (which_alternative == 2)
2005 return "movabs{q}\t{%1, %0|%0, %1}";
2007 return "mov{q}\t{%1, %0|%0, %1}";
2011 (cond [(eq_attr "alternative" "5")
2012 (const_string "mmx")
2013 (eq_attr "alternative" "6,7,8,9,10")
2014 (const_string "mmxmov")
2015 (eq_attr "alternative" "11")
2016 (const_string "sselog1")
2017 (eq_attr "alternative" "12,13,14,15,16")
2018 (const_string "ssemov")
2019 (eq_attr "alternative" "17,18")
2020 (const_string "ssecvt")
2021 (eq_attr "alternative" "4")
2022 (const_string "multi")
2023 (match_operand:DI 1 "pic_32bit_operand" "")
2024 (const_string "lea")
2026 (const_string "imov")))
2029 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2031 (const_string "*")))
2032 (set (attr "length_immediate")
2034 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2036 (const_string "*")))
2037 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2038 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2039 (set (attr "prefix")
2040 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2041 (const_string "maybe_vex")
2042 (const_string "orig")))
2043 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2045 ;; Convert impossible stores of immediate to existing instructions.
2046 ;; First try to get scratch register and go through it. In case this
2047 ;; fails, move by 32bit parts.
2049 [(match_scratch:DI 2 "r")
2050 (set (match_operand:DI 0 "memory_operand" "")
2051 (match_operand:DI 1 "immediate_operand" ""))]
2052 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2053 && !x86_64_immediate_operand (operands[1], DImode)"
2054 [(set (match_dup 2) (match_dup 1))
2055 (set (match_dup 0) (match_dup 2))])
2057 ;; We need to define this as both peepholer and splitter for case
2058 ;; peephole2 pass is not run.
2059 ;; "&& 1" is needed to keep it from matching the previous pattern.
2061 [(set (match_operand:DI 0 "memory_operand" "")
2062 (match_operand:DI 1 "immediate_operand" ""))]
2063 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2064 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2065 [(set (match_dup 2) (match_dup 3))
2066 (set (match_dup 4) (match_dup 5))]
2067 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2070 [(set (match_operand:DI 0 "memory_operand" "")
2071 (match_operand:DI 1 "immediate_operand" ""))]
2072 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2073 ? epilogue_completed : reload_completed)
2074 && !symbolic_operand (operands[1], DImode)
2075 && !x86_64_immediate_operand (operands[1], DImode)"
2076 [(set (match_dup 2) (match_dup 3))
2077 (set (match_dup 4) (match_dup 5))]
2078 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2080 (define_insn "*movdi_internal"
2081 [(set (match_operand:DI 0 "nonimmediate_operand"
2082 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2083 (match_operand:DI 1 "general_operand"
2084 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2085 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2090 movq\t{%1, %0|%0, %1}
2091 movq\t{%1, %0|%0, %1}
2093 %vmovq\t{%1, %0|%0, %1}
2094 %vmovdqa\t{%1, %0|%0, %1}
2095 %vmovq\t{%1, %0|%0, %1}
2097 movlps\t{%1, %0|%0, %1}
2098 movaps\t{%1, %0|%0, %1}
2099 movlps\t{%1, %0|%0, %1}"
2100 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2101 (set (attr "prefix")
2102 (if_then_else (eq_attr "alternative" "5,6,7,8")
2103 (const_string "vex")
2104 (const_string "orig")))
2105 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2108 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2109 (match_operand:DI 1 "general_operand" ""))]
2110 "!TARGET_64BIT && reload_completed
2111 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2112 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2114 "ix86_split_long_move (operands); DONE;")
2116 (define_insn "*movsi_internal"
2117 [(set (match_operand:SI 0 "nonimmediate_operand"
2118 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2119 (match_operand:SI 1 "general_operand"
2120 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2121 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2123 switch (get_attr_type (insn))
2126 if (get_attr_mode (insn) == MODE_TI)
2127 return "%vpxor\t%0, %d0";
2128 return "%vxorps\t%0, %d0";
2131 switch (get_attr_mode (insn))
2134 return "%vmovdqa\t{%1, %0|%0, %1}";
2136 return "%vmovaps\t{%1, %0|%0, %1}";
2138 return "%vmovd\t{%1, %0|%0, %1}";
2140 return "%vmovss\t{%1, %0|%0, %1}";
2146 return "pxor\t%0, %0";
2149 if (get_attr_mode (insn) == MODE_DI)
2150 return "movq\t{%1, %0|%0, %1}";
2151 return "movd\t{%1, %0|%0, %1}";
2154 return "lea{l}\t{%a1, %0|%0, %a1}";
2157 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2158 return "mov{l}\t{%1, %0|%0, %1}";
2162 (cond [(eq_attr "alternative" "2")
2163 (const_string "mmx")
2164 (eq_attr "alternative" "3,4,5")
2165 (const_string "mmxmov")
2166 (eq_attr "alternative" "6")
2167 (const_string "sselog1")
2168 (eq_attr "alternative" "7,8,9,10,11")
2169 (const_string "ssemov")
2170 (match_operand:DI 1 "pic_32bit_operand" "")
2171 (const_string "lea")
2173 (const_string "imov")))
2174 (set (attr "prefix")
2175 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2176 (const_string "orig")
2177 (const_string "maybe_vex")))
2178 (set (attr "prefix_data16")
2179 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2181 (const_string "*")))
2183 (cond [(eq_attr "alternative" "2,3")
2185 (eq_attr "alternative" "6,7")
2187 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2188 (const_string "V4SF")
2189 (const_string "TI"))
2190 (and (eq_attr "alternative" "8,9,10,11")
2191 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2194 (const_string "SI")))])
2196 (define_insn "*movhi_internal"
2197 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2198 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2199 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2201 switch (get_attr_type (insn))
2204 /* movzwl is faster than movw on p2 due to partial word stalls,
2205 though not as fast as an aligned movl. */
2206 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2208 if (get_attr_mode (insn) == MODE_SI)
2209 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2211 return "mov{w}\t{%1, %0|%0, %1}";
2215 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2217 (const_string "imov")
2218 (and (eq_attr "alternative" "0")
2219 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2221 (eq (symbol_ref "TARGET_HIMODE_MATH")
2223 (const_string "imov")
2224 (and (eq_attr "alternative" "1,2")
2225 (match_operand:HI 1 "aligned_operand" ""))
2226 (const_string "imov")
2227 (and (ne (symbol_ref "TARGET_MOVX")
2229 (eq_attr "alternative" "0,2"))
2230 (const_string "imovx")
2232 (const_string "imov")))
2234 (cond [(eq_attr "type" "imovx")
2236 (and (eq_attr "alternative" "1,2")
2237 (match_operand:HI 1 "aligned_operand" ""))
2239 (and (eq_attr "alternative" "0")
2240 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2242 (eq (symbol_ref "TARGET_HIMODE_MATH")
2246 (const_string "HI")))])
2248 ;; Situation is quite tricky about when to choose full sized (SImode) move
2249 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2250 ;; partial register dependency machines (such as AMD Athlon), where QImode
2251 ;; moves issue extra dependency and for partial register stalls machines
2252 ;; that don't use QImode patterns (and QImode move cause stall on the next
2255 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2256 ;; register stall machines with, where we use QImode instructions, since
2257 ;; partial register stall can be caused there. Then we use movzx.
2258 (define_insn "*movqi_internal"
2259 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2260 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2261 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2263 switch (get_attr_type (insn))
2266 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2267 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2269 if (get_attr_mode (insn) == MODE_SI)
2270 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2272 return "mov{b}\t{%1, %0|%0, %1}";
2276 (cond [(and (eq_attr "alternative" "5")
2277 (not (match_operand:QI 1 "aligned_operand" "")))
2278 (const_string "imovx")
2279 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281 (const_string "imov")
2282 (and (eq_attr "alternative" "3")
2283 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285 (eq (symbol_ref "TARGET_QIMODE_MATH")
2287 (const_string "imov")
2288 (eq_attr "alternative" "3,5")
2289 (const_string "imovx")
2290 (and (ne (symbol_ref "TARGET_MOVX")
2292 (eq_attr "alternative" "2"))
2293 (const_string "imovx")
2295 (const_string "imov")))
2297 (cond [(eq_attr "alternative" "3,4,5")
2299 (eq_attr "alternative" "6")
2301 (eq_attr "type" "imovx")
2303 (and (eq_attr "type" "imov")
2304 (and (eq_attr "alternative" "0,1")
2305 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2307 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2309 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2312 ;; Avoid partial register stalls when not using QImode arithmetic
2313 (and (eq_attr "type" "imov")
2314 (and (eq_attr "alternative" "0,1")
2315 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2317 (eq (symbol_ref "TARGET_QIMODE_MATH")
2321 (const_string "QI")))])
2323 ;; Stores and loads of ax to arbitrary constant address.
2324 ;; We fake an second form of instruction to force reload to load address
2325 ;; into register when rax is not available
2326 (define_insn "*movabs<mode>_1"
2327 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2328 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2329 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2331 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2332 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2333 [(set_attr "type" "imov")
2334 (set_attr "modrm" "0,*")
2335 (set_attr "length_address" "8,0")
2336 (set_attr "length_immediate" "0,*")
2337 (set_attr "memory" "store")
2338 (set_attr "mode" "<MODE>")])
2340 (define_insn "*movabs<mode>_2"
2341 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2342 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2343 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2345 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2346 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2347 [(set_attr "type" "imov")
2348 (set_attr "modrm" "0,*")
2349 (set_attr "length_address" "8,0")
2350 (set_attr "length_immediate" "0")
2351 (set_attr "memory" "load")
2352 (set_attr "mode" "<MODE>")])
2354 (define_insn "*swap<mode>"
2355 [(set (match_operand:SWI48 0 "register_operand" "+r")
2356 (match_operand:SWI48 1 "register_operand" "+r"))
2360 "xchg{<imodesuffix>}\t%1, %0"
2361 [(set_attr "type" "imov")
2362 (set_attr "mode" "<MODE>")
2363 (set_attr "pent_pair" "np")
2364 (set_attr "athlon_decode" "vector")
2365 (set_attr "amdfam10_decode" "double")
2366 (set_attr "bdver1_decode" "double")])
2368 (define_insn "*swap<mode>_1"
2369 [(set (match_operand:SWI12 0 "register_operand" "+r")
2370 (match_operand:SWI12 1 "register_operand" "+r"))
2373 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2375 [(set_attr "type" "imov")
2376 (set_attr "mode" "SI")
2377 (set_attr "pent_pair" "np")
2378 (set_attr "athlon_decode" "vector")
2379 (set_attr "amdfam10_decode" "double")
2380 (set_attr "bdver1_decode" "double")])
2382 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2383 ;; is disabled for AMDFAM10
2384 (define_insn "*swap<mode>_2"
2385 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2386 (match_operand:SWI12 1 "register_operand" "+<r>"))
2389 "TARGET_PARTIAL_REG_STALL"
2390 "xchg{<imodesuffix>}\t%1, %0"
2391 [(set_attr "type" "imov")
2392 (set_attr "mode" "<MODE>")
2393 (set_attr "pent_pair" "np")
2394 (set_attr "athlon_decode" "vector")])
2396 (define_expand "movstrict<mode>"
2397 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2398 (match_operand:SWI12 1 "general_operand" ""))]
2401 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2403 /* Don't generate memory->memory moves, go through a register */
2404 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2405 operands[1] = force_reg (<MODE>mode, operands[1]);
2408 (define_insn "*movstrict<mode>_1"
2409 [(set (strict_low_part
2410 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2411 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2412 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2413 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2414 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2415 [(set_attr "type" "imov")
2416 (set_attr "mode" "<MODE>")])
2418 (define_insn "*movstrict<mode>_xor"
2419 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2420 (match_operand:SWI12 1 "const0_operand" ""))
2421 (clobber (reg:CC FLAGS_REG))]
2423 "xor{<imodesuffix>}\t%0, %0"
2424 [(set_attr "type" "alu1")
2425 (set_attr "mode" "<MODE>")
2426 (set_attr "length_immediate" "0")])
2428 (define_insn "*mov<mode>_extv_1"
2429 [(set (match_operand:SWI24 0 "register_operand" "=R")
2430 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2434 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2435 [(set_attr "type" "imovx")
2436 (set_attr "mode" "SI")])
2438 (define_insn "*movqi_extv_1_rex64"
2439 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2440 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2445 switch (get_attr_type (insn))
2448 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2450 return "mov{b}\t{%h1, %0|%0, %h1}";
2454 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2455 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2456 (ne (symbol_ref "TARGET_MOVX")
2458 (const_string "imovx")
2459 (const_string "imov")))
2461 (if_then_else (eq_attr "type" "imovx")
2463 (const_string "QI")))])
2465 (define_insn "*movqi_extv_1"
2466 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2467 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2472 switch (get_attr_type (insn))
2475 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2477 return "mov{b}\t{%h1, %0|%0, %h1}";
2481 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2482 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2483 (ne (symbol_ref "TARGET_MOVX")
2485 (const_string "imovx")
2486 (const_string "imov")))
2488 (if_then_else (eq_attr "type" "imovx")
2490 (const_string "QI")))])
2492 (define_insn "*mov<mode>_extzv_1"
2493 [(set (match_operand:SWI48 0 "register_operand" "=R")
2494 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2498 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2499 [(set_attr "type" "imovx")
2500 (set_attr "mode" "SI")])
2502 (define_insn "*movqi_extzv_2_rex64"
2503 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2505 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2510 switch (get_attr_type (insn))
2513 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2515 return "mov{b}\t{%h1, %0|%0, %h1}";
2519 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2520 (ne (symbol_ref "TARGET_MOVX")
2522 (const_string "imovx")
2523 (const_string "imov")))
2525 (if_then_else (eq_attr "type" "imovx")
2527 (const_string "QI")))])
2529 (define_insn "*movqi_extzv_2"
2530 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2532 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2537 switch (get_attr_type (insn))
2540 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2542 return "mov{b}\t{%h1, %0|%0, %h1}";
2546 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2547 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2548 (ne (symbol_ref "TARGET_MOVX")
2550 (const_string "imovx")
2551 (const_string "imov")))
2553 (if_then_else (eq_attr "type" "imovx")
2555 (const_string "QI")))])
2557 (define_expand "mov<mode>_insv_1"
2558 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2561 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2563 (define_insn "*mov<mode>_insv_1_rex64"
2564 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2567 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2569 "mov{b}\t{%b1, %h0|%h0, %b1}"
2570 [(set_attr "type" "imov")
2571 (set_attr "mode" "QI")])
2573 (define_insn "*movsi_insv_1"
2574 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2577 (match_operand:SI 1 "general_operand" "Qmn"))]
2579 "mov{b}\t{%b1, %h0|%h0, %b1}"
2580 [(set_attr "type" "imov")
2581 (set_attr "mode" "QI")])
2583 (define_insn "*movqi_insv_2"
2584 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2587 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2590 "mov{b}\t{%h1, %h0|%h0, %h1}"
2591 [(set_attr "type" "imov")
2592 (set_attr "mode" "QI")])
2594 ;; Floating point push instructions.
2596 (define_insn "*pushtf"
2597 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2598 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2601 /* This insn should be already split before reg-stack. */
2604 [(set_attr "type" "multi")
2605 (set_attr "unit" "sse,*,*")
2606 (set_attr "mode" "TF,SI,SI")])
2609 [(set (match_operand:TF 0 "push_operand" "")
2610 (match_operand:TF 1 "sse_reg_operand" ""))]
2611 "TARGET_SSE2 && reload_completed"
2612 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2613 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2616 [(set (match_operand:TF 0 "push_operand" "")
2617 (match_operand:TF 1 "general_operand" ""))]
2618 "TARGET_SSE2 && reload_completed
2619 && !SSE_REG_P (operands[1])"
2621 "ix86_split_long_move (operands); DONE;")
2623 (define_insn "*pushxf"
2624 [(set (match_operand:XF 0 "push_operand" "=<,<")
2625 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2626 "optimize_function_for_speed_p (cfun)"
2628 /* This insn should be already split before reg-stack. */
2631 [(set_attr "type" "multi")
2632 (set_attr "unit" "i387,*")
2633 (set_attr "mode" "XF,SI")])
2635 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2636 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2637 ;; Pushing using integer instructions is longer except for constants
2638 ;; and direct memory references (assuming that any given constant is pushed
2639 ;; only once, but this ought to be handled elsewhere).
2641 (define_insn "*pushxf_nointeger"
2642 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2643 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2644 "optimize_function_for_size_p (cfun)"
2646 /* This insn should be already split before reg-stack. */
2649 [(set_attr "type" "multi")
2650 (set_attr "unit" "i387,*,*")
2651 (set_attr "mode" "XF,SI,SI")])
2654 [(set (match_operand:XF 0 "push_operand" "")
2655 (match_operand:XF 1 "fp_register_operand" ""))]
2657 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2658 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2659 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2662 [(set (match_operand:XF 0 "push_operand" "")
2663 (match_operand:XF 1 "general_operand" ""))]
2665 && !FP_REG_P (operands[1])"
2667 "ix86_split_long_move (operands); DONE;")
2669 (define_insn "*pushdf"
2670 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2671 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2672 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2674 /* This insn should be already split before reg-stack. */
2677 [(set_attr "type" "multi")
2678 (set_attr "unit" "i387,*,*")
2679 (set_attr "mode" "DF,SI,DF")])
2681 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2682 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2683 ;; On the average, pushdf using integers can be still shorter. Allow this
2684 ;; pattern for optimize_size too.
2686 (define_insn "*pushdf_nointeger"
2687 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2688 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2689 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2691 /* This insn should be already split before reg-stack. */
2694 [(set_attr "type" "multi")
2695 (set_attr "unit" "i387,*,*,*")
2696 (set_attr "mode" "DF,SI,SI,DF")])
2698 ;; %%% Kill this when call knows how to work this out.
2700 [(set (match_operand:DF 0 "push_operand" "")
2701 (match_operand:DF 1 "any_fp_register_operand" ""))]
2703 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2704 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2707 [(set (match_operand:DF 0 "push_operand" "")
2708 (match_operand:DF 1 "general_operand" ""))]
2710 && !ANY_FP_REG_P (operands[1])"
2712 "ix86_split_long_move (operands); DONE;")
2714 (define_insn "*pushsf_rex64"
2715 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2716 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2719 /* Anything else should be already split before reg-stack. */
2720 gcc_assert (which_alternative == 1);
2721 return "push{q}\t%q1";
2723 [(set_attr "type" "multi,push,multi")
2724 (set_attr "unit" "i387,*,*")
2725 (set_attr "mode" "SF,DI,SF")])
2727 (define_insn "*pushsf"
2728 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2729 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2732 /* Anything else should be already split before reg-stack. */
2733 gcc_assert (which_alternative == 1);
2734 return "push{l}\t%1";
2736 [(set_attr "type" "multi,push,multi")
2737 (set_attr "unit" "i387,*,*")
2738 (set_attr "mode" "SF,SI,SF")])
2741 [(set (match_operand:SF 0 "push_operand" "")
2742 (match_operand:SF 1 "memory_operand" ""))]
2744 && MEM_P (operands[1])
2745 && (operands[2] = find_constant_src (insn))"
2749 ;; %%% Kill this when call knows how to work this out.
2751 [(set (match_operand:SF 0 "push_operand" "")
2752 (match_operand:SF 1 "any_fp_register_operand" ""))]
2754 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2755 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2756 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2758 ;; Floating point move instructions.
2760 (define_expand "movtf"
2761 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2762 (match_operand:TF 1 "nonimmediate_operand" ""))]
2765 ix86_expand_move (TFmode, operands);
2769 (define_expand "mov<mode>"
2770 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2771 (match_operand:X87MODEF 1 "general_operand" ""))]
2773 "ix86_expand_move (<MODE>mode, operands); DONE;")
2775 (define_insn "*movtf_internal"
2776 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2777 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2781 switch (which_alternative)
2785 if (get_attr_mode (insn) == MODE_V4SF)
2786 return "%vmovaps\t{%1, %0|%0, %1}";
2788 return "%vmovdqa\t{%1, %0|%0, %1}";
2790 if (get_attr_mode (insn) == MODE_V4SF)
2791 return "%vxorps\t%0, %d0";
2793 return "%vpxor\t%0, %d0";
2801 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2802 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2804 (cond [(eq_attr "alternative" "0,2")
2806 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2808 (const_string "V4SF")
2809 (const_string "TI"))
2810 (eq_attr "alternative" "1")
2812 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2814 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2816 (const_string "V4SF")
2817 (const_string "TI"))]
2818 (const_string "DI")))])
2821 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2822 (match_operand:TF 1 "general_operand" ""))]
2824 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2826 "ix86_split_long_move (operands); DONE;")
2828 (define_insn "*movxf_internal"
2829 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2830 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2831 "optimize_function_for_speed_p (cfun)
2832 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2833 && (reload_in_progress || reload_completed
2834 || GET_CODE (operands[1]) != CONST_DOUBLE
2835 || memory_operand (operands[0], XFmode))"
2837 switch (which_alternative)
2841 return output_387_reg_move (insn, operands);
2844 return standard_80387_constant_opcode (operands[1]);
2853 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2854 (set_attr "mode" "XF,XF,XF,SI,SI")])
2856 ;; Do not use integer registers when optimizing for size
2857 (define_insn "*movxf_internal_nointeger"
2858 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2859 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2860 "optimize_function_for_size_p (cfun)
2861 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2862 && (reload_in_progress || reload_completed
2863 || standard_80387_constant_p (operands[1])
2864 || GET_CODE (operands[1]) != CONST_DOUBLE
2865 || memory_operand (operands[0], XFmode))"
2867 switch (which_alternative)
2871 return output_387_reg_move (insn, operands);
2874 return standard_80387_constant_opcode (operands[1]);
2882 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2883 (set_attr "mode" "XF,XF,XF,SI,SI")])
2886 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2887 (match_operand:XF 1 "general_operand" ""))]
2889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890 && ! (FP_REG_P (operands[0]) ||
2891 (GET_CODE (operands[0]) == SUBREG
2892 && FP_REG_P (SUBREG_REG (operands[0]))))
2893 && ! (FP_REG_P (operands[1]) ||
2894 (GET_CODE (operands[1]) == SUBREG
2895 && FP_REG_P (SUBREG_REG (operands[1]))))"
2897 "ix86_split_long_move (operands); DONE;")
2899 (define_insn "*movdf_internal_rex64"
2900 [(set (match_operand:DF 0 "nonimmediate_operand"
2901 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2902 (match_operand:DF 1 "general_operand"
2903 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2904 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2905 && (reload_in_progress || reload_completed
2906 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2907 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2908 && optimize_function_for_size_p (cfun)
2909 && standard_80387_constant_p (operands[1]))
2910 || GET_CODE (operands[1]) != CONST_DOUBLE
2911 || memory_operand (operands[0], DFmode))"
2913 switch (which_alternative)
2917 return output_387_reg_move (insn, operands);
2920 return standard_80387_constant_opcode (operands[1]);
2927 switch (get_attr_mode (insn))
2930 return "%vxorps\t%0, %d0";
2932 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2933 return "%vxorps\t%0, %d0";
2935 return "%vxorpd\t%0, %d0";
2937 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vxorps\t%0, %d0";
2940 return "%vpxor\t%0, %d0";
2947 switch (get_attr_mode (insn))
2950 return "%vmovaps\t{%1, %0|%0, %1}";
2952 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2953 return "%vmovaps\t{%1, %0|%0, %1}";
2955 return "%vmovapd\t{%1, %0|%0, %1}";
2957 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2958 return "%vmovaps\t{%1, %0|%0, %1}";
2960 return "%vmovdqa\t{%1, %0|%0, %1}";
2962 return "%vmovq\t{%1, %0|%0, %1}";
2966 if (REG_P (operands[0]) && REG_P (operands[1]))
2967 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2969 return "vmovsd\t{%1, %0|%0, %1}";
2972 return "movsd\t{%1, %0|%0, %1}";
2974 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2976 return "%vmovlps\t{%1, %d0|%d0, %1}";
2983 return "%vmovd\t{%1, %0|%0, %1}";
2989 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2990 (set (attr "prefix")
2991 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2992 (const_string "orig")
2993 (const_string "maybe_vex")))
2994 (set (attr "prefix_data16")
2995 (if_then_else (eq_attr "mode" "V1DF")
2997 (const_string "*")))
2999 (cond [(eq_attr "alternative" "0,1,2")
3001 (eq_attr "alternative" "3,4,9,10")
3004 /* For SSE1, we have many fewer alternatives. */
3005 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3006 (cond [(eq_attr "alternative" "5,6")
3007 (const_string "V4SF")
3009 (const_string "V2SF"))
3011 /* xorps is one byte shorter. */
3012 (eq_attr "alternative" "5")
3013 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3015 (const_string "V4SF")
3016 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3020 (const_string "V2DF"))
3022 /* For architectures resolving dependencies on
3023 whole SSE registers use APD move to break dependency
3024 chains, otherwise use short move to avoid extra work.
3026 movaps encodes one byte shorter. */
3027 (eq_attr "alternative" "6")
3029 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031 (const_string "V4SF")
3032 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3034 (const_string "V2DF")
3036 (const_string "DF"))
3037 /* For architectures resolving dependencies on register
3038 parts we may avoid extra work to zero out upper part
3040 (eq_attr "alternative" "7")
3042 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3044 (const_string "V1DF")
3045 (const_string "DF"))
3047 (const_string "DF")))])
3049 (define_insn "*movdf_internal"
3050 [(set (match_operand:DF 0 "nonimmediate_operand"
3051 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3052 (match_operand:DF 1 "general_operand"
3053 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3054 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3055 && optimize_function_for_speed_p (cfun)
3056 && TARGET_INTEGER_DFMODE_MOVES
3057 && (reload_in_progress || reload_completed
3058 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3059 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3060 && optimize_function_for_size_p (cfun)
3061 && standard_80387_constant_p (operands[1]))
3062 || GET_CODE (operands[1]) != CONST_DOUBLE
3063 || memory_operand (operands[0], DFmode))"
3065 switch (which_alternative)
3069 return output_387_reg_move (insn, operands);
3072 return standard_80387_constant_opcode (operands[1]);
3079 switch (get_attr_mode (insn))
3082 return "xorps\t%0, %0";
3084 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3085 return "xorps\t%0, %0";
3087 return "xorpd\t%0, %0";
3089 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3090 return "xorps\t%0, %0";
3092 return "pxor\t%0, %0";
3099 switch (get_attr_mode (insn))
3102 return "movaps\t{%1, %0|%0, %1}";
3104 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3105 return "movaps\t{%1, %0|%0, %1}";
3107 return "movapd\t{%1, %0|%0, %1}";
3109 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3110 return "movaps\t{%1, %0|%0, %1}";
3112 return "movdqa\t{%1, %0|%0, %1}";
3114 return "movq\t{%1, %0|%0, %1}";
3116 return "movsd\t{%1, %0|%0, %1}";
3118 return "movlpd\t{%1, %0|%0, %1}";
3120 return "movlps\t{%1, %0|%0, %1}";
3129 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3130 (set (attr "prefix_data16")
3131 (if_then_else (eq_attr "mode" "V1DF")
3133 (const_string "*")))
3135 (cond [(eq_attr "alternative" "0,1,2")
3137 (eq_attr "alternative" "3,4")
3140 /* For SSE1, we have many fewer alternatives. */
3141 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3142 (cond [(eq_attr "alternative" "5,6")
3143 (const_string "V4SF")
3145 (const_string "V2SF"))
3147 /* xorps is one byte shorter. */
3148 (eq_attr "alternative" "5")
3149 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3151 (const_string "V4SF")
3152 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3156 (const_string "V2DF"))
3158 /* For architectures resolving dependencies on
3159 whole SSE registers use APD move to break dependency
3160 chains, otherwise use short move to avoid extra work.
3162 movaps encodes one byte shorter. */
3163 (eq_attr "alternative" "6")
3165 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3167 (const_string "V4SF")
3168 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3170 (const_string "V2DF")
3172 (const_string "DF"))
3173 /* For architectures resolving dependencies on register
3174 parts we may avoid extra work to zero out upper part
3176 (eq_attr "alternative" "7")
3178 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3180 (const_string "V1DF")
3181 (const_string "DF"))
3183 (const_string "DF")))])
3185 ;; Moving is usually shorter when only FP registers are used. This separate
3186 ;; movdf pattern avoids the use of integer registers for FP operations
3187 ;; when optimizing for size.
3189 (define_insn "*movdf_internal_nointeger"
3190 [(set (match_operand:DF 0 "nonimmediate_operand"
3191 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3192 (match_operand:DF 1 "general_operand"
3193 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3195 && ((optimize_function_for_size_p (cfun)
3196 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3197 && (reload_in_progress || reload_completed
3198 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3199 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3200 && optimize_function_for_size_p (cfun)
3201 && !memory_operand (operands[0], DFmode)
3202 && standard_80387_constant_p (operands[1]))
3203 || GET_CODE (operands[1]) != CONST_DOUBLE
3204 || ((optimize_function_for_size_p (cfun)
3205 || !TARGET_MEMORY_MISMATCH_STALL
3206 || reload_in_progress || reload_completed)
3207 && memory_operand (operands[0], DFmode)))"
3209 switch (which_alternative)
3213 return output_387_reg_move (insn, operands);
3216 return standard_80387_constant_opcode (operands[1]);
3223 switch (get_attr_mode (insn))
3226 return "%vxorps\t%0, %d0";
3228 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3229 return "%vxorps\t%0, %d0";
3231 return "%vxorpd\t%0, %d0";
3233 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3234 return "%vxorps\t%0, %d0";
3236 return "%vpxor\t%0, %d0";
3243 switch (get_attr_mode (insn))
3246 return "%vmovaps\t{%1, %0|%0, %1}";
3248 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3249 return "%vmovaps\t{%1, %0|%0, %1}";
3251 return "%vmovapd\t{%1, %0|%0, %1}";
3253 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3254 return "%vmovaps\t{%1, %0|%0, %1}";
3256 return "%vmovdqa\t{%1, %0|%0, %1}";
3258 return "%vmovq\t{%1, %0|%0, %1}";
3262 if (REG_P (operands[0]) && REG_P (operands[1]))
3263 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3265 return "vmovsd\t{%1, %0|%0, %1}";
3268 return "movsd\t{%1, %0|%0, %1}";
3272 if (REG_P (operands[0]))
3273 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3275 return "vmovlpd\t{%1, %0|%0, %1}";
3278 return "movlpd\t{%1, %0|%0, %1}";
3282 if (REG_P (operands[0]))
3283 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3285 return "vmovlps\t{%1, %0|%0, %1}";
3288 return "movlps\t{%1, %0|%0, %1}";
3297 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3298 (set (attr "prefix")
3299 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3300 (const_string "orig")
3301 (const_string "maybe_vex")))
3302 (set (attr "prefix_data16")
3303 (if_then_else (eq_attr "mode" "V1DF")
3305 (const_string "*")))
3307 (cond [(eq_attr "alternative" "0,1,2")
3309 (eq_attr "alternative" "3,4")
3312 /* For SSE1, we have many fewer alternatives. */
3313 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3314 (cond [(eq_attr "alternative" "5,6")
3315 (const_string "V4SF")
3317 (const_string "V2SF"))
3319 /* xorps is one byte shorter. */
3320 (eq_attr "alternative" "5")
3321 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3323 (const_string "V4SF")
3324 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3328 (const_string "V2DF"))
3330 /* For architectures resolving dependencies on
3331 whole SSE registers use APD move to break dependency
3332 chains, otherwise use short move to avoid extra work.
3334 movaps encodes one byte shorter. */
3335 (eq_attr "alternative" "6")
3337 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3339 (const_string "V4SF")
3340 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3342 (const_string "V2DF")
3344 (const_string "DF"))
3345 /* For architectures resolving dependencies on register
3346 parts we may avoid extra work to zero out upper part
3348 (eq_attr "alternative" "7")
3350 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3352 (const_string "V1DF")
3353 (const_string "DF"))
3355 (const_string "DF")))])
3358 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3359 (match_operand:DF 1 "general_operand" ""))]
3361 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3362 && ! (ANY_FP_REG_P (operands[0]) ||
3363 (GET_CODE (operands[0]) == SUBREG
3364 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3365 && ! (ANY_FP_REG_P (operands[1]) ||
3366 (GET_CODE (operands[1]) == SUBREG
3367 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3369 "ix86_split_long_move (operands); DONE;")
3371 (define_insn "*movsf_internal"
3372 [(set (match_operand:SF 0 "nonimmediate_operand"
3373 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3374 (match_operand:SF 1 "general_operand"
3375 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3376 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3377 && (reload_in_progress || reload_completed
3378 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3379 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3380 && standard_80387_constant_p (operands[1]))
3381 || GET_CODE (operands[1]) != CONST_DOUBLE
3382 || memory_operand (operands[0], SFmode))"
3384 switch (which_alternative)
3388 return output_387_reg_move (insn, operands);
3391 return standard_80387_constant_opcode (operands[1]);
3395 return "mov{l}\t{%1, %0|%0, %1}";
3397 if (get_attr_mode (insn) == MODE_TI)
3398 return "%vpxor\t%0, %d0";
3400 return "%vxorps\t%0, %d0";
3402 if (get_attr_mode (insn) == MODE_V4SF)
3403 return "%vmovaps\t{%1, %0|%0, %1}";
3405 return "%vmovss\t{%1, %d0|%d0, %1}";
3408 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3409 : "vmovss\t{%1, %0|%0, %1}";
3411 return "movss\t{%1, %0|%0, %1}";
3413 return "%vmovss\t{%1, %0|%0, %1}";
3415 case 9: case 10: case 14: case 15:
3416 return "movd\t{%1, %0|%0, %1}";
3418 return "%vmovd\t{%1, %0|%0, %1}";
3421 return "movq\t{%1, %0|%0, %1}";
3427 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3428 (set (attr "prefix")
3429 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3430 (const_string "maybe_vex")
3431 (const_string "orig")))
3433 (cond [(eq_attr "alternative" "3,4,9,10")
3435 (eq_attr "alternative" "5")
3437 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3439 (ne (symbol_ref "TARGET_SSE2")
3441 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3444 (const_string "V4SF"))
3445 /* For architectures resolving dependencies on
3446 whole SSE registers use APS move to break dependency
3447 chains, otherwise use short move to avoid extra work.
3449 Do the same for architectures resolving dependencies on
3450 the parts. While in DF mode it is better to always handle
3451 just register parts, the SF mode is different due to lack
3452 of instructions to load just part of the register. It is
3453 better to maintain the whole registers in single format
3454 to avoid problems on using packed logical operations. */
3455 (eq_attr "alternative" "6")
3457 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3459 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3461 (const_string "V4SF")
3462 (const_string "SF"))
3463 (eq_attr "alternative" "11")
3464 (const_string "DI")]
3465 (const_string "SF")))])
3468 [(set (match_operand 0 "register_operand" "")
3469 (match_operand 1 "memory_operand" ""))]
3471 && MEM_P (operands[1])
3472 && (GET_MODE (operands[0]) == TFmode
3473 || GET_MODE (operands[0]) == XFmode
3474 || GET_MODE (operands[0]) == DFmode
3475 || GET_MODE (operands[0]) == SFmode)
3476 && (operands[2] = find_constant_src (insn))"
3477 [(set (match_dup 0) (match_dup 2))]
3479 rtx c = operands[2];
3480 rtx r = operands[0];
3482 if (GET_CODE (r) == SUBREG)
3487 if (!standard_sse_constant_p (c))
3490 else if (FP_REG_P (r))
3492 if (!standard_80387_constant_p (c))
3495 else if (MMX_REG_P (r))
3500 [(set (match_operand 0 "register_operand" "")
3501 (float_extend (match_operand 1 "memory_operand" "")))]
3503 && MEM_P (operands[1])
3504 && (GET_MODE (operands[0]) == TFmode
3505 || GET_MODE (operands[0]) == XFmode
3506 || GET_MODE (operands[0]) == DFmode
3507 || GET_MODE (operands[0]) == SFmode)
3508 && (operands[2] = find_constant_src (insn))"
3509 [(set (match_dup 0) (match_dup 2))]
3511 rtx c = operands[2];
3512 rtx r = operands[0];
3514 if (GET_CODE (r) == SUBREG)
3519 if (!standard_sse_constant_p (c))
3522 else if (FP_REG_P (r))
3524 if (!standard_80387_constant_p (c))
3527 else if (MMX_REG_P (r))
3531 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3533 [(set (match_operand:X87MODEF 0 "register_operand" "")
3534 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3535 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3536 && (standard_80387_constant_p (operands[1]) == 8
3537 || standard_80387_constant_p (operands[1]) == 9)"
3538 [(set (match_dup 0)(match_dup 1))
3540 (neg:X87MODEF (match_dup 0)))]
3544 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3545 if (real_isnegzero (&r))
3546 operands[1] = CONST0_RTX (<MODE>mode);
3548 operands[1] = CONST1_RTX (<MODE>mode);
3551 (define_insn "swapxf"
3552 [(set (match_operand:XF 0 "register_operand" "+f")
3553 (match_operand:XF 1 "register_operand" "+f"))
3558 if (STACK_TOP_P (operands[0]))
3563 [(set_attr "type" "fxch")
3564 (set_attr "mode" "XF")])
3566 (define_insn "*swap<mode>"
3567 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3568 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3571 "TARGET_80387 || reload_completed"
3573 if (STACK_TOP_P (operands[0]))
3578 [(set_attr "type" "fxch")
3579 (set_attr "mode" "<MODE>")])
3581 ;; Zero extension instructions
3583 (define_expand "zero_extendsidi2"
3584 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3585 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3590 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3595 (define_insn "*zero_extendsidi2_rex64"
3596 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3598 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3601 mov\t{%k1, %k0|%k0, %k1}
3603 movd\t{%1, %0|%0, %1}
3604 movd\t{%1, %0|%0, %1}
3605 %vmovd\t{%1, %0|%0, %1}
3606 %vmovd\t{%1, %0|%0, %1}"
3607 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3608 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3609 (set_attr "prefix_0f" "0,*,*,*,*,*")
3610 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3613 [(set (match_operand:DI 0 "memory_operand" "")
3614 (zero_extend:DI (match_dup 0)))]
3616 [(set (match_dup 4) (const_int 0))]
3617 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_insn "zero_extendsidi2_1"
3621 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3623 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3624 (clobber (reg:CC FLAGS_REG))]
3630 movd\t{%1, %0|%0, %1}
3631 movd\t{%1, %0|%0, %1}
3632 %vmovd\t{%1, %0|%0, %1}
3633 %vmovd\t{%1, %0|%0, %1}"
3634 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3635 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3636 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3639 [(set (match_operand:DI 0 "register_operand" "")
3640 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3641 (clobber (reg:CC FLAGS_REG))]
3642 "!TARGET_64BIT && reload_completed
3643 && true_regnum (operands[0]) == true_regnum (operands[1])"
3644 [(set (match_dup 4) (const_int 0))]
3645 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3648 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3649 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3650 (clobber (reg:CC FLAGS_REG))]
3651 "!TARGET_64BIT && reload_completed
3652 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3653 [(set (match_dup 3) (match_dup 1))
3654 (set (match_dup 4) (const_int 0))]
3655 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3657 (define_insn "zero_extend<mode>di2"
3658 [(set (match_operand:DI 0 "register_operand" "=r")
3660 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3662 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3663 [(set_attr "type" "imovx")
3664 (set_attr "mode" "SI")])
3666 (define_expand "zero_extendhisi2"
3667 [(set (match_operand:SI 0 "register_operand" "")
3668 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3671 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3673 operands[1] = force_reg (HImode, operands[1]);
3674 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3679 (define_insn_and_split "zero_extendhisi2_and"
3680 [(set (match_operand:SI 0 "register_operand" "=r")
3681 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3682 (clobber (reg:CC FLAGS_REG))]
3683 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3685 "&& reload_completed"
3686 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3687 (clobber (reg:CC FLAGS_REG))])]
3689 [(set_attr "type" "alu1")
3690 (set_attr "mode" "SI")])
3692 (define_insn "*zero_extendhisi2_movzwl"
3693 [(set (match_operand:SI 0 "register_operand" "=r")
3694 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3695 "!TARGET_ZERO_EXTEND_WITH_AND
3696 || optimize_function_for_size_p (cfun)"
3697 "movz{wl|x}\t{%1, %0|%0, %1}"
3698 [(set_attr "type" "imovx")
3699 (set_attr "mode" "SI")])
3701 (define_expand "zero_extendqi<mode>2"
3703 [(set (match_operand:SWI24 0 "register_operand" "")
3704 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3705 (clobber (reg:CC FLAGS_REG))])])
3707 (define_insn "*zero_extendqi<mode>2_and"
3708 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3709 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3710 (clobber (reg:CC FLAGS_REG))]
3711 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3713 [(set_attr "type" "alu1")
3714 (set_attr "mode" "<MODE>")])
3716 ;; When source and destination does not overlap, clear destination
3717 ;; first and then do the movb
3719 [(set (match_operand:SWI24 0 "register_operand" "")
3720 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3721 (clobber (reg:CC FLAGS_REG))]
3723 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3724 && ANY_QI_REG_P (operands[0])
3725 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3726 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3727 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3729 operands[2] = gen_lowpart (QImode, operands[0]);
3730 ix86_expand_clear (operands[0]);
3733 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3734 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3735 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3736 (clobber (reg:CC FLAGS_REG))]
3737 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3739 [(set_attr "type" "imovx,alu1")
3740 (set_attr "mode" "<MODE>")])
3742 ;; For the movzbl case strip only the clobber
3744 [(set (match_operand:SWI24 0 "register_operand" "")
3745 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3746 (clobber (reg:CC FLAGS_REG))]
3748 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3749 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3751 (zero_extend:SWI24 (match_dup 1)))])
3753 ; zero extend to SImode to avoid partial register stalls
3754 (define_insn "*zero_extendqi<mode>2_movzbl"
3755 [(set (match_operand:SWI24 0 "register_operand" "=r")
3756 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3758 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3759 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3760 [(set_attr "type" "imovx")
3761 (set_attr "mode" "SI")])
3763 ;; Rest is handled by single and.
3765 [(set (match_operand:SWI24 0 "register_operand" "")
3766 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3767 (clobber (reg:CC FLAGS_REG))]
3769 && true_regnum (operands[0]) == true_regnum (operands[1])"
3770 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3771 (clobber (reg:CC FLAGS_REG))])])
3773 ;; Sign extension instructions
3775 (define_expand "extendsidi2"
3776 [(set (match_operand:DI 0 "register_operand" "")
3777 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3782 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3787 (define_insn "*extendsidi2_rex64"
3788 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3789 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3793 movs{lq|x}\t{%1, %0|%0, %1}"
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "DI")
3796 (set_attr "prefix_0f" "0")
3797 (set_attr "modrm" "0,1")])
3799 (define_insn "extendsidi2_1"
3800 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3801 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3802 (clobber (reg:CC FLAGS_REG))
3803 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3807 ;; Extend to memory case when source register does die.
3809 [(set (match_operand:DI 0 "memory_operand" "")
3810 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3811 (clobber (reg:CC FLAGS_REG))
3812 (clobber (match_operand:SI 2 "register_operand" ""))]
3814 && dead_or_set_p (insn, operands[1])
3815 && !reg_mentioned_p (operands[1], operands[0]))"
3816 [(set (match_dup 3) (match_dup 1))
3817 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3818 (clobber (reg:CC FLAGS_REG))])
3819 (set (match_dup 4) (match_dup 1))]
3820 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3822 ;; Extend to memory case when source register does not die.
3824 [(set (match_operand:DI 0 "memory_operand" "")
3825 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3826 (clobber (reg:CC FLAGS_REG))
3827 (clobber (match_operand:SI 2 "register_operand" ""))]
3831 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3833 emit_move_insn (operands[3], operands[1]);
3835 /* Generate a cltd if possible and doing so it profitable. */
3836 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3837 && true_regnum (operands[1]) == AX_REG
3838 && true_regnum (operands[2]) == DX_REG)
3840 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3844 emit_move_insn (operands[2], operands[1]);
3845 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3847 emit_move_insn (operands[4], operands[2]);
3851 ;; Extend to register case. Optimize case where source and destination
3852 ;; registers match and cases where we can use cltd.
3854 [(set (match_operand:DI 0 "register_operand" "")
3855 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3856 (clobber (reg:CC FLAGS_REG))
3857 (clobber (match_scratch:SI 2 ""))]
3861 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3863 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3864 emit_move_insn (operands[3], operands[1]);
3866 /* Generate a cltd if possible and doing so it profitable. */
3867 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3868 && true_regnum (operands[3]) == AX_REG
3869 && true_regnum (operands[4]) == DX_REG)
3871 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3875 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3876 emit_move_insn (operands[4], operands[1]);
3878 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3882 (define_insn "extend<mode>di2"
3883 [(set (match_operand:DI 0 "register_operand" "=r")
3885 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3887 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3888 [(set_attr "type" "imovx")
3889 (set_attr "mode" "DI")])
3891 (define_insn "extendhisi2"
3892 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3893 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3896 switch (get_attr_prefix_0f (insn))
3899 return "{cwtl|cwde}";
3901 return "movs{wl|x}\t{%1, %0|%0, %1}";
3904 [(set_attr "type" "imovx")
3905 (set_attr "mode" "SI")
3906 (set (attr "prefix_0f")
3907 ;; movsx is short decodable while cwtl is vector decoded.
3908 (if_then_else (and (eq_attr "cpu" "!k6")
3909 (eq_attr "alternative" "0"))
3911 (const_string "1")))
3913 (if_then_else (eq_attr "prefix_0f" "0")
3915 (const_string "1")))])
3917 (define_insn "*extendhisi2_zext"
3918 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3921 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3924 switch (get_attr_prefix_0f (insn))
3927 return "{cwtl|cwde}";
3929 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")
3934 (set (attr "prefix_0f")
3935 ;; movsx is short decodable while cwtl is vector decoded.
3936 (if_then_else (and (eq_attr "cpu" "!k6")
3937 (eq_attr "alternative" "0"))
3939 (const_string "1")))
3941 (if_then_else (eq_attr "prefix_0f" "0")
3943 (const_string "1")))])
3945 (define_insn "extendqisi2"
3946 [(set (match_operand:SI 0 "register_operand" "=r")
3947 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3949 "movs{bl|x}\t{%1, %0|%0, %1}"
3950 [(set_attr "type" "imovx")
3951 (set_attr "mode" "SI")])
3953 (define_insn "*extendqisi2_zext"
3954 [(set (match_operand:DI 0 "register_operand" "=r")
3956 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3958 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3959 [(set_attr "type" "imovx")
3960 (set_attr "mode" "SI")])
3962 (define_insn "extendqihi2"
3963 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3964 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3967 switch (get_attr_prefix_0f (insn))
3970 return "{cbtw|cbw}";
3972 return "movs{bw|x}\t{%1, %0|%0, %1}";
3975 [(set_attr "type" "imovx")
3976 (set_attr "mode" "HI")
3977 (set (attr "prefix_0f")
3978 ;; movsx is short decodable while cwtl is vector decoded.
3979 (if_then_else (and (eq_attr "cpu" "!k6")
3980 (eq_attr "alternative" "0"))
3982 (const_string "1")))
3984 (if_then_else (eq_attr "prefix_0f" "0")
3986 (const_string "1")))])
3988 ;; Conversions between float and double.
3990 ;; These are all no-ops in the model used for the 80387.
3991 ;; So just emit moves.
3993 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3995 [(set (match_operand:DF 0 "push_operand" "")
3996 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3998 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3999 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4002 [(set (match_operand:XF 0 "push_operand" "")
4003 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4005 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4006 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4007 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4009 (define_expand "extendsfdf2"
4010 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4011 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4012 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4014 /* ??? Needed for compress_float_constant since all fp constants
4015 are LEGITIMATE_CONSTANT_P. */
4016 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4018 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4019 && standard_80387_constant_p (operands[1]) > 0)
4021 operands[1] = simplify_const_unary_operation
4022 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4023 emit_move_insn_1 (operands[0], operands[1]);
4026 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4030 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4032 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4034 We do the conversion post reload to avoid producing of 128bit spills
4035 that might lead to ICE on 32bit target. The sequence unlikely combine
4038 [(set (match_operand:DF 0 "register_operand" "")
4040 (match_operand:SF 1 "nonimmediate_operand" "")))]
4041 "TARGET_USE_VECTOR_FP_CONVERTS
4042 && optimize_insn_for_speed_p ()
4043 && reload_completed && SSE_REG_P (operands[0])"
4048 (parallel [(const_int 0) (const_int 1)]))))]
4050 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4051 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4052 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4053 Try to avoid move when unpacking can be done in source. */
4054 if (REG_P (operands[1]))
4056 /* If it is unsafe to overwrite upper half of source, we need
4057 to move to destination and unpack there. */
4058 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4059 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4060 && true_regnum (operands[0]) != true_regnum (operands[1]))
4062 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4063 emit_move_insn (tmp, operands[1]);
4066 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4067 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4071 emit_insn (gen_vec_setv4sf_0 (operands[3],
4072 CONST0_RTX (V4SFmode), operands[1]));
4075 (define_insn "*extendsfdf2_mixed"
4076 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4078 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4079 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4081 switch (which_alternative)
4085 return output_387_reg_move (insn, operands);
4088 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4094 [(set_attr "type" "fmov,fmov,ssecvt")
4095 (set_attr "prefix" "orig,orig,maybe_vex")
4096 (set_attr "mode" "SF,XF,DF")])
4098 (define_insn "*extendsfdf2_sse"
4099 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4100 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4101 "TARGET_SSE2 && TARGET_SSE_MATH"
4102 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4103 [(set_attr "type" "ssecvt")
4104 (set_attr "prefix" "maybe_vex")
4105 (set_attr "mode" "DF")])
4107 (define_insn "*extendsfdf2_i387"
4108 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4109 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4111 "* return output_387_reg_move (insn, operands);"
4112 [(set_attr "type" "fmov")
4113 (set_attr "mode" "SF,XF")])
4115 (define_expand "extend<mode>xf2"
4116 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4117 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4120 /* ??? Needed for compress_float_constant since all fp constants
4121 are LEGITIMATE_CONSTANT_P. */
4122 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4124 if (standard_80387_constant_p (operands[1]) > 0)
4126 operands[1] = simplify_const_unary_operation
4127 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4128 emit_move_insn_1 (operands[0], operands[1]);
4131 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4135 (define_insn "*extend<mode>xf2_i387"
4136 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4138 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4140 "* return output_387_reg_move (insn, operands);"
4141 [(set_attr "type" "fmov")
4142 (set_attr "mode" "<MODE>,XF")])
4144 ;; %%% This seems bad bad news.
4145 ;; This cannot output into an f-reg because there is no way to be sure
4146 ;; of truncating in that case. Otherwise this is just like a simple move
4147 ;; insn. So we pretend we can output to a reg in order to get better
4148 ;; register preferencing, but we really use a stack slot.
4150 ;; Conversion from DFmode to SFmode.
4152 (define_expand "truncdfsf2"
4153 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4155 (match_operand:DF 1 "nonimmediate_operand" "")))]
4156 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4158 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4160 else if (flag_unsafe_math_optimizations)
4164 enum ix86_stack_slot slot = (virtuals_instantiated
4167 rtx temp = assign_386_stack_local (SFmode, slot);
4168 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4173 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4175 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4177 We do the conversion post reload to avoid producing of 128bit spills
4178 that might lead to ICE on 32bit target. The sequence unlikely combine
4181 [(set (match_operand:SF 0 "register_operand" "")
4183 (match_operand:DF 1 "nonimmediate_operand" "")))]
4184 "TARGET_USE_VECTOR_FP_CONVERTS
4185 && optimize_insn_for_speed_p ()
4186 && reload_completed && SSE_REG_P (operands[0])"
4189 (float_truncate:V2SF
4193 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4194 operands[3] = CONST0_RTX (V2SFmode);
4195 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4196 /* Use movsd for loading from memory, unpcklpd for registers.
4197 Try to avoid move when unpacking can be done in source, or SSE3
4198 movddup is available. */
4199 if (REG_P (operands[1]))
4202 && true_regnum (operands[0]) != true_regnum (operands[1])
4203 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4204 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4206 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4207 emit_move_insn (tmp, operands[1]);
4210 else if (!TARGET_SSE3)
4211 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4212 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4215 emit_insn (gen_sse2_loadlpd (operands[4],
4216 CONST0_RTX (V2DFmode), operands[1]));
4219 (define_expand "truncdfsf2_with_temp"
4220 [(parallel [(set (match_operand:SF 0 "" "")
4221 (float_truncate:SF (match_operand:DF 1 "" "")))
4222 (clobber (match_operand:SF 2 "" ""))])])
4224 (define_insn "*truncdfsf_fast_mixed"
4225 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4227 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4228 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4230 switch (which_alternative)
4233 return output_387_reg_move (insn, operands);
4235 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4240 [(set_attr "type" "fmov,ssecvt")
4241 (set_attr "prefix" "orig,maybe_vex")
4242 (set_attr "mode" "SF")])
4244 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4245 ;; because nothing we do here is unsafe.
4246 (define_insn "*truncdfsf_fast_sse"
4247 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4249 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4250 "TARGET_SSE2 && TARGET_SSE_MATH"
4251 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4252 [(set_attr "type" "ssecvt")
4253 (set_attr "prefix" "maybe_vex")
4254 (set_attr "mode" "SF")])
4256 (define_insn "*truncdfsf_fast_i387"
4257 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4259 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4260 "TARGET_80387 && flag_unsafe_math_optimizations"
4261 "* return output_387_reg_move (insn, operands);"
4262 [(set_attr "type" "fmov")
4263 (set_attr "mode" "SF")])
4265 (define_insn "*truncdfsf_mixed"
4266 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4268 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4269 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4270 "TARGET_MIX_SSE_I387"
4272 switch (which_alternative)
4275 return output_387_reg_move (insn, operands);
4277 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4283 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4284 (set_attr "unit" "*,*,i387,i387,i387")
4285 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4286 (set_attr "mode" "SF")])
4288 (define_insn "*truncdfsf_i387"
4289 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4291 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4292 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4295 switch (which_alternative)
4298 return output_387_reg_move (insn, operands);
4304 [(set_attr "type" "fmov,multi,multi,multi")
4305 (set_attr "unit" "*,i387,i387,i387")
4306 (set_attr "mode" "SF")])
4308 (define_insn "*truncdfsf2_i387_1"
4309 [(set (match_operand:SF 0 "memory_operand" "=m")
4311 (match_operand:DF 1 "register_operand" "f")))]
4313 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4314 && !TARGET_MIX_SSE_I387"
4315 "* return output_387_reg_move (insn, operands);"
4316 [(set_attr "type" "fmov")
4317 (set_attr "mode" "SF")])
4320 [(set (match_operand:SF 0 "register_operand" "")
4322 (match_operand:DF 1 "fp_register_operand" "")))
4323 (clobber (match_operand 2 "" ""))]
4325 [(set (match_dup 2) (match_dup 1))
4326 (set (match_dup 0) (match_dup 2))]
4327 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4329 ;; Conversion from XFmode to {SF,DF}mode
4331 (define_expand "truncxf<mode>2"
4332 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4333 (float_truncate:MODEF
4334 (match_operand:XF 1 "register_operand" "")))
4335 (clobber (match_dup 2))])]
4338 if (flag_unsafe_math_optimizations)
4340 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4341 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4342 if (reg != operands[0])
4343 emit_move_insn (operands[0], reg);
4348 enum ix86_stack_slot slot = (virtuals_instantiated
4351 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4355 (define_insn "*truncxfsf2_mixed"
4356 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4358 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4359 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4362 gcc_assert (!which_alternative);
4363 return output_387_reg_move (insn, operands);
4365 [(set_attr "type" "fmov,multi,multi,multi")
4366 (set_attr "unit" "*,i387,i387,i387")
4367 (set_attr "mode" "SF")])
4369 (define_insn "*truncxfdf2_mixed"
4370 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4372 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4373 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4376 gcc_assert (!which_alternative);
4377 return output_387_reg_move (insn, operands);
4379 [(set_attr "type" "fmov,multi,multi,multi")
4380 (set_attr "unit" "*,i387,i387,i387")
4381 (set_attr "mode" "DF")])
4383 (define_insn "truncxf<mode>2_i387_noop"
4384 [(set (match_operand:MODEF 0 "register_operand" "=f")
4385 (float_truncate:MODEF
4386 (match_operand:XF 1 "register_operand" "f")))]
4387 "TARGET_80387 && flag_unsafe_math_optimizations"
4388 "* return output_387_reg_move (insn, operands);"
4389 [(set_attr "type" "fmov")
4390 (set_attr "mode" "<MODE>")])
4392 (define_insn "*truncxf<mode>2_i387"
4393 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4394 (float_truncate:MODEF
4395 (match_operand:XF 1 "register_operand" "f")))]
4397 "* return output_387_reg_move (insn, operands);"
4398 [(set_attr "type" "fmov")
4399 (set_attr "mode" "<MODE>")])
4402 [(set (match_operand:MODEF 0 "register_operand" "")
4403 (float_truncate:MODEF
4404 (match_operand:XF 1 "register_operand" "")))
4405 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4406 "TARGET_80387 && reload_completed"
4407 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4408 (set (match_dup 0) (match_dup 2))])
4411 [(set (match_operand:MODEF 0 "memory_operand" "")
4412 (float_truncate:MODEF
4413 (match_operand:XF 1 "register_operand" "")))
4414 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4416 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4418 ;; Signed conversion to DImode.
4420 (define_expand "fix_truncxfdi2"
4421 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422 (fix:DI (match_operand:XF 1 "register_operand" "")))
4423 (clobber (reg:CC FLAGS_REG))])]
4428 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4433 (define_expand "fix_trunc<mode>di2"
4434 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4435 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4436 (clobber (reg:CC FLAGS_REG))])]
4437 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4440 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4442 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4445 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4447 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4448 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4449 if (out != operands[0])
4450 emit_move_insn (operands[0], out);
4455 ;; Signed conversion to SImode.
4457 (define_expand "fix_truncxfsi2"
4458 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459 (fix:SI (match_operand:XF 1 "register_operand" "")))
4460 (clobber (reg:CC FLAGS_REG))])]
4465 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4470 (define_expand "fix_trunc<mode>si2"
4471 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4472 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4473 (clobber (reg:CC FLAGS_REG))])]
4474 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4477 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4479 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4482 if (SSE_FLOAT_MODE_P (<MODE>mode))
4484 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4485 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4486 if (out != operands[0])
4487 emit_move_insn (operands[0], out);
4492 ;; Signed conversion to HImode.
4494 (define_expand "fix_trunc<mode>hi2"
4495 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4496 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4497 (clobber (reg:CC FLAGS_REG))])]
4499 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4503 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4508 ;; Unsigned conversion to SImode.
4510 (define_expand "fixuns_trunc<mode>si2"
4512 [(set (match_operand:SI 0 "register_operand" "")
4514 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4516 (clobber (match_scratch:<ssevecmode> 3 ""))
4517 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4518 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4520 enum machine_mode mode = <MODE>mode;
4521 enum machine_mode vecmode = <ssevecmode>mode;
4522 REAL_VALUE_TYPE TWO31r;
4525 if (optimize_insn_for_size_p ())
4528 real_ldexp (&TWO31r, &dconst1, 31);
4529 two31 = const_double_from_real_value (TWO31r, mode);
4530 two31 = ix86_build_const_vector (vecmode, true, two31);
4531 operands[2] = force_reg (vecmode, two31);
4534 (define_insn_and_split "*fixuns_trunc<mode>_1"
4535 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4537 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4538 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4539 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4540 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4541 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4542 && optimize_function_for_speed_p (cfun)"
4544 "&& reload_completed"
4547 ix86_split_convert_uns_si_sse (operands);
4551 ;; Unsigned conversion to HImode.
4552 ;; Without these patterns, we'll try the unsigned SI conversion which
4553 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4555 (define_expand "fixuns_trunc<mode>hi2"
4557 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4558 (set (match_operand:HI 0 "nonimmediate_operand" "")
4559 (subreg:HI (match_dup 2) 0))]
4560 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4561 "operands[2] = gen_reg_rtx (SImode);")
4563 ;; When SSE is available, it is always faster to use it!
4564 (define_insn "fix_trunc<mode>di_sse"
4565 [(set (match_operand:DI 0 "register_operand" "=r,r")
4566 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4567 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4568 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4569 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4570 [(set_attr "type" "sseicvt")
4571 (set_attr "prefix" "maybe_vex")
4572 (set_attr "prefix_rex" "1")
4573 (set_attr "mode" "<MODE>")
4574 (set_attr "athlon_decode" "double,vector")
4575 (set_attr "amdfam10_decode" "double,double")
4576 (set_attr "bdver1_decode" "double,double")])
4578 (define_insn "fix_trunc<mode>si_sse"
4579 [(set (match_operand:SI 0 "register_operand" "=r,r")
4580 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4581 "SSE_FLOAT_MODE_P (<MODE>mode)
4582 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4583 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4584 [(set_attr "type" "sseicvt")
4585 (set_attr "prefix" "maybe_vex")
4586 (set_attr "mode" "<MODE>")
4587 (set_attr "athlon_decode" "double,vector")
4588 (set_attr "amdfam10_decode" "double,double")
4589 (set_attr "bdver1_decode" "double,double")])
4591 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4593 [(set (match_operand:MODEF 0 "register_operand" "")
4594 (match_operand:MODEF 1 "memory_operand" ""))
4595 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4596 (fix:SSEMODEI24 (match_dup 0)))]
4597 "TARGET_SHORTEN_X87_SSE
4598 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4599 && peep2_reg_dead_p (2, operands[0])"
4600 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4602 ;; Avoid vector decoded forms of the instruction.
4604 [(match_scratch:DF 2 "Y2")
4605 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4606 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4607 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4608 [(set (match_dup 2) (match_dup 1))
4609 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4612 [(match_scratch:SF 2 "x")
4613 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4614 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4615 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4616 [(set (match_dup 2) (match_dup 1))
4617 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4619 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4620 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4621 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4622 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4624 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4625 && (TARGET_64BIT || <MODE>mode != DImode))
4627 && can_create_pseudo_p ()"
4632 if (memory_operand (operands[0], VOIDmode))
4633 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4636 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4637 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4643 [(set_attr "type" "fisttp")
4644 (set_attr "mode" "<MODE>")])
4646 (define_insn "fix_trunc<mode>_i387_fisttp"
4647 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4648 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4649 (clobber (match_scratch:XF 2 "=&1f"))]
4650 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && (TARGET_64BIT || <MODE>mode != DImode))
4654 && TARGET_SSE_MATH)"
4655 "* return output_fix_trunc (insn, operands, 1);"
4656 [(set_attr "type" "fisttp")
4657 (set_attr "mode" "<MODE>")])
4659 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4660 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4661 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4662 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4663 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4664 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4666 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4667 && (TARGET_64BIT || <MODE>mode != DImode))
4668 && TARGET_SSE_MATH)"
4670 [(set_attr "type" "fisttp")
4671 (set_attr "mode" "<MODE>")])
4674 [(set (match_operand:X87MODEI 0 "register_operand" "")
4675 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4676 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4677 (clobber (match_scratch 3 ""))]
4679 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4680 (clobber (match_dup 3))])
4681 (set (match_dup 0) (match_dup 2))])
4684 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4685 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4686 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4687 (clobber (match_scratch 3 ""))]
4689 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4690 (clobber (match_dup 3))])])
4692 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4693 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4694 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4695 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4696 ;; function in i386.c.
4697 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4698 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4699 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4700 (clobber (reg:CC FLAGS_REG))]
4701 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4703 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4704 && (TARGET_64BIT || <MODE>mode != DImode))
4705 && can_create_pseudo_p ()"
4710 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4712 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4713 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4714 if (memory_operand (operands[0], VOIDmode))
4715 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4716 operands[2], operands[3]));
4719 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4720 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4721 operands[2], operands[3],
4726 [(set_attr "type" "fistp")
4727 (set_attr "i387_cw" "trunc")
4728 (set_attr "mode" "<MODE>")])
4730 (define_insn "fix_truncdi_i387"
4731 [(set (match_operand:DI 0 "memory_operand" "=m")
4732 (fix:DI (match_operand 1 "register_operand" "f")))
4733 (use (match_operand:HI 2 "memory_operand" "m"))
4734 (use (match_operand:HI 3 "memory_operand" "m"))
4735 (clobber (match_scratch:XF 4 "=&1f"))]
4736 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4738 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4739 "* return output_fix_trunc (insn, operands, 0);"
4740 [(set_attr "type" "fistp")
4741 (set_attr "i387_cw" "trunc")
4742 (set_attr "mode" "DI")])
4744 (define_insn "fix_truncdi_i387_with_temp"
4745 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4746 (fix:DI (match_operand 1 "register_operand" "f,f")))
4747 (use (match_operand:HI 2 "memory_operand" "m,m"))
4748 (use (match_operand:HI 3 "memory_operand" "m,m"))
4749 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4750 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4751 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4753 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4755 [(set_attr "type" "fistp")
4756 (set_attr "i387_cw" "trunc")
4757 (set_attr "mode" "DI")])
4760 [(set (match_operand:DI 0 "register_operand" "")
4761 (fix:DI (match_operand 1 "register_operand" "")))
4762 (use (match_operand:HI 2 "memory_operand" ""))
4763 (use (match_operand:HI 3 "memory_operand" ""))
4764 (clobber (match_operand:DI 4 "memory_operand" ""))
4765 (clobber (match_scratch 5 ""))]
4767 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4770 (clobber (match_dup 5))])
4771 (set (match_dup 0) (match_dup 4))])
4774 [(set (match_operand:DI 0 "memory_operand" "")
4775 (fix:DI (match_operand 1 "register_operand" "")))
4776 (use (match_operand:HI 2 "memory_operand" ""))
4777 (use (match_operand:HI 3 "memory_operand" ""))
4778 (clobber (match_operand:DI 4 "memory_operand" ""))
4779 (clobber (match_scratch 5 ""))]
4781 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4784 (clobber (match_dup 5))])])
4786 (define_insn "fix_trunc<mode>_i387"
4787 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4788 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4789 (use (match_operand:HI 2 "memory_operand" "m"))
4790 (use (match_operand:HI 3 "memory_operand" "m"))]
4791 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4793 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4794 "* return output_fix_trunc (insn, operands, 0);"
4795 [(set_attr "type" "fistp")
4796 (set_attr "i387_cw" "trunc")
4797 (set_attr "mode" "<MODE>")])
4799 (define_insn "fix_trunc<mode>_i387_with_temp"
4800 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4801 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4802 (use (match_operand:HI 2 "memory_operand" "m,m"))
4803 (use (match_operand:HI 3 "memory_operand" "m,m"))
4804 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4805 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4807 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4809 [(set_attr "type" "fistp")
4810 (set_attr "i387_cw" "trunc")
4811 (set_attr "mode" "<MODE>")])
4814 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4815 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4816 (use (match_operand:HI 2 "memory_operand" ""))
4817 (use (match_operand:HI 3 "memory_operand" ""))
4818 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4820 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4822 (use (match_dup 3))])
4823 (set (match_dup 0) (match_dup 4))])
4826 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4827 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4828 (use (match_operand:HI 2 "memory_operand" ""))
4829 (use (match_operand:HI 3 "memory_operand" ""))
4830 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4832 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4834 (use (match_dup 3))])])
4836 (define_insn "x86_fnstcw_1"
4837 [(set (match_operand:HI 0 "memory_operand" "=m")
4838 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4841 [(set (attr "length")
4842 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4843 (set_attr "mode" "HI")
4844 (set_attr "unit" "i387")
4845 (set_attr "bdver1_decode" "vector")])
4847 (define_insn "x86_fldcw_1"
4848 [(set (reg:HI FPCR_REG)
4849 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4852 [(set (attr "length")
4853 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4854 (set_attr "mode" "HI")
4855 (set_attr "unit" "i387")
4856 (set_attr "athlon_decode" "vector")
4857 (set_attr "amdfam10_decode" "vector")
4858 (set_attr "bdver1_decode" "vector")])
4860 ;; Conversion between fixed point and floating point.
4862 ;; Even though we only accept memory inputs, the backend _really_
4863 ;; wants to be able to do this between registers.
4865 (define_expand "floathi<mode>2"
4866 [(set (match_operand:X87MODEF 0 "register_operand" "")
4867 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870 || TARGET_MIX_SSE_I387)")
4872 ;; Pre-reload splitter to add memory clobber to the pattern.
4873 (define_insn_and_split "*floathi<mode>2_1"
4874 [(set (match_operand:X87MODEF 0 "register_operand" "")
4875 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4878 || TARGET_MIX_SSE_I387)
4879 && can_create_pseudo_p ()"
4882 [(parallel [(set (match_dup 0)
4883 (float:X87MODEF (match_dup 1)))
4884 (clobber (match_dup 2))])]
4885 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4887 (define_insn "*floathi<mode>2_i387_with_temp"
4888 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4889 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4890 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4893 || TARGET_MIX_SSE_I387)"
4895 [(set_attr "type" "fmov,multi")
4896 (set_attr "mode" "<MODE>")
4897 (set_attr "unit" "*,i387")
4898 (set_attr "fp_int_src" "true")])
4900 (define_insn "*floathi<mode>2_i387"
4901 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4902 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4905 || TARGET_MIX_SSE_I387)"
4907 [(set_attr "type" "fmov")
4908 (set_attr "mode" "<MODE>")
4909 (set_attr "fp_int_src" "true")])
4912 [(set (match_operand:X87MODEF 0 "register_operand" "")
4913 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4914 (clobber (match_operand:HI 2 "memory_operand" ""))]
4916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4917 || TARGET_MIX_SSE_I387)
4918 && reload_completed"
4919 [(set (match_dup 2) (match_dup 1))
4920 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4923 [(set (match_operand:X87MODEF 0 "register_operand" "")
4924 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4925 (clobber (match_operand:HI 2 "memory_operand" ""))]
4927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4928 || TARGET_MIX_SSE_I387)
4929 && reload_completed"
4930 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4932 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4933 [(set (match_operand:X87MODEF 0 "register_operand" "")
4935 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4937 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4938 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4940 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4941 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4942 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4944 rtx reg = gen_reg_rtx (XFmode);
4947 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4949 if (<X87MODEF:MODE>mode == SFmode)
4950 insn = gen_truncxfsf2 (operands[0], reg);
4951 else if (<X87MODEF:MODE>mode == DFmode)
4952 insn = gen_truncxfdf2 (operands[0], reg);
4961 ;; Pre-reload splitter to add memory clobber to the pattern.
4962 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4963 [(set (match_operand:X87MODEF 0 "register_operand" "")
4964 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4966 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4967 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4968 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4969 || TARGET_MIX_SSE_I387))
4970 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4971 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4972 && ((<SSEMODEI24:MODE>mode == SImode
4973 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4974 && optimize_function_for_speed_p (cfun)
4975 && flag_trapping_math)
4976 || !(TARGET_INTER_UNIT_CONVERSIONS
4977 || optimize_function_for_size_p (cfun)))))
4978 && can_create_pseudo_p ()"
4981 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4982 (clobber (match_dup 2))])]
4984 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4986 /* Avoid store forwarding (partial memory) stall penalty
4987 by passing DImode value through XMM registers. */
4988 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4989 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4990 && optimize_function_for_speed_p (cfun))
4992 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4999 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5000 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5002 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5003 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5004 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5008 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5009 (set_attr "unit" "*,i387,*,*,*")
5010 (set_attr "athlon_decode" "*,*,double,direct,double")
5011 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5012 (set_attr "bdver1_decode" "*,*,double,direct,double")
5013 (set_attr "fp_int_src" "true")])
5015 (define_insn "*floatsi<mode>2_vector_mixed"
5016 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5017 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5018 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5023 [(set_attr "type" "fmov,sseicvt")
5024 (set_attr "mode" "<MODE>,<ssevecmode>")
5025 (set_attr "unit" "i387,*")
5026 (set_attr "athlon_decode" "*,direct")
5027 (set_attr "amdfam10_decode" "*,double")
5028 (set_attr "bdver1_decode" "*,direct")
5029 (set_attr "fp_int_src" "true")])
5031 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5032 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5034 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5035 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5036 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5037 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5039 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5040 (set_attr "mode" "<MODEF:MODE>")
5041 (set_attr "unit" "*,i387,*,*")
5042 (set_attr "athlon_decode" "*,*,double,direct")
5043 (set_attr "amdfam10_decode" "*,*,vector,double")
5044 (set_attr "bdver1_decode" "*,*,double,direct")
5045 (set_attr "fp_int_src" "true")])
5048 [(set (match_operand:MODEF 0 "register_operand" "")
5049 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5050 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5051 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5052 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5053 && TARGET_INTER_UNIT_CONVERSIONS
5055 && (SSE_REG_P (operands[0])
5056 || (GET_CODE (operands[0]) == SUBREG
5057 && SSE_REG_P (operands[0])))"
5058 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5061 [(set (match_operand:MODEF 0 "register_operand" "")
5062 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5063 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5064 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5065 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5066 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5068 && (SSE_REG_P (operands[0])
5069 || (GET_CODE (operands[0]) == SUBREG
5070 && SSE_REG_P (operands[0])))"
5071 [(set (match_dup 2) (match_dup 1))
5072 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5074 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5075 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5077 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5078 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5080 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5083 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5084 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5085 [(set_attr "type" "fmov,sseicvt,sseicvt")
5086 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5087 (set_attr "mode" "<MODEF:MODE>")
5088 (set (attr "prefix_rex")
5090 (and (eq_attr "prefix" "maybe_vex")
5091 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5093 (const_string "*")))
5094 (set_attr "unit" "i387,*,*")
5095 (set_attr "athlon_decode" "*,double,direct")
5096 (set_attr "amdfam10_decode" "*,vector,double")
5097 (set_attr "bdver1_decode" "*,double,direct")
5098 (set_attr "fp_int_src" "true")])
5100 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5101 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5103 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5104 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5106 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5109 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5110 [(set_attr "type" "fmov,sseicvt")
5111 (set_attr "prefix" "orig,maybe_vex")
5112 (set_attr "mode" "<MODEF:MODE>")
5113 (set (attr "prefix_rex")
5115 (and (eq_attr "prefix" "maybe_vex")
5116 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5118 (const_string "*")))
5119 (set_attr "athlon_decode" "*,direct")
5120 (set_attr "amdfam10_decode" "*,double")
5121 (set_attr "bdver1_decode" "*,direct")
5122 (set_attr "fp_int_src" "true")])
5124 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5125 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5127 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5128 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5129 "TARGET_SSE2 && TARGET_SSE_MATH
5130 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5132 [(set_attr "type" "sseicvt")
5133 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5134 (set_attr "athlon_decode" "double,direct,double")
5135 (set_attr "amdfam10_decode" "vector,double,double")
5136 (set_attr "bdver1_decode" "double,direct,double")
5137 (set_attr "fp_int_src" "true")])
5139 (define_insn "*floatsi<mode>2_vector_sse"
5140 [(set (match_operand:MODEF 0 "register_operand" "=x")
5141 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5142 "TARGET_SSE2 && TARGET_SSE_MATH
5143 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5145 [(set_attr "type" "sseicvt")
5146 (set_attr "mode" "<MODE>")
5147 (set_attr "athlon_decode" "direct")
5148 (set_attr "amdfam10_decode" "double")
5149 (set_attr "bdver1_decode" "direct")
5150 (set_attr "fp_int_src" "true")])
5153 [(set (match_operand:MODEF 0 "register_operand" "")
5154 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5155 (clobber (match_operand:SI 2 "memory_operand" ""))]
5156 "TARGET_SSE2 && TARGET_SSE_MATH
5157 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5159 && (SSE_REG_P (operands[0])
5160 || (GET_CODE (operands[0]) == SUBREG
5161 && SSE_REG_P (operands[0])))"
5164 rtx op1 = operands[1];
5166 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5168 if (GET_CODE (op1) == SUBREG)
5169 op1 = SUBREG_REG (op1);
5171 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5173 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5174 emit_insn (gen_sse2_loadld (operands[4],
5175 CONST0_RTX (V4SImode), operands[1]));
5177 /* We can ignore possible trapping value in the
5178 high part of SSE register for non-trapping math. */
5179 else if (SSE_REG_P (op1) && !flag_trapping_math)
5180 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5183 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5184 emit_move_insn (operands[2], operands[1]);
5185 emit_insn (gen_sse2_loadld (operands[4],
5186 CONST0_RTX (V4SImode), operands[2]));
5189 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5194 [(set (match_operand:MODEF 0 "register_operand" "")
5195 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5196 (clobber (match_operand:SI 2 "memory_operand" ""))]
5197 "TARGET_SSE2 && TARGET_SSE_MATH
5198 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5200 && (SSE_REG_P (operands[0])
5201 || (GET_CODE (operands[0]) == SUBREG
5202 && SSE_REG_P (operands[0])))"
5205 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5207 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5209 emit_insn (gen_sse2_loadld (operands[4],
5210 CONST0_RTX (V4SImode), operands[1]));
5212 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5217 [(set (match_operand:MODEF 0 "register_operand" "")
5218 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5219 "TARGET_SSE2 && TARGET_SSE_MATH
5220 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5222 && (SSE_REG_P (operands[0])
5223 || (GET_CODE (operands[0]) == SUBREG
5224 && SSE_REG_P (operands[0])))"
5227 rtx op1 = operands[1];
5229 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5231 if (GET_CODE (op1) == SUBREG)
5232 op1 = SUBREG_REG (op1);
5234 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5236 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5237 emit_insn (gen_sse2_loadld (operands[4],
5238 CONST0_RTX (V4SImode), operands[1]));
5240 /* We can ignore possible trapping value in the
5241 high part of SSE register for non-trapping math. */
5242 else if (SSE_REG_P (op1) && !flag_trapping_math)
5243 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5247 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5252 [(set (match_operand:MODEF 0 "register_operand" "")
5253 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5254 "TARGET_SSE2 && TARGET_SSE_MATH
5255 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5257 && (SSE_REG_P (operands[0])
5258 || (GET_CODE (operands[0]) == SUBREG
5259 && SSE_REG_P (operands[0])))"
5262 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5264 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5266 emit_insn (gen_sse2_loadld (operands[4],
5267 CONST0_RTX (V4SImode), operands[1]));
5269 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5273 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5274 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5276 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5277 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5278 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5279 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5281 [(set_attr "type" "sseicvt")
5282 (set_attr "mode" "<MODEF:MODE>")
5283 (set_attr "athlon_decode" "double,direct")
5284 (set_attr "amdfam10_decode" "vector,double")
5285 (set_attr "bdver1_decode" "double,direct")
5286 (set_attr "fp_int_src" "true")])
5288 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5289 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5291 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5292 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5293 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5294 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5295 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5296 [(set_attr "type" "sseicvt")
5297 (set_attr "prefix" "maybe_vex")
5298 (set_attr "mode" "<MODEF:MODE>")
5299 (set (attr "prefix_rex")
5301 (and (eq_attr "prefix" "maybe_vex")
5302 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5304 (const_string "*")))
5305 (set_attr "athlon_decode" "double,direct")
5306 (set_attr "amdfam10_decode" "vector,double")
5307 (set_attr "bdver1_decode" "double,direct")
5308 (set_attr "fp_int_src" "true")])
5311 [(set (match_operand:MODEF 0 "register_operand" "")
5312 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5313 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5314 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5315 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5316 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5318 && (SSE_REG_P (operands[0])
5319 || (GET_CODE (operands[0]) == SUBREG
5320 && SSE_REG_P (operands[0])))"
5321 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5323 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5324 [(set (match_operand:MODEF 0 "register_operand" "=x")
5326 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5327 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5328 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5329 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5330 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5331 [(set_attr "type" "sseicvt")
5332 (set_attr "prefix" "maybe_vex")
5333 (set_attr "mode" "<MODEF:MODE>")
5334 (set (attr "prefix_rex")
5336 (and (eq_attr "prefix" "maybe_vex")
5337 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5339 (const_string "*")))
5340 (set_attr "athlon_decode" "direct")
5341 (set_attr "amdfam10_decode" "double")
5342 (set_attr "bdver1_decode" "direct")
5343 (set_attr "fp_int_src" "true")])
5346 [(set (match_operand:MODEF 0 "register_operand" "")
5347 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5348 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5349 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5350 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5351 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5353 && (SSE_REG_P (operands[0])
5354 || (GET_CODE (operands[0]) == SUBREG
5355 && SSE_REG_P (operands[0])))"
5356 [(set (match_dup 2) (match_dup 1))
5357 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5360 [(set (match_operand:MODEF 0 "register_operand" "")
5361 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5362 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5363 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5366 && (SSE_REG_P (operands[0])
5367 || (GET_CODE (operands[0]) == SUBREG
5368 && SSE_REG_P (operands[0])))"
5369 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5371 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5372 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5374 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5375 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5377 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5381 [(set_attr "type" "fmov,multi")
5382 (set_attr "mode" "<X87MODEF:MODE>")
5383 (set_attr "unit" "*,i387")
5384 (set_attr "fp_int_src" "true")])
5386 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5387 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5389 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5391 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5393 [(set_attr "type" "fmov")
5394 (set_attr "mode" "<X87MODEF:MODE>")
5395 (set_attr "fp_int_src" "true")])
5398 [(set (match_operand:X87MODEF 0 "register_operand" "")
5399 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5400 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5402 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5404 && FP_REG_P (operands[0])"
5405 [(set (match_dup 2) (match_dup 1))
5406 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5409 [(set (match_operand:X87MODEF 0 "register_operand" "")
5410 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5411 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5413 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5415 && FP_REG_P (operands[0])"
5416 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5418 ;; Avoid store forwarding (partial memory) stall penalty
5419 ;; by passing DImode value through XMM registers. */
5421 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5422 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5424 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5425 (clobber (match_scratch:V4SI 3 "=X,x"))
5426 (clobber (match_scratch:V4SI 4 "=X,x"))
5427 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5428 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5429 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5430 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5432 [(set_attr "type" "multi")
5433 (set_attr "mode" "<X87MODEF:MODE>")
5434 (set_attr "unit" "i387")
5435 (set_attr "fp_int_src" "true")])
5438 [(set (match_operand:X87MODEF 0 "register_operand" "")
5439 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5440 (clobber (match_scratch:V4SI 3 ""))
5441 (clobber (match_scratch:V4SI 4 ""))
5442 (clobber (match_operand:DI 2 "memory_operand" ""))]
5443 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5444 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5445 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5447 && FP_REG_P (operands[0])"
5448 [(set (match_dup 2) (match_dup 3))
5449 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5451 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5452 Assemble the 64-bit DImode value in an xmm register. */
5453 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5454 gen_rtx_SUBREG (SImode, operands[1], 0)));
5455 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5456 gen_rtx_SUBREG (SImode, operands[1], 4)));
5457 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5460 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5464 [(set (match_operand:X87MODEF 0 "register_operand" "")
5465 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5466 (clobber (match_scratch:V4SI 3 ""))
5467 (clobber (match_scratch:V4SI 4 ""))
5468 (clobber (match_operand:DI 2 "memory_operand" ""))]
5469 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5470 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5471 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5473 && FP_REG_P (operands[0])"
5474 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5476 ;; Avoid store forwarding (partial memory) stall penalty by extending
5477 ;; SImode value to DImode through XMM register instead of pushing two
5478 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5479 ;; targets benefit from this optimization. Also note that fild
5480 ;; loads from memory only.
5482 (define_insn "*floatunssi<mode>2_1"
5483 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5484 (unsigned_float:X87MODEF
5485 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5486 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5487 (clobber (match_scratch:SI 3 "=X,x"))]
5489 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5492 [(set_attr "type" "multi")
5493 (set_attr "mode" "<MODE>")])
5496 [(set (match_operand:X87MODEF 0 "register_operand" "")
5497 (unsigned_float:X87MODEF
5498 (match_operand:SI 1 "register_operand" "")))
5499 (clobber (match_operand:DI 2 "memory_operand" ""))
5500 (clobber (match_scratch:SI 3 ""))]
5502 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5504 && reload_completed"
5505 [(set (match_dup 2) (match_dup 1))
5507 (float:X87MODEF (match_dup 2)))]
5508 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5511 [(set (match_operand:X87MODEF 0 "register_operand" "")
5512 (unsigned_float:X87MODEF
5513 (match_operand:SI 1 "memory_operand" "")))
5514 (clobber (match_operand:DI 2 "memory_operand" ""))
5515 (clobber (match_scratch:SI 3 ""))]
5517 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5519 && reload_completed"
5520 [(set (match_dup 2) (match_dup 3))
5522 (float:X87MODEF (match_dup 2)))]
5524 emit_move_insn (operands[3], operands[1]);
5525 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5528 (define_expand "floatunssi<mode>2"
5530 [(set (match_operand:X87MODEF 0 "register_operand" "")
5531 (unsigned_float:X87MODEF
5532 (match_operand:SI 1 "nonimmediate_operand" "")))
5533 (clobber (match_dup 2))
5534 (clobber (match_scratch:SI 3 ""))])]
5536 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5538 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5540 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5542 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5547 enum ix86_stack_slot slot = (virtuals_instantiated
5550 operands[2] = assign_386_stack_local (DImode, slot);
5554 (define_expand "floatunsdisf2"
5555 [(use (match_operand:SF 0 "register_operand" ""))
5556 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5557 "TARGET_64BIT && TARGET_SSE_MATH"
5558 "x86_emit_floatuns (operands); DONE;")
5560 (define_expand "floatunsdidf2"
5561 [(use (match_operand:DF 0 "register_operand" ""))
5562 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5563 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5564 && TARGET_SSE2 && TARGET_SSE_MATH"
5567 x86_emit_floatuns (operands);
5569 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5575 (define_expand "add<mode>3"
5576 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5577 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5578 (match_operand:SDWIM 2 "<general_operand>" "")))]
5580 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5582 (define_insn_and_split "*add<dwi>3_doubleword"
5583 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5585 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5586 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5587 (clobber (reg:CC FLAGS_REG))]
5588 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5591 [(parallel [(set (reg:CC FLAGS_REG)
5592 (unspec:CC [(match_dup 1) (match_dup 2)]
5595 (plus:DWIH (match_dup 1) (match_dup 2)))])
5596 (parallel [(set (match_dup 3)
5600 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5602 (clobber (reg:CC FLAGS_REG))])]
5603 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5605 (define_insn "*add<mode>3_cc"
5606 [(set (reg:CC FLAGS_REG)
5608 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5609 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5611 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5612 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5613 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5614 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5615 [(set_attr "type" "alu")
5616 (set_attr "mode" "<MODE>")])
5618 (define_insn "addqi3_cc"
5619 [(set (reg:CC FLAGS_REG)
5621 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5622 (match_operand:QI 2 "general_operand" "qn,qm")]
5624 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5625 (plus:QI (match_dup 1) (match_dup 2)))]
5626 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5627 "add{b}\t{%2, %0|%0, %2}"
5628 [(set_attr "type" "alu")
5629 (set_attr "mode" "QI")])
5631 (define_insn "*lea_1"
5632 [(set (match_operand:P 0 "register_operand" "=r")
5633 (match_operand:P 1 "no_seg_address_operand" "p"))]
5635 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5636 [(set_attr "type" "lea")
5637 (set_attr "mode" "<MODE>")])
5639 (define_insn "*lea_2"
5640 [(set (match_operand:SI 0 "register_operand" "=r")
5641 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5643 "lea{l}\t{%a1, %0|%0, %a1}"
5644 [(set_attr "type" "lea")
5645 (set_attr "mode" "SI")])
5647 (define_insn "*lea_2_zext"
5648 [(set (match_operand:DI 0 "register_operand" "=r")
5650 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5652 "lea{l}\t{%a1, %k0|%k0, %a1}"
5653 [(set_attr "type" "lea")
5654 (set_attr "mode" "SI")])
5656 (define_insn "*add<mode>_1"
5657 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5659 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5660 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5661 (clobber (reg:CC FLAGS_REG))]
5662 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5664 switch (get_attr_type (insn))
5670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671 if (operands[2] == const1_rtx)
5672 return "inc{<imodesuffix>}\t%0";
5675 gcc_assert (operands[2] == constm1_rtx);
5676 return "dec{<imodesuffix>}\t%0";
5680 /* For most processors, ADD is faster than LEA. This alternative
5681 was added to use ADD as much as possible. */
5682 if (which_alternative == 2)
5685 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5690 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5692 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5696 (cond [(eq_attr "alternative" "3")
5697 (const_string "lea")
5698 (match_operand:SWI48 2 "incdec_operand" "")
5699 (const_string "incdec")
5701 (const_string "alu")))
5702 (set (attr "length_immediate")
5704 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5706 (const_string "*")))
5707 (set_attr "mode" "<MODE>")])
5709 ;; It may seem that nonimmediate operand is proper one for operand 1.
5710 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5711 ;; we take care in ix86_binary_operator_ok to not allow two memory
5712 ;; operands so proper swapping will be done in reload. This allow
5713 ;; patterns constructed from addsi_1 to match.
5715 (define_insn "*addsi_1_zext"
5716 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5718 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5719 (match_operand:SI 2 "general_operand" "g,0,li"))))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5723 switch (get_attr_type (insn))
5729 if (operands[2] == const1_rtx)
5730 return "inc{l}\t%k0";
5733 gcc_assert (operands[2] == constm1_rtx);
5734 return "dec{l}\t%k0";
5738 /* For most processors, ADD is faster than LEA. This alternative
5739 was added to use ADD as much as possible. */
5740 if (which_alternative == 1)
5743 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5746 if (x86_maybe_negate_const_int (&operands[2], SImode))
5747 return "sub{l}\t{%2, %k0|%k0, %2}";
5749 return "add{l}\t{%2, %k0|%k0, %2}";
5753 (cond [(eq_attr "alternative" "2")
5754 (const_string "lea")
5755 (match_operand:SI 2 "incdec_operand" "")
5756 (const_string "incdec")
5758 (const_string "alu")))
5759 (set (attr "length_immediate")
5761 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5763 (const_string "*")))
5764 (set_attr "mode" "SI")])
5766 (define_insn "*addhi_1"
5767 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5768 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5769 (match_operand:HI 2 "general_operand" "rn,rm")))
5770 (clobber (reg:CC FLAGS_REG))]
5771 "TARGET_PARTIAL_REG_STALL
5772 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5774 switch (get_attr_type (insn))
5777 if (operands[2] == const1_rtx)
5778 return "inc{w}\t%0";
5781 gcc_assert (operands[2] == constm1_rtx);
5782 return "dec{w}\t%0";
5786 if (x86_maybe_negate_const_int (&operands[2], HImode))
5787 return "sub{w}\t{%2, %0|%0, %2}";
5789 return "add{w}\t{%2, %0|%0, %2}";
5793 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set (attr "length_immediate")
5798 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5800 (const_string "*")))
5801 (set_attr "mode" "HI")])
5803 (define_insn "*addhi_1_lea"
5804 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5805 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5806 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5807 (clobber (reg:CC FLAGS_REG))]
5808 "!TARGET_PARTIAL_REG_STALL
5809 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5811 switch (get_attr_type (insn))
5817 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818 if (operands[2] == const1_rtx)
5819 return "inc{w}\t%0";
5822 gcc_assert (operands[2] == constm1_rtx);
5823 return "dec{w}\t%0";
5827 /* For most processors, ADD is faster than LEA. This alternative
5828 was added to use ADD as much as possible. */
5829 if (which_alternative == 2)
5832 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5835 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5836 if (x86_maybe_negate_const_int (&operands[2], HImode))
5837 return "sub{w}\t{%2, %0|%0, %2}";
5839 return "add{w}\t{%2, %0|%0, %2}";
5843 (cond [(eq_attr "alternative" "3")
5844 (const_string "lea")
5845 (match_operand:HI 2 "incdec_operand" "")
5846 (const_string "incdec")
5848 (const_string "alu")))
5849 (set (attr "length_immediate")
5851 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5853 (const_string "*")))
5854 (set_attr "mode" "HI,HI,HI,SI")])
5856 ;; %%% Potential partial reg stall on alternative 2. What to do?
5857 (define_insn "*addqi_1"
5858 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5859 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5860 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5861 (clobber (reg:CC FLAGS_REG))]
5862 "TARGET_PARTIAL_REG_STALL
5863 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5865 int widen = (which_alternative == 2);
5866 switch (get_attr_type (insn))
5869 if (operands[2] == const1_rtx)
5870 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5873 gcc_assert (operands[2] == constm1_rtx);
5874 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5878 if (x86_maybe_negate_const_int (&operands[2], QImode))
5881 return "sub{l}\t{%2, %k0|%k0, %2}";
5883 return "sub{b}\t{%2, %0|%0, %2}";
5886 return "add{l}\t{%k2, %k0|%k0, %k2}";
5888 return "add{b}\t{%2, %0|%0, %2}";
5892 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5893 (const_string "incdec")
5894 (const_string "alu")))
5895 (set (attr "length_immediate")
5897 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5899 (const_string "*")))
5900 (set_attr "mode" "QI,QI,SI")])
5902 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5903 (define_insn "*addqi_1_lea"
5904 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5905 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5906 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5907 (clobber (reg:CC FLAGS_REG))]
5908 "!TARGET_PARTIAL_REG_STALL
5909 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5911 int widen = (which_alternative == 3 || which_alternative == 4);
5913 switch (get_attr_type (insn))
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (operands[2] == const1_rtx)
5921 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5929 /* For most processors, ADD is faster than LEA. These alternatives
5930 were added to use ADD as much as possible. */
5931 if (which_alternative == 2 || which_alternative == 4)
5934 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5937 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5938 if (x86_maybe_negate_const_int (&operands[2], QImode))
5941 return "sub{l}\t{%2, %k0|%k0, %2}";
5943 return "sub{b}\t{%2, %0|%0, %2}";
5946 return "add{l}\t{%k2, %k0|%k0, %k2}";
5948 return "add{b}\t{%2, %0|%0, %2}";
5952 (cond [(eq_attr "alternative" "5")
5953 (const_string "lea")
5954 (match_operand:QI 2 "incdec_operand" "")
5955 (const_string "incdec")
5957 (const_string "alu")))
5958 (set (attr "length_immediate")
5960 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5962 (const_string "*")))
5963 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5965 (define_insn "*addqi_1_slp"
5966 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5967 (plus:QI (match_dup 0)
5968 (match_operand:QI 1 "general_operand" "qn,qnm")))
5969 (clobber (reg:CC FLAGS_REG))]
5970 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5971 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5973 switch (get_attr_type (insn))
5976 if (operands[1] == const1_rtx)
5977 return "inc{b}\t%0";
5980 gcc_assert (operands[1] == constm1_rtx);
5981 return "dec{b}\t%0";
5985 if (x86_maybe_negate_const_int (&operands[1], QImode))
5986 return "sub{b}\t{%1, %0|%0, %1}";
5988 return "add{b}\t{%1, %0|%0, %1}";
5992 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5993 (const_string "incdec")
5994 (const_string "alu1")))
5995 (set (attr "memory")
5996 (if_then_else (match_operand 1 "memory_operand" "")
5997 (const_string "load")
5998 (const_string "none")))
5999 (set_attr "mode" "QI")])
6001 ;; Convert lea to the lea pattern to avoid flags dependency.
6003 [(set (match_operand 0 "register_operand" "")
6004 (plus (match_operand 1 "register_operand" "")
6005 (match_operand 2 "nonmemory_operand" "")))
6006 (clobber (reg:CC FLAGS_REG))]
6007 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6011 enum machine_mode mode = GET_MODE (operands[0]);
6013 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6014 may confuse gen_lowpart. */
6017 operands[1] = gen_lowpart (Pmode, operands[1]);
6018 operands[2] = gen_lowpart (Pmode, operands[2]);
6021 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6023 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6024 operands[0] = gen_lowpart (SImode, operands[0]);
6026 if (TARGET_64BIT && mode != Pmode)
6027 pat = gen_rtx_SUBREG (SImode, pat, 0);
6029 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6033 ;; Convert lea to the lea pattern to avoid flags dependency.
6034 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6035 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6037 [(set (match_operand:DI 0 "register_operand" "")
6038 (plus:DI (match_operand:DI 1 "register_operand" "")
6039 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6040 (clobber (reg:CC FLAGS_REG))]
6041 "TARGET_64BIT && reload_completed
6042 && true_regnum (operands[0]) != true_regnum (operands[1])"
6044 (plus:DI (match_dup 1) (match_dup 2)))])
6046 ;; Convert lea to the lea pattern to avoid flags dependency.
6048 [(set (match_operand:DI 0 "register_operand" "")
6050 (plus:SI (match_operand:SI 1 "register_operand" "")
6051 (match_operand:SI 2 "nonmemory_operand" ""))))
6052 (clobber (reg:CC FLAGS_REG))]
6053 "TARGET_64BIT && reload_completed
6054 && ix86_lea_for_add_ok (insn, operands)"
6056 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6058 operands[1] = gen_lowpart (DImode, operands[1]);
6059 operands[2] = gen_lowpart (DImode, operands[2]);
6062 (define_insn "*add<mode>_2"
6063 [(set (reg FLAGS_REG)
6066 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6067 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6069 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6070 (plus:SWI (match_dup 1) (match_dup 2)))]
6071 "ix86_match_ccmode (insn, CCGOCmode)
6072 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6074 switch (get_attr_type (insn))
6077 if (operands[2] == const1_rtx)
6078 return "inc{<imodesuffix>}\t%0";
6081 gcc_assert (operands[2] == constm1_rtx);
6082 return "dec{<imodesuffix>}\t%0";
6086 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6087 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6089 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6093 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6094 (const_string "incdec")
6095 (const_string "alu")))
6096 (set (attr "length_immediate")
6098 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6100 (const_string "*")))
6101 (set_attr "mode" "<MODE>")])
6103 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6104 (define_insn "*addsi_2_zext"
6105 [(set (reg FLAGS_REG)
6107 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6108 (match_operand:SI 2 "general_operand" "g"))
6110 (set (match_operand:DI 0 "register_operand" "=r")
6111 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6112 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6113 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6115 switch (get_attr_type (insn))
6118 if (operands[2] == const1_rtx)
6119 return "inc{l}\t%k0";
6122 gcc_assert (operands[2] == constm1_rtx);
6123 return "dec{l}\t%k0";
6127 if (x86_maybe_negate_const_int (&operands[2], SImode))
6128 return "sub{l}\t{%2, %k0|%k0, %2}";
6130 return "add{l}\t{%2, %k0|%k0, %2}";
6134 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu")))
6137 (set (attr "length_immediate")
6139 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141 (const_string "*")))
6142 (set_attr "mode" "SI")])
6144 (define_insn "*add<mode>_3"
6145 [(set (reg FLAGS_REG)
6147 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6148 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6149 (clobber (match_scratch:SWI 0 "=<r>"))]
6150 "ix86_match_ccmode (insn, CCZmode)
6151 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6153 switch (get_attr_type (insn))
6156 if (operands[2] == const1_rtx)
6157 return "inc{<imodesuffix>}\t%0";
6160 gcc_assert (operands[2] == constm1_rtx);
6161 return "dec{<imodesuffix>}\t%0";
6165 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6166 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6168 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6172 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set (attr "length_immediate")
6177 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6179 (const_string "*")))
6180 (set_attr "mode" "<MODE>")])
6182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6183 (define_insn "*addsi_3_zext"
6184 [(set (reg FLAGS_REG)
6186 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6187 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6188 (set (match_operand:DI 0 "register_operand" "=r")
6189 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6190 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6191 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6193 switch (get_attr_type (insn))
6196 if (operands[2] == const1_rtx)
6197 return "inc{l}\t%k0";
6200 gcc_assert (operands[2] == constm1_rtx);
6201 return "dec{l}\t%k0";
6205 if (x86_maybe_negate_const_int (&operands[2], SImode))
6206 return "sub{l}\t{%2, %k0|%k0, %2}";
6208 return "add{l}\t{%2, %k0|%k0, %2}";
6212 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6213 (const_string "incdec")
6214 (const_string "alu")))
6215 (set (attr "length_immediate")
6217 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6219 (const_string "*")))
6220 (set_attr "mode" "SI")])
6222 ; For comparisons against 1, -1 and 128, we may generate better code
6223 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6224 ; is matched then. We can't accept general immediate, because for
6225 ; case of overflows, the result is messed up.
6226 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6227 ; only for comparisons not depending on it.
6229 (define_insn "*adddi_4"
6230 [(set (reg FLAGS_REG)
6232 (match_operand:DI 1 "nonimmediate_operand" "0")
6233 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6234 (clobber (match_scratch:DI 0 "=rm"))]
6236 && ix86_match_ccmode (insn, CCGCmode)"
6238 switch (get_attr_type (insn))
6241 if (operands[2] == constm1_rtx)
6242 return "inc{q}\t%0";
6245 gcc_assert (operands[2] == const1_rtx);
6246 return "dec{q}\t%0";
6250 if (x86_maybe_negate_const_int (&operands[2], DImode))
6251 return "add{q}\t{%2, %0|%0, %2}";
6253 return "sub{q}\t{%2, %0|%0, %2}";
6257 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6258 (const_string "incdec")
6259 (const_string "alu")))
6260 (set (attr "length_immediate")
6262 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6264 (const_string "*")))
6265 (set_attr "mode" "DI")])
6267 ; For comparisons against 1, -1 and 128, we may generate better code
6268 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6269 ; is matched then. We can't accept general immediate, because for
6270 ; case of overflows, the result is messed up.
6271 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6272 ; only for comparisons not depending on it.
6274 (define_insn "*add<mode>_4"
6275 [(set (reg FLAGS_REG)
6277 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6278 (match_operand:SWI124 2 "const_int_operand" "n")))
6279 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6280 "ix86_match_ccmode (insn, CCGCmode)"
6282 switch (get_attr_type (insn))
6285 if (operands[2] == constm1_rtx)
6286 return "inc{<imodesuffix>}\t%0";
6289 gcc_assert (operands[2] == const1_rtx);
6290 return "dec{<imodesuffix>}\t%0";
6294 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6295 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6297 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6301 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6302 (const_string "incdec")
6303 (const_string "alu")))
6304 (set (attr "length_immediate")
6306 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6308 (const_string "*")))
6309 (set_attr "mode" "<MODE>")])
6311 (define_insn "*add<mode>_5"
6312 [(set (reg FLAGS_REG)
6315 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6316 (match_operand:SWI 2 "<general_operand>" "<g>"))
6318 (clobber (match_scratch:SWI 0 "=<r>"))]
6319 "ix86_match_ccmode (insn, CCGOCmode)
6320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6322 switch (get_attr_type (insn))
6325 if (operands[2] == const1_rtx)
6326 return "inc{<imodesuffix>}\t%0";
6329 gcc_assert (operands[2] == constm1_rtx);
6330 return "dec{<imodesuffix>}\t%0";
6334 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6335 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6337 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6341 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6342 (const_string "incdec")
6343 (const_string "alu")))
6344 (set (attr "length_immediate")
6346 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6348 (const_string "*")))
6349 (set_attr "mode" "<MODE>")])
6351 (define_insn "*addqi_ext_1_rex64"
6352 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6357 (match_operand 1 "ext_register_operand" "0")
6360 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6361 (clobber (reg:CC FLAGS_REG))]
6364 switch (get_attr_type (insn))
6367 if (operands[2] == const1_rtx)
6368 return "inc{b}\t%h0";
6371 gcc_assert (operands[2] == constm1_rtx);
6372 return "dec{b}\t%h0";
6376 return "add{b}\t{%2, %h0|%h0, %2}";
6380 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6381 (const_string "incdec")
6382 (const_string "alu")))
6383 (set_attr "modrm" "1")
6384 (set_attr "mode" "QI")])
6386 (define_insn "addqi_ext_1"
6387 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6392 (match_operand 1 "ext_register_operand" "0")
6395 (match_operand:QI 2 "general_operand" "Qmn")))
6396 (clobber (reg:CC FLAGS_REG))]
6399 switch (get_attr_type (insn))
6402 if (operands[2] == const1_rtx)
6403 return "inc{b}\t%h0";
6406 gcc_assert (operands[2] == constm1_rtx);
6407 return "dec{b}\t%h0";
6411 return "add{b}\t{%2, %h0|%h0, %2}";
6415 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6416 (const_string "incdec")
6417 (const_string "alu")))
6418 (set_attr "modrm" "1")
6419 (set_attr "mode" "QI")])
6421 (define_insn "*addqi_ext_2"
6422 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6427 (match_operand 1 "ext_register_operand" "%0")
6431 (match_operand 2 "ext_register_operand" "Q")
6434 (clobber (reg:CC FLAGS_REG))]
6436 "add{b}\t{%h2, %h0|%h0, %h2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "QI")])
6440 ;; The lea patterns for non-Pmodes needs to be matched by
6441 ;; several insns converted to real lea by splitters.
6443 (define_insn_and_split "*lea_general_1"
6444 [(set (match_operand 0 "register_operand" "=r")
6445 (plus (plus (match_operand 1 "index_register_operand" "l")
6446 (match_operand 2 "register_operand" "r"))
6447 (match_operand 3 "immediate_operand" "i")))]
6448 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6449 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6450 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6451 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6452 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6453 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6454 || GET_MODE (operands[3]) == VOIDmode)"
6456 "&& reload_completed"
6460 operands[0] = gen_lowpart (SImode, operands[0]);
6461 operands[1] = gen_lowpart (Pmode, operands[1]);
6462 operands[2] = gen_lowpart (Pmode, operands[2]);
6463 operands[3] = gen_lowpart (Pmode, operands[3]);
6464 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6466 if (Pmode != SImode)
6467 pat = gen_rtx_SUBREG (SImode, pat, 0);
6468 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6471 [(set_attr "type" "lea")
6472 (set_attr "mode" "SI")])
6474 (define_insn_and_split "*lea_general_1_zext"
6475 [(set (match_operand:DI 0 "register_operand" "=r")
6478 (match_operand:SI 1 "index_register_operand" "l")
6479 (match_operand:SI 2 "register_operand" "r"))
6480 (match_operand:SI 3 "immediate_operand" "i"))))]
6483 "&& reload_completed"
6485 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6487 (match_dup 3)) 0)))]
6489 operands[1] = gen_lowpart (Pmode, operands[1]);
6490 operands[2] = gen_lowpart (Pmode, operands[2]);
6491 operands[3] = gen_lowpart (Pmode, operands[3]);
6493 [(set_attr "type" "lea")
6494 (set_attr "mode" "SI")])
6496 (define_insn_and_split "*lea_general_2"
6497 [(set (match_operand 0 "register_operand" "=r")
6498 (plus (mult (match_operand 1 "index_register_operand" "l")
6499 (match_operand 2 "const248_operand" "i"))
6500 (match_operand 3 "nonmemory_operand" "ri")))]
6501 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6502 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6503 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6504 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6505 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6506 || GET_MODE (operands[3]) == VOIDmode)"
6508 "&& reload_completed"
6512 operands[0] = gen_lowpart (SImode, operands[0]);
6513 operands[1] = gen_lowpart (Pmode, operands[1]);
6514 operands[3] = gen_lowpart (Pmode, operands[3]);
6515 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6517 if (Pmode != SImode)
6518 pat = gen_rtx_SUBREG (SImode, pat, 0);
6519 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6522 [(set_attr "type" "lea")
6523 (set_attr "mode" "SI")])
6525 (define_insn_and_split "*lea_general_2_zext"
6526 [(set (match_operand:DI 0 "register_operand" "=r")
6529 (match_operand:SI 1 "index_register_operand" "l")
6530 (match_operand:SI 2 "const248_operand" "n"))
6531 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6534 "&& reload_completed"
6536 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6538 (match_dup 3)) 0)))]
6540 operands[1] = gen_lowpart (Pmode, operands[1]);
6541 operands[3] = gen_lowpart (Pmode, operands[3]);
6543 [(set_attr "type" "lea")
6544 (set_attr "mode" "SI")])
6546 (define_insn_and_split "*lea_general_3"
6547 [(set (match_operand 0 "register_operand" "=r")
6548 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6549 (match_operand 2 "const248_operand" "i"))
6550 (match_operand 3 "register_operand" "r"))
6551 (match_operand 4 "immediate_operand" "i")))]
6552 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6553 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6554 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6555 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6556 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6558 "&& reload_completed"
6562 operands[0] = gen_lowpart (SImode, operands[0]);
6563 operands[1] = gen_lowpart (Pmode, operands[1]);
6564 operands[3] = gen_lowpart (Pmode, operands[3]);
6565 operands[4] = gen_lowpart (Pmode, operands[4]);
6566 pat = gen_rtx_PLUS (Pmode,
6567 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6571 if (Pmode != SImode)
6572 pat = gen_rtx_SUBREG (SImode, pat, 0);
6573 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6576 [(set_attr "type" "lea")
6577 (set_attr "mode" "SI")])
6579 (define_insn_and_split "*lea_general_3_zext"
6580 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (match_operand:SI 1 "index_register_operand" "l")
6585 (match_operand:SI 2 "const248_operand" "n"))
6586 (match_operand:SI 3 "register_operand" "r"))
6587 (match_operand:SI 4 "immediate_operand" "i"))))]
6590 "&& reload_completed"
6592 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6595 (match_dup 4)) 0)))]
6597 operands[1] = gen_lowpart (Pmode, operands[1]);
6598 operands[3] = gen_lowpart (Pmode, operands[3]);
6599 operands[4] = gen_lowpart (Pmode, operands[4]);
6601 [(set_attr "type" "lea")
6602 (set_attr "mode" "SI")])
6604 ;; Subtract instructions
6606 (define_expand "sub<mode>3"
6607 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6608 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6609 (match_operand:SDWIM 2 "<general_operand>" "")))]
6611 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6613 (define_insn_and_split "*sub<dwi>3_doubleword"
6614 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6616 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6617 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6618 (clobber (reg:CC FLAGS_REG))]
6619 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6622 [(parallel [(set (reg:CC FLAGS_REG)
6623 (compare:CC (match_dup 1) (match_dup 2)))
6625 (minus:DWIH (match_dup 1) (match_dup 2)))])
6626 (parallel [(set (match_dup 3)
6630 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6632 (clobber (reg:CC FLAGS_REG))])]
6633 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6635 (define_insn "*sub<mode>_1"
6636 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6638 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6639 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6640 (clobber (reg:CC FLAGS_REG))]
6641 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6642 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "mode" "<MODE>")])
6646 (define_insn "*subsi_1_zext"
6647 [(set (match_operand:DI 0 "register_operand" "=r")
6649 (minus:SI (match_operand:SI 1 "register_operand" "0")
6650 (match_operand:SI 2 "general_operand" "g"))))
6651 (clobber (reg:CC FLAGS_REG))]
6652 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6653 "sub{l}\t{%2, %k0|%k0, %2}"
6654 [(set_attr "type" "alu")
6655 (set_attr "mode" "SI")])
6657 (define_insn "*subqi_1_slp"
6658 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6659 (minus:QI (match_dup 0)
6660 (match_operand:QI 1 "general_operand" "qn,qm")))
6661 (clobber (reg:CC FLAGS_REG))]
6662 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6663 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6664 "sub{b}\t{%1, %0|%0, %1}"
6665 [(set_attr "type" "alu1")
6666 (set_attr "mode" "QI")])
6668 (define_insn "*sub<mode>_2"
6669 [(set (reg FLAGS_REG)
6672 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6675 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6676 (minus:SWI (match_dup 1) (match_dup 2)))]
6677 "ix86_match_ccmode (insn, CCGOCmode)
6678 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6679 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "mode" "<MODE>")])
6683 (define_insn "*subsi_2_zext"
6684 [(set (reg FLAGS_REG)
6686 (minus:SI (match_operand:SI 1 "register_operand" "0")
6687 (match_operand:SI 2 "general_operand" "g"))
6689 (set (match_operand:DI 0 "register_operand" "=r")
6691 (minus:SI (match_dup 1)
6693 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695 "sub{l}\t{%2, %k0|%k0, %2}"
6696 [(set_attr "type" "alu")
6697 (set_attr "mode" "SI")])
6699 (define_insn "*sub<mode>_3"
6700 [(set (reg FLAGS_REG)
6701 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6702 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6703 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6704 (minus:SWI (match_dup 1) (match_dup 2)))]
6705 "ix86_match_ccmode (insn, CCmode)
6706 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6707 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "<MODE>")])
6711 (define_insn "*subsi_3_zext"
6712 [(set (reg FLAGS_REG)
6713 (compare (match_operand:SI 1 "register_operand" "0")
6714 (match_operand:SI 2 "general_operand" "g")))
6715 (set (match_operand:DI 0 "register_operand" "=r")
6717 (minus:SI (match_dup 1)
6719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{l}\t{%2, %1|%1, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "SI")])
6725 ;; Add with carry and subtract with borrow
6727 (define_expand "<plusminus_insn><mode>3_carry"
6729 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6731 (match_operand:SWI 1 "nonimmediate_operand" "")
6732 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6733 [(match_operand 3 "flags_reg_operand" "")
6735 (match_operand:SWI 2 "<general_operand>" ""))))
6736 (clobber (reg:CC FLAGS_REG))])]
6737 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6739 (define_insn "*<plusminus_insn><mode>3_carry"
6740 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6742 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6744 (match_operator 3 "ix86_carry_flag_operator"
6745 [(reg FLAGS_REG) (const_int 0)])
6746 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6747 (clobber (reg:CC FLAGS_REG))]
6748 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6749 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "use_carry" "1")
6752 (set_attr "pent_pair" "pu")
6753 (set_attr "mode" "<MODE>")])
6755 (define_insn "*addsi3_carry_zext"
6756 [(set (match_operand:DI 0 "register_operand" "=r")
6758 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6759 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6760 [(reg FLAGS_REG) (const_int 0)])
6761 (match_operand:SI 2 "general_operand" "g")))))
6762 (clobber (reg:CC FLAGS_REG))]
6763 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6764 "adc{l}\t{%2, %k0|%k0, %2}"
6765 [(set_attr "type" "alu")
6766 (set_attr "use_carry" "1")
6767 (set_attr "pent_pair" "pu")
6768 (set_attr "mode" "SI")])
6770 (define_insn "*subsi3_carry_zext"
6771 [(set (match_operand:DI 0 "register_operand" "=r")
6773 (minus:SI (match_operand:SI 1 "register_operand" "0")
6774 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6775 [(reg FLAGS_REG) (const_int 0)])
6776 (match_operand:SI 2 "general_operand" "g")))))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779 "sbb{l}\t{%2, %k0|%k0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "pent_pair" "pu")
6782 (set_attr "mode" "SI")])
6784 ;; Overflow setting add and subtract instructions
6786 (define_insn "*add<mode>3_cconly_overflow"
6787 [(set (reg:CCC FLAGS_REG)
6790 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6791 (match_operand:SWI 2 "<general_operand>" "<g>"))
6793 (clobber (match_scratch:SWI 0 "=<r>"))]
6794 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "mode" "<MODE>")])
6799 (define_insn "*sub<mode>3_cconly_overflow"
6800 [(set (reg:CCC FLAGS_REG)
6803 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6804 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6807 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6808 [(set_attr "type" "icmp")
6809 (set_attr "mode" "<MODE>")])
6811 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6812 [(set (reg:CCC FLAGS_REG)
6815 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6816 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6818 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6819 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6820 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6821 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6822 [(set_attr "type" "alu")
6823 (set_attr "mode" "<MODE>")])
6825 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6826 [(set (reg:CCC FLAGS_REG)
6829 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6830 (match_operand:SI 2 "general_operand" "g"))
6832 (set (match_operand:DI 0 "register_operand" "=r")
6833 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6834 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6835 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6836 [(set_attr "type" "alu")
6837 (set_attr "mode" "SI")])
6839 ;; The patterns that match these are at the end of this file.
6841 (define_expand "<plusminus_insn>xf3"
6842 [(set (match_operand:XF 0 "register_operand" "")
6844 (match_operand:XF 1 "register_operand" "")
6845 (match_operand:XF 2 "register_operand" "")))]
6848 (define_expand "<plusminus_insn><mode>3"
6849 [(set (match_operand:MODEF 0 "register_operand" "")
6851 (match_operand:MODEF 1 "register_operand" "")
6852 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6853 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6854 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6856 ;; Multiply instructions
6858 (define_expand "mul<mode>3"
6859 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6861 (match_operand:SWIM248 1 "register_operand" "")
6862 (match_operand:SWIM248 2 "<general_operand>" "")))
6863 (clobber (reg:CC FLAGS_REG))])])
6865 (define_expand "mulqi3"
6866 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6868 (match_operand:QI 1 "register_operand" "")
6869 (match_operand:QI 2 "nonimmediate_operand" "")))
6870 (clobber (reg:CC FLAGS_REG))])]
6871 "TARGET_QIMODE_MATH")
6874 ;; IMUL reg32/64, reg32/64, imm8 Direct
6875 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6876 ;; IMUL reg32/64, reg32/64, imm32 Direct
6877 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6878 ;; IMUL reg32/64, reg32/64 Direct
6879 ;; IMUL reg32/64, mem32/64 Direct
6881 ;; On BDVER1, all above IMULs use DirectPath
6883 (define_insn "*mul<mode>3_1"
6884 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6886 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6891 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6892 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6893 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6894 [(set_attr "type" "imul")
6895 (set_attr "prefix_0f" "0,0,1")
6896 (set (attr "athlon_decode")
6897 (cond [(eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (eq_attr "alternative" "1")
6900 (const_string "vector")
6901 (and (eq_attr "alternative" "2")
6902 (match_operand 1 "memory_operand" ""))
6903 (const_string "vector")]
6904 (const_string "direct")))
6905 (set (attr "amdfam10_decode")
6906 (cond [(and (eq_attr "alternative" "0,1")
6907 (match_operand 1 "memory_operand" ""))
6908 (const_string "vector")]
6909 (const_string "direct")))
6910 (set_attr "bdver1_decode" "direct")
6911 (set_attr "mode" "<MODE>")])
6913 (define_insn "*mulsi3_1_zext"
6914 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6916 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6917 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6918 (clobber (reg:CC FLAGS_REG))]
6920 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6924 imul{l}\t{%2, %k0|%k0, %2}"
6925 [(set_attr "type" "imul")
6926 (set_attr "prefix_0f" "0,0,1")
6927 (set (attr "athlon_decode")
6928 (cond [(eq_attr "cpu" "athlon")
6929 (const_string "vector")
6930 (eq_attr "alternative" "1")
6931 (const_string "vector")
6932 (and (eq_attr "alternative" "2")
6933 (match_operand 1 "memory_operand" ""))
6934 (const_string "vector")]
6935 (const_string "direct")))
6936 (set (attr "amdfam10_decode")
6937 (cond [(and (eq_attr "alternative" "0,1")
6938 (match_operand 1 "memory_operand" ""))
6939 (const_string "vector")]
6940 (const_string "direct")))
6941 (set_attr "bdver1_decode" "direct")
6942 (set_attr "mode" "SI")])
6945 ;; IMUL reg16, reg16, imm8 VectorPath
6946 ;; IMUL reg16, mem16, imm8 VectorPath
6947 ;; IMUL reg16, reg16, imm16 VectorPath
6948 ;; IMUL reg16, mem16, imm16 VectorPath
6949 ;; IMUL reg16, reg16 Direct
6950 ;; IMUL reg16, mem16 Direct
6952 ;; On BDVER1, all HI MULs use DoublePath
6954 (define_insn "*mulhi3_1"
6955 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6956 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6957 (match_operand:HI 2 "general_operand" "K,n,mr")))
6958 (clobber (reg:CC FLAGS_REG))]
6960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962 imul{w}\t{%2, %1, %0|%0, %1, %2}
6963 imul{w}\t{%2, %1, %0|%0, %1, %2}
6964 imul{w}\t{%2, %0|%0, %2}"
6965 [(set_attr "type" "imul")
6966 (set_attr "prefix_0f" "0,0,1")
6967 (set (attr "athlon_decode")
6968 (cond [(eq_attr "cpu" "athlon")
6969 (const_string "vector")
6970 (eq_attr "alternative" "1,2")
6971 (const_string "vector")]
6972 (const_string "direct")))
6973 (set (attr "amdfam10_decode")
6974 (cond [(eq_attr "alternative" "0,1")
6975 (const_string "vector")]
6976 (const_string "direct")))
6977 (set_attr "bdver1_decode" "double")
6978 (set_attr "mode" "HI")])
6980 ;;On AMDFAM10 and BDVER1
6984 (define_insn "*mulqi3_1"
6985 [(set (match_operand:QI 0 "register_operand" "=a")
6986 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6987 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6988 (clobber (reg:CC FLAGS_REG))]
6990 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6992 [(set_attr "type" "imul")
6993 (set_attr "length_immediate" "0")
6994 (set (attr "athlon_decode")
6995 (if_then_else (eq_attr "cpu" "athlon")
6996 (const_string "vector")
6997 (const_string "direct")))
6998 (set_attr "amdfam10_decode" "direct")
6999 (set_attr "bdver1_decode" "direct")
7000 (set_attr "mode" "QI")])
7002 (define_expand "<u>mul<mode><dwi>3"
7003 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7006 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7008 (match_operand:DWIH 2 "register_operand" ""))))
7009 (clobber (reg:CC FLAGS_REG))])])
7011 (define_expand "<u>mulqihi3"
7012 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7015 (match_operand:QI 1 "nonimmediate_operand" ""))
7017 (match_operand:QI 2 "register_operand" ""))))
7018 (clobber (reg:CC FLAGS_REG))])]
7019 "TARGET_QIMODE_MATH")
7021 (define_insn "*<u>mul<mode><dwi>3_1"
7022 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7025 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7027 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7028 (clobber (reg:CC FLAGS_REG))]
7029 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7030 "<sgnprefix>mul{<imodesuffix>}\t%2"
7031 [(set_attr "type" "imul")
7032 (set_attr "length_immediate" "0")
7033 (set (attr "athlon_decode")
7034 (if_then_else (eq_attr "cpu" "athlon")
7035 (const_string "vector")
7036 (const_string "double")))
7037 (set_attr "amdfam10_decode" "double")
7038 (set_attr "bdver1_decode" "direct")
7039 (set_attr "mode" "<MODE>")])
7041 (define_insn "*<u>mulqihi3_1"
7042 [(set (match_operand:HI 0 "register_operand" "=a")
7045 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7047 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7048 (clobber (reg:CC FLAGS_REG))]
7050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7051 "<sgnprefix>mul{b}\t%2"
7052 [(set_attr "type" "imul")
7053 (set_attr "length_immediate" "0")
7054 (set (attr "athlon_decode")
7055 (if_then_else (eq_attr "cpu" "athlon")
7056 (const_string "vector")
7057 (const_string "direct")))
7058 (set_attr "amdfam10_decode" "direct")
7059 (set_attr "bdver1_decode" "direct")
7060 (set_attr "mode" "QI")])
7062 (define_expand "<s>mul<mode>3_highpart"
7063 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7068 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7070 (match_operand:SWI48 2 "register_operand" "")))
7072 (clobber (match_scratch:SWI48 3 ""))
7073 (clobber (reg:CC FLAGS_REG))])]
7075 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7077 (define_insn "*<s>muldi3_highpart_1"
7078 [(set (match_operand:DI 0 "register_operand" "=d")
7083 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7085 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7087 (clobber (match_scratch:DI 3 "=1"))
7088 (clobber (reg:CC FLAGS_REG))]
7090 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7091 "<sgnprefix>mul{q}\t%2"
7092 [(set_attr "type" "imul")
7093 (set_attr "length_immediate" "0")
7094 (set (attr "athlon_decode")
7095 (if_then_else (eq_attr "cpu" "athlon")
7096 (const_string "vector")
7097 (const_string "double")))
7098 (set_attr "amdfam10_decode" "double")
7099 (set_attr "bdver1_decode" "direct")
7100 (set_attr "mode" "DI")])
7102 (define_insn "*<s>mulsi3_highpart_1"
7103 [(set (match_operand:SI 0 "register_operand" "=d")
7108 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7110 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7112 (clobber (match_scratch:SI 3 "=1"))
7113 (clobber (reg:CC FLAGS_REG))]
7114 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7115 "<sgnprefix>mul{l}\t%2"
7116 [(set_attr "type" "imul")
7117 (set_attr "length_immediate" "0")
7118 (set (attr "athlon_decode")
7119 (if_then_else (eq_attr "cpu" "athlon")
7120 (const_string "vector")
7121 (const_string "double")))
7122 (set_attr "amdfam10_decode" "double")
7123 (set_attr "bdver1_decode" "direct")
7124 (set_attr "mode" "SI")])
7126 (define_insn "*<s>mulsi3_highpart_zext"
7127 [(set (match_operand:DI 0 "register_operand" "=d")
7128 (zero_extend:DI (truncate:SI
7130 (mult:DI (any_extend:DI
7131 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7133 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7135 (clobber (match_scratch:SI 3 "=1"))
7136 (clobber (reg:CC FLAGS_REG))]
7138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7139 "<sgnprefix>mul{l}\t%2"
7140 [(set_attr "type" "imul")
7141 (set_attr "length_immediate" "0")
7142 (set (attr "athlon_decode")
7143 (if_then_else (eq_attr "cpu" "athlon")
7144 (const_string "vector")
7145 (const_string "double")))
7146 (set_attr "amdfam10_decode" "double")
7147 (set_attr "bdver1_decode" "direct")
7148 (set_attr "mode" "SI")])
7150 ;; The patterns that match these are at the end of this file.
7152 (define_expand "mulxf3"
7153 [(set (match_operand:XF 0 "register_operand" "")
7154 (mult:XF (match_operand:XF 1 "register_operand" "")
7155 (match_operand:XF 2 "register_operand" "")))]
7158 (define_expand "mul<mode>3"
7159 [(set (match_operand:MODEF 0 "register_operand" "")
7160 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7161 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7162 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7163 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7165 ;; Divide instructions
7167 ;; The patterns that match these are at the end of this file.
7169 (define_expand "divxf3"
7170 [(set (match_operand:XF 0 "register_operand" "")
7171 (div:XF (match_operand:XF 1 "register_operand" "")
7172 (match_operand:XF 2 "register_operand" "")))]
7175 (define_expand "divdf3"
7176 [(set (match_operand:DF 0 "register_operand" "")
7177 (div:DF (match_operand:DF 1 "register_operand" "")
7178 (match_operand:DF 2 "nonimmediate_operand" "")))]
7179 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7180 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7182 (define_expand "divsf3"
7183 [(set (match_operand:SF 0 "register_operand" "")
7184 (div:SF (match_operand:SF 1 "register_operand" "")
7185 (match_operand:SF 2 "nonimmediate_operand" "")))]
7186 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7189 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7190 && flag_finite_math_only && !flag_trapping_math
7191 && flag_unsafe_math_optimizations)
7193 ix86_emit_swdivsf (operands[0], operands[1],
7194 operands[2], SFmode);
7199 ;; Divmod instructions.
7201 (define_expand "divmod<mode>4"
7202 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7204 (match_operand:SWIM248 1 "register_operand" "")
7205 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7206 (set (match_operand:SWIM248 3 "register_operand" "")
7207 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7208 (clobber (reg:CC FLAGS_REG))])])
7210 ;; Split with 8bit unsigned divide:
7211 ;; if (dividend an divisor are in [0-255])
7212 ;; use 8bit unsigned integer divide
7214 ;; use original integer divide
7216 [(set (match_operand:SWI48 0 "register_operand" "")
7217 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7218 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7219 (set (match_operand:SWI48 1 "register_operand" "")
7220 (mod:SWI48 (match_dup 2) (match_dup 3)))
7221 (clobber (reg:CC FLAGS_REG))]
7222 "TARGET_USE_8BIT_IDIV
7223 && TARGET_QIMODE_MATH
7224 && can_create_pseudo_p ()
7225 && !optimize_insn_for_size_p ()"
7227 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7229 (define_insn_and_split "divmod<mode>4_1"
7230 [(set (match_operand:SWI48 0 "register_operand" "=a")
7231 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7232 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7233 (set (match_operand:SWI48 1 "register_operand" "=&d")
7234 (mod:SWI48 (match_dup 2) (match_dup 3)))
7235 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7236 (clobber (reg:CC FLAGS_REG))]
7240 [(parallel [(set (match_dup 1)
7241 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7242 (clobber (reg:CC FLAGS_REG))])
7243 (parallel [(set (match_dup 0)
7244 (div:SWI48 (match_dup 2) (match_dup 3)))
7246 (mod:SWI48 (match_dup 2) (match_dup 3)))
7248 (clobber (reg:CC FLAGS_REG))])]
7250 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7252 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7253 operands[4] = operands[2];
7256 /* Avoid use of cltd in favor of a mov+shift. */
7257 emit_move_insn (operands[1], operands[2]);
7258 operands[4] = operands[1];
7261 [(set_attr "type" "multi")
7262 (set_attr "mode" "<MODE>")])
7264 (define_insn_and_split "*divmod<mode>4"
7265 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7266 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7267 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7268 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7269 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7270 (clobber (reg:CC FLAGS_REG))]
7274 [(parallel [(set (match_dup 1)
7275 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7276 (clobber (reg:CC FLAGS_REG))])
7277 (parallel [(set (match_dup 0)
7278 (div:SWIM248 (match_dup 2) (match_dup 3)))
7280 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7282 (clobber (reg:CC FLAGS_REG))])]
7284 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7286 if (<MODE>mode != HImode
7287 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7288 operands[4] = operands[2];
7291 /* Avoid use of cltd in favor of a mov+shift. */
7292 emit_move_insn (operands[1], operands[2]);
7293 operands[4] = operands[1];
7296 [(set_attr "type" "multi")
7297 (set_attr "mode" "<MODE>")])
7299 (define_insn "*divmod<mode>4_noext"
7300 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7301 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7302 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7303 (set (match_operand:SWIM248 1 "register_operand" "=d")
7304 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7305 (use (match_operand:SWIM248 4 "register_operand" "1"))
7306 (clobber (reg:CC FLAGS_REG))]
7308 "idiv{<imodesuffix>}\t%3"
7309 [(set_attr "type" "idiv")
7310 (set_attr "mode" "<MODE>")])
7312 (define_expand "divmodqi4"
7313 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7315 (match_operand:QI 1 "register_operand" "")
7316 (match_operand:QI 2 "nonimmediate_operand" "")))
7317 (set (match_operand:QI 3 "register_operand" "")
7318 (mod:QI (match_dup 1) (match_dup 2)))
7319 (clobber (reg:CC FLAGS_REG))])]
7320 "TARGET_QIMODE_MATH"
7325 tmp0 = gen_reg_rtx (HImode);
7326 tmp1 = gen_reg_rtx (HImode);
7328 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7330 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7331 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7333 /* Extract remainder from AH. */
7334 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7335 insn = emit_move_insn (operands[3], tmp1);
7337 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7338 set_unique_reg_note (insn, REG_EQUAL, mod);
7340 /* Extract quotient from AL. */
7341 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7343 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7344 set_unique_reg_note (insn, REG_EQUAL, div);
7349 ;; Divide AX by r/m8, with result stored in
7352 ;; Change div/mod to HImode and extend the second argument to HImode
7353 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7354 ;; combine may fail.
7355 (define_insn "divmodhiqi3"
7356 [(set (match_operand:HI 0 "register_operand" "=a")
7361 (mod:HI (match_operand:HI 1 "register_operand" "0")
7363 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7367 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7368 (clobber (reg:CC FLAGS_REG))]
7369 "TARGET_QIMODE_MATH"
7371 [(set_attr "type" "idiv")
7372 (set_attr "mode" "QI")])
7374 (define_expand "udivmod<mode>4"
7375 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7377 (match_operand:SWIM248 1 "register_operand" "")
7378 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7379 (set (match_operand:SWIM248 3 "register_operand" "")
7380 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7381 (clobber (reg:CC FLAGS_REG))])])
7383 ;; Split with 8bit unsigned divide:
7384 ;; if (dividend an divisor are in [0-255])
7385 ;; use 8bit unsigned integer divide
7387 ;; use original integer divide
7389 [(set (match_operand:SWI48 0 "register_operand" "")
7390 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7391 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7392 (set (match_operand:SWI48 1 "register_operand" "")
7393 (umod:SWI48 (match_dup 2) (match_dup 3)))
7394 (clobber (reg:CC FLAGS_REG))]
7395 "TARGET_USE_8BIT_IDIV
7396 && TARGET_QIMODE_MATH
7397 && can_create_pseudo_p ()
7398 && !optimize_insn_for_size_p ()"
7400 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7402 (define_insn_and_split "udivmod<mode>4_1"
7403 [(set (match_operand:SWI48 0 "register_operand" "=a")
7404 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7405 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7406 (set (match_operand:SWI48 1 "register_operand" "=&d")
7407 (umod:SWI48 (match_dup 2) (match_dup 3)))
7408 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7409 (clobber (reg:CC FLAGS_REG))]
7413 [(set (match_dup 1) (const_int 0))
7414 (parallel [(set (match_dup 0)
7415 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7417 (umod:SWI48 (match_dup 2) (match_dup 3)))
7419 (clobber (reg:CC FLAGS_REG))])]
7421 [(set_attr "type" "multi")
7422 (set_attr "mode" "<MODE>")])
7424 (define_insn_and_split "*udivmod<mode>4"
7425 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7426 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7427 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7428 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7429 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7430 (clobber (reg:CC FLAGS_REG))]
7434 [(set (match_dup 1) (const_int 0))
7435 (parallel [(set (match_dup 0)
7436 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7438 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7440 (clobber (reg:CC FLAGS_REG))])]
7442 [(set_attr "type" "multi")
7443 (set_attr "mode" "<MODE>")])
7445 (define_insn "*udivmod<mode>4_noext"
7446 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7447 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7448 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7449 (set (match_operand:SWIM248 1 "register_operand" "=d")
7450 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7451 (use (match_operand:SWIM248 4 "register_operand" "1"))
7452 (clobber (reg:CC FLAGS_REG))]
7454 "div{<imodesuffix>}\t%3"
7455 [(set_attr "type" "idiv")
7456 (set_attr "mode" "<MODE>")])
7458 (define_expand "udivmodqi4"
7459 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7461 (match_operand:QI 1 "register_operand" "")
7462 (match_operand:QI 2 "nonimmediate_operand" "")))
7463 (set (match_operand:QI 3 "register_operand" "")
7464 (umod:QI (match_dup 1) (match_dup 2)))
7465 (clobber (reg:CC FLAGS_REG))])]
7466 "TARGET_QIMODE_MATH"
7471 tmp0 = gen_reg_rtx (HImode);
7472 tmp1 = gen_reg_rtx (HImode);
7474 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7476 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7477 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7479 /* Extract remainder from AH. */
7480 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7481 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7482 insn = emit_move_insn (operands[3], tmp1);
7484 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7485 set_unique_reg_note (insn, REG_EQUAL, mod);
7487 /* Extract quotient from AL. */
7488 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7490 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7491 set_unique_reg_note (insn, REG_EQUAL, div);
7496 (define_insn "udivmodhiqi3"
7497 [(set (match_operand:HI 0 "register_operand" "=a")
7502 (mod:HI (match_operand:HI 1 "register_operand" "0")
7504 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7508 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7509 (clobber (reg:CC FLAGS_REG))]
7510 "TARGET_QIMODE_MATH"
7512 [(set_attr "type" "idiv")
7513 (set_attr "mode" "QI")])
7515 ;; We cannot use div/idiv for double division, because it causes
7516 ;; "division by zero" on the overflow and that's not what we expect
7517 ;; from truncate. Because true (non truncating) double division is
7518 ;; never generated, we can't create this insn anyway.
7521 ; [(set (match_operand:SI 0 "register_operand" "=a")
7523 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7525 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7526 ; (set (match_operand:SI 3 "register_operand" "=d")
7528 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7529 ; (clobber (reg:CC FLAGS_REG))]
7531 ; "div{l}\t{%2, %0|%0, %2}"
7532 ; [(set_attr "type" "idiv")])
7534 ;;- Logical AND instructions
7536 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7537 ;; Note that this excludes ah.
7539 (define_expand "testsi_ccno_1"
7540 [(set (reg:CCNO FLAGS_REG)
7542 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7543 (match_operand:SI 1 "nonmemory_operand" ""))
7546 (define_expand "testqi_ccz_1"
7547 [(set (reg:CCZ FLAGS_REG)
7548 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7549 (match_operand:QI 1 "nonmemory_operand" ""))
7552 (define_expand "testdi_ccno_1"
7553 [(set (reg:CCNO FLAGS_REG)
7555 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7556 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7558 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7560 (define_insn "*testdi_1"
7561 [(set (reg FLAGS_REG)
7564 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7565 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7567 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7568 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7570 test{l}\t{%k1, %k0|%k0, %k1}
7571 test{l}\t{%k1, %k0|%k0, %k1}
7572 test{q}\t{%1, %0|%0, %1}
7573 test{q}\t{%1, %0|%0, %1}
7574 test{q}\t{%1, %0|%0, %1}"
7575 [(set_attr "type" "test")
7576 (set_attr "modrm" "0,1,0,1,1")
7577 (set_attr "mode" "SI,SI,DI,DI,DI")])
7579 (define_insn "*testqi_1_maybe_si"
7580 [(set (reg FLAGS_REG)
7583 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7584 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7586 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7587 && ix86_match_ccmode (insn,
7588 CONST_INT_P (operands[1])
7589 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7591 if (which_alternative == 3)
7593 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7594 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7595 return "test{l}\t{%1, %k0|%k0, %1}";
7597 return "test{b}\t{%1, %0|%0, %1}";
7599 [(set_attr "type" "test")
7600 (set_attr "modrm" "0,1,1,1")
7601 (set_attr "mode" "QI,QI,QI,SI")
7602 (set_attr "pent_pair" "uv,np,uv,np")])
7604 (define_insn "*test<mode>_1"
7605 [(set (reg FLAGS_REG)
7608 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7609 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7611 "ix86_match_ccmode (insn, CCNOmode)
7612 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7613 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7614 [(set_attr "type" "test")
7615 (set_attr "modrm" "0,1,1")
7616 (set_attr "mode" "<MODE>")
7617 (set_attr "pent_pair" "uv,np,uv")])
7619 (define_expand "testqi_ext_ccno_0"
7620 [(set (reg:CCNO FLAGS_REG)
7624 (match_operand 0 "ext_register_operand" "")
7627 (match_operand 1 "const_int_operand" ""))
7630 (define_insn "*testqi_ext_0"
7631 [(set (reg FLAGS_REG)
7635 (match_operand 0 "ext_register_operand" "Q")
7638 (match_operand 1 "const_int_operand" "n"))
7640 "ix86_match_ccmode (insn, CCNOmode)"
7641 "test{b}\t{%1, %h0|%h0, %1}"
7642 [(set_attr "type" "test")
7643 (set_attr "mode" "QI")
7644 (set_attr "length_immediate" "1")
7645 (set_attr "modrm" "1")
7646 (set_attr "pent_pair" "np")])
7648 (define_insn "*testqi_ext_1_rex64"
7649 [(set (reg FLAGS_REG)
7653 (match_operand 0 "ext_register_operand" "Q")
7657 (match_operand:QI 1 "register_operand" "Q")))
7659 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7660 "test{b}\t{%1, %h0|%h0, %1}"
7661 [(set_attr "type" "test")
7662 (set_attr "mode" "QI")])
7664 (define_insn "*testqi_ext_1"
7665 [(set (reg FLAGS_REG)
7669 (match_operand 0 "ext_register_operand" "Q")
7673 (match_operand:QI 1 "general_operand" "Qm")))
7675 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7676 "test{b}\t{%1, %h0|%h0, %1}"
7677 [(set_attr "type" "test")
7678 (set_attr "mode" "QI")])
7680 (define_insn "*testqi_ext_2"
7681 [(set (reg FLAGS_REG)
7685 (match_operand 0 "ext_register_operand" "Q")
7689 (match_operand 1 "ext_register_operand" "Q")
7693 "ix86_match_ccmode (insn, CCNOmode)"
7694 "test{b}\t{%h1, %h0|%h0, %h1}"
7695 [(set_attr "type" "test")
7696 (set_attr "mode" "QI")])
7698 (define_insn "*testqi_ext_3_rex64"
7699 [(set (reg FLAGS_REG)
7700 (compare (zero_extract:DI
7701 (match_operand 0 "nonimmediate_operand" "rm")
7702 (match_operand:DI 1 "const_int_operand" "")
7703 (match_operand:DI 2 "const_int_operand" ""))
7706 && ix86_match_ccmode (insn, CCNOmode)
7707 && INTVAL (operands[1]) > 0
7708 && INTVAL (operands[2]) >= 0
7709 /* Ensure that resulting mask is zero or sign extended operand. */
7710 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7711 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7712 && INTVAL (operands[1]) > 32))
7713 && (GET_MODE (operands[0]) == SImode
7714 || GET_MODE (operands[0]) == DImode
7715 || GET_MODE (operands[0]) == HImode
7716 || GET_MODE (operands[0]) == QImode)"
7719 ;; Combine likes to form bit extractions for some tests. Humor it.
7720 (define_insn "*testqi_ext_3"
7721 [(set (reg FLAGS_REG)
7722 (compare (zero_extract:SI
7723 (match_operand 0 "nonimmediate_operand" "rm")
7724 (match_operand:SI 1 "const_int_operand" "")
7725 (match_operand:SI 2 "const_int_operand" ""))
7727 "ix86_match_ccmode (insn, CCNOmode)
7728 && INTVAL (operands[1]) > 0
7729 && INTVAL (operands[2]) >= 0
7730 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7731 && (GET_MODE (operands[0]) == SImode
7732 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7733 || GET_MODE (operands[0]) == HImode
7734 || GET_MODE (operands[0]) == QImode)"
7738 [(set (match_operand 0 "flags_reg_operand" "")
7739 (match_operator 1 "compare_operator"
7741 (match_operand 2 "nonimmediate_operand" "")
7742 (match_operand 3 "const_int_operand" "")
7743 (match_operand 4 "const_int_operand" ""))
7745 "ix86_match_ccmode (insn, CCNOmode)"
7746 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7748 rtx val = operands[2];
7749 HOST_WIDE_INT len = INTVAL (operands[3]);
7750 HOST_WIDE_INT pos = INTVAL (operands[4]);
7752 enum machine_mode mode, submode;
7754 mode = GET_MODE (val);
7757 /* ??? Combine likes to put non-volatile mem extractions in QImode
7758 no matter the size of the test. So find a mode that works. */
7759 if (! MEM_VOLATILE_P (val))
7761 mode = smallest_mode_for_size (pos + len, MODE_INT);
7762 val = adjust_address (val, mode, 0);
7765 else if (GET_CODE (val) == SUBREG
7766 && (submode = GET_MODE (SUBREG_REG (val)),
7767 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7768 && pos + len <= GET_MODE_BITSIZE (submode)
7769 && GET_MODE_CLASS (submode) == MODE_INT)
7771 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7773 val = SUBREG_REG (val);
7775 else if (mode == HImode && pos + len <= 8)
7777 /* Small HImode tests can be converted to QImode. */
7779 val = gen_lowpart (QImode, val);
7782 if (len == HOST_BITS_PER_WIDE_INT)
7785 mask = ((HOST_WIDE_INT)1 << len) - 1;
7788 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7791 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7792 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7793 ;; this is relatively important trick.
7794 ;; Do the conversion only post-reload to avoid limiting of the register class
7797 [(set (match_operand 0 "flags_reg_operand" "")
7798 (match_operator 1 "compare_operator"
7799 [(and (match_operand 2 "register_operand" "")
7800 (match_operand 3 "const_int_operand" ""))
7803 && QI_REG_P (operands[2])
7804 && GET_MODE (operands[2]) != QImode
7805 && ((ix86_match_ccmode (insn, CCZmode)
7806 && !(INTVAL (operands[3]) & ~(255 << 8)))
7807 || (ix86_match_ccmode (insn, CCNOmode)
7808 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7811 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7814 "operands[2] = gen_lowpart (SImode, operands[2]);
7815 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7818 [(set (match_operand 0 "flags_reg_operand" "")
7819 (match_operator 1 "compare_operator"
7820 [(and (match_operand 2 "nonimmediate_operand" "")
7821 (match_operand 3 "const_int_operand" ""))
7824 && GET_MODE (operands[2]) != QImode
7825 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7826 && ((ix86_match_ccmode (insn, CCZmode)
7827 && !(INTVAL (operands[3]) & ~255))
7828 || (ix86_match_ccmode (insn, CCNOmode)
7829 && !(INTVAL (operands[3]) & ~127)))"
7831 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7833 "operands[2] = gen_lowpart (QImode, operands[2]);
7834 operands[3] = gen_lowpart (QImode, operands[3]);")
7836 ;; %%% This used to optimize known byte-wide and operations to memory,
7837 ;; and sometimes to QImode registers. If this is considered useful,
7838 ;; it should be done with splitters.
7840 (define_expand "and<mode>3"
7841 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7842 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7843 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7845 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7847 (define_insn "*anddi_1"
7848 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7850 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7851 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7852 (clobber (reg:CC FLAGS_REG))]
7853 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7855 switch (get_attr_type (insn))
7859 enum machine_mode mode;
7861 gcc_assert (CONST_INT_P (operands[2]));
7862 if (INTVAL (operands[2]) == 0xff)
7866 gcc_assert (INTVAL (operands[2]) == 0xffff);
7870 operands[1] = gen_lowpart (mode, operands[1]);
7872 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7874 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7878 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7879 if (get_attr_mode (insn) == MODE_SI)
7880 return "and{l}\t{%k2, %k0|%k0, %k2}";
7882 return "and{q}\t{%2, %0|%0, %2}";
7885 [(set_attr "type" "alu,alu,alu,imovx")
7886 (set_attr "length_immediate" "*,*,*,0")
7887 (set (attr "prefix_rex")
7889 (and (eq_attr "type" "imovx")
7890 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7891 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7893 (const_string "*")))
7894 (set_attr "mode" "SI,DI,DI,SI")])
7896 (define_insn "*andsi_1"
7897 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7898 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7899 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7900 (clobber (reg:CC FLAGS_REG))]
7901 "ix86_binary_operator_ok (AND, SImode, operands)"
7903 switch (get_attr_type (insn))
7907 enum machine_mode mode;
7909 gcc_assert (CONST_INT_P (operands[2]));
7910 if (INTVAL (operands[2]) == 0xff)
7914 gcc_assert (INTVAL (operands[2]) == 0xffff);
7918 operands[1] = gen_lowpart (mode, operands[1]);
7920 return "movz{bl|x}\t{%1, %0|%0, %1}";
7922 return "movz{wl|x}\t{%1, %0|%0, %1}";
7926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7927 return "and{l}\t{%2, %0|%0, %2}";
7930 [(set_attr "type" "alu,alu,imovx")
7931 (set (attr "prefix_rex")
7933 (and (eq_attr "type" "imovx")
7934 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7935 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7937 (const_string "*")))
7938 (set_attr "length_immediate" "*,*,0")
7939 (set_attr "mode" "SI")])
7941 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7942 (define_insn "*andsi_1_zext"
7943 [(set (match_operand:DI 0 "register_operand" "=r")
7945 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7946 (match_operand:SI 2 "general_operand" "g"))))
7947 (clobber (reg:CC FLAGS_REG))]
7948 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7949 "and{l}\t{%2, %k0|%k0, %2}"
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "SI")])
7953 (define_insn "*andhi_1"
7954 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7955 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7956 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7957 (clobber (reg:CC FLAGS_REG))]
7958 "ix86_binary_operator_ok (AND, HImode, operands)"
7960 switch (get_attr_type (insn))
7963 gcc_assert (CONST_INT_P (operands[2]));
7964 gcc_assert (INTVAL (operands[2]) == 0xff);
7965 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7968 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7970 return "and{w}\t{%2, %0|%0, %2}";
7973 [(set_attr "type" "alu,alu,imovx")
7974 (set_attr "length_immediate" "*,*,0")
7975 (set (attr "prefix_rex")
7977 (and (eq_attr "type" "imovx")
7978 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7980 (const_string "*")))
7981 (set_attr "mode" "HI,HI,SI")])
7983 ;; %%% Potential partial reg stall on alternative 2. What to do?
7984 (define_insn "*andqi_1"
7985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7986 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7987 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7988 (clobber (reg:CC FLAGS_REG))]
7989 "ix86_binary_operator_ok (AND, QImode, operands)"
7991 and{b}\t{%2, %0|%0, %2}
7992 and{b}\t{%2, %0|%0, %2}
7993 and{l}\t{%k2, %k0|%k0, %k2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "mode" "QI,QI,SI")])
7997 (define_insn "*andqi_1_slp"
7998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7999 (and:QI (match_dup 0)
8000 (match_operand:QI 1 "general_operand" "qn,qmn")))
8001 (clobber (reg:CC FLAGS_REG))]
8002 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8003 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8004 "and{b}\t{%1, %0|%0, %1}"
8005 [(set_attr "type" "alu1")
8006 (set_attr "mode" "QI")])
8009 [(set (match_operand 0 "register_operand" "")
8011 (const_int -65536)))
8012 (clobber (reg:CC FLAGS_REG))]
8013 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8014 || optimize_function_for_size_p (cfun)"
8015 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8016 "operands[1] = gen_lowpart (HImode, operands[0]);")
8019 [(set (match_operand 0 "ext_register_operand" "")
8022 (clobber (reg:CC FLAGS_REG))]
8023 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8024 && reload_completed"
8025 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8026 "operands[1] = gen_lowpart (QImode, operands[0]);")
8029 [(set (match_operand 0 "ext_register_operand" "")
8031 (const_int -65281)))
8032 (clobber (reg:CC FLAGS_REG))]
8033 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034 && reload_completed"
8035 [(parallel [(set (zero_extract:SI (match_dup 0)
8039 (zero_extract:SI (match_dup 0)
8042 (zero_extract:SI (match_dup 0)
8045 (clobber (reg:CC FLAGS_REG))])]
8046 "operands[0] = gen_lowpart (SImode, operands[0]);")
8048 (define_insn "*anddi_2"
8049 [(set (reg FLAGS_REG)
8052 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8055 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056 (and:DI (match_dup 1) (match_dup 2)))]
8057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058 && ix86_binary_operator_ok (AND, DImode, operands)"
8060 and{l}\t{%k2, %k0|%k0, %k2}
8061 and{q}\t{%2, %0|%0, %2}
8062 and{q}\t{%2, %0|%0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "mode" "SI,DI,DI")])
8066 (define_insn "*andqi_2_maybe_si"
8067 [(set (reg FLAGS_REG)
8069 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8070 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8072 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8073 (and:QI (match_dup 1) (match_dup 2)))]
8074 "ix86_binary_operator_ok (AND, QImode, operands)
8075 && ix86_match_ccmode (insn,
8076 CONST_INT_P (operands[2])
8077 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8079 if (which_alternative == 2)
8081 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8082 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8083 return "and{l}\t{%2, %k0|%k0, %2}";
8085 return "and{b}\t{%2, %0|%0, %2}";
8087 [(set_attr "type" "alu")
8088 (set_attr "mode" "QI,QI,SI")])
8090 (define_insn "*and<mode>_2"
8091 [(set (reg FLAGS_REG)
8092 (compare (and:SWI124
8093 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8094 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8096 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8097 (and:SWI124 (match_dup 1) (match_dup 2)))]
8098 "ix86_match_ccmode (insn, CCNOmode)
8099 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8100 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "mode" "<MODE>")])
8104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8105 (define_insn "*andsi_2_zext"
8106 [(set (reg FLAGS_REG)
8108 (match_operand:SI 1 "nonimmediate_operand" "%0")
8109 (match_operand:SI 2 "general_operand" "g"))
8111 (set (match_operand:DI 0 "register_operand" "=r")
8112 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8113 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8114 && ix86_binary_operator_ok (AND, SImode, operands)"
8115 "and{l}\t{%2, %k0|%k0, %2}"
8116 [(set_attr "type" "alu")
8117 (set_attr "mode" "SI")])
8119 (define_insn "*andqi_2_slp"
8120 [(set (reg FLAGS_REG)
8122 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8123 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8125 (set (strict_low_part (match_dup 0))
8126 (and:QI (match_dup 0) (match_dup 1)))]
8127 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8128 && ix86_match_ccmode (insn, CCNOmode)
8129 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8130 "and{b}\t{%1, %0|%0, %1}"
8131 [(set_attr "type" "alu1")
8132 (set_attr "mode" "QI")])
8134 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8135 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8136 ;; for a QImode operand, which of course failed.
8137 (define_insn "andqi_ext_0"
8138 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8143 (match_operand 1 "ext_register_operand" "0")
8146 (match_operand 2 "const_int_operand" "n")))
8147 (clobber (reg:CC FLAGS_REG))]
8149 "and{b}\t{%2, %h0|%h0, %2}"
8150 [(set_attr "type" "alu")
8151 (set_attr "length_immediate" "1")
8152 (set_attr "modrm" "1")
8153 (set_attr "mode" "QI")])
8155 ;; Generated by peephole translating test to and. This shows up
8156 ;; often in fp comparisons.
8157 (define_insn "*andqi_ext_0_cc"
8158 [(set (reg FLAGS_REG)
8162 (match_operand 1 "ext_register_operand" "0")
8165 (match_operand 2 "const_int_operand" "n"))
8167 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8176 "ix86_match_ccmode (insn, CCNOmode)"
8177 "and{b}\t{%2, %h0|%h0, %2}"
8178 [(set_attr "type" "alu")
8179 (set_attr "length_immediate" "1")
8180 (set_attr "modrm" "1")
8181 (set_attr "mode" "QI")])
8183 (define_insn "*andqi_ext_1_rex64"
8184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8189 (match_operand 1 "ext_register_operand" "0")
8193 (match_operand 2 "ext_register_operand" "Q"))))
8194 (clobber (reg:CC FLAGS_REG))]
8196 "and{b}\t{%2, %h0|%h0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "length_immediate" "0")
8199 (set_attr "mode" "QI")])
8201 (define_insn "*andqi_ext_1"
8202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8207 (match_operand 1 "ext_register_operand" "0")
8211 (match_operand:QI 2 "general_operand" "Qm"))))
8212 (clobber (reg:CC FLAGS_REG))]
8214 "and{b}\t{%2, %h0|%h0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "length_immediate" "0")
8217 (set_attr "mode" "QI")])
8219 (define_insn "*andqi_ext_2"
8220 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8225 (match_operand 1 "ext_register_operand" "%0")
8229 (match_operand 2 "ext_register_operand" "Q")
8232 (clobber (reg:CC FLAGS_REG))]
8234 "and{b}\t{%h2, %h0|%h0, %h2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "length_immediate" "0")
8237 (set_attr "mode" "QI")])
8239 ;; Convert wide AND instructions with immediate operand to shorter QImode
8240 ;; equivalents when possible.
8241 ;; Don't do the splitting with memory operands, since it introduces risk
8242 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8243 ;; for size, but that can (should?) be handled by generic code instead.
8245 [(set (match_operand 0 "register_operand" "")
8246 (and (match_operand 1 "register_operand" "")
8247 (match_operand 2 "const_int_operand" "")))
8248 (clobber (reg:CC FLAGS_REG))]
8250 && QI_REG_P (operands[0])
8251 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8252 && !(~INTVAL (operands[2]) & ~(255 << 8))
8253 && GET_MODE (operands[0]) != QImode"
8254 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8255 (and:SI (zero_extract:SI (match_dup 1)
8256 (const_int 8) (const_int 8))
8258 (clobber (reg:CC FLAGS_REG))])]
8259 "operands[0] = gen_lowpart (SImode, operands[0]);
8260 operands[1] = gen_lowpart (SImode, operands[1]);
8261 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8263 ;; Since AND can be encoded with sign extended immediate, this is only
8264 ;; profitable when 7th bit is not set.
8266 [(set (match_operand 0 "register_operand" "")
8267 (and (match_operand 1 "general_operand" "")
8268 (match_operand 2 "const_int_operand" "")))
8269 (clobber (reg:CC FLAGS_REG))]
8271 && ANY_QI_REG_P (operands[0])
8272 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8273 && !(~INTVAL (operands[2]) & ~255)
8274 && !(INTVAL (operands[2]) & 128)
8275 && GET_MODE (operands[0]) != QImode"
8276 [(parallel [(set (strict_low_part (match_dup 0))
8277 (and:QI (match_dup 1)
8279 (clobber (reg:CC FLAGS_REG))])]
8280 "operands[0] = gen_lowpart (QImode, operands[0]);
8281 operands[1] = gen_lowpart (QImode, operands[1]);
8282 operands[2] = gen_lowpart (QImode, operands[2]);")
8284 ;; Logical inclusive and exclusive OR instructions
8286 ;; %%% This used to optimize known byte-wide and operations to memory.
8287 ;; If this is considered useful, it should be done with splitters.
8289 (define_expand "<code><mode>3"
8290 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8291 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8292 (match_operand:SWIM 2 "<general_operand>" "")))]
8294 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8296 (define_insn "*<code><mode>_1"
8297 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8299 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8300 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8301 (clobber (reg:CC FLAGS_REG))]
8302 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8303 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8304 [(set_attr "type" "alu")
8305 (set_attr "mode" "<MODE>")])
8307 ;; %%% Potential partial reg stall on alternative 2. What to do?
8308 (define_insn "*<code>qi_1"
8309 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8310 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8311 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8315 <logic>{b}\t{%2, %0|%0, %2}
8316 <logic>{b}\t{%2, %0|%0, %2}
8317 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "QI,QI,SI")])
8321 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8322 (define_insn "*<code>si_1_zext"
8323 [(set (match_operand:DI 0 "register_operand" "=r")
8325 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8326 (match_operand:SI 2 "general_operand" "g"))))
8327 (clobber (reg:CC FLAGS_REG))]
8328 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8329 "<logic>{l}\t{%2, %k0|%k0, %2}"
8330 [(set_attr "type" "alu")
8331 (set_attr "mode" "SI")])
8333 (define_insn "*<code>si_1_zext_imm"
8334 [(set (match_operand:DI 0 "register_operand" "=r")
8336 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8337 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8338 (clobber (reg:CC FLAGS_REG))]
8339 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8340 "<logic>{l}\t{%2, %k0|%k0, %2}"
8341 [(set_attr "type" "alu")
8342 (set_attr "mode" "SI")])
8344 (define_insn "*<code>qi_1_slp"
8345 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8346 (any_or:QI (match_dup 0)
8347 (match_operand:QI 1 "general_operand" "qmn,qn")))
8348 (clobber (reg:CC FLAGS_REG))]
8349 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8350 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8351 "<logic>{b}\t{%1, %0|%0, %1}"
8352 [(set_attr "type" "alu1")
8353 (set_attr "mode" "QI")])
8355 (define_insn "*<code><mode>_2"
8356 [(set (reg FLAGS_REG)
8357 (compare (any_or:SWI
8358 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8359 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8361 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8362 (any_or:SWI (match_dup 1) (match_dup 2)))]
8363 "ix86_match_ccmode (insn, CCNOmode)
8364 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8365 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8366 [(set_attr "type" "alu")
8367 (set_attr "mode" "<MODE>")])
8369 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8370 ;; ??? Special case for immediate operand is missing - it is tricky.
8371 (define_insn "*<code>si_2_zext"
8372 [(set (reg FLAGS_REG)
8373 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8374 (match_operand:SI 2 "general_operand" "g"))
8376 (set (match_operand:DI 0 "register_operand" "=r")
8377 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8378 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8379 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8380 "<logic>{l}\t{%2, %k0|%k0, %2}"
8381 [(set_attr "type" "alu")
8382 (set_attr "mode" "SI")])
8384 (define_insn "*<code>si_2_zext_imm"
8385 [(set (reg FLAGS_REG)
8387 (match_operand:SI 1 "nonimmediate_operand" "%0")
8388 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8390 (set (match_operand:DI 0 "register_operand" "=r")
8391 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8392 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8393 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8394 "<logic>{l}\t{%2, %k0|%k0, %2}"
8395 [(set_attr "type" "alu")
8396 (set_attr "mode" "SI")])
8398 (define_insn "*<code>qi_2_slp"
8399 [(set (reg FLAGS_REG)
8400 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8401 (match_operand:QI 1 "general_operand" "qmn,qn"))
8403 (set (strict_low_part (match_dup 0))
8404 (any_or:QI (match_dup 0) (match_dup 1)))]
8405 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8406 && ix86_match_ccmode (insn, CCNOmode)
8407 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8408 "<logic>{b}\t{%1, %0|%0, %1}"
8409 [(set_attr "type" "alu1")
8410 (set_attr "mode" "QI")])
8412 (define_insn "*<code><mode>_3"
8413 [(set (reg FLAGS_REG)
8414 (compare (any_or:SWI
8415 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8416 (match_operand:SWI 2 "<general_operand>" "<g>"))
8418 (clobber (match_scratch:SWI 0 "=<r>"))]
8419 "ix86_match_ccmode (insn, CCNOmode)
8420 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8421 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8422 [(set_attr "type" "alu")
8423 (set_attr "mode" "<MODE>")])
8425 (define_insn "*<code>qi_ext_0"
8426 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8431 (match_operand 1 "ext_register_operand" "0")
8434 (match_operand 2 "const_int_operand" "n")))
8435 (clobber (reg:CC FLAGS_REG))]
8436 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8437 "<logic>{b}\t{%2, %h0|%h0, %2}"
8438 [(set_attr "type" "alu")
8439 (set_attr "length_immediate" "1")
8440 (set_attr "modrm" "1")
8441 (set_attr "mode" "QI")])
8443 (define_insn "*<code>qi_ext_1_rex64"
8444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8449 (match_operand 1 "ext_register_operand" "0")
8453 (match_operand 2 "ext_register_operand" "Q"))))
8454 (clobber (reg:CC FLAGS_REG))]
8456 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8457 "<logic>{b}\t{%2, %h0|%h0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "length_immediate" "0")
8460 (set_attr "mode" "QI")])
8462 (define_insn "*<code>qi_ext_1"
8463 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8468 (match_operand 1 "ext_register_operand" "0")
8472 (match_operand:QI 2 "general_operand" "Qm"))))
8473 (clobber (reg:CC FLAGS_REG))]
8475 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8476 "<logic>{b}\t{%2, %h0|%h0, %2}"
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "0")
8479 (set_attr "mode" "QI")])
8481 (define_insn "*<code>qi_ext_2"
8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8486 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8489 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8492 (clobber (reg:CC FLAGS_REG))]
8493 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8494 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8500 [(set (match_operand 0 "register_operand" "")
8501 (any_or (match_operand 1 "register_operand" "")
8502 (match_operand 2 "const_int_operand" "")))
8503 (clobber (reg:CC FLAGS_REG))]
8505 && QI_REG_P (operands[0])
8506 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8507 && !(INTVAL (operands[2]) & ~(255 << 8))
8508 && GET_MODE (operands[0]) != QImode"
8509 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8510 (any_or:SI (zero_extract:SI (match_dup 1)
8511 (const_int 8) (const_int 8))
8513 (clobber (reg:CC FLAGS_REG))])]
8514 "operands[0] = gen_lowpart (SImode, operands[0]);
8515 operands[1] = gen_lowpart (SImode, operands[1]);
8516 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8518 ;; Since OR can be encoded with sign extended immediate, this is only
8519 ;; profitable when 7th bit is set.
8521 [(set (match_operand 0 "register_operand" "")
8522 (any_or (match_operand 1 "general_operand" "")
8523 (match_operand 2 "const_int_operand" "")))
8524 (clobber (reg:CC FLAGS_REG))]
8526 && ANY_QI_REG_P (operands[0])
8527 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8528 && !(INTVAL (operands[2]) & ~255)
8529 && (INTVAL (operands[2]) & 128)
8530 && GET_MODE (operands[0]) != QImode"
8531 [(parallel [(set (strict_low_part (match_dup 0))
8532 (any_or:QI (match_dup 1)
8534 (clobber (reg:CC FLAGS_REG))])]
8535 "operands[0] = gen_lowpart (QImode, operands[0]);
8536 operands[1] = gen_lowpart (QImode, operands[1]);
8537 operands[2] = gen_lowpart (QImode, operands[2]);")
8539 (define_expand "xorqi_cc_ext_1"
8541 (set (reg:CCNO FLAGS_REG)
8545 (match_operand 1 "ext_register_operand" "")
8548 (match_operand:QI 2 "general_operand" ""))
8550 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8560 (define_insn "*xorqi_cc_ext_1_rex64"
8561 [(set (reg FLAGS_REG)
8565 (match_operand 1 "ext_register_operand" "0")
8568 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8570 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8579 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8580 "xor{b}\t{%2, %h0|%h0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "modrm" "1")
8583 (set_attr "mode" "QI")])
8585 (define_insn "*xorqi_cc_ext_1"
8586 [(set (reg FLAGS_REG)
8590 (match_operand 1 "ext_register_operand" "0")
8593 (match_operand:QI 2 "general_operand" "qmn"))
8595 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8604 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8605 "xor{b}\t{%2, %h0|%h0, %2}"
8606 [(set_attr "type" "alu")
8607 (set_attr "modrm" "1")
8608 (set_attr "mode" "QI")])
8610 ;; Negation instructions
8612 (define_expand "neg<mode>2"
8613 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8614 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8616 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8618 (define_insn_and_split "*neg<dwi>2_doubleword"
8619 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8620 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8621 (clobber (reg:CC FLAGS_REG))]
8622 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8626 [(set (reg:CCZ FLAGS_REG)
8627 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8628 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8631 (plus:DWIH (match_dup 3)
8632 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8634 (clobber (reg:CC FLAGS_REG))])
8637 (neg:DWIH (match_dup 2)))
8638 (clobber (reg:CC FLAGS_REG))])]
8639 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8641 (define_insn "*neg<mode>2_1"
8642 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8643 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8644 (clobber (reg:CC FLAGS_REG))]
8645 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8646 "neg{<imodesuffix>}\t%0"
8647 [(set_attr "type" "negnot")
8648 (set_attr "mode" "<MODE>")])
8650 ;; Combine is quite creative about this pattern.
8651 (define_insn "*negsi2_1_zext"
8652 [(set (match_operand:DI 0 "register_operand" "=r")
8654 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8657 (clobber (reg:CC FLAGS_REG))]
8658 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8660 [(set_attr "type" "negnot")
8661 (set_attr "mode" "SI")])
8663 ;; The problem with neg is that it does not perform (compare x 0),
8664 ;; it really performs (compare 0 x), which leaves us with the zero
8665 ;; flag being the only useful item.
8667 (define_insn "*neg<mode>2_cmpz"
8668 [(set (reg:CCZ FLAGS_REG)
8670 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8673 (neg:SWI (match_dup 1)))]
8674 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8675 "neg{<imodesuffix>}\t%0"
8676 [(set_attr "type" "negnot")
8677 (set_attr "mode" "<MODE>")])
8679 (define_insn "*negsi2_cmpz_zext"
8680 [(set (reg:CCZ FLAGS_REG)
8684 (match_operand:DI 1 "register_operand" "0")
8688 (set (match_operand:DI 0 "register_operand" "=r")
8689 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8692 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8694 [(set_attr "type" "negnot")
8695 (set_attr "mode" "SI")])
8697 ;; Changing of sign for FP values is doable using integer unit too.
8699 (define_expand "<code><mode>2"
8700 [(set (match_operand:X87MODEF 0 "register_operand" "")
8701 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8702 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8703 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8705 (define_insn "*absneg<mode>2_mixed"
8706 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8707 (match_operator:MODEF 3 "absneg_operator"
8708 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8709 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8714 (define_insn "*absneg<mode>2_sse"
8715 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8716 (match_operator:MODEF 3 "absneg_operator"
8717 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8718 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8719 (clobber (reg:CC FLAGS_REG))]
8720 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8723 (define_insn "*absneg<mode>2_i387"
8724 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8725 (match_operator:X87MODEF 3 "absneg_operator"
8726 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8727 (use (match_operand 2 "" ""))
8728 (clobber (reg:CC FLAGS_REG))]
8729 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8732 (define_expand "<code>tf2"
8733 [(set (match_operand:TF 0 "register_operand" "")
8734 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8736 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8738 (define_insn "*absnegtf2_sse"
8739 [(set (match_operand:TF 0 "register_operand" "=x,x")
8740 (match_operator:TF 3 "absneg_operator"
8741 [(match_operand:TF 1 "register_operand" "0,x")]))
8742 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8743 (clobber (reg:CC FLAGS_REG))]
8747 ;; Splitters for fp abs and neg.
8750 [(set (match_operand 0 "fp_register_operand" "")
8751 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8752 (use (match_operand 2 "" ""))
8753 (clobber (reg:CC FLAGS_REG))]
8755 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8758 [(set (match_operand 0 "register_operand" "")
8759 (match_operator 3 "absneg_operator"
8760 [(match_operand 1 "register_operand" "")]))
8761 (use (match_operand 2 "nonimmediate_operand" ""))
8762 (clobber (reg:CC FLAGS_REG))]
8763 "reload_completed && SSE_REG_P (operands[0])"
8764 [(set (match_dup 0) (match_dup 3))]
8766 enum machine_mode mode = GET_MODE (operands[0]);
8767 enum machine_mode vmode = GET_MODE (operands[2]);
8770 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8771 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8772 if (operands_match_p (operands[0], operands[2]))
8775 operands[1] = operands[2];
8778 if (GET_CODE (operands[3]) == ABS)
8779 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8781 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8786 [(set (match_operand:SF 0 "register_operand" "")
8787 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8788 (use (match_operand:V4SF 2 "" ""))
8789 (clobber (reg:CC FLAGS_REG))]
8791 [(parallel [(set (match_dup 0) (match_dup 1))
8792 (clobber (reg:CC FLAGS_REG))])]
8795 operands[0] = gen_lowpart (SImode, operands[0]);
8796 if (GET_CODE (operands[1]) == ABS)
8798 tmp = gen_int_mode (0x7fffffff, SImode);
8799 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8803 tmp = gen_int_mode (0x80000000, SImode);
8804 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8810 [(set (match_operand:DF 0 "register_operand" "")
8811 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8812 (use (match_operand 2 "" ""))
8813 (clobber (reg:CC FLAGS_REG))]
8815 [(parallel [(set (match_dup 0) (match_dup 1))
8816 (clobber (reg:CC FLAGS_REG))])]
8821 tmp = gen_lowpart (DImode, operands[0]);
8822 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8825 if (GET_CODE (operands[1]) == ABS)
8828 tmp = gen_rtx_NOT (DImode, tmp);
8832 operands[0] = gen_highpart (SImode, operands[0]);
8833 if (GET_CODE (operands[1]) == ABS)
8835 tmp = gen_int_mode (0x7fffffff, SImode);
8836 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8840 tmp = gen_int_mode (0x80000000, SImode);
8841 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8848 [(set (match_operand:XF 0 "register_operand" "")
8849 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8850 (use (match_operand 2 "" ""))
8851 (clobber (reg:CC FLAGS_REG))]
8853 [(parallel [(set (match_dup 0) (match_dup 1))
8854 (clobber (reg:CC FLAGS_REG))])]
8857 operands[0] = gen_rtx_REG (SImode,
8858 true_regnum (operands[0])
8859 + (TARGET_64BIT ? 1 : 2));
8860 if (GET_CODE (operands[1]) == ABS)
8862 tmp = GEN_INT (0x7fff);
8863 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8867 tmp = GEN_INT (0x8000);
8868 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8873 ;; Conditionalize these after reload. If they match before reload, we
8874 ;; lose the clobber and ability to use integer instructions.
8876 (define_insn "*<code><mode>2_1"
8877 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8878 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8880 && (reload_completed
8881 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8882 "f<absneg_mnemonic>"
8883 [(set_attr "type" "fsgn")
8884 (set_attr "mode" "<MODE>")])
8886 (define_insn "*<code>extendsfdf2"
8887 [(set (match_operand:DF 0 "register_operand" "=f")
8888 (absneg:DF (float_extend:DF
8889 (match_operand:SF 1 "register_operand" "0"))))]
8890 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8891 "f<absneg_mnemonic>"
8892 [(set_attr "type" "fsgn")
8893 (set_attr "mode" "DF")])
8895 (define_insn "*<code>extendsfxf2"
8896 [(set (match_operand:XF 0 "register_operand" "=f")
8897 (absneg:XF (float_extend:XF
8898 (match_operand:SF 1 "register_operand" "0"))))]
8900 "f<absneg_mnemonic>"
8901 [(set_attr "type" "fsgn")
8902 (set_attr "mode" "XF")])
8904 (define_insn "*<code>extenddfxf2"
8905 [(set (match_operand:XF 0 "register_operand" "=f")
8906 (absneg:XF (float_extend:XF
8907 (match_operand:DF 1 "register_operand" "0"))))]
8909 "f<absneg_mnemonic>"
8910 [(set_attr "type" "fsgn")
8911 (set_attr "mode" "XF")])
8913 ;; Copysign instructions
8915 (define_mode_iterator CSGNMODE [SF DF TF])
8916 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8918 (define_expand "copysign<mode>3"
8919 [(match_operand:CSGNMODE 0 "register_operand" "")
8920 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8921 (match_operand:CSGNMODE 2 "register_operand" "")]
8922 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8923 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8924 "ix86_expand_copysign (operands); DONE;")
8926 (define_insn_and_split "copysign<mode>3_const"
8927 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8929 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8930 (match_operand:CSGNMODE 2 "register_operand" "0")
8931 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8933 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8934 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8936 "&& reload_completed"
8938 "ix86_split_copysign_const (operands); DONE;")
8940 (define_insn "copysign<mode>3_var"
8941 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8943 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8944 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8945 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8946 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8948 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8949 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8950 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8954 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8956 [(match_operand:CSGNMODE 2 "register_operand" "")
8957 (match_operand:CSGNMODE 3 "register_operand" "")
8958 (match_operand:<CSGNVMODE> 4 "" "")
8959 (match_operand:<CSGNVMODE> 5 "" "")]
8961 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8962 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8963 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8964 && reload_completed"
8966 "ix86_split_copysign_var (operands); DONE;")
8968 ;; One complement instructions
8970 (define_expand "one_cmpl<mode>2"
8971 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8972 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8974 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8976 (define_insn "*one_cmpl<mode>2_1"
8977 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8978 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8979 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8980 "not{<imodesuffix>}\t%0"
8981 [(set_attr "type" "negnot")
8982 (set_attr "mode" "<MODE>")])
8984 ;; %%% Potential partial reg stall on alternative 1. What to do?
8985 (define_insn "*one_cmplqi2_1"
8986 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8987 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8988 "ix86_unary_operator_ok (NOT, QImode, operands)"
8992 [(set_attr "type" "negnot")
8993 (set_attr "mode" "QI,SI")])
8995 ;; ??? Currently never generated - xor is used instead.
8996 (define_insn "*one_cmplsi2_1_zext"
8997 [(set (match_operand:DI 0 "register_operand" "=r")
8999 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9000 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9002 [(set_attr "type" "negnot")
9003 (set_attr "mode" "SI")])
9005 (define_insn "*one_cmpl<mode>2_2"
9006 [(set (reg FLAGS_REG)
9007 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9009 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9010 (not:SWI (match_dup 1)))]
9011 "ix86_match_ccmode (insn, CCNOmode)
9012 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9014 [(set_attr "type" "alu1")
9015 (set_attr "mode" "<MODE>")])
9018 [(set (match_operand 0 "flags_reg_operand" "")
9019 (match_operator 2 "compare_operator"
9020 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9022 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9023 (not:SWI (match_dup 3)))]
9024 "ix86_match_ccmode (insn, CCNOmode)"
9025 [(parallel [(set (match_dup 0)
9026 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9029 (xor:SWI (match_dup 3) (const_int -1)))])])
9031 ;; ??? Currently never generated - xor is used instead.
9032 (define_insn "*one_cmplsi2_2_zext"
9033 [(set (reg FLAGS_REG)
9034 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9036 (set (match_operand:DI 0 "register_operand" "=r")
9037 (zero_extend:DI (not:SI (match_dup 1))))]
9038 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9039 && ix86_unary_operator_ok (NOT, SImode, operands)"
9041 [(set_attr "type" "alu1")
9042 (set_attr "mode" "SI")])
9045 [(set (match_operand 0 "flags_reg_operand" "")
9046 (match_operator 2 "compare_operator"
9047 [(not:SI (match_operand:SI 3 "register_operand" ""))
9049 (set (match_operand:DI 1 "register_operand" "")
9050 (zero_extend:DI (not:SI (match_dup 3))))]
9051 "ix86_match_ccmode (insn, CCNOmode)"
9052 [(parallel [(set (match_dup 0)
9053 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9056 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9058 ;; Shift instructions
9060 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9061 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9062 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9063 ;; from the assembler input.
9065 ;; This instruction shifts the target reg/mem as usual, but instead of
9066 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9067 ;; is a left shift double, bits are taken from the high order bits of
9068 ;; reg, else if the insn is a shift right double, bits are taken from the
9069 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9070 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9072 ;; Since sh[lr]d does not change the `reg' operand, that is done
9073 ;; separately, making all shifts emit pairs of shift double and normal
9074 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9075 ;; support a 63 bit shift, each shift where the count is in a reg expands
9076 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9078 ;; If the shift count is a constant, we need never emit more than one
9079 ;; shift pair, instead using moves and sign extension for counts greater
9082 (define_expand "ashl<mode>3"
9083 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9084 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9085 (match_operand:QI 2 "nonmemory_operand" "")))]
9087 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9089 (define_insn "*ashl<mode>3_doubleword"
9090 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9091 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9092 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9093 (clobber (reg:CC FLAGS_REG))]
9096 [(set_attr "type" "multi")])
9099 [(set (match_operand:DWI 0 "register_operand" "")
9100 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9101 (match_operand:QI 2 "nonmemory_operand" "")))
9102 (clobber (reg:CC FLAGS_REG))]
9103 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9105 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9107 ;; By default we don't ask for a scratch register, because when DWImode
9108 ;; values are manipulated, registers are already at a premium. But if
9109 ;; we have one handy, we won't turn it away.
9112 [(match_scratch:DWIH 3 "r")
9113 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9115 (match_operand:<DWI> 1 "nonmemory_operand" "")
9116 (match_operand:QI 2 "nonmemory_operand" "")))
9117 (clobber (reg:CC FLAGS_REG))])
9121 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9123 (define_insn "x86_64_shld"
9124 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9125 (ior:DI (ashift:DI (match_dup 0)
9126 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9127 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9128 (minus:QI (const_int 64) (match_dup 2)))))
9129 (clobber (reg:CC FLAGS_REG))]
9131 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9132 [(set_attr "type" "ishift")
9133 (set_attr "prefix_0f" "1")
9134 (set_attr "mode" "DI")
9135 (set_attr "athlon_decode" "vector")
9136 (set_attr "amdfam10_decode" "vector")
9137 (set_attr "bdver1_decode" "vector")])
9139 (define_insn "x86_shld"
9140 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9141 (ior:SI (ashift:SI (match_dup 0)
9142 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9143 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9144 (minus:QI (const_int 32) (match_dup 2)))))
9145 (clobber (reg:CC FLAGS_REG))]
9147 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9148 [(set_attr "type" "ishift")
9149 (set_attr "prefix_0f" "1")
9150 (set_attr "mode" "SI")
9151 (set_attr "pent_pair" "np")
9152 (set_attr "athlon_decode" "vector")
9153 (set_attr "amdfam10_decode" "vector")
9154 (set_attr "bdver1_decode" "vector")])
9156 (define_expand "x86_shift<mode>_adj_1"
9157 [(set (reg:CCZ FLAGS_REG)
9158 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9161 (set (match_operand:SWI48 0 "register_operand" "")
9162 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9163 (match_operand:SWI48 1 "register_operand" "")
9166 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9167 (match_operand:SWI48 3 "register_operand" "r")
9170 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9172 (define_expand "x86_shift<mode>_adj_2"
9173 [(use (match_operand:SWI48 0 "register_operand" ""))
9174 (use (match_operand:SWI48 1 "register_operand" ""))
9175 (use (match_operand:QI 2 "register_operand" ""))]
9178 rtx label = gen_label_rtx ();
9181 emit_insn (gen_testqi_ccz_1 (operands[2],
9182 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9184 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9185 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9186 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9187 gen_rtx_LABEL_REF (VOIDmode, label),
9189 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9190 JUMP_LABEL (tmp) = label;
9192 emit_move_insn (operands[0], operands[1]);
9193 ix86_expand_clear (operands[1]);
9196 LABEL_NUSES (label) = 1;
9201 ;; Avoid useless masking of count operand.
9202 (define_insn_and_split "*ashl<mode>3_mask"
9203 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9205 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9208 (match_operand:SI 2 "nonimmediate_operand" "c")
9209 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9210 (clobber (reg:CC FLAGS_REG))]
9211 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9212 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9213 == GET_MODE_BITSIZE (<MODE>mode)-1"
9216 [(parallel [(set (match_dup 0)
9217 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9218 (clobber (reg:CC FLAGS_REG))])]
9220 if (can_create_pseudo_p ())
9221 operands [2] = force_reg (SImode, operands[2]);
9223 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9225 [(set_attr "type" "ishift")
9226 (set_attr "mode" "<MODE>")])
9228 (define_insn "*ashl<mode>3_1"
9229 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9230 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9231 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9232 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9235 switch (get_attr_type (insn))
9241 gcc_assert (operands[2] == const1_rtx);
9242 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9243 return "add{<imodesuffix>}\t%0, %0";
9246 if (operands[2] == const1_rtx
9247 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9248 return "sal{<imodesuffix>}\t%0";
9250 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9254 (cond [(eq_attr "alternative" "1")
9255 (const_string "lea")
9256 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9258 (match_operand 0 "register_operand" ""))
9259 (match_operand 2 "const1_operand" ""))
9260 (const_string "alu")
9262 (const_string "ishift")))
9263 (set (attr "length_immediate")
9265 (ior (eq_attr "type" "alu")
9266 (and (eq_attr "type" "ishift")
9267 (and (match_operand 2 "const1_operand" "")
9268 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9271 (const_string "*")))
9272 (set_attr "mode" "<MODE>")])
9274 (define_insn "*ashlsi3_1_zext"
9275 [(set (match_operand:DI 0 "register_operand" "=r,r")
9277 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9278 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9279 (clobber (reg:CC FLAGS_REG))]
9280 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9282 switch (get_attr_type (insn))
9288 gcc_assert (operands[2] == const1_rtx);
9289 return "add{l}\t%k0, %k0";
9292 if (operands[2] == const1_rtx
9293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9294 return "sal{l}\t%k0";
9296 return "sal{l}\t{%2, %k0|%k0, %2}";
9300 (cond [(eq_attr "alternative" "1")
9301 (const_string "lea")
9302 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9304 (match_operand 2 "const1_operand" ""))
9305 (const_string "alu")
9307 (const_string "ishift")))
9308 (set (attr "length_immediate")
9310 (ior (eq_attr "type" "alu")
9311 (and (eq_attr "type" "ishift")
9312 (and (match_operand 2 "const1_operand" "")
9313 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9316 (const_string "*")))
9317 (set_attr "mode" "SI")])
9319 (define_insn "*ashlhi3_1"
9320 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9321 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9322 (match_operand:QI 2 "nonmemory_operand" "cI")))
9323 (clobber (reg:CC FLAGS_REG))]
9324 "TARGET_PARTIAL_REG_STALL
9325 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9327 switch (get_attr_type (insn))
9330 gcc_assert (operands[2] == const1_rtx);
9331 return "add{w}\t%0, %0";
9334 if (operands[2] == const1_rtx
9335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9336 return "sal{w}\t%0";
9338 return "sal{w}\t{%2, %0|%0, %2}";
9342 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9344 (match_operand 0 "register_operand" ""))
9345 (match_operand 2 "const1_operand" ""))
9346 (const_string "alu")
9348 (const_string "ishift")))
9349 (set (attr "length_immediate")
9351 (ior (eq_attr "type" "alu")
9352 (and (eq_attr "type" "ishift")
9353 (and (match_operand 2 "const1_operand" "")
9354 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9357 (const_string "*")))
9358 (set_attr "mode" "HI")])
9360 (define_insn "*ashlhi3_1_lea"
9361 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9362 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9363 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "!TARGET_PARTIAL_REG_STALL
9366 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9368 switch (get_attr_type (insn))
9374 gcc_assert (operands[2] == const1_rtx);
9375 return "add{w}\t%0, %0";
9378 if (operands[2] == const1_rtx
9379 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380 return "sal{w}\t%0";
9382 return "sal{w}\t{%2, %0|%0, %2}";
9386 (cond [(eq_attr "alternative" "1")
9387 (const_string "lea")
9388 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9390 (match_operand 0 "register_operand" ""))
9391 (match_operand 2 "const1_operand" ""))
9392 (const_string "alu")
9394 (const_string "ishift")))
9395 (set (attr "length_immediate")
9397 (ior (eq_attr "type" "alu")
9398 (and (eq_attr "type" "ishift")
9399 (and (match_operand 2 "const1_operand" "")
9400 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9403 (const_string "*")))
9404 (set_attr "mode" "HI,SI")])
9406 (define_insn "*ashlqi3_1"
9407 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9408 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9409 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "TARGET_PARTIAL_REG_STALL
9412 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9414 switch (get_attr_type (insn))
9417 gcc_assert (operands[2] == const1_rtx);
9418 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9419 return "add{l}\t%k0, %k0";
9421 return "add{b}\t%0, %0";
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9427 if (get_attr_mode (insn) == MODE_SI)
9428 return "sal{l}\t%k0";
9430 return "sal{b}\t%0";
9434 if (get_attr_mode (insn) == MODE_SI)
9435 return "sal{l}\t{%2, %k0|%k0, %2}";
9437 return "sal{b}\t{%2, %0|%0, %2}";
9442 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9444 (match_operand 0 "register_operand" ""))
9445 (match_operand 2 "const1_operand" ""))
9446 (const_string "alu")
9448 (const_string "ishift")))
9449 (set (attr "length_immediate")
9451 (ior (eq_attr "type" "alu")
9452 (and (eq_attr "type" "ishift")
9453 (and (match_operand 2 "const1_operand" "")
9454 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9457 (const_string "*")))
9458 (set_attr "mode" "QI,SI")])
9460 ;; %%% Potential partial reg stall on alternative 2. What to do?
9461 (define_insn "*ashlqi3_1_lea"
9462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9463 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9464 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9465 (clobber (reg:CC FLAGS_REG))]
9466 "!TARGET_PARTIAL_REG_STALL
9467 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9469 switch (get_attr_type (insn))
9475 gcc_assert (operands[2] == const1_rtx);
9476 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9477 return "add{l}\t%k0, %k0";
9479 return "add{b}\t%0, %0";
9482 if (operands[2] == const1_rtx
9483 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9485 if (get_attr_mode (insn) == MODE_SI)
9486 return "sal{l}\t%k0";
9488 return "sal{b}\t%0";
9492 if (get_attr_mode (insn) == MODE_SI)
9493 return "sal{l}\t{%2, %k0|%k0, %2}";
9495 return "sal{b}\t{%2, %0|%0, %2}";
9500 (cond [(eq_attr "alternative" "2")
9501 (const_string "lea")
9502 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9504 (match_operand 0 "register_operand" ""))
9505 (match_operand 2 "const1_operand" ""))
9506 (const_string "alu")
9508 (const_string "ishift")))
9509 (set (attr "length_immediate")
9511 (ior (eq_attr "type" "alu")
9512 (and (eq_attr "type" "ishift")
9513 (and (match_operand 2 "const1_operand" "")
9514 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9517 (const_string "*")))
9518 (set_attr "mode" "QI,SI,SI")])
9520 (define_insn "*ashlqi3_1_slp"
9521 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9522 (ashift:QI (match_dup 0)
9523 (match_operand:QI 1 "nonmemory_operand" "cI")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "(optimize_function_for_size_p (cfun)
9526 || !TARGET_PARTIAL_FLAG_REG_STALL
9527 || (operands[1] == const1_rtx
9529 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9531 switch (get_attr_type (insn))
9534 gcc_assert (operands[1] == const1_rtx);
9535 return "add{b}\t%0, %0";
9538 if (operands[1] == const1_rtx
9539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540 return "sal{b}\t%0";
9542 return "sal{b}\t{%1, %0|%0, %1}";
9546 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9548 (match_operand 0 "register_operand" ""))
9549 (match_operand 1 "const1_operand" ""))
9550 (const_string "alu")
9552 (const_string "ishift1")))
9553 (set (attr "length_immediate")
9555 (ior (eq_attr "type" "alu")
9556 (and (eq_attr "type" "ishift1")
9557 (and (match_operand 1 "const1_operand" "")
9558 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9561 (const_string "*")))
9562 (set_attr "mode" "QI")])
9564 ;; Convert lea to the lea pattern to avoid flags dependency.
9566 [(set (match_operand 0 "register_operand" "")
9567 (ashift (match_operand 1 "index_register_operand" "")
9568 (match_operand:QI 2 "const_int_operand" "")))
9569 (clobber (reg:CC FLAGS_REG))]
9571 && true_regnum (operands[0]) != true_regnum (operands[1])"
9575 enum machine_mode mode = GET_MODE (operands[0]);
9578 operands[1] = gen_lowpart (Pmode, operands[1]);
9579 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9581 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9583 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9584 operands[0] = gen_lowpart (SImode, operands[0]);
9586 if (TARGET_64BIT && mode != Pmode)
9587 pat = gen_rtx_SUBREG (SImode, pat, 0);
9589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9593 ;; Convert lea to the lea pattern to avoid flags dependency.
9595 [(set (match_operand:DI 0 "register_operand" "")
9597 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9598 (match_operand:QI 2 "const_int_operand" ""))))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "TARGET_64BIT && reload_completed
9601 && true_regnum (operands[0]) != true_regnum (operands[1])"
9603 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9605 operands[1] = gen_lowpart (DImode, operands[1]);
9606 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9609 ;; This pattern can't accept a variable shift count, since shifts by
9610 ;; zero don't affect the flags. We assume that shifts by constant
9611 ;; zero are optimized away.
9612 (define_insn "*ashl<mode>3_cmp"
9613 [(set (reg FLAGS_REG)
9615 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9616 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9618 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9619 (ashift:SWI (match_dup 1) (match_dup 2)))]
9620 "(optimize_function_for_size_p (cfun)
9621 || !TARGET_PARTIAL_FLAG_REG_STALL
9622 || (operands[2] == const1_rtx
9624 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9625 && ix86_match_ccmode (insn, CCGOCmode)
9626 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9628 switch (get_attr_type (insn))
9631 gcc_assert (operands[2] == const1_rtx);
9632 return "add{<imodesuffix>}\t%0, %0";
9635 if (operands[2] == const1_rtx
9636 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9637 return "sal{<imodesuffix>}\t%0";
9639 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9643 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9645 (match_operand 0 "register_operand" ""))
9646 (match_operand 2 "const1_operand" ""))
9647 (const_string "alu")
9649 (const_string "ishift")))
9650 (set (attr "length_immediate")
9652 (ior (eq_attr "type" "alu")
9653 (and (eq_attr "type" "ishift")
9654 (and (match_operand 2 "const1_operand" "")
9655 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9658 (const_string "*")))
9659 (set_attr "mode" "<MODE>")])
9661 (define_insn "*ashlsi3_cmp_zext"
9662 [(set (reg FLAGS_REG)
9664 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9665 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9667 (set (match_operand:DI 0 "register_operand" "=r")
9668 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9670 && (optimize_function_for_size_p (cfun)
9671 || !TARGET_PARTIAL_FLAG_REG_STALL
9672 || (operands[2] == const1_rtx
9674 || TARGET_DOUBLE_WITH_ADD)))
9675 && ix86_match_ccmode (insn, CCGOCmode)
9676 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9678 switch (get_attr_type (insn))
9681 gcc_assert (operands[2] == const1_rtx);
9682 return "add{l}\t%k0, %k0";
9685 if (operands[2] == const1_rtx
9686 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9687 return "sal{l}\t%k0";
9689 return "sal{l}\t{%2, %k0|%k0, %2}";
9693 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9695 (match_operand 2 "const1_operand" ""))
9696 (const_string "alu")
9698 (const_string "ishift")))
9699 (set (attr "length_immediate")
9701 (ior (eq_attr "type" "alu")
9702 (and (eq_attr "type" "ishift")
9703 (and (match_operand 2 "const1_operand" "")
9704 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9707 (const_string "*")))
9708 (set_attr "mode" "SI")])
9710 (define_insn "*ashl<mode>3_cconly"
9711 [(set (reg FLAGS_REG)
9713 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9714 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9716 (clobber (match_scratch:SWI 0 "=<r>"))]
9717 "(optimize_function_for_size_p (cfun)
9718 || !TARGET_PARTIAL_FLAG_REG_STALL
9719 || (operands[2] == const1_rtx
9721 || TARGET_DOUBLE_WITH_ADD)))
9722 && ix86_match_ccmode (insn, CCGOCmode)
9723 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9725 switch (get_attr_type (insn))
9728 gcc_assert (operands[2] == const1_rtx);
9729 return "add{<imodesuffix>}\t%0, %0";
9732 if (operands[2] == const1_rtx
9733 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9734 return "sal{<imodesuffix>}\t%0";
9736 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9740 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9742 (match_operand 0 "register_operand" ""))
9743 (match_operand 2 "const1_operand" ""))
9744 (const_string "alu")
9746 (const_string "ishift")))
9747 (set (attr "length_immediate")
9749 (ior (eq_attr "type" "alu")
9750 (and (eq_attr "type" "ishift")
9751 (and (match_operand 2 "const1_operand" "")
9752 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9755 (const_string "*")))
9756 (set_attr "mode" "<MODE>")])
9758 ;; See comment above `ashl<mode>3' about how this works.
9760 (define_expand "<shiftrt_insn><mode>3"
9761 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9762 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9763 (match_operand:QI 2 "nonmemory_operand" "")))]
9765 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9767 ;; Avoid useless masking of count operand.
9768 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9769 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9771 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9774 (match_operand:SI 2 "nonimmediate_operand" "c")
9775 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9778 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9779 == GET_MODE_BITSIZE (<MODE>mode)-1"
9782 [(parallel [(set (match_dup 0)
9783 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9784 (clobber (reg:CC FLAGS_REG))])]
9786 if (can_create_pseudo_p ())
9787 operands [2] = force_reg (SImode, operands[2]);
9789 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9791 [(set_attr "type" "ishift")
9792 (set_attr "mode" "<MODE>")])
9794 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9795 [(set (match_operand:DWI 0 "register_operand" "=r")
9796 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9797 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9798 (clobber (reg:CC FLAGS_REG))]
9801 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9803 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9804 [(set_attr "type" "multi")])
9806 ;; By default we don't ask for a scratch register, because when DWImode
9807 ;; values are manipulated, registers are already at a premium. But if
9808 ;; we have one handy, we won't turn it away.
9811 [(match_scratch:DWIH 3 "r")
9812 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9814 (match_operand:<DWI> 1 "register_operand" "")
9815 (match_operand:QI 2 "nonmemory_operand" "")))
9816 (clobber (reg:CC FLAGS_REG))])
9820 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9822 (define_insn "x86_64_shrd"
9823 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9824 (ior:DI (ashiftrt:DI (match_dup 0)
9825 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9826 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9827 (minus:QI (const_int 64) (match_dup 2)))))
9828 (clobber (reg:CC FLAGS_REG))]
9830 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9831 [(set_attr "type" "ishift")
9832 (set_attr "prefix_0f" "1")
9833 (set_attr "mode" "DI")
9834 (set_attr "athlon_decode" "vector")
9835 (set_attr "amdfam10_decode" "vector")
9836 (set_attr "bdver1_decode" "vector")])
9838 (define_insn "x86_shrd"
9839 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9840 (ior:SI (ashiftrt:SI (match_dup 0)
9841 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9842 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9843 (minus:QI (const_int 32) (match_dup 2)))))
9844 (clobber (reg:CC FLAGS_REG))]
9846 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9847 [(set_attr "type" "ishift")
9848 (set_attr "prefix_0f" "1")
9849 (set_attr "mode" "SI")
9850 (set_attr "pent_pair" "np")
9851 (set_attr "athlon_decode" "vector")
9852 (set_attr "amdfam10_decode" "vector")
9853 (set_attr "bdver1_decode" "vector")])
9855 (define_insn "ashrdi3_cvt"
9856 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9857 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9858 (match_operand:QI 2 "const_int_operand" "")))
9859 (clobber (reg:CC FLAGS_REG))]
9860 "TARGET_64BIT && INTVAL (operands[2]) == 63
9861 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9862 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9865 sar{q}\t{%2, %0|%0, %2}"
9866 [(set_attr "type" "imovx,ishift")
9867 (set_attr "prefix_0f" "0,*")
9868 (set_attr "length_immediate" "0,*")
9869 (set_attr "modrm" "0,1")
9870 (set_attr "mode" "DI")])
9872 (define_insn "ashrsi3_cvt"
9873 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9874 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9875 (match_operand:QI 2 "const_int_operand" "")))
9876 (clobber (reg:CC FLAGS_REG))]
9877 "INTVAL (operands[2]) == 31
9878 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9879 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9882 sar{l}\t{%2, %0|%0, %2}"
9883 [(set_attr "type" "imovx,ishift")
9884 (set_attr "prefix_0f" "0,*")
9885 (set_attr "length_immediate" "0,*")
9886 (set_attr "modrm" "0,1")
9887 (set_attr "mode" "SI")])
9889 (define_insn "*ashrsi3_cvt_zext"
9890 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9892 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9893 (match_operand:QI 2 "const_int_operand" ""))))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "TARGET_64BIT && INTVAL (operands[2]) == 31
9896 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9897 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9900 sar{l}\t{%2, %k0|%k0, %2}"
9901 [(set_attr "type" "imovx,ishift")
9902 (set_attr "prefix_0f" "0,*")
9903 (set_attr "length_immediate" "0,*")
9904 (set_attr "modrm" "0,1")
9905 (set_attr "mode" "SI")])
9907 (define_expand "x86_shift<mode>_adj_3"
9908 [(use (match_operand:SWI48 0 "register_operand" ""))
9909 (use (match_operand:SWI48 1 "register_operand" ""))
9910 (use (match_operand:QI 2 "register_operand" ""))]
9913 rtx label = gen_label_rtx ();
9916 emit_insn (gen_testqi_ccz_1 (operands[2],
9917 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9919 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9920 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9921 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9922 gen_rtx_LABEL_REF (VOIDmode, label),
9924 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9925 JUMP_LABEL (tmp) = label;
9927 emit_move_insn (operands[0], operands[1]);
9928 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9929 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9931 LABEL_NUSES (label) = 1;
9936 (define_insn "*<shiftrt_insn><mode>3_1"
9937 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9938 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9939 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9940 (clobber (reg:CC FLAGS_REG))]
9941 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9943 if (operands[2] == const1_rtx
9944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9945 return "<shiftrt>{<imodesuffix>}\t%0";
9947 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9949 [(set_attr "type" "ishift")
9950 (set (attr "length_immediate")
9952 (and (match_operand 2 "const1_operand" "")
9953 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9956 (const_string "*")))
9957 (set_attr "mode" "<MODE>")])
9959 (define_insn "*<shiftrt_insn>si3_1_zext"
9960 [(set (match_operand:DI 0 "register_operand" "=r")
9962 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9963 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9964 (clobber (reg:CC FLAGS_REG))]
9965 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9967 if (operands[2] == const1_rtx
9968 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9969 return "<shiftrt>{l}\t%k0";
9971 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9973 [(set_attr "type" "ishift")
9974 (set (attr "length_immediate")
9976 (and (match_operand 2 "const1_operand" "")
9977 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9980 (const_string "*")))
9981 (set_attr "mode" "SI")])
9983 (define_insn "*<shiftrt_insn>qi3_1_slp"
9984 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9985 (any_shiftrt:QI (match_dup 0)
9986 (match_operand:QI 1 "nonmemory_operand" "cI")))
9987 (clobber (reg:CC FLAGS_REG))]
9988 "(optimize_function_for_size_p (cfun)
9989 || !TARGET_PARTIAL_REG_STALL
9990 || (operands[1] == const1_rtx
9993 if (operands[1] == const1_rtx
9994 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995 return "<shiftrt>{b}\t%0";
9997 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9999 [(set_attr "type" "ishift1")
10000 (set (attr "length_immediate")
10002 (and (match_operand 1 "const1_operand" "")
10003 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10006 (const_string "*")))
10007 (set_attr "mode" "QI")])
10009 ;; This pattern can't accept a variable shift count, since shifts by
10010 ;; zero don't affect the flags. We assume that shifts by constant
10011 ;; zero are optimized away.
10012 (define_insn "*<shiftrt_insn><mode>3_cmp"
10013 [(set (reg FLAGS_REG)
10016 (match_operand:SWI 1 "nonimmediate_operand" "0")
10017 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10019 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10020 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10021 "(optimize_function_for_size_p (cfun)
10022 || !TARGET_PARTIAL_FLAG_REG_STALL
10023 || (operands[2] == const1_rtx
10025 && ix86_match_ccmode (insn, CCGOCmode)
10026 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10028 if (operands[2] == const1_rtx
10029 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10030 return "<shiftrt>{<imodesuffix>}\t%0";
10032 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10034 [(set_attr "type" "ishift")
10035 (set (attr "length_immediate")
10037 (and (match_operand 2 "const1_operand" "")
10038 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10041 (const_string "*")))
10042 (set_attr "mode" "<MODE>")])
10044 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10045 [(set (reg FLAGS_REG)
10047 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10048 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10050 (set (match_operand:DI 0 "register_operand" "=r")
10051 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10053 && (optimize_function_for_size_p (cfun)
10054 || !TARGET_PARTIAL_FLAG_REG_STALL
10055 || (operands[2] == const1_rtx
10057 && ix86_match_ccmode (insn, CCGOCmode)
10058 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10060 if (operands[2] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<shiftrt>{l}\t%k0";
10064 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10066 [(set_attr "type" "ishift")
10067 (set (attr "length_immediate")
10069 (and (match_operand 2 "const1_operand" "")
10070 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10073 (const_string "*")))
10074 (set_attr "mode" "SI")])
10076 (define_insn "*<shiftrt_insn><mode>3_cconly"
10077 [(set (reg FLAGS_REG)
10080 (match_operand:SWI 1 "nonimmediate_operand" "0")
10081 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10083 (clobber (match_scratch:SWI 0 "=<r>"))]
10084 "(optimize_function_for_size_p (cfun)
10085 || !TARGET_PARTIAL_FLAG_REG_STALL
10086 || (operands[2] == const1_rtx
10088 && ix86_match_ccmode (insn, CCGOCmode)
10089 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10091 if (operands[2] == const1_rtx
10092 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10093 return "<shiftrt>{<imodesuffix>}\t%0";
10095 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10097 [(set_attr "type" "ishift")
10098 (set (attr "length_immediate")
10100 (and (match_operand 2 "const1_operand" "")
10101 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10104 (const_string "*")))
10105 (set_attr "mode" "<MODE>")])
10107 ;; Rotate instructions
10109 (define_expand "<rotate_insn>ti3"
10110 [(set (match_operand:TI 0 "register_operand" "")
10111 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10112 (match_operand:QI 2 "nonmemory_operand" "")))]
10115 if (const_1_to_63_operand (operands[2], VOIDmode))
10116 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10117 (operands[0], operands[1], operands[2]));
10124 (define_expand "<rotate_insn>di3"
10125 [(set (match_operand:DI 0 "shiftdi_operand" "")
10126 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10127 (match_operand:QI 2 "nonmemory_operand" "")))]
10131 ix86_expand_binary_operator (<CODE>, DImode, operands);
10132 else if (const_1_to_31_operand (operands[2], VOIDmode))
10133 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10134 (operands[0], operands[1], operands[2]));
10141 (define_expand "<rotate_insn><mode>3"
10142 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10143 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10144 (match_operand:QI 2 "nonmemory_operand" "")))]
10146 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10148 ;; Avoid useless masking of count operand.
10149 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10150 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10152 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10155 (match_operand:SI 2 "nonimmediate_operand" "c")
10156 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10157 (clobber (reg:CC FLAGS_REG))]
10158 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10159 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10160 == GET_MODE_BITSIZE (<MODE>mode)-1"
10163 [(parallel [(set (match_dup 0)
10164 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10165 (clobber (reg:CC FLAGS_REG))])]
10167 if (can_create_pseudo_p ())
10168 operands [2] = force_reg (SImode, operands[2]);
10170 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10172 [(set_attr "type" "rotate")
10173 (set_attr "mode" "<MODE>")])
10175 ;; Implement rotation using two double-precision
10176 ;; shift instructions and a scratch register.
10178 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10179 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10180 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10181 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10182 (clobber (reg:CC FLAGS_REG))
10183 (clobber (match_scratch:DWIH 3 "=&r"))]
10187 [(set (match_dup 3) (match_dup 4))
10189 [(set (match_dup 4)
10190 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10191 (lshiftrt:DWIH (match_dup 5)
10192 (minus:QI (match_dup 6) (match_dup 2)))))
10193 (clobber (reg:CC FLAGS_REG))])
10195 [(set (match_dup 5)
10196 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10197 (lshiftrt:DWIH (match_dup 3)
10198 (minus:QI (match_dup 6) (match_dup 2)))))
10199 (clobber (reg:CC FLAGS_REG))])]
10201 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10203 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10206 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10207 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10208 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10209 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10210 (clobber (reg:CC FLAGS_REG))
10211 (clobber (match_scratch:DWIH 3 "=&r"))]
10215 [(set (match_dup 3) (match_dup 4))
10217 [(set (match_dup 4)
10218 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10219 (ashift:DWIH (match_dup 5)
10220 (minus:QI (match_dup 6) (match_dup 2)))))
10221 (clobber (reg:CC FLAGS_REG))])
10223 [(set (match_dup 5)
10224 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10225 (ashift:DWIH (match_dup 3)
10226 (minus:QI (match_dup 6) (match_dup 2)))))
10227 (clobber (reg:CC FLAGS_REG))])]
10229 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10231 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10234 (define_insn "*<rotate_insn><mode>3_1"
10235 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10236 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10237 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10241 if (operands[2] == const1_rtx
10242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10243 return "<rotate>{<imodesuffix>}\t%0";
10245 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10247 [(set_attr "type" "rotate")
10248 (set (attr "length_immediate")
10250 (and (match_operand 2 "const1_operand" "")
10251 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10254 (const_string "*")))
10255 (set_attr "mode" "<MODE>")])
10257 (define_insn "*<rotate_insn>si3_1_zext"
10258 [(set (match_operand:DI 0 "register_operand" "=r")
10260 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10261 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10262 (clobber (reg:CC FLAGS_REG))]
10263 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10265 if (operands[2] == const1_rtx
10266 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10267 return "<rotate>{l}\t%k0";
10269 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10271 [(set_attr "type" "rotate")
10272 (set (attr "length_immediate")
10274 (and (match_operand 2 "const1_operand" "")
10275 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10278 (const_string "*")))
10279 (set_attr "mode" "SI")])
10281 (define_insn "*<rotate_insn>qi3_1_slp"
10282 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10283 (any_rotate:QI (match_dup 0)
10284 (match_operand:QI 1 "nonmemory_operand" "cI")))
10285 (clobber (reg:CC FLAGS_REG))]
10286 "(optimize_function_for_size_p (cfun)
10287 || !TARGET_PARTIAL_REG_STALL
10288 || (operands[1] == const1_rtx
10289 && TARGET_SHIFT1))"
10291 if (operands[1] == const1_rtx
10292 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10293 return "<rotate>{b}\t%0";
10295 return "<rotate>{b}\t{%1, %0|%0, %1}";
10297 [(set_attr "type" "rotate1")
10298 (set (attr "length_immediate")
10300 (and (match_operand 1 "const1_operand" "")
10301 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10304 (const_string "*")))
10305 (set_attr "mode" "QI")])
10308 [(set (match_operand:HI 0 "register_operand" "")
10309 (any_rotate:HI (match_dup 0) (const_int 8)))
10310 (clobber (reg:CC FLAGS_REG))]
10312 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10313 [(parallel [(set (strict_low_part (match_dup 0))
10314 (bswap:HI (match_dup 0)))
10315 (clobber (reg:CC FLAGS_REG))])])
10317 ;; Bit set / bit test instructions
10319 (define_expand "extv"
10320 [(set (match_operand:SI 0 "register_operand" "")
10321 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10322 (match_operand:SI 2 "const8_operand" "")
10323 (match_operand:SI 3 "const8_operand" "")))]
10326 /* Handle extractions from %ah et al. */
10327 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10330 /* From mips.md: extract_bit_field doesn't verify that our source
10331 matches the predicate, so check it again here. */
10332 if (! ext_register_operand (operands[1], VOIDmode))
10336 (define_expand "extzv"
10337 [(set (match_operand:SI 0 "register_operand" "")
10338 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10339 (match_operand:SI 2 "const8_operand" "")
10340 (match_operand:SI 3 "const8_operand" "")))]
10343 /* Handle extractions from %ah et al. */
10344 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10347 /* From mips.md: extract_bit_field doesn't verify that our source
10348 matches the predicate, so check it again here. */
10349 if (! ext_register_operand (operands[1], VOIDmode))
10353 (define_expand "insv"
10354 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10355 (match_operand 1 "const8_operand" "")
10356 (match_operand 2 "const8_operand" ""))
10357 (match_operand 3 "register_operand" ""))]
10360 rtx (*gen_mov_insv_1) (rtx, rtx);
10362 /* Handle insertions to %ah et al. */
10363 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10366 /* From mips.md: insert_bit_field doesn't verify that our source
10367 matches the predicate, so check it again here. */
10368 if (! ext_register_operand (operands[0], VOIDmode))
10371 gen_mov_insv_1 = (TARGET_64BIT
10372 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10374 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10378 ;; %%% bts, btr, btc, bt.
10379 ;; In general these instructions are *slow* when applied to memory,
10380 ;; since they enforce atomic operation. When applied to registers,
10381 ;; it depends on the cpu implementation. They're never faster than
10382 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10383 ;; no point. But in 64-bit, we can't hold the relevant immediates
10384 ;; within the instruction itself, so operating on bits in the high
10385 ;; 32-bits of a register becomes easier.
10387 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10388 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10389 ;; negdf respectively, so they can never be disabled entirely.
10391 (define_insn "*btsq"
10392 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10394 (match_operand:DI 1 "const_0_to_63_operand" ""))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10398 "bts{q}\t{%1, %0|%0, %1}"
10399 [(set_attr "type" "alu1")
10400 (set_attr "prefix_0f" "1")
10401 (set_attr "mode" "DI")])
10403 (define_insn "*btrq"
10404 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406 (match_operand:DI 1 "const_0_to_63_operand" ""))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10410 "btr{q}\t{%1, %0|%0, %1}"
10411 [(set_attr "type" "alu1")
10412 (set_attr "prefix_0f" "1")
10413 (set_attr "mode" "DI")])
10415 (define_insn "*btcq"
10416 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418 (match_operand:DI 1 "const_0_to_63_operand" ""))
10419 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10422 "btc{q}\t{%1, %0|%0, %1}"
10423 [(set_attr "type" "alu1")
10424 (set_attr "prefix_0f" "1")
10425 (set_attr "mode" "DI")])
10427 ;; Allow Nocona to avoid these instructions if a register is available.
10430 [(match_scratch:DI 2 "r")
10431 (parallel [(set (zero_extract:DI
10432 (match_operand:DI 0 "register_operand" "")
10434 (match_operand:DI 1 "const_0_to_63_operand" ""))
10436 (clobber (reg:CC FLAGS_REG))])]
10437 "TARGET_64BIT && !TARGET_USE_BT"
10440 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10443 if (HOST_BITS_PER_WIDE_INT >= 64)
10444 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445 else if (i < HOST_BITS_PER_WIDE_INT)
10446 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450 op1 = immed_double_const (lo, hi, DImode);
10453 emit_move_insn (operands[2], op1);
10457 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10462 [(match_scratch:DI 2 "r")
10463 (parallel [(set (zero_extract:DI
10464 (match_operand:DI 0 "register_operand" "")
10466 (match_operand:DI 1 "const_0_to_63_operand" ""))
10468 (clobber (reg:CC FLAGS_REG))])]
10469 "TARGET_64BIT && !TARGET_USE_BT"
10472 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475 if (HOST_BITS_PER_WIDE_INT >= 64)
10476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477 else if (i < HOST_BITS_PER_WIDE_INT)
10478 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10480 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10482 op1 = immed_double_const (~lo, ~hi, DImode);
10485 emit_move_insn (operands[2], op1);
10489 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10494 [(match_scratch:DI 2 "r")
10495 (parallel [(set (zero_extract:DI
10496 (match_operand:DI 0 "register_operand" "")
10498 (match_operand:DI 1 "const_0_to_63_operand" ""))
10499 (not:DI (zero_extract:DI
10500 (match_dup 0) (const_int 1) (match_dup 1))))
10501 (clobber (reg:CC FLAGS_REG))])]
10502 "TARGET_64BIT && !TARGET_USE_BT"
10505 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10508 if (HOST_BITS_PER_WIDE_INT >= 64)
10509 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10510 else if (i < HOST_BITS_PER_WIDE_INT)
10511 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10513 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10515 op1 = immed_double_const (lo, hi, DImode);
10518 emit_move_insn (operands[2], op1);
10522 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10526 (define_insn "*bt<mode>"
10527 [(set (reg:CCC FLAGS_REG)
10529 (zero_extract:SWI48
10530 (match_operand:SWI48 0 "register_operand" "r")
10532 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10534 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10535 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10536 [(set_attr "type" "alu1")
10537 (set_attr "prefix_0f" "1")
10538 (set_attr "mode" "<MODE>")])
10540 ;; Store-flag instructions.
10542 ;; For all sCOND expanders, also expand the compare or test insn that
10543 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10545 (define_insn_and_split "*setcc_di_1"
10546 [(set (match_operand:DI 0 "register_operand" "=q")
10547 (match_operator:DI 1 "ix86_comparison_operator"
10548 [(reg FLAGS_REG) (const_int 0)]))]
10549 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10551 "&& reload_completed"
10552 [(set (match_dup 2) (match_dup 1))
10553 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10555 PUT_MODE (operands[1], QImode);
10556 operands[2] = gen_lowpart (QImode, operands[0]);
10559 (define_insn_and_split "*setcc_si_1_and"
10560 [(set (match_operand:SI 0 "register_operand" "=q")
10561 (match_operator:SI 1 "ix86_comparison_operator"
10562 [(reg FLAGS_REG) (const_int 0)]))
10563 (clobber (reg:CC FLAGS_REG))]
10564 "!TARGET_PARTIAL_REG_STALL
10565 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10567 "&& reload_completed"
10568 [(set (match_dup 2) (match_dup 1))
10569 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10570 (clobber (reg:CC FLAGS_REG))])]
10572 PUT_MODE (operands[1], QImode);
10573 operands[2] = gen_lowpart (QImode, operands[0]);
10576 (define_insn_and_split "*setcc_si_1_movzbl"
10577 [(set (match_operand:SI 0 "register_operand" "=q")
10578 (match_operator:SI 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)]))]
10580 "!TARGET_PARTIAL_REG_STALL
10581 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10583 "&& reload_completed"
10584 [(set (match_dup 2) (match_dup 1))
10585 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10587 PUT_MODE (operands[1], QImode);
10588 operands[2] = gen_lowpart (QImode, operands[0]);
10591 (define_insn "*setcc_qi"
10592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10593 (match_operator:QI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10597 [(set_attr "type" "setcc")
10598 (set_attr "mode" "QI")])
10600 (define_insn "*setcc_qi_slp"
10601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10602 (match_operator:QI 1 "ix86_comparison_operator"
10603 [(reg FLAGS_REG) (const_int 0)]))]
10606 [(set_attr "type" "setcc")
10607 (set_attr "mode" "QI")])
10609 ;; In general it is not safe to assume too much about CCmode registers,
10610 ;; so simplify-rtx stops when it sees a second one. Under certain
10611 ;; conditions this is safe on x86, so help combine not create
10618 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10619 (ne:QI (match_operator 1 "ix86_comparison_operator"
10620 [(reg FLAGS_REG) (const_int 0)])
10623 [(set (match_dup 0) (match_dup 1))]
10624 "PUT_MODE (operands[1], QImode);")
10627 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10628 (ne:QI (match_operator 1 "ix86_comparison_operator"
10629 [(reg FLAGS_REG) (const_int 0)])
10632 [(set (match_dup 0) (match_dup 1))]
10633 "PUT_MODE (operands[1], QImode);")
10636 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10637 (eq:QI (match_operator 1 "ix86_comparison_operator"
10638 [(reg FLAGS_REG) (const_int 0)])
10641 [(set (match_dup 0) (match_dup 1))]
10643 rtx new_op1 = copy_rtx (operands[1]);
10644 operands[1] = new_op1;
10645 PUT_MODE (new_op1, QImode);
10646 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10647 GET_MODE (XEXP (new_op1, 0))));
10649 /* Make sure that (a) the CCmode we have for the flags is strong
10650 enough for the reversed compare or (b) we have a valid FP compare. */
10651 if (! ix86_comparison_operator (new_op1, VOIDmode))
10656 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10657 (eq:QI (match_operator 1 "ix86_comparison_operator"
10658 [(reg FLAGS_REG) (const_int 0)])
10661 [(set (match_dup 0) (match_dup 1))]
10663 rtx new_op1 = copy_rtx (operands[1]);
10664 operands[1] = new_op1;
10665 PUT_MODE (new_op1, QImode);
10666 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10667 GET_MODE (XEXP (new_op1, 0))));
10669 /* Make sure that (a) the CCmode we have for the flags is strong
10670 enough for the reversed compare or (b) we have a valid FP compare. */
10671 if (! ix86_comparison_operator (new_op1, VOIDmode))
10675 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10676 ;; subsequent logical operations are used to imitate conditional moves.
10677 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10680 (define_insn "*avx_setcc<mode>"
10681 [(set (match_operand:MODEF 0 "register_operand" "=x")
10682 (match_operator:MODEF 1 "avx_comparison_float_operator"
10683 [(match_operand:MODEF 2 "register_operand" "x")
10684 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10686 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10687 [(set_attr "type" "ssecmp")
10688 (set_attr "prefix" "vex")
10689 (set_attr "length_immediate" "1")
10690 (set_attr "mode" "<MODE>")])
10692 (define_insn "*sse_setcc<mode>"
10693 [(set (match_operand:MODEF 0 "register_operand" "=x")
10694 (match_operator:MODEF 1 "sse_comparison_operator"
10695 [(match_operand:MODEF 2 "register_operand" "0")
10696 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10697 "SSE_FLOAT_MODE_P (<MODE>mode)"
10698 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10699 [(set_attr "type" "ssecmp")
10700 (set_attr "length_immediate" "1")
10701 (set_attr "mode" "<MODE>")])
10703 ;; Basic conditional jump instructions.
10704 ;; We ignore the overflow flag for signed branch instructions.
10706 (define_insn "*jcc_1"
10708 (if_then_else (match_operator 1 "ix86_comparison_operator"
10709 [(reg FLAGS_REG) (const_int 0)])
10710 (label_ref (match_operand 0 "" ""))
10714 [(set_attr "type" "ibr")
10715 (set_attr "modrm" "0")
10716 (set (attr "length")
10717 (if_then_else (and (ge (minus (match_dup 0) (pc))
10719 (lt (minus (match_dup 0) (pc))
10724 (define_insn "*jcc_2"
10726 (if_then_else (match_operator 1 "ix86_comparison_operator"
10727 [(reg FLAGS_REG) (const_int 0)])
10729 (label_ref (match_operand 0 "" ""))))]
10732 [(set_attr "type" "ibr")
10733 (set_attr "modrm" "0")
10734 (set (attr "length")
10735 (if_then_else (and (ge (minus (match_dup 0) (pc))
10737 (lt (minus (match_dup 0) (pc))
10742 ;; In general it is not safe to assume too much about CCmode registers,
10743 ;; so simplify-rtx stops when it sees a second one. Under certain
10744 ;; conditions this is safe on x86, so help combine not create
10752 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10753 [(reg FLAGS_REG) (const_int 0)])
10755 (label_ref (match_operand 1 "" ""))
10759 (if_then_else (match_dup 0)
10760 (label_ref (match_dup 1))
10762 "PUT_MODE (operands[0], VOIDmode);")
10766 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10767 [(reg FLAGS_REG) (const_int 0)])
10769 (label_ref (match_operand 1 "" ""))
10773 (if_then_else (match_dup 0)
10774 (label_ref (match_dup 1))
10777 rtx new_op0 = copy_rtx (operands[0]);
10778 operands[0] = new_op0;
10779 PUT_MODE (new_op0, VOIDmode);
10780 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10781 GET_MODE (XEXP (new_op0, 0))));
10783 /* Make sure that (a) the CCmode we have for the flags is strong
10784 enough for the reversed compare or (b) we have a valid FP compare. */
10785 if (! ix86_comparison_operator (new_op0, VOIDmode))
10789 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10790 ;; pass generates from shift insn with QImode operand. Actually, the mode
10791 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10792 ;; appropriate modulo of the bit offset value.
10794 (define_insn_and_split "*jcc_bt<mode>"
10796 (if_then_else (match_operator 0 "bt_comparison_operator"
10797 [(zero_extract:SWI48
10798 (match_operand:SWI48 1 "register_operand" "r")
10801 (match_operand:QI 2 "register_operand" "r")))
10803 (label_ref (match_operand 3 "" ""))
10805 (clobber (reg:CC FLAGS_REG))]
10806 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10809 [(set (reg:CCC FLAGS_REG)
10811 (zero_extract:SWI48
10817 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10818 (label_ref (match_dup 3))
10821 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10823 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10826 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10827 ;; also for DImode, this is what combine produces.
10828 (define_insn_and_split "*jcc_bt<mode>_mask"
10830 (if_then_else (match_operator 0 "bt_comparison_operator"
10831 [(zero_extract:SWI48
10832 (match_operand:SWI48 1 "register_operand" "r")
10835 (match_operand:SI 2 "register_operand" "r")
10836 (match_operand:SI 3 "const_int_operand" "n")))])
10837 (label_ref (match_operand 4 "" ""))
10839 (clobber (reg:CC FLAGS_REG))]
10840 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10841 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10842 == GET_MODE_BITSIZE (<MODE>mode)-1"
10845 [(set (reg:CCC FLAGS_REG)
10847 (zero_extract:SWI48
10853 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10854 (label_ref (match_dup 4))
10857 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10859 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10862 (define_insn_and_split "*jcc_btsi_1"
10864 (if_then_else (match_operator 0 "bt_comparison_operator"
10867 (match_operand:SI 1 "register_operand" "r")
10868 (match_operand:QI 2 "register_operand" "r"))
10871 (label_ref (match_operand 3 "" ""))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10877 [(set (reg:CCC FLAGS_REG)
10885 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10886 (label_ref (match_dup 3))
10889 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10891 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10894 ;; avoid useless masking of bit offset operand
10895 (define_insn_and_split "*jcc_btsi_mask_1"
10898 (match_operator 0 "bt_comparison_operator"
10901 (match_operand:SI 1 "register_operand" "r")
10904 (match_operand:SI 2 "register_operand" "r")
10905 (match_operand:SI 3 "const_int_operand" "n")) 0))
10908 (label_ref (match_operand 4 "" ""))
10910 (clobber (reg:CC FLAGS_REG))]
10911 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10912 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10915 [(set (reg:CCC FLAGS_REG)
10923 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10924 (label_ref (match_dup 4))
10926 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10928 ;; Define combination compare-and-branch fp compare instructions to help
10931 (define_insn "*fp_jcc_1_387"
10933 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10934 [(match_operand 1 "register_operand" "f")
10935 (match_operand 2 "nonimmediate_operand" "fm")])
10936 (label_ref (match_operand 3 "" ""))
10938 (clobber (reg:CCFP FPSR_REG))
10939 (clobber (reg:CCFP FLAGS_REG))
10940 (clobber (match_scratch:HI 4 "=a"))]
10942 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10943 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10944 && SELECT_CC_MODE (GET_CODE (operands[0]),
10945 operands[1], operands[2]) == CCFPmode
10949 (define_insn "*fp_jcc_1r_387"
10951 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10952 [(match_operand 1 "register_operand" "f")
10953 (match_operand 2 "nonimmediate_operand" "fm")])
10955 (label_ref (match_operand 3 "" ""))))
10956 (clobber (reg:CCFP FPSR_REG))
10957 (clobber (reg:CCFP FLAGS_REG))
10958 (clobber (match_scratch:HI 4 "=a"))]
10960 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10961 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10962 && SELECT_CC_MODE (GET_CODE (operands[0]),
10963 operands[1], operands[2]) == CCFPmode
10967 (define_insn "*fp_jcc_2_387"
10969 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10970 [(match_operand 1 "register_operand" "f")
10971 (match_operand 2 "register_operand" "f")])
10972 (label_ref (match_operand 3 "" ""))
10974 (clobber (reg:CCFP FPSR_REG))
10975 (clobber (reg:CCFP FLAGS_REG))
10976 (clobber (match_scratch:HI 4 "=a"))]
10977 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10978 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10982 (define_insn "*fp_jcc_2r_387"
10984 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10985 [(match_operand 1 "register_operand" "f")
10986 (match_operand 2 "register_operand" "f")])
10988 (label_ref (match_operand 3 "" ""))))
10989 (clobber (reg:CCFP FPSR_REG))
10990 (clobber (reg:CCFP FLAGS_REG))
10991 (clobber (match_scratch:HI 4 "=a"))]
10992 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10993 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10997 (define_insn "*fp_jcc_3_387"
10999 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11000 [(match_operand 1 "register_operand" "f")
11001 (match_operand 2 "const0_operand" "")])
11002 (label_ref (match_operand 3 "" ""))
11004 (clobber (reg:CCFP FPSR_REG))
11005 (clobber (reg:CCFP FLAGS_REG))
11006 (clobber (match_scratch:HI 4 "=a"))]
11007 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11008 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11009 && SELECT_CC_MODE (GET_CODE (operands[0]),
11010 operands[1], operands[2]) == CCFPmode
11016 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11017 [(match_operand 1 "register_operand" "")
11018 (match_operand 2 "nonimmediate_operand" "")])
11019 (match_operand 3 "" "")
11020 (match_operand 4 "" "")))
11021 (clobber (reg:CCFP FPSR_REG))
11022 (clobber (reg:CCFP FLAGS_REG))]
11026 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11027 operands[3], operands[4], NULL_RTX, NULL_RTX);
11033 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11034 [(match_operand 1 "register_operand" "")
11035 (match_operand 2 "general_operand" "")])
11036 (match_operand 3 "" "")
11037 (match_operand 4 "" "")))
11038 (clobber (reg:CCFP FPSR_REG))
11039 (clobber (reg:CCFP FLAGS_REG))
11040 (clobber (match_scratch:HI 5 "=a"))]
11044 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11045 operands[3], operands[4], operands[5], NULL_RTX);
11049 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11050 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11051 ;; with a precedence over other operators and is always put in the first
11052 ;; place. Swap condition and operands to match ficom instruction.
11054 (define_insn "*fp_jcc_4_<mode>_387"
11057 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11058 [(match_operator 1 "float_operator"
11059 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11060 (match_operand 3 "register_operand" "f,f")])
11061 (label_ref (match_operand 4 "" ""))
11063 (clobber (reg:CCFP FPSR_REG))
11064 (clobber (reg:CCFP FLAGS_REG))
11065 (clobber (match_scratch:HI 5 "=a,a"))]
11066 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11067 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11068 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11069 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11076 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11077 [(match_operator 1 "float_operator"
11078 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11079 (match_operand 3 "register_operand" "")])
11080 (match_operand 4 "" "")
11081 (match_operand 5 "" "")))
11082 (clobber (reg:CCFP FPSR_REG))
11083 (clobber (reg:CCFP FLAGS_REG))
11084 (clobber (match_scratch:HI 6 "=a"))]
11088 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11090 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11091 operands[3], operands[7],
11092 operands[4], operands[5], operands[6], NULL_RTX);
11096 ;; %%% Kill this when reload knows how to do it.
11100 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11101 [(match_operator 1 "float_operator"
11102 [(match_operand:X87MODEI12 2 "register_operand" "")])
11103 (match_operand 3 "register_operand" "")])
11104 (match_operand 4 "" "")
11105 (match_operand 5 "" "")))
11106 (clobber (reg:CCFP FPSR_REG))
11107 (clobber (reg:CCFP FLAGS_REG))
11108 (clobber (match_scratch:HI 6 "=a"))]
11112 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11113 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11115 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11116 operands[3], operands[7],
11117 operands[4], operands[5], operands[6], operands[2]);
11121 ;; Unconditional and other jump instructions
11123 (define_insn "jump"
11125 (label_ref (match_operand 0 "" "")))]
11128 [(set_attr "type" "ibr")
11129 (set (attr "length")
11130 (if_then_else (and (ge (minus (match_dup 0) (pc))
11132 (lt (minus (match_dup 0) (pc))
11136 (set_attr "modrm" "0")])
11138 (define_expand "indirect_jump"
11139 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11143 (define_insn "*indirect_jump"
11144 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11147 [(set_attr "type" "ibr")
11148 (set_attr "length_immediate" "0")])
11150 (define_expand "tablejump"
11151 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11152 (use (label_ref (match_operand 1 "" "")))])]
11155 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11156 relative. Convert the relative address to an absolute address. */
11160 enum rtx_code code;
11162 /* We can't use @GOTOFF for text labels on VxWorks;
11163 see gotoff_operand. */
11164 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11168 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11170 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11174 op1 = pic_offset_table_rtx;
11179 op0 = pic_offset_table_rtx;
11183 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11188 (define_insn "*tablejump_1"
11189 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11190 (use (label_ref (match_operand 1 "" "")))]
11193 [(set_attr "type" "ibr")
11194 (set_attr "length_immediate" "0")])
11196 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11199 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11200 (set (match_operand:QI 1 "register_operand" "")
11201 (match_operator:QI 2 "ix86_comparison_operator"
11202 [(reg FLAGS_REG) (const_int 0)]))
11203 (set (match_operand 3 "q_regs_operand" "")
11204 (zero_extend (match_dup 1)))]
11205 "(peep2_reg_dead_p (3, operands[1])
11206 || operands_match_p (operands[1], operands[3]))
11207 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11208 [(set (match_dup 4) (match_dup 0))
11209 (set (strict_low_part (match_dup 5))
11212 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11213 operands[5] = gen_lowpart (QImode, operands[3]);
11214 ix86_expand_clear (operands[3]);
11217 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11220 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11221 (set (match_operand:QI 1 "register_operand" "")
11222 (match_operator:QI 2 "ix86_comparison_operator"
11223 [(reg FLAGS_REG) (const_int 0)]))
11224 (parallel [(set (match_operand 3 "q_regs_operand" "")
11225 (zero_extend (match_dup 1)))
11226 (clobber (reg:CC FLAGS_REG))])]
11227 "(peep2_reg_dead_p (3, operands[1])
11228 || operands_match_p (operands[1], operands[3]))
11229 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11230 [(set (match_dup 4) (match_dup 0))
11231 (set (strict_low_part (match_dup 5))
11234 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11235 operands[5] = gen_lowpart (QImode, operands[3]);
11236 ix86_expand_clear (operands[3]);
11239 ;; Call instructions.
11241 ;; The predicates normally associated with named expanders are not properly
11242 ;; checked for calls. This is a bug in the generic code, but it isn't that
11243 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11245 ;; P6 processors will jump to the address after the decrement when %esp
11246 ;; is used as a call operand, so they will execute return address as a code.
11247 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11249 ;; Call subroutine returning no value.
11251 (define_expand "call_pop"
11252 [(parallel [(call (match_operand:QI 0 "" "")
11253 (match_operand:SI 1 "" ""))
11254 (set (reg:SI SP_REG)
11255 (plus:SI (reg:SI SP_REG)
11256 (match_operand:SI 3 "" "")))])]
11259 ix86_expand_call (NULL, operands[0], operands[1],
11260 operands[2], operands[3], 0);
11264 (define_insn_and_split "*call_pop_0_vzeroupper"
11265 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11266 (match_operand:SI 1 "" ""))
11267 (set (reg:SI SP_REG)
11268 (plus:SI (reg:SI SP_REG)
11269 (match_operand:SI 2 "immediate_operand" "")))
11270 (unspec [(match_operand 3 "const_int_operand" "")]
11271 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11272 "TARGET_VZEROUPPER && !TARGET_64BIT"
11274 "&& reload_completed"
11276 "ix86_split_call_pop_vzeroupper (curr_insn, operands[3]); DONE;"
11277 [(set_attr "type" "call")])
11279 (define_insn "*call_pop_0"
11280 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11281 (match_operand:SI 1 "" ""))
11282 (set (reg:SI SP_REG)
11283 (plus:SI (reg:SI SP_REG)
11284 (match_operand:SI 2 "immediate_operand" "")))]
11287 if (SIBLING_CALL_P (insn))
11290 return "call\t%P0";
11292 [(set_attr "type" "call")])
11294 (define_insn_and_split "*call_pop_1_vzeroupper"
11295 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11296 (match_operand:SI 1 "" ""))
11297 (set (reg:SI SP_REG)
11298 (plus:SI (reg:SI SP_REG)
11299 (match_operand:SI 2 "immediate_operand" "i")))
11300 (unspec [(match_operand 3 "const_int_operand" "")]
11301 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11302 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11304 "&& reload_completed"
11306 "ix86_split_call_pop_vzeroupper (curr_insn, operands[3]); DONE;"
11307 [(set_attr "type" "call")])
11309 (define_insn "*call_pop_1"
11310 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11311 (match_operand:SI 1 "" ""))
11312 (set (reg:SI SP_REG)
11313 (plus:SI (reg:SI SP_REG)
11314 (match_operand:SI 2 "immediate_operand" "i")))]
11315 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11317 if (constant_call_address_operand (operands[0], Pmode))
11318 return "call\t%P0";
11319 return "call\t%A0";
11321 [(set_attr "type" "call")])
11323 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11324 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11325 (match_operand:SI 1 "" ""))
11326 (set (reg:SI SP_REG)
11327 (plus:SI (reg:SI SP_REG)
11328 (match_operand:SI 2 "immediate_operand" "i,i")))
11329 (unspec [(match_operand 3 "const_int_operand" "")]
11330 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11331 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11333 "&& reload_completed"
11335 "ix86_split_call_pop_vzeroupper (curr_insn, operands[3]); DONE;"
11336 [(set_attr "type" "call")])
11338 (define_insn "*sibcall_pop_1"
11339 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11340 (match_operand:SI 1 "" ""))
11341 (set (reg:SI SP_REG)
11342 (plus:SI (reg:SI SP_REG)
11343 (match_operand:SI 2 "immediate_operand" "i,i")))]
11344 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11348 [(set_attr "type" "call")])
11350 (define_expand "call"
11351 [(call (match_operand:QI 0 "" "")
11352 (match_operand 1 "" ""))
11353 (use (match_operand 2 "" ""))]
11356 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11360 (define_expand "sibcall"
11361 [(call (match_operand:QI 0 "" "")
11362 (match_operand 1 "" ""))
11363 (use (match_operand 2 "" ""))]
11366 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11370 (define_insn_and_split "*call_0_vzeroupper"
11371 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11372 (match_operand 1 "" ""))
11373 (unspec [(match_operand 2 "const_int_operand" "")]
11374 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11375 "TARGET_VZEROUPPER"
11377 "&& reload_completed"
11379 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11380 [(set_attr "type" "call")])
11382 (define_insn "*call_0"
11383 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11384 (match_operand 1 "" ""))]
11386 { return ix86_output_call_insn (insn, operands[0], 0); }
11387 [(set_attr "type" "call")])
11389 (define_insn_and_split "*call_1_vzeroupper"
11390 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11391 (match_operand 1 "" ""))
11392 (unspec [(match_operand 2 "const_int_operand" "")]
11393 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11394 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11396 "&& reload_completed"
11398 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11399 [(set_attr "type" "call")])
11401 (define_insn "*call_1"
11402 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11403 (match_operand 1 "" ""))]
11404 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11405 { return ix86_output_call_insn (insn, operands[0], 0); }
11406 [(set_attr "type" "call")])
11408 (define_insn_and_split "*sibcall_1_vzeroupper"
11409 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11410 (match_operand 1 "" ""))
11411 (unspec [(match_operand 2 "const_int_operand" "")]
11412 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11413 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11415 "&& reload_completed"
11417 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11418 [(set_attr "type" "call")])
11420 (define_insn "*sibcall_1"
11421 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11422 (match_operand 1 "" ""))]
11423 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11424 { return ix86_output_call_insn (insn, operands[0], 0); }
11425 [(set_attr "type" "call")])
11427 (define_insn_and_split "*call_1_rex64_vzeroupper"
11428 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11429 (match_operand 1 "" ""))
11430 (unspec [(match_operand 2 "const_int_operand" "")]
11431 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11432 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11433 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11435 "&& reload_completed"
11437 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11438 [(set_attr "type" "call")])
11440 (define_insn "*call_1_rex64"
11441 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11442 (match_operand 1 "" ""))]
11443 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11444 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11445 { return ix86_output_call_insn (insn, operands[0], 0); }
11446 [(set_attr "type" "call")])
11448 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11450 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11451 (match_operand 1 "" ""))
11452 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11453 (clobber (reg:TI XMM6_REG))
11454 (clobber (reg:TI XMM7_REG))
11455 (clobber (reg:TI XMM8_REG))
11456 (clobber (reg:TI XMM9_REG))
11457 (clobber (reg:TI XMM10_REG))
11458 (clobber (reg:TI XMM11_REG))
11459 (clobber (reg:TI XMM12_REG))
11460 (clobber (reg:TI XMM13_REG))
11461 (clobber (reg:TI XMM14_REG))
11462 (clobber (reg:TI XMM15_REG))
11463 (clobber (reg:DI SI_REG))
11464 (clobber (reg:DI DI_REG))])
11465 (unspec [(match_operand 2 "const_int_operand" "")]
11466 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11467 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11469 "&& reload_completed"
11471 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11472 [(set_attr "type" "call")])
11474 (define_insn "*call_1_rex64_ms_sysv"
11475 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11476 (match_operand 1 "" ""))
11477 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11478 (clobber (reg:TI XMM6_REG))
11479 (clobber (reg:TI XMM7_REG))
11480 (clobber (reg:TI XMM8_REG))
11481 (clobber (reg:TI XMM9_REG))
11482 (clobber (reg:TI XMM10_REG))
11483 (clobber (reg:TI XMM11_REG))
11484 (clobber (reg:TI XMM12_REG))
11485 (clobber (reg:TI XMM13_REG))
11486 (clobber (reg:TI XMM14_REG))
11487 (clobber (reg:TI XMM15_REG))
11488 (clobber (reg:DI SI_REG))
11489 (clobber (reg:DI DI_REG))]
11490 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11491 { return ix86_output_call_insn (insn, operands[0], 0); }
11492 [(set_attr "type" "call")])
11494 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11495 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11496 (match_operand 1 "" ""))
11497 (unspec [(match_operand 2 "const_int_operand" "")]
11498 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11499 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11501 "&& reload_completed"
11503 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11504 [(set_attr "type" "call")])
11506 (define_insn "*call_1_rex64_large"
11507 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11508 (match_operand 1 "" ""))]
11509 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11510 { return ix86_output_call_insn (insn, operands[0], 0); }
11511 [(set_attr "type" "call")])
11513 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11514 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11515 (match_operand 1 "" ""))
11516 (unspec [(match_operand 2 "const_int_operand" "")]
11517 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11518 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11520 "&& reload_completed"
11522 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11523 [(set_attr "type" "call")])
11525 (define_insn "*sibcall_1_rex64"
11526 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11527 (match_operand 1 "" ""))]
11528 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11529 { return ix86_output_call_insn (insn, operands[0], 0); }
11530 [(set_attr "type" "call")])
11532 ;; Call subroutine, returning value in operand 0
11533 (define_expand "call_value_pop"
11534 [(parallel [(set (match_operand 0 "" "")
11535 (call (match_operand:QI 1 "" "")
11536 (match_operand:SI 2 "" "")))
11537 (set (reg:SI SP_REG)
11538 (plus:SI (reg:SI SP_REG)
11539 (match_operand:SI 4 "" "")))])]
11542 ix86_expand_call (operands[0], operands[1], operands[2],
11543 operands[3], operands[4], 0);
11547 (define_expand "call_value"
11548 [(set (match_operand 0 "" "")
11549 (call (match_operand:QI 1 "" "")
11550 (match_operand:SI 2 "" "")))
11551 (use (match_operand:SI 3 "" ""))]
11552 ;; Operand 3 is not used on the i386.
11555 ix86_expand_call (operands[0], operands[1], operands[2],
11556 operands[3], NULL, 0);
11560 (define_expand "sibcall_value"
11561 [(set (match_operand 0 "" "")
11562 (call (match_operand:QI 1 "" "")
11563 (match_operand:SI 2 "" "")))
11564 (use (match_operand:SI 3 "" ""))]
11565 ;; Operand 3 is not used on the i386.
11568 ix86_expand_call (operands[0], operands[1], operands[2],
11569 operands[3], NULL, 1);
11573 ;; Call subroutine returning any type.
11575 (define_expand "untyped_call"
11576 [(parallel [(call (match_operand 0 "" "")
11578 (match_operand 1 "" "")
11579 (match_operand 2 "" "")])]
11584 /* In order to give reg-stack an easier job in validating two
11585 coprocessor registers as containing a possible return value,
11586 simply pretend the untyped call returns a complex long double
11589 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11590 and should have the default ABI. */
11592 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11593 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11594 operands[0], const0_rtx,
11595 GEN_INT ((TARGET_64BIT
11596 ? (ix86_abi == SYSV_ABI
11597 ? X86_64_SSE_REGPARM_MAX
11598 : X86_64_MS_SSE_REGPARM_MAX)
11599 : X86_32_SSE_REGPARM_MAX)
11603 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11605 rtx set = XVECEXP (operands[2], 0, i);
11606 emit_move_insn (SET_DEST (set), SET_SRC (set));
11609 /* The optimizer does not know that the call sets the function value
11610 registers we stored in the result block. We avoid problems by
11611 claiming that all hard registers are used and clobbered at this
11613 emit_insn (gen_blockage ());
11618 ;; Prologue and epilogue instructions
11620 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11621 ;; all of memory. This blocks insns from being moved across this point.
11623 (define_insn "blockage"
11624 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11627 [(set_attr "length" "0")])
11629 ;; Do not schedule instructions accessing memory across this point.
11631 (define_expand "memory_blockage"
11632 [(set (match_dup 0)
11633 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11636 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11637 MEM_VOLATILE_P (operands[0]) = 1;
11640 (define_insn "*memory_blockage"
11641 [(set (match_operand:BLK 0 "" "")
11642 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11645 [(set_attr "length" "0")])
11647 ;; As USE insns aren't meaningful after reload, this is used instead
11648 ;; to prevent deleting instructions setting registers for PIC code
11649 (define_insn "prologue_use"
11650 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11653 [(set_attr "length" "0")])
11655 ;; Insn emitted into the body of a function to return from a function.
11656 ;; This is only done if the function's epilogue is known to be simple.
11657 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11659 (define_expand "return"
11661 "ix86_can_use_return_insn_p ()"
11663 if (crtl->args.pops_args)
11665 rtx popc = GEN_INT (crtl->args.pops_args);
11666 emit_jump_insn (gen_return_pop_internal (popc));
11671 (define_insn "return_internal"
11675 [(set_attr "length" "1")
11676 (set_attr "atom_unit" "jeu")
11677 (set_attr "length_immediate" "0")
11678 (set_attr "modrm" "0")])
11680 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11681 ;; instruction Athlon and K8 have.
11683 (define_insn "return_internal_long"
11685 (unspec [(const_int 0)] UNSPEC_REP)]
11688 [(set_attr "length" "2")
11689 (set_attr "atom_unit" "jeu")
11690 (set_attr "length_immediate" "0")
11691 (set_attr "prefix_rep" "1")
11692 (set_attr "modrm" "0")])
11694 (define_insn "return_pop_internal"
11696 (use (match_operand:SI 0 "const_int_operand" ""))]
11699 [(set_attr "length" "3")
11700 (set_attr "atom_unit" "jeu")
11701 (set_attr "length_immediate" "2")
11702 (set_attr "modrm" "0")])
11704 (define_insn "return_indirect_internal"
11706 (use (match_operand:SI 0 "register_operand" "r"))]
11709 [(set_attr "type" "ibr")
11710 (set_attr "length_immediate" "0")])
11716 [(set_attr "length" "1")
11717 (set_attr "length_immediate" "0")
11718 (set_attr "modrm" "0")])
11720 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11721 (define_insn "nops"
11722 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11726 int num = INTVAL (operands[0]);
11728 gcc_assert (num >= 1 && num <= 8);
11731 fputs ("\tnop\n", asm_out_file);
11735 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11736 (set_attr "length_immediate" "0")
11737 (set_attr "modrm" "0")])
11739 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11740 ;; branch prediction penalty for the third jump in a 16-byte
11744 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11747 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11748 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11750 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11751 The align insn is used to avoid 3 jump instructions in the row to improve
11752 branch prediction and the benefits hardly outweigh the cost of extra 8
11753 nops on the average inserted by full alignment pseudo operation. */
11757 [(set_attr "length" "16")])
11759 (define_expand "prologue"
11762 "ix86_expand_prologue (); DONE;")
11764 (define_insn "set_got"
11765 [(set (match_operand:SI 0 "register_operand" "=r")
11766 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11767 (clobber (reg:CC FLAGS_REG))]
11769 "* return output_set_got (operands[0], NULL_RTX);"
11770 [(set_attr "type" "multi")
11771 (set_attr "length" "12")])
11773 (define_insn "set_got_labelled"
11774 [(set (match_operand:SI 0 "register_operand" "=r")
11775 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11777 (clobber (reg:CC FLAGS_REG))]
11779 "* return output_set_got (operands[0], operands[1]);"
11780 [(set_attr "type" "multi")
11781 (set_attr "length" "12")])
11783 (define_insn "set_got_rex64"
11784 [(set (match_operand:DI 0 "register_operand" "=r")
11785 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11787 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11788 [(set_attr "type" "lea")
11789 (set_attr "length_address" "4")
11790 (set_attr "mode" "DI")])
11792 (define_insn "set_rip_rex64"
11793 [(set (match_operand:DI 0 "register_operand" "=r")
11794 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11796 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11797 [(set_attr "type" "lea")
11798 (set_attr "length_address" "4")
11799 (set_attr "mode" "DI")])
11801 (define_insn "set_got_offset_rex64"
11802 [(set (match_operand:DI 0 "register_operand" "=r")
11804 [(label_ref (match_operand 1 "" ""))]
11805 UNSPEC_SET_GOT_OFFSET))]
11807 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11808 [(set_attr "type" "imov")
11809 (set_attr "length_immediate" "0")
11810 (set_attr "length_address" "8")
11811 (set_attr "mode" "DI")])
11813 (define_expand "epilogue"
11816 "ix86_expand_epilogue (1); DONE;")
11818 (define_expand "sibcall_epilogue"
11821 "ix86_expand_epilogue (0); DONE;")
11823 (define_expand "eh_return"
11824 [(use (match_operand 0 "register_operand" ""))]
11827 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11829 /* Tricky bit: we write the address of the handler to which we will
11830 be returning into someone else's stack frame, one word below the
11831 stack address we wish to restore. */
11832 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11833 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11834 tmp = gen_rtx_MEM (Pmode, tmp);
11835 emit_move_insn (tmp, ra);
11837 emit_jump_insn (gen_eh_return_internal ());
11842 (define_insn_and_split "eh_return_internal"
11846 "epilogue_completed"
11848 "ix86_expand_epilogue (2); DONE;")
11850 (define_insn "leave"
11851 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11852 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11853 (clobber (mem:BLK (scratch)))]
11856 [(set_attr "type" "leave")])
11858 (define_insn "leave_rex64"
11859 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11860 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11861 (clobber (mem:BLK (scratch)))]
11864 [(set_attr "type" "leave")])
11866 ;; Handle -fsplit-stack.
11868 (define_expand "split_stack_prologue"
11872 ix86_expand_split_stack_prologue ();
11876 ;; In order to support the call/return predictor, we use a return
11877 ;; instruction which the middle-end doesn't see.
11878 (define_insn "split_stack_return"
11879 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11880 UNSPECV_SPLIT_STACK_RETURN)]
11883 if (operands[0] == const0_rtx)
11888 [(set_attr "atom_unit" "jeu")
11889 (set_attr "modrm" "0")
11890 (set (attr "length")
11891 (if_then_else (match_operand:SI 0 "const0_operand" "")
11894 (set (attr "length_immediate")
11895 (if_then_else (match_operand:SI 0 "const0_operand" "")
11899 ;; If there are operand 0 bytes available on the stack, jump to
11902 (define_expand "split_stack_space_check"
11903 [(set (pc) (if_then_else
11904 (ltu (minus (reg SP_REG)
11905 (match_operand 0 "register_operand" ""))
11906 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11907 (label_ref (match_operand 1 "" ""))
11911 rtx reg, size, limit;
11913 reg = gen_reg_rtx (Pmode);
11914 size = force_reg (Pmode, operands[0]);
11915 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11916 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11917 UNSPEC_STACK_CHECK);
11918 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11919 ix86_expand_branch (GEU, reg, limit, operands[1]);
11924 ;; Bit manipulation instructions.
11926 (define_expand "ffs<mode>2"
11927 [(set (match_dup 2) (const_int -1))
11928 (parallel [(set (reg:CCZ FLAGS_REG)
11930 (match_operand:SWI48 1 "nonimmediate_operand" "")
11932 (set (match_operand:SWI48 0 "register_operand" "")
11933 (ctz:SWI48 (match_dup 1)))])
11934 (set (match_dup 0) (if_then_else:SWI48
11935 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11938 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11939 (clobber (reg:CC FLAGS_REG))])]
11942 if (<MODE>mode == SImode && !TARGET_CMOVE)
11944 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11947 operands[2] = gen_reg_rtx (<MODE>mode);
11950 (define_insn_and_split "ffssi2_no_cmove"
11951 [(set (match_operand:SI 0 "register_operand" "=r")
11952 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11953 (clobber (match_scratch:SI 2 "=&q"))
11954 (clobber (reg:CC FLAGS_REG))]
11957 "&& reload_completed"
11958 [(parallel [(set (reg:CCZ FLAGS_REG)
11959 (compare:CCZ (match_dup 1) (const_int 0)))
11960 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11961 (set (strict_low_part (match_dup 3))
11962 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11963 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11964 (clobber (reg:CC FLAGS_REG))])
11965 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11966 (clobber (reg:CC FLAGS_REG))])
11967 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11968 (clobber (reg:CC FLAGS_REG))])]
11970 operands[3] = gen_lowpart (QImode, operands[2]);
11971 ix86_expand_clear (operands[2]);
11974 (define_insn "*ffs<mode>_1"
11975 [(set (reg:CCZ FLAGS_REG)
11976 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11978 (set (match_operand:SWI48 0 "register_operand" "=r")
11979 (ctz:SWI48 (match_dup 1)))]
11981 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11982 [(set_attr "type" "alu1")
11983 (set_attr "prefix_0f" "1")
11984 (set_attr "mode" "<MODE>")])
11986 (define_insn "ctz<mode>2"
11987 [(set (match_operand:SWI48 0 "register_operand" "=r")
11988 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11989 (clobber (reg:CC FLAGS_REG))]
11991 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11992 [(set_attr "type" "alu1")
11993 (set_attr "prefix_0f" "1")
11994 (set_attr "mode" "<MODE>")])
11996 (define_expand "clz<mode>2"
11998 [(set (match_operand:SWI248 0 "register_operand" "")
12001 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12002 (clobber (reg:CC FLAGS_REG))])
12004 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12005 (clobber (reg:CC FLAGS_REG))])]
12010 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12013 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12016 (define_insn "clz<mode>2_abm"
12017 [(set (match_operand:SWI248 0 "register_operand" "=r")
12018 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12019 (clobber (reg:CC FLAGS_REG))]
12021 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12022 [(set_attr "prefix_rep" "1")
12023 (set_attr "type" "bitmanip")
12024 (set_attr "mode" "<MODE>")])
12026 (define_insn "bsr_rex64"
12027 [(set (match_operand:DI 0 "register_operand" "=r")
12028 (minus:DI (const_int 63)
12029 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12030 (clobber (reg:CC FLAGS_REG))]
12032 "bsr{q}\t{%1, %0|%0, %1}"
12033 [(set_attr "type" "alu1")
12034 (set_attr "prefix_0f" "1")
12035 (set_attr "mode" "DI")])
12038 [(set (match_operand:SI 0 "register_operand" "=r")
12039 (minus:SI (const_int 31)
12040 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12041 (clobber (reg:CC FLAGS_REG))]
12043 "bsr{l}\t{%1, %0|%0, %1}"
12044 [(set_attr "type" "alu1")
12045 (set_attr "prefix_0f" "1")
12046 (set_attr "mode" "SI")])
12048 (define_insn "*bsrhi"
12049 [(set (match_operand:HI 0 "register_operand" "=r")
12050 (minus:HI (const_int 15)
12051 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12052 (clobber (reg:CC FLAGS_REG))]
12054 "bsr{w}\t{%1, %0|%0, %1}"
12055 [(set_attr "type" "alu1")
12056 (set_attr "prefix_0f" "1")
12057 (set_attr "mode" "HI")])
12059 (define_insn "popcount<mode>2"
12060 [(set (match_operand:SWI248 0 "register_operand" "=r")
12062 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12063 (clobber (reg:CC FLAGS_REG))]
12067 return "popcnt\t{%1, %0|%0, %1}";
12069 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12072 [(set_attr "prefix_rep" "1")
12073 (set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 (define_insn "*popcount<mode>2_cmp"
12077 [(set (reg FLAGS_REG)
12080 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12082 (set (match_operand:SWI248 0 "register_operand" "=r")
12083 (popcount:SWI248 (match_dup 1)))]
12084 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12087 return "popcnt\t{%1, %0|%0, %1}";
12089 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12092 [(set_attr "prefix_rep" "1")
12093 (set_attr "type" "bitmanip")
12094 (set_attr "mode" "<MODE>")])
12096 (define_insn "*popcountsi2_cmp_zext"
12097 [(set (reg FLAGS_REG)
12099 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12101 (set (match_operand:DI 0 "register_operand" "=r")
12102 (zero_extend:DI(popcount:SI (match_dup 1))))]
12103 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12106 return "popcnt\t{%1, %0|%0, %1}";
12108 return "popcnt{l}\t{%1, %0|%0, %1}";
12111 [(set_attr "prefix_rep" "1")
12112 (set_attr "type" "bitmanip")
12113 (set_attr "mode" "SI")])
12115 (define_expand "bswap<mode>2"
12116 [(set (match_operand:SWI48 0 "register_operand" "")
12117 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12120 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12122 rtx x = operands[0];
12124 emit_move_insn (x, operands[1]);
12125 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12126 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12127 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12132 (define_insn "*bswap<mode>2_movbe"
12133 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12134 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12136 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12139 movbe\t{%1, %0|%0, %1}
12140 movbe\t{%1, %0|%0, %1}"
12141 [(set_attr "type" "bitmanip,imov,imov")
12142 (set_attr "modrm" "0,1,1")
12143 (set_attr "prefix_0f" "*,1,1")
12144 (set_attr "prefix_extra" "*,1,1")
12145 (set_attr "mode" "<MODE>")])
12147 (define_insn "*bswap<mode>2_1"
12148 [(set (match_operand:SWI48 0 "register_operand" "=r")
12149 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12152 [(set_attr "type" "bitmanip")
12153 (set_attr "modrm" "0")
12154 (set_attr "mode" "<MODE>")])
12156 (define_insn "*bswaphi_lowpart_1"
12157 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12158 (bswap:HI (match_dup 0)))
12159 (clobber (reg:CC FLAGS_REG))]
12160 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12162 xchg{b}\t{%h0, %b0|%b0, %h0}
12163 rol{w}\t{$8, %0|%0, 8}"
12164 [(set_attr "length" "2,4")
12165 (set_attr "mode" "QI,HI")])
12167 (define_insn "bswaphi_lowpart"
12168 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12169 (bswap:HI (match_dup 0)))
12170 (clobber (reg:CC FLAGS_REG))]
12172 "rol{w}\t{$8, %0|%0, 8}"
12173 [(set_attr "length" "4")
12174 (set_attr "mode" "HI")])
12176 (define_expand "paritydi2"
12177 [(set (match_operand:DI 0 "register_operand" "")
12178 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12181 rtx scratch = gen_reg_rtx (QImode);
12184 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12185 NULL_RTX, operands[1]));
12187 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12188 gen_rtx_REG (CCmode, FLAGS_REG),
12190 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12193 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12196 rtx tmp = gen_reg_rtx (SImode);
12198 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12199 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12204 (define_expand "paritysi2"
12205 [(set (match_operand:SI 0 "register_operand" "")
12206 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12209 rtx scratch = gen_reg_rtx (QImode);
12212 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12214 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12215 gen_rtx_REG (CCmode, FLAGS_REG),
12217 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12219 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12223 (define_insn_and_split "paritydi2_cmp"
12224 [(set (reg:CC FLAGS_REG)
12225 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12227 (clobber (match_scratch:DI 0 "=r"))
12228 (clobber (match_scratch:SI 1 "=&r"))
12229 (clobber (match_scratch:HI 2 "=Q"))]
12232 "&& reload_completed"
12234 [(set (match_dup 1)
12235 (xor:SI (match_dup 1) (match_dup 4)))
12236 (clobber (reg:CC FLAGS_REG))])
12238 [(set (reg:CC FLAGS_REG)
12239 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12240 (clobber (match_dup 1))
12241 (clobber (match_dup 2))])]
12243 operands[4] = gen_lowpart (SImode, operands[3]);
12247 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12248 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12251 operands[1] = gen_highpart (SImode, operands[3]);
12254 (define_insn_and_split "paritysi2_cmp"
12255 [(set (reg:CC FLAGS_REG)
12256 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12258 (clobber (match_scratch:SI 0 "=r"))
12259 (clobber (match_scratch:HI 1 "=&Q"))]
12262 "&& reload_completed"
12264 [(set (match_dup 1)
12265 (xor:HI (match_dup 1) (match_dup 3)))
12266 (clobber (reg:CC FLAGS_REG))])
12268 [(set (reg:CC FLAGS_REG)
12269 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12270 (clobber (match_dup 1))])]
12272 operands[3] = gen_lowpart (HImode, operands[2]);
12274 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12275 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12278 (define_insn "*parityhi2_cmp"
12279 [(set (reg:CC FLAGS_REG)
12280 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12282 (clobber (match_scratch:HI 0 "=Q"))]
12284 "xor{b}\t{%h0, %b0|%b0, %h0}"
12285 [(set_attr "length" "2")
12286 (set_attr "mode" "HI")])
12288 ;; Thread-local storage patterns for ELF.
12290 ;; Note that these code sequences must appear exactly as shown
12291 ;; in order to allow linker relaxation.
12293 (define_insn "*tls_global_dynamic_32_gnu"
12294 [(set (match_operand:SI 0 "register_operand" "=a")
12295 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12296 (match_operand:SI 2 "tls_symbolic_operand" "")
12297 (match_operand:SI 3 "call_insn_operand" "")]
12299 (clobber (match_scratch:SI 4 "=d"))
12300 (clobber (match_scratch:SI 5 "=c"))
12301 (clobber (reg:CC FLAGS_REG))]
12302 "!TARGET_64BIT && TARGET_GNU_TLS"
12303 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12304 [(set_attr "type" "multi")
12305 (set_attr "length" "12")])
12307 (define_expand "tls_global_dynamic_32"
12308 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12311 (match_operand:SI 1 "tls_symbolic_operand" "")
12314 (clobber (match_scratch:SI 4 ""))
12315 (clobber (match_scratch:SI 5 ""))
12316 (clobber (reg:CC FLAGS_REG))])]
12320 operands[2] = pic_offset_table_rtx;
12323 operands[2] = gen_reg_rtx (Pmode);
12324 emit_insn (gen_set_got (operands[2]));
12326 if (TARGET_GNU2_TLS)
12328 emit_insn (gen_tls_dynamic_gnu2_32
12329 (operands[0], operands[1], operands[2]));
12332 operands[3] = ix86_tls_get_addr ();
12335 (define_insn "*tls_global_dynamic_64"
12336 [(set (match_operand:DI 0 "register_operand" "=a")
12337 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12338 (match_operand:DI 3 "" "")))
12339 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12342 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12343 [(set_attr "type" "multi")
12344 (set_attr "length" "16")])
12346 (define_expand "tls_global_dynamic_64"
12347 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12348 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12349 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12353 if (TARGET_GNU2_TLS)
12355 emit_insn (gen_tls_dynamic_gnu2_64
12356 (operands[0], operands[1]));
12359 operands[2] = ix86_tls_get_addr ();
12362 (define_insn "*tls_local_dynamic_base_32_gnu"
12363 [(set (match_operand:SI 0 "register_operand" "=a")
12364 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12365 (match_operand:SI 2 "call_insn_operand" "")]
12366 UNSPEC_TLS_LD_BASE))
12367 (clobber (match_scratch:SI 3 "=d"))
12368 (clobber (match_scratch:SI 4 "=c"))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "!TARGET_64BIT && TARGET_GNU_TLS"
12371 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12372 [(set_attr "type" "multi")
12373 (set_attr "length" "11")])
12375 (define_expand "tls_local_dynamic_base_32"
12376 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12377 (unspec:SI [(match_dup 1) (match_dup 2)]
12378 UNSPEC_TLS_LD_BASE))
12379 (clobber (match_scratch:SI 3 ""))
12380 (clobber (match_scratch:SI 4 ""))
12381 (clobber (reg:CC FLAGS_REG))])]
12385 operands[1] = pic_offset_table_rtx;
12388 operands[1] = gen_reg_rtx (Pmode);
12389 emit_insn (gen_set_got (operands[1]));
12391 if (TARGET_GNU2_TLS)
12393 emit_insn (gen_tls_dynamic_gnu2_32
12394 (operands[0], ix86_tls_module_base (), operands[1]));
12397 operands[2] = ix86_tls_get_addr ();
12400 (define_insn "*tls_local_dynamic_base_64"
12401 [(set (match_operand:DI 0 "register_operand" "=a")
12402 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12403 (match_operand:DI 2 "" "")))
12404 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12406 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12407 [(set_attr "type" "multi")
12408 (set_attr "length" "12")])
12410 (define_expand "tls_local_dynamic_base_64"
12411 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12412 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12413 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12416 if (TARGET_GNU2_TLS)
12418 emit_insn (gen_tls_dynamic_gnu2_64
12419 (operands[0], ix86_tls_module_base ()));
12422 operands[1] = ix86_tls_get_addr ();
12425 ;; Local dynamic of a single variable is a lose. Show combine how
12426 ;; to convert that back to global dynamic.
12428 (define_insn_and_split "*tls_local_dynamic_32_once"
12429 [(set (match_operand:SI 0 "register_operand" "=a")
12430 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12431 (match_operand:SI 2 "call_insn_operand" "")]
12432 UNSPEC_TLS_LD_BASE)
12433 (const:SI (unspec:SI
12434 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12436 (clobber (match_scratch:SI 4 "=d"))
12437 (clobber (match_scratch:SI 5 "=c"))
12438 (clobber (reg:CC FLAGS_REG))]
12442 [(parallel [(set (match_dup 0)
12443 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12445 (clobber (match_dup 4))
12446 (clobber (match_dup 5))
12447 (clobber (reg:CC FLAGS_REG))])])
12449 ;; Segment register for the thread base ptr load
12450 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12452 ;; Load and add the thread base pointer from %gs:0.
12453 (define_insn "*load_tp_<mode>"
12454 [(set (match_operand:P 0 "register_operand" "=r")
12455 (unspec:P [(const_int 0)] UNSPEC_TP))]
12457 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12458 [(set_attr "type" "imov")
12459 (set_attr "modrm" "0")
12460 (set_attr "length" "7")
12461 (set_attr "memory" "load")
12462 (set_attr "imm_disp" "false")])
12464 (define_insn "*add_tp_<mode>"
12465 [(set (match_operand:P 0 "register_operand" "=r")
12466 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12467 (match_operand:P 1 "register_operand" "0")))
12468 (clobber (reg:CC FLAGS_REG))]
12470 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12471 [(set_attr "type" "alu")
12472 (set_attr "modrm" "0")
12473 (set_attr "length" "7")
12474 (set_attr "memory" "load")
12475 (set_attr "imm_disp" "false")])
12477 ;; GNU2 TLS patterns can be split.
12479 (define_expand "tls_dynamic_gnu2_32"
12480 [(set (match_dup 3)
12481 (plus:SI (match_operand:SI 2 "register_operand" "")
12483 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12486 [(set (match_operand:SI 0 "register_operand" "")
12487 (unspec:SI [(match_dup 1) (match_dup 3)
12488 (match_dup 2) (reg:SI SP_REG)]
12490 (clobber (reg:CC FLAGS_REG))])]
12491 "!TARGET_64BIT && TARGET_GNU2_TLS"
12493 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12494 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12497 (define_insn "*tls_dynamic_lea_32"
12498 [(set (match_operand:SI 0 "register_operand" "=r")
12499 (plus:SI (match_operand:SI 1 "register_operand" "b")
12501 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12502 UNSPEC_TLSDESC))))]
12503 "!TARGET_64BIT && TARGET_GNU2_TLS"
12504 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12505 [(set_attr "type" "lea")
12506 (set_attr "mode" "SI")
12507 (set_attr "length" "6")
12508 (set_attr "length_address" "4")])
12510 (define_insn "*tls_dynamic_call_32"
12511 [(set (match_operand:SI 0 "register_operand" "=a")
12512 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12513 (match_operand:SI 2 "register_operand" "0")
12514 ;; we have to make sure %ebx still points to the GOT
12515 (match_operand:SI 3 "register_operand" "b")
12518 (clobber (reg:CC FLAGS_REG))]
12519 "!TARGET_64BIT && TARGET_GNU2_TLS"
12520 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12521 [(set_attr "type" "call")
12522 (set_attr "length" "2")
12523 (set_attr "length_address" "0")])
12525 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12526 [(set (match_operand:SI 0 "register_operand" "=&a")
12528 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12529 (match_operand:SI 4 "" "")
12530 (match_operand:SI 2 "register_operand" "b")
12533 (const:SI (unspec:SI
12534 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12536 (clobber (reg:CC FLAGS_REG))]
12537 "!TARGET_64BIT && TARGET_GNU2_TLS"
12540 [(set (match_dup 0) (match_dup 5))]
12542 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12543 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12546 (define_expand "tls_dynamic_gnu2_64"
12547 [(set (match_dup 2)
12548 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12551 [(set (match_operand:DI 0 "register_operand" "")
12552 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12554 (clobber (reg:CC FLAGS_REG))])]
12555 "TARGET_64BIT && TARGET_GNU2_TLS"
12557 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12558 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12561 (define_insn "*tls_dynamic_lea_64"
12562 [(set (match_operand:DI 0 "register_operand" "=r")
12563 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12565 "TARGET_64BIT && TARGET_GNU2_TLS"
12566 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12567 [(set_attr "type" "lea")
12568 (set_attr "mode" "DI")
12569 (set_attr "length" "7")
12570 (set_attr "length_address" "4")])
12572 (define_insn "*tls_dynamic_call_64"
12573 [(set (match_operand:DI 0 "register_operand" "=a")
12574 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12575 (match_operand:DI 2 "register_operand" "0")
12578 (clobber (reg:CC FLAGS_REG))]
12579 "TARGET_64BIT && TARGET_GNU2_TLS"
12580 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12581 [(set_attr "type" "call")
12582 (set_attr "length" "2")
12583 (set_attr "length_address" "0")])
12585 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12586 [(set (match_operand:DI 0 "register_operand" "=&a")
12588 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12589 (match_operand:DI 3 "" "")
12592 (const:DI (unspec:DI
12593 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12595 (clobber (reg:CC FLAGS_REG))]
12596 "TARGET_64BIT && TARGET_GNU2_TLS"
12599 [(set (match_dup 0) (match_dup 4))]
12601 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12602 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12605 ;; These patterns match the binary 387 instructions for addM3, subM3,
12606 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12607 ;; SFmode. The first is the normal insn, the second the same insn but
12608 ;; with one operand a conversion, and the third the same insn but with
12609 ;; the other operand a conversion. The conversion may be SFmode or
12610 ;; SImode if the target mode DFmode, but only SImode if the target mode
12613 ;; Gcc is slightly more smart about handling normal two address instructions
12614 ;; so use special patterns for add and mull.
12616 (define_insn "*fop_<mode>_comm_mixed_avx"
12617 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12618 (match_operator:MODEF 3 "binary_fp_operator"
12619 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12620 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12621 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12622 && COMMUTATIVE_ARITH_P (operands[3])
12623 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12624 "* return output_387_binary_op (insn, operands);"
12625 [(set (attr "type")
12626 (if_then_else (eq_attr "alternative" "1")
12627 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12628 (const_string "ssemul")
12629 (const_string "sseadd"))
12630 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12631 (const_string "fmul")
12632 (const_string "fop"))))
12633 (set_attr "prefix" "orig,maybe_vex")
12634 (set_attr "mode" "<MODE>")])
12636 (define_insn "*fop_<mode>_comm_mixed"
12637 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12638 (match_operator:MODEF 3 "binary_fp_operator"
12639 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12640 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12641 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12642 && COMMUTATIVE_ARITH_P (operands[3])
12643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12644 "* return output_387_binary_op (insn, operands);"
12645 [(set (attr "type")
12646 (if_then_else (eq_attr "alternative" "1")
12647 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12648 (const_string "ssemul")
12649 (const_string "sseadd"))
12650 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12651 (const_string "fmul")
12652 (const_string "fop"))))
12653 (set_attr "mode" "<MODE>")])
12655 (define_insn "*fop_<mode>_comm_avx"
12656 [(set (match_operand:MODEF 0 "register_operand" "=x")
12657 (match_operator:MODEF 3 "binary_fp_operator"
12658 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12659 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12660 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12661 && COMMUTATIVE_ARITH_P (operands[3])
12662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12663 "* return output_387_binary_op (insn, operands);"
12664 [(set (attr "type")
12665 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12666 (const_string "ssemul")
12667 (const_string "sseadd")))
12668 (set_attr "prefix" "vex")
12669 (set_attr "mode" "<MODE>")])
12671 (define_insn "*fop_<mode>_comm_sse"
12672 [(set (match_operand:MODEF 0 "register_operand" "=x")
12673 (match_operator:MODEF 3 "binary_fp_operator"
12674 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12675 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12677 && COMMUTATIVE_ARITH_P (operands[3])
12678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12679 "* return output_387_binary_op (insn, operands);"
12680 [(set (attr "type")
12681 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12682 (const_string "ssemul")
12683 (const_string "sseadd")))
12684 (set_attr "mode" "<MODE>")])
12686 (define_insn "*fop_<mode>_comm_i387"
12687 [(set (match_operand:MODEF 0 "register_operand" "=f")
12688 (match_operator:MODEF 3 "binary_fp_operator"
12689 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12690 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12691 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12692 && COMMUTATIVE_ARITH_P (operands[3])
12693 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12694 "* return output_387_binary_op (insn, operands);"
12695 [(set (attr "type")
12696 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12697 (const_string "fmul")
12698 (const_string "fop")))
12699 (set_attr "mode" "<MODE>")])
12701 (define_insn "*fop_<mode>_1_mixed_avx"
12702 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12703 (match_operator:MODEF 3 "binary_fp_operator"
12704 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12705 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12706 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12707 && !COMMUTATIVE_ARITH_P (operands[3])
12708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12709 "* return output_387_binary_op (insn, operands);"
12710 [(set (attr "type")
12711 (cond [(and (eq_attr "alternative" "2")
12712 (match_operand:MODEF 3 "mult_operator" ""))
12713 (const_string "ssemul")
12714 (and (eq_attr "alternative" "2")
12715 (match_operand:MODEF 3 "div_operator" ""))
12716 (const_string "ssediv")
12717 (eq_attr "alternative" "2")
12718 (const_string "sseadd")
12719 (match_operand:MODEF 3 "mult_operator" "")
12720 (const_string "fmul")
12721 (match_operand:MODEF 3 "div_operator" "")
12722 (const_string "fdiv")
12724 (const_string "fop")))
12725 (set_attr "prefix" "orig,orig,maybe_vex")
12726 (set_attr "mode" "<MODE>")])
12728 (define_insn "*fop_<mode>_1_mixed"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12733 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734 && !COMMUTATIVE_ARITH_P (operands[3])
12735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (cond [(and (eq_attr "alternative" "2")
12739 (match_operand:MODEF 3 "mult_operator" ""))
12740 (const_string "ssemul")
12741 (and (eq_attr "alternative" "2")
12742 (match_operand:MODEF 3 "div_operator" ""))
12743 (const_string "ssediv")
12744 (eq_attr "alternative" "2")
12745 (const_string "sseadd")
12746 (match_operand:MODEF 3 "mult_operator" "")
12747 (const_string "fmul")
12748 (match_operand:MODEF 3 "div_operator" "")
12749 (const_string "fdiv")
12751 (const_string "fop")))
12752 (set_attr "mode" "<MODE>")])
12754 (define_insn "*rcpsf2_sse"
12755 [(set (match_operand:SF 0 "register_operand" "=x")
12756 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12759 "%vrcpss\t{%1, %d0|%d0, %1}"
12760 [(set_attr "type" "sse")
12761 (set_attr "atom_sse_attr" "rcp")
12762 (set_attr "prefix" "maybe_vex")
12763 (set_attr "mode" "SF")])
12765 (define_insn "*fop_<mode>_1_avx"
12766 [(set (match_operand:MODEF 0 "register_operand" "=x")
12767 (match_operator:MODEF 3 "binary_fp_operator"
12768 [(match_operand:MODEF 1 "register_operand" "x")
12769 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12770 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12771 && !COMMUTATIVE_ARITH_P (operands[3])"
12772 "* return output_387_binary_op (insn, operands);"
12773 [(set (attr "type")
12774 (cond [(match_operand:MODEF 3 "mult_operator" "")
12775 (const_string "ssemul")
12776 (match_operand:MODEF 3 "div_operator" "")
12777 (const_string "ssediv")
12779 (const_string "sseadd")))
12780 (set_attr "prefix" "vex")
12781 (set_attr "mode" "<MODE>")])
12783 (define_insn "*fop_<mode>_1_sse"
12784 [(set (match_operand:MODEF 0 "register_operand" "=x")
12785 (match_operator:MODEF 3 "binary_fp_operator"
12786 [(match_operand:MODEF 1 "register_operand" "0")
12787 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12788 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12789 && !COMMUTATIVE_ARITH_P (operands[3])"
12790 "* return output_387_binary_op (insn, operands);"
12791 [(set (attr "type")
12792 (cond [(match_operand:MODEF 3 "mult_operator" "")
12793 (const_string "ssemul")
12794 (match_operand:MODEF 3 "div_operator" "")
12795 (const_string "ssediv")
12797 (const_string "sseadd")))
12798 (set_attr "mode" "<MODE>")])
12800 ;; This pattern is not fully shadowed by the pattern above.
12801 (define_insn "*fop_<mode>_1_i387"
12802 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12803 (match_operator:MODEF 3 "binary_fp_operator"
12804 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12805 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12806 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12807 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12808 && !COMMUTATIVE_ARITH_P (operands[3])
12809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12810 "* return output_387_binary_op (insn, operands);"
12811 [(set (attr "type")
12812 (cond [(match_operand:MODEF 3 "mult_operator" "")
12813 (const_string "fmul")
12814 (match_operand:MODEF 3 "div_operator" "")
12815 (const_string "fdiv")
12817 (const_string "fop")))
12818 (set_attr "mode" "<MODE>")])
12820 ;; ??? Add SSE splitters for these!
12821 (define_insn "*fop_<MODEF:mode>_2_i387"
12822 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12823 (match_operator:MODEF 3 "binary_fp_operator"
12825 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12826 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12827 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12828 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12829 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12830 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12831 [(set (attr "type")
12832 (cond [(match_operand:MODEF 3 "mult_operator" "")
12833 (const_string "fmul")
12834 (match_operand:MODEF 3 "div_operator" "")
12835 (const_string "fdiv")
12837 (const_string "fop")))
12838 (set_attr "fp_int_src" "true")
12839 (set_attr "mode" "<X87MODEI12:MODE>")])
12841 (define_insn "*fop_<MODEF:mode>_3_i387"
12842 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12843 (match_operator:MODEF 3 "binary_fp_operator"
12844 [(match_operand:MODEF 1 "register_operand" "0,0")
12846 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12847 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12848 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12849 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12850 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12851 [(set (attr "type")
12852 (cond [(match_operand:MODEF 3 "mult_operator" "")
12853 (const_string "fmul")
12854 (match_operand:MODEF 3 "div_operator" "")
12855 (const_string "fdiv")
12857 (const_string "fop")))
12858 (set_attr "fp_int_src" "true")
12859 (set_attr "mode" "<MODE>")])
12861 (define_insn "*fop_df_4_i387"
12862 [(set (match_operand:DF 0 "register_operand" "=f,f")
12863 (match_operator:DF 3 "binary_fp_operator"
12865 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12866 (match_operand:DF 2 "register_operand" "0,f")]))]
12867 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12868 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12869 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12870 "* return output_387_binary_op (insn, operands);"
12871 [(set (attr "type")
12872 (cond [(match_operand:DF 3 "mult_operator" "")
12873 (const_string "fmul")
12874 (match_operand:DF 3 "div_operator" "")
12875 (const_string "fdiv")
12877 (const_string "fop")))
12878 (set_attr "mode" "SF")])
12880 (define_insn "*fop_df_5_i387"
12881 [(set (match_operand:DF 0 "register_operand" "=f,f")
12882 (match_operator:DF 3 "binary_fp_operator"
12883 [(match_operand:DF 1 "register_operand" "0,f")
12885 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12886 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12887 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12888 "* return output_387_binary_op (insn, operands);"
12889 [(set (attr "type")
12890 (cond [(match_operand:DF 3 "mult_operator" "")
12891 (const_string "fmul")
12892 (match_operand:DF 3 "div_operator" "")
12893 (const_string "fdiv")
12895 (const_string "fop")))
12896 (set_attr "mode" "SF")])
12898 (define_insn "*fop_df_6_i387"
12899 [(set (match_operand:DF 0 "register_operand" "=f,f")
12900 (match_operator:DF 3 "binary_fp_operator"
12902 (match_operand:SF 1 "register_operand" "0,f"))
12904 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12905 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12906 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12907 "* return output_387_binary_op (insn, operands);"
12908 [(set (attr "type")
12909 (cond [(match_operand:DF 3 "mult_operator" "")
12910 (const_string "fmul")
12911 (match_operand:DF 3 "div_operator" "")
12912 (const_string "fdiv")
12914 (const_string "fop")))
12915 (set_attr "mode" "SF")])
12917 (define_insn "*fop_xf_comm_i387"
12918 [(set (match_operand:XF 0 "register_operand" "=f")
12919 (match_operator:XF 3 "binary_fp_operator"
12920 [(match_operand:XF 1 "register_operand" "%0")
12921 (match_operand:XF 2 "register_operand" "f")]))]
12923 && COMMUTATIVE_ARITH_P (operands[3])"
12924 "* return output_387_binary_op (insn, operands);"
12925 [(set (attr "type")
12926 (if_then_else (match_operand:XF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (const_string "fop")))
12929 (set_attr "mode" "XF")])
12931 (define_insn "*fop_xf_1_i387"
12932 [(set (match_operand:XF 0 "register_operand" "=f,f")
12933 (match_operator:XF 3 "binary_fp_operator"
12934 [(match_operand:XF 1 "register_operand" "0,f")
12935 (match_operand:XF 2 "register_operand" "f,0")]))]
12937 && !COMMUTATIVE_ARITH_P (operands[3])"
12938 "* return output_387_binary_op (insn, operands);"
12939 [(set (attr "type")
12940 (cond [(match_operand:XF 3 "mult_operator" "")
12941 (const_string "fmul")
12942 (match_operand:XF 3 "div_operator" "")
12943 (const_string "fdiv")
12945 (const_string "fop")))
12946 (set_attr "mode" "XF")])
12948 (define_insn "*fop_xf_2_i387"
12949 [(set (match_operand:XF 0 "register_operand" "=f,f")
12950 (match_operator:XF 3 "binary_fp_operator"
12952 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12953 (match_operand:XF 2 "register_operand" "0,0")]))]
12954 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12955 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12956 [(set (attr "type")
12957 (cond [(match_operand:XF 3 "mult_operator" "")
12958 (const_string "fmul")
12959 (match_operand:XF 3 "div_operator" "")
12960 (const_string "fdiv")
12962 (const_string "fop")))
12963 (set_attr "fp_int_src" "true")
12964 (set_attr "mode" "<MODE>")])
12966 (define_insn "*fop_xf_3_i387"
12967 [(set (match_operand:XF 0 "register_operand" "=f,f")
12968 (match_operator:XF 3 "binary_fp_operator"
12969 [(match_operand:XF 1 "register_operand" "0,0")
12971 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12972 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12973 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (cond [(match_operand:XF 3 "mult_operator" "")
12976 (const_string "fmul")
12977 (match_operand:XF 3 "div_operator" "")
12978 (const_string "fdiv")
12980 (const_string "fop")))
12981 (set_attr "fp_int_src" "true")
12982 (set_attr "mode" "<MODE>")])
12984 (define_insn "*fop_xf_4_i387"
12985 [(set (match_operand:XF 0 "register_operand" "=f,f")
12986 (match_operator:XF 3 "binary_fp_operator"
12988 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12989 (match_operand:XF 2 "register_operand" "0,f")]))]
12991 "* return output_387_binary_op (insn, operands);"
12992 [(set (attr "type")
12993 (cond [(match_operand:XF 3 "mult_operator" "")
12994 (const_string "fmul")
12995 (match_operand:XF 3 "div_operator" "")
12996 (const_string "fdiv")
12998 (const_string "fop")))
12999 (set_attr "mode" "<MODE>")])
13001 (define_insn "*fop_xf_5_i387"
13002 [(set (match_operand:XF 0 "register_operand" "=f,f")
13003 (match_operator:XF 3 "binary_fp_operator"
13004 [(match_operand:XF 1 "register_operand" "0,f")
13006 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13008 "* return output_387_binary_op (insn, operands);"
13009 [(set (attr "type")
13010 (cond [(match_operand:XF 3 "mult_operator" "")
13011 (const_string "fmul")
13012 (match_operand:XF 3 "div_operator" "")
13013 (const_string "fdiv")
13015 (const_string "fop")))
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*fop_xf_6_i387"
13019 [(set (match_operand:XF 0 "register_operand" "=f,f")
13020 (match_operator:XF 3 "binary_fp_operator"
13022 (match_operand:MODEF 1 "register_operand" "0,f"))
13024 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13026 "* return output_387_binary_op (insn, operands);"
13027 [(set (attr "type")
13028 (cond [(match_operand:XF 3 "mult_operator" "")
13029 (const_string "fmul")
13030 (match_operand:XF 3 "div_operator" "")
13031 (const_string "fdiv")
13033 (const_string "fop")))
13034 (set_attr "mode" "<MODE>")])
13037 [(set (match_operand 0 "register_operand" "")
13038 (match_operator 3 "binary_fp_operator"
13039 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13040 (match_operand 2 "register_operand" "")]))]
13042 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13043 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13046 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13047 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13048 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13049 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13050 GET_MODE (operands[3]),
13053 ix86_free_from_memory (GET_MODE (operands[1]));
13058 [(set (match_operand 0 "register_operand" "")
13059 (match_operator 3 "binary_fp_operator"
13060 [(match_operand 1 "register_operand" "")
13061 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13063 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13064 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13067 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13068 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13069 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13070 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13071 GET_MODE (operands[3]),
13074 ix86_free_from_memory (GET_MODE (operands[2]));
13078 ;; FPU special functions.
13080 ;; This pattern implements a no-op XFmode truncation for
13081 ;; all fancy i386 XFmode math functions.
13083 (define_insn "truncxf<mode>2_i387_noop_unspec"
13084 [(set (match_operand:MODEF 0 "register_operand" "=f")
13085 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13086 UNSPEC_TRUNC_NOOP))]
13087 "TARGET_USE_FANCY_MATH_387"
13088 "* return output_387_reg_move (insn, operands);"
13089 [(set_attr "type" "fmov")
13090 (set_attr "mode" "<MODE>")])
13092 (define_insn "sqrtxf2"
13093 [(set (match_operand:XF 0 "register_operand" "=f")
13094 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13095 "TARGET_USE_FANCY_MATH_387"
13097 [(set_attr "type" "fpspc")
13098 (set_attr "mode" "XF")
13099 (set_attr "athlon_decode" "direct")
13100 (set_attr "amdfam10_decode" "direct")
13101 (set_attr "bdver1_decode" "direct")])
13103 (define_insn "sqrt_extend<mode>xf2_i387"
13104 [(set (match_operand:XF 0 "register_operand" "=f")
13107 (match_operand:MODEF 1 "register_operand" "0"))))]
13108 "TARGET_USE_FANCY_MATH_387"
13110 [(set_attr "type" "fpspc")
13111 (set_attr "mode" "XF")
13112 (set_attr "athlon_decode" "direct")
13113 (set_attr "amdfam10_decode" "direct")
13114 (set_attr "bdver1_decode" "direct")])
13116 (define_insn "*rsqrtsf2_sse"
13117 [(set (match_operand:SF 0 "register_operand" "=x")
13118 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13121 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13122 [(set_attr "type" "sse")
13123 (set_attr "atom_sse_attr" "rcp")
13124 (set_attr "prefix" "maybe_vex")
13125 (set_attr "mode" "SF")])
13127 (define_expand "rsqrtsf2"
13128 [(set (match_operand:SF 0 "register_operand" "")
13129 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13133 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13137 (define_insn "*sqrt<mode>2_sse"
13138 [(set (match_operand:MODEF 0 "register_operand" "=x")
13140 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13141 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13142 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13143 [(set_attr "type" "sse")
13144 (set_attr "atom_sse_attr" "sqrt")
13145 (set_attr "prefix" "maybe_vex")
13146 (set_attr "mode" "<MODE>")
13147 (set_attr "athlon_decode" "*")
13148 (set_attr "amdfam10_decode" "*")
13149 (set_attr "bdver1_decode" "*")])
13151 (define_expand "sqrt<mode>2"
13152 [(set (match_operand:MODEF 0 "register_operand" "")
13154 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13155 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13156 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13158 if (<MODE>mode == SFmode
13159 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13160 && flag_finite_math_only && !flag_trapping_math
13161 && flag_unsafe_math_optimizations)
13163 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13167 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13169 rtx op0 = gen_reg_rtx (XFmode);
13170 rtx op1 = force_reg (<MODE>mode, operands[1]);
13172 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13173 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13178 (define_insn "fpremxf4_i387"
13179 [(set (match_operand:XF 0 "register_operand" "=f")
13180 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13181 (match_operand:XF 3 "register_operand" "1")]
13183 (set (match_operand:XF 1 "register_operand" "=u")
13184 (unspec:XF [(match_dup 2) (match_dup 3)]
13186 (set (reg:CCFP FPSR_REG)
13187 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13189 "TARGET_USE_FANCY_MATH_387"
13191 [(set_attr "type" "fpspc")
13192 (set_attr "mode" "XF")])
13194 (define_expand "fmodxf3"
13195 [(use (match_operand:XF 0 "register_operand" ""))
13196 (use (match_operand:XF 1 "general_operand" ""))
13197 (use (match_operand:XF 2 "general_operand" ""))]
13198 "TARGET_USE_FANCY_MATH_387"
13200 rtx label = gen_label_rtx ();
13202 rtx op1 = gen_reg_rtx (XFmode);
13203 rtx op2 = gen_reg_rtx (XFmode);
13205 emit_move_insn (op2, operands[2]);
13206 emit_move_insn (op1, operands[1]);
13208 emit_label (label);
13209 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13210 ix86_emit_fp_unordered_jump (label);
13211 LABEL_NUSES (label) = 1;
13213 emit_move_insn (operands[0], op1);
13217 (define_expand "fmod<mode>3"
13218 [(use (match_operand:MODEF 0 "register_operand" ""))
13219 (use (match_operand:MODEF 1 "general_operand" ""))
13220 (use (match_operand:MODEF 2 "general_operand" ""))]
13221 "TARGET_USE_FANCY_MATH_387"
13223 rtx (*gen_truncxf) (rtx, rtx);
13225 rtx label = gen_label_rtx ();
13227 rtx op1 = gen_reg_rtx (XFmode);
13228 rtx op2 = gen_reg_rtx (XFmode);
13230 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13231 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13233 emit_label (label);
13234 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13235 ix86_emit_fp_unordered_jump (label);
13236 LABEL_NUSES (label) = 1;
13238 /* Truncate the result properly for strict SSE math. */
13239 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13240 && !TARGET_MIX_SSE_I387)
13241 gen_truncxf = gen_truncxf<mode>2;
13243 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13245 emit_insn (gen_truncxf (operands[0], op1));
13249 (define_insn "fprem1xf4_i387"
13250 [(set (match_operand:XF 0 "register_operand" "=f")
13251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13252 (match_operand:XF 3 "register_operand" "1")]
13254 (set (match_operand:XF 1 "register_operand" "=u")
13255 (unspec:XF [(match_dup 2) (match_dup 3)]
13257 (set (reg:CCFP FPSR_REG)
13258 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13260 "TARGET_USE_FANCY_MATH_387"
13262 [(set_attr "type" "fpspc")
13263 (set_attr "mode" "XF")])
13265 (define_expand "remainderxf3"
13266 [(use (match_operand:XF 0 "register_operand" ""))
13267 (use (match_operand:XF 1 "general_operand" ""))
13268 (use (match_operand:XF 2 "general_operand" ""))]
13269 "TARGET_USE_FANCY_MATH_387"
13271 rtx label = gen_label_rtx ();
13273 rtx op1 = gen_reg_rtx (XFmode);
13274 rtx op2 = gen_reg_rtx (XFmode);
13276 emit_move_insn (op2, operands[2]);
13277 emit_move_insn (op1, operands[1]);
13279 emit_label (label);
13280 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13281 ix86_emit_fp_unordered_jump (label);
13282 LABEL_NUSES (label) = 1;
13284 emit_move_insn (operands[0], op1);
13288 (define_expand "remainder<mode>3"
13289 [(use (match_operand:MODEF 0 "register_operand" ""))
13290 (use (match_operand:MODEF 1 "general_operand" ""))
13291 (use (match_operand:MODEF 2 "general_operand" ""))]
13292 "TARGET_USE_FANCY_MATH_387"
13294 rtx (*gen_truncxf) (rtx, rtx);
13296 rtx label = gen_label_rtx ();
13298 rtx op1 = gen_reg_rtx (XFmode);
13299 rtx op2 = gen_reg_rtx (XFmode);
13301 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13302 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13304 emit_label (label);
13306 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13307 ix86_emit_fp_unordered_jump (label);
13308 LABEL_NUSES (label) = 1;
13310 /* Truncate the result properly for strict SSE math. */
13311 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13312 && !TARGET_MIX_SSE_I387)
13313 gen_truncxf = gen_truncxf<mode>2;
13315 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13317 emit_insn (gen_truncxf (operands[0], op1));
13321 (define_insn "*sinxf2_i387"
13322 [(set (match_operand:XF 0 "register_operand" "=f")
13323 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13324 "TARGET_USE_FANCY_MATH_387
13325 && flag_unsafe_math_optimizations"
13327 [(set_attr "type" "fpspc")
13328 (set_attr "mode" "XF")])
13330 (define_insn "*sin_extend<mode>xf2_i387"
13331 [(set (match_operand:XF 0 "register_operand" "=f")
13332 (unspec:XF [(float_extend:XF
13333 (match_operand:MODEF 1 "register_operand" "0"))]
13335 "TARGET_USE_FANCY_MATH_387
13336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13337 || TARGET_MIX_SSE_I387)
13338 && flag_unsafe_math_optimizations"
13340 [(set_attr "type" "fpspc")
13341 (set_attr "mode" "XF")])
13343 (define_insn "*cosxf2_i387"
13344 [(set (match_operand:XF 0 "register_operand" "=f")
13345 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13346 "TARGET_USE_FANCY_MATH_387
13347 && flag_unsafe_math_optimizations"
13349 [(set_attr "type" "fpspc")
13350 (set_attr "mode" "XF")])
13352 (define_insn "*cos_extend<mode>xf2_i387"
13353 [(set (match_operand:XF 0 "register_operand" "=f")
13354 (unspec:XF [(float_extend:XF
13355 (match_operand:MODEF 1 "register_operand" "0"))]
13357 "TARGET_USE_FANCY_MATH_387
13358 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13359 || TARGET_MIX_SSE_I387)
13360 && flag_unsafe_math_optimizations"
13362 [(set_attr "type" "fpspc")
13363 (set_attr "mode" "XF")])
13365 ;; When sincos pattern is defined, sin and cos builtin functions will be
13366 ;; expanded to sincos pattern with one of its outputs left unused.
13367 ;; CSE pass will figure out if two sincos patterns can be combined,
13368 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13369 ;; depending on the unused output.
13371 (define_insn "sincosxf3"
13372 [(set (match_operand:XF 0 "register_operand" "=f")
13373 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13374 UNSPEC_SINCOS_COS))
13375 (set (match_operand:XF 1 "register_operand" "=u")
13376 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13377 "TARGET_USE_FANCY_MATH_387
13378 && flag_unsafe_math_optimizations"
13380 [(set_attr "type" "fpspc")
13381 (set_attr "mode" "XF")])
13384 [(set (match_operand:XF 0 "register_operand" "")
13385 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13386 UNSPEC_SINCOS_COS))
13387 (set (match_operand:XF 1 "register_operand" "")
13388 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13389 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13390 && !(reload_completed || reload_in_progress)"
13391 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13394 [(set (match_operand:XF 0 "register_operand" "")
13395 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13396 UNSPEC_SINCOS_COS))
13397 (set (match_operand:XF 1 "register_operand" "")
13398 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13399 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13400 && !(reload_completed || reload_in_progress)"
13401 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13403 (define_insn "sincos_extend<mode>xf3_i387"
13404 [(set (match_operand:XF 0 "register_operand" "=f")
13405 (unspec:XF [(float_extend:XF
13406 (match_operand:MODEF 2 "register_operand" "0"))]
13407 UNSPEC_SINCOS_COS))
13408 (set (match_operand:XF 1 "register_operand" "=u")
13409 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13410 "TARGET_USE_FANCY_MATH_387
13411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13412 || TARGET_MIX_SSE_I387)
13413 && flag_unsafe_math_optimizations"
13415 [(set_attr "type" "fpspc")
13416 (set_attr "mode" "XF")])
13419 [(set (match_operand:XF 0 "register_operand" "")
13420 (unspec:XF [(float_extend:XF
13421 (match_operand:MODEF 2 "register_operand" ""))]
13422 UNSPEC_SINCOS_COS))
13423 (set (match_operand:XF 1 "register_operand" "")
13424 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13425 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13426 && !(reload_completed || reload_in_progress)"
13427 [(set (match_dup 1)
13428 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13431 [(set (match_operand:XF 0 "register_operand" "")
13432 (unspec:XF [(float_extend:XF
13433 (match_operand:MODEF 2 "register_operand" ""))]
13434 UNSPEC_SINCOS_COS))
13435 (set (match_operand:XF 1 "register_operand" "")
13436 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13437 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13438 && !(reload_completed || reload_in_progress)"
13439 [(set (match_dup 0)
13440 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13442 (define_expand "sincos<mode>3"
13443 [(use (match_operand:MODEF 0 "register_operand" ""))
13444 (use (match_operand:MODEF 1 "register_operand" ""))
13445 (use (match_operand:MODEF 2 "register_operand" ""))]
13446 "TARGET_USE_FANCY_MATH_387
13447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13448 || TARGET_MIX_SSE_I387)
13449 && flag_unsafe_math_optimizations"
13451 rtx op0 = gen_reg_rtx (XFmode);
13452 rtx op1 = gen_reg_rtx (XFmode);
13454 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13460 (define_insn "fptanxf4_i387"
13461 [(set (match_operand:XF 0 "register_operand" "=f")
13462 (match_operand:XF 3 "const_double_operand" "F"))
13463 (set (match_operand:XF 1 "register_operand" "=u")
13464 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13466 "TARGET_USE_FANCY_MATH_387
13467 && flag_unsafe_math_optimizations
13468 && standard_80387_constant_p (operands[3]) == 2"
13470 [(set_attr "type" "fpspc")
13471 (set_attr "mode" "XF")])
13473 (define_insn "fptan_extend<mode>xf4_i387"
13474 [(set (match_operand:MODEF 0 "register_operand" "=f")
13475 (match_operand:MODEF 3 "const_double_operand" "F"))
13476 (set (match_operand:XF 1 "register_operand" "=u")
13477 (unspec:XF [(float_extend:XF
13478 (match_operand:MODEF 2 "register_operand" "0"))]
13480 "TARGET_USE_FANCY_MATH_387
13481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13482 || TARGET_MIX_SSE_I387)
13483 && flag_unsafe_math_optimizations
13484 && standard_80387_constant_p (operands[3]) == 2"
13486 [(set_attr "type" "fpspc")
13487 (set_attr "mode" "XF")])
13489 (define_expand "tanxf2"
13490 [(use (match_operand:XF 0 "register_operand" ""))
13491 (use (match_operand:XF 1 "register_operand" ""))]
13492 "TARGET_USE_FANCY_MATH_387
13493 && flag_unsafe_math_optimizations"
13495 rtx one = gen_reg_rtx (XFmode);
13496 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13498 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13502 (define_expand "tan<mode>2"
13503 [(use (match_operand:MODEF 0 "register_operand" ""))
13504 (use (match_operand:MODEF 1 "register_operand" ""))]
13505 "TARGET_USE_FANCY_MATH_387
13506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13507 || TARGET_MIX_SSE_I387)
13508 && flag_unsafe_math_optimizations"
13510 rtx op0 = gen_reg_rtx (XFmode);
13512 rtx one = gen_reg_rtx (<MODE>mode);
13513 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13515 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13516 operands[1], op2));
13517 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13521 (define_insn "*fpatanxf3_i387"
13522 [(set (match_operand:XF 0 "register_operand" "=f")
13523 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13524 (match_operand:XF 2 "register_operand" "u")]
13526 (clobber (match_scratch:XF 3 "=2"))]
13527 "TARGET_USE_FANCY_MATH_387
13528 && flag_unsafe_math_optimizations"
13530 [(set_attr "type" "fpspc")
13531 (set_attr "mode" "XF")])
13533 (define_insn "fpatan_extend<mode>xf3_i387"
13534 [(set (match_operand:XF 0 "register_operand" "=f")
13535 (unspec:XF [(float_extend:XF
13536 (match_operand:MODEF 1 "register_operand" "0"))
13538 (match_operand:MODEF 2 "register_operand" "u"))]
13540 (clobber (match_scratch:XF 3 "=2"))]
13541 "TARGET_USE_FANCY_MATH_387
13542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13543 || TARGET_MIX_SSE_I387)
13544 && flag_unsafe_math_optimizations"
13546 [(set_attr "type" "fpspc")
13547 (set_attr "mode" "XF")])
13549 (define_expand "atan2xf3"
13550 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13551 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13552 (match_operand:XF 1 "register_operand" "")]
13554 (clobber (match_scratch:XF 3 ""))])]
13555 "TARGET_USE_FANCY_MATH_387
13556 && flag_unsafe_math_optimizations")
13558 (define_expand "atan2<mode>3"
13559 [(use (match_operand:MODEF 0 "register_operand" ""))
13560 (use (match_operand:MODEF 1 "register_operand" ""))
13561 (use (match_operand:MODEF 2 "register_operand" ""))]
13562 "TARGET_USE_FANCY_MATH_387
13563 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13564 || TARGET_MIX_SSE_I387)
13565 && flag_unsafe_math_optimizations"
13567 rtx op0 = gen_reg_rtx (XFmode);
13569 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13570 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13574 (define_expand "atanxf2"
13575 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13576 (unspec:XF [(match_dup 2)
13577 (match_operand:XF 1 "register_operand" "")]
13579 (clobber (match_scratch:XF 3 ""))])]
13580 "TARGET_USE_FANCY_MATH_387
13581 && flag_unsafe_math_optimizations"
13583 operands[2] = gen_reg_rtx (XFmode);
13584 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13587 (define_expand "atan<mode>2"
13588 [(use (match_operand:MODEF 0 "register_operand" ""))
13589 (use (match_operand:MODEF 1 "register_operand" ""))]
13590 "TARGET_USE_FANCY_MATH_387
13591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13592 || TARGET_MIX_SSE_I387)
13593 && flag_unsafe_math_optimizations"
13595 rtx op0 = gen_reg_rtx (XFmode);
13597 rtx op2 = gen_reg_rtx (<MODE>mode);
13598 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13600 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13601 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13605 (define_expand "asinxf2"
13606 [(set (match_dup 2)
13607 (mult:XF (match_operand:XF 1 "register_operand" "")
13609 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13610 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13611 (parallel [(set (match_operand:XF 0 "register_operand" "")
13612 (unspec:XF [(match_dup 5) (match_dup 1)]
13614 (clobber (match_scratch:XF 6 ""))])]
13615 "TARGET_USE_FANCY_MATH_387
13616 && flag_unsafe_math_optimizations"
13620 if (optimize_insn_for_size_p ())
13623 for (i = 2; i < 6; i++)
13624 operands[i] = gen_reg_rtx (XFmode);
13626 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13629 (define_expand "asin<mode>2"
13630 [(use (match_operand:MODEF 0 "register_operand" ""))
13631 (use (match_operand:MODEF 1 "general_operand" ""))]
13632 "TARGET_USE_FANCY_MATH_387
13633 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13634 || TARGET_MIX_SSE_I387)
13635 && flag_unsafe_math_optimizations"
13637 rtx op0 = gen_reg_rtx (XFmode);
13638 rtx op1 = gen_reg_rtx (XFmode);
13640 if (optimize_insn_for_size_p ())
13643 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13644 emit_insn (gen_asinxf2 (op0, op1));
13645 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13649 (define_expand "acosxf2"
13650 [(set (match_dup 2)
13651 (mult:XF (match_operand:XF 1 "register_operand" "")
13653 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13654 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13655 (parallel [(set (match_operand:XF 0 "register_operand" "")
13656 (unspec:XF [(match_dup 1) (match_dup 5)]
13658 (clobber (match_scratch:XF 6 ""))])]
13659 "TARGET_USE_FANCY_MATH_387
13660 && flag_unsafe_math_optimizations"
13664 if (optimize_insn_for_size_p ())
13667 for (i = 2; i < 6; i++)
13668 operands[i] = gen_reg_rtx (XFmode);
13670 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13673 (define_expand "acos<mode>2"
13674 [(use (match_operand:MODEF 0 "register_operand" ""))
13675 (use (match_operand:MODEF 1 "general_operand" ""))]
13676 "TARGET_USE_FANCY_MATH_387
13677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13678 || TARGET_MIX_SSE_I387)
13679 && flag_unsafe_math_optimizations"
13681 rtx op0 = gen_reg_rtx (XFmode);
13682 rtx op1 = gen_reg_rtx (XFmode);
13684 if (optimize_insn_for_size_p ())
13687 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13688 emit_insn (gen_acosxf2 (op0, op1));
13689 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13693 (define_insn "fyl2xxf3_i387"
13694 [(set (match_operand:XF 0 "register_operand" "=f")
13695 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13696 (match_operand:XF 2 "register_operand" "u")]
13698 (clobber (match_scratch:XF 3 "=2"))]
13699 "TARGET_USE_FANCY_MATH_387
13700 && flag_unsafe_math_optimizations"
13702 [(set_attr "type" "fpspc")
13703 (set_attr "mode" "XF")])
13705 (define_insn "fyl2x_extend<mode>xf3_i387"
13706 [(set (match_operand:XF 0 "register_operand" "=f")
13707 (unspec:XF [(float_extend:XF
13708 (match_operand:MODEF 1 "register_operand" "0"))
13709 (match_operand:XF 2 "register_operand" "u")]
13711 (clobber (match_scratch:XF 3 "=2"))]
13712 "TARGET_USE_FANCY_MATH_387
13713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13714 || TARGET_MIX_SSE_I387)
13715 && flag_unsafe_math_optimizations"
13717 [(set_attr "type" "fpspc")
13718 (set_attr "mode" "XF")])
13720 (define_expand "logxf2"
13721 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13722 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13723 (match_dup 2)] UNSPEC_FYL2X))
13724 (clobber (match_scratch:XF 3 ""))])]
13725 "TARGET_USE_FANCY_MATH_387
13726 && flag_unsafe_math_optimizations"
13728 operands[2] = gen_reg_rtx (XFmode);
13729 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13732 (define_expand "log<mode>2"
13733 [(use (match_operand:MODEF 0 "register_operand" ""))
13734 (use (match_operand:MODEF 1 "register_operand" ""))]
13735 "TARGET_USE_FANCY_MATH_387
13736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737 || TARGET_MIX_SSE_I387)
13738 && flag_unsafe_math_optimizations"
13740 rtx op0 = gen_reg_rtx (XFmode);
13742 rtx op2 = gen_reg_rtx (XFmode);
13743 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13745 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13750 (define_expand "log10xf2"
13751 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13752 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13753 (match_dup 2)] UNSPEC_FYL2X))
13754 (clobber (match_scratch:XF 3 ""))])]
13755 "TARGET_USE_FANCY_MATH_387
13756 && flag_unsafe_math_optimizations"
13758 operands[2] = gen_reg_rtx (XFmode);
13759 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13762 (define_expand "log10<mode>2"
13763 [(use (match_operand:MODEF 0 "register_operand" ""))
13764 (use (match_operand:MODEF 1 "register_operand" ""))]
13765 "TARGET_USE_FANCY_MATH_387
13766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767 || TARGET_MIX_SSE_I387)
13768 && flag_unsafe_math_optimizations"
13770 rtx op0 = gen_reg_rtx (XFmode);
13772 rtx op2 = gen_reg_rtx (XFmode);
13773 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13775 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13776 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13780 (define_expand "log2xf2"
13781 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13782 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13783 (match_dup 2)] UNSPEC_FYL2X))
13784 (clobber (match_scratch:XF 3 ""))])]
13785 "TARGET_USE_FANCY_MATH_387
13786 && flag_unsafe_math_optimizations"
13788 operands[2] = gen_reg_rtx (XFmode);
13789 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13792 (define_expand "log2<mode>2"
13793 [(use (match_operand:MODEF 0 "register_operand" ""))
13794 (use (match_operand:MODEF 1 "register_operand" ""))]
13795 "TARGET_USE_FANCY_MATH_387
13796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13797 || TARGET_MIX_SSE_I387)
13798 && flag_unsafe_math_optimizations"
13800 rtx op0 = gen_reg_rtx (XFmode);
13802 rtx op2 = gen_reg_rtx (XFmode);
13803 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13805 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13806 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13810 (define_insn "fyl2xp1xf3_i387"
13811 [(set (match_operand:XF 0 "register_operand" "=f")
13812 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13813 (match_operand:XF 2 "register_operand" "u")]
13815 (clobber (match_scratch:XF 3 "=2"))]
13816 "TARGET_USE_FANCY_MATH_387
13817 && flag_unsafe_math_optimizations"
13819 [(set_attr "type" "fpspc")
13820 (set_attr "mode" "XF")])
13822 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13823 [(set (match_operand:XF 0 "register_operand" "=f")
13824 (unspec:XF [(float_extend:XF
13825 (match_operand:MODEF 1 "register_operand" "0"))
13826 (match_operand:XF 2 "register_operand" "u")]
13828 (clobber (match_scratch:XF 3 "=2"))]
13829 "TARGET_USE_FANCY_MATH_387
13830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13831 || TARGET_MIX_SSE_I387)
13832 && flag_unsafe_math_optimizations"
13834 [(set_attr "type" "fpspc")
13835 (set_attr "mode" "XF")])
13837 (define_expand "log1pxf2"
13838 [(use (match_operand:XF 0 "register_operand" ""))
13839 (use (match_operand:XF 1 "register_operand" ""))]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13843 if (optimize_insn_for_size_p ())
13846 ix86_emit_i387_log1p (operands[0], operands[1]);
13850 (define_expand "log1p<mode>2"
13851 [(use (match_operand:MODEF 0 "register_operand" ""))
13852 (use (match_operand:MODEF 1 "register_operand" ""))]
13853 "TARGET_USE_FANCY_MATH_387
13854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13855 || TARGET_MIX_SSE_I387)
13856 && flag_unsafe_math_optimizations"
13860 if (optimize_insn_for_size_p ())
13863 op0 = gen_reg_rtx (XFmode);
13865 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13867 ix86_emit_i387_log1p (op0, operands[1]);
13868 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13872 (define_insn "fxtractxf3_i387"
13873 [(set (match_operand:XF 0 "register_operand" "=f")
13874 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13875 UNSPEC_XTRACT_FRACT))
13876 (set (match_operand:XF 1 "register_operand" "=u")
13877 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13878 "TARGET_USE_FANCY_MATH_387
13879 && flag_unsafe_math_optimizations"
13881 [(set_attr "type" "fpspc")
13882 (set_attr "mode" "XF")])
13884 (define_insn "fxtract_extend<mode>xf3_i387"
13885 [(set (match_operand:XF 0 "register_operand" "=f")
13886 (unspec:XF [(float_extend:XF
13887 (match_operand:MODEF 2 "register_operand" "0"))]
13888 UNSPEC_XTRACT_FRACT))
13889 (set (match_operand:XF 1 "register_operand" "=u")
13890 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13891 "TARGET_USE_FANCY_MATH_387
13892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13893 || TARGET_MIX_SSE_I387)
13894 && flag_unsafe_math_optimizations"
13896 [(set_attr "type" "fpspc")
13897 (set_attr "mode" "XF")])
13899 (define_expand "logbxf2"
13900 [(parallel [(set (match_dup 2)
13901 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13902 UNSPEC_XTRACT_FRACT))
13903 (set (match_operand:XF 0 "register_operand" "")
13904 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13905 "TARGET_USE_FANCY_MATH_387
13906 && flag_unsafe_math_optimizations"
13907 "operands[2] = gen_reg_rtx (XFmode);")
13909 (define_expand "logb<mode>2"
13910 [(use (match_operand:MODEF 0 "register_operand" ""))
13911 (use (match_operand:MODEF 1 "register_operand" ""))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914 || TARGET_MIX_SSE_I387)
13915 && flag_unsafe_math_optimizations"
13917 rtx op0 = gen_reg_rtx (XFmode);
13918 rtx op1 = gen_reg_rtx (XFmode);
13920 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13921 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13925 (define_expand "ilogbxf2"
13926 [(use (match_operand:SI 0 "register_operand" ""))
13927 (use (match_operand:XF 1 "register_operand" ""))]
13928 "TARGET_USE_FANCY_MATH_387
13929 && flag_unsafe_math_optimizations"
13933 if (optimize_insn_for_size_p ())
13936 op0 = gen_reg_rtx (XFmode);
13937 op1 = gen_reg_rtx (XFmode);
13939 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13940 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13944 (define_expand "ilogb<mode>2"
13945 [(use (match_operand:SI 0 "register_operand" ""))
13946 (use (match_operand:MODEF 1 "register_operand" ""))]
13947 "TARGET_USE_FANCY_MATH_387
13948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13949 || TARGET_MIX_SSE_I387)
13950 && flag_unsafe_math_optimizations"
13954 if (optimize_insn_for_size_p ())
13957 op0 = gen_reg_rtx (XFmode);
13958 op1 = gen_reg_rtx (XFmode);
13960 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13961 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13965 (define_insn "*f2xm1xf2_i387"
13966 [(set (match_operand:XF 0 "register_operand" "=f")
13967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13975 (define_insn "*fscalexf4_i387"
13976 [(set (match_operand:XF 0 "register_operand" "=f")
13977 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13978 (match_operand:XF 3 "register_operand" "1")]
13979 UNSPEC_FSCALE_FRACT))
13980 (set (match_operand:XF 1 "register_operand" "=u")
13981 (unspec:XF [(match_dup 2) (match_dup 3)]
13982 UNSPEC_FSCALE_EXP))]
13983 "TARGET_USE_FANCY_MATH_387
13984 && flag_unsafe_math_optimizations"
13986 [(set_attr "type" "fpspc")
13987 (set_attr "mode" "XF")])
13989 (define_expand "expNcorexf3"
13990 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13991 (match_operand:XF 2 "register_operand" "")))
13992 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13993 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13994 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13995 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13996 (parallel [(set (match_operand:XF 0 "register_operand" "")
13997 (unspec:XF [(match_dup 8) (match_dup 4)]
13998 UNSPEC_FSCALE_FRACT))
14000 (unspec:XF [(match_dup 8) (match_dup 4)]
14001 UNSPEC_FSCALE_EXP))])]
14002 "TARGET_USE_FANCY_MATH_387
14003 && flag_unsafe_math_optimizations"
14007 if (optimize_insn_for_size_p ())
14010 for (i = 3; i < 10; i++)
14011 operands[i] = gen_reg_rtx (XFmode);
14013 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14016 (define_expand "expxf2"
14017 [(use (match_operand:XF 0 "register_operand" ""))
14018 (use (match_operand:XF 1 "register_operand" ""))]
14019 "TARGET_USE_FANCY_MATH_387
14020 && flag_unsafe_math_optimizations"
14024 if (optimize_insn_for_size_p ())
14027 op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14030 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14034 (define_expand "exp<mode>2"
14035 [(use (match_operand:MODEF 0 "register_operand" ""))
14036 (use (match_operand:MODEF 1 "general_operand" ""))]
14037 "TARGET_USE_FANCY_MATH_387
14038 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14039 || TARGET_MIX_SSE_I387)
14040 && flag_unsafe_math_optimizations"
14044 if (optimize_insn_for_size_p ())
14047 op0 = gen_reg_rtx (XFmode);
14048 op1 = gen_reg_rtx (XFmode);
14050 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14051 emit_insn (gen_expxf2 (op0, op1));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14056 (define_expand "exp10xf2"
14057 [(use (match_operand:XF 0 "register_operand" ""))
14058 (use (match_operand:XF 1 "register_operand" ""))]
14059 "TARGET_USE_FANCY_MATH_387
14060 && flag_unsafe_math_optimizations"
14064 if (optimize_insn_for_size_p ())
14067 op2 = gen_reg_rtx (XFmode);
14068 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14070 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14074 (define_expand "exp10<mode>2"
14075 [(use (match_operand:MODEF 0 "register_operand" ""))
14076 (use (match_operand:MODEF 1 "general_operand" ""))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079 || TARGET_MIX_SSE_I387)
14080 && flag_unsafe_math_optimizations"
14084 if (optimize_insn_for_size_p ())
14087 op0 = gen_reg_rtx (XFmode);
14088 op1 = gen_reg_rtx (XFmode);
14090 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14091 emit_insn (gen_exp10xf2 (op0, op1));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_expand "exp2xf2"
14097 [(use (match_operand:XF 0 "register_operand" ""))
14098 (use (match_operand:XF 1 "register_operand" ""))]
14099 "TARGET_USE_FANCY_MATH_387
14100 && flag_unsafe_math_optimizations"
14104 if (optimize_insn_for_size_p ())
14107 op2 = gen_reg_rtx (XFmode);
14108 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14110 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14114 (define_expand "exp2<mode>2"
14115 [(use (match_operand:MODEF 0 "register_operand" ""))
14116 (use (match_operand:MODEF 1 "general_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"
14124 if (optimize_insn_for_size_p ())
14127 op0 = gen_reg_rtx (XFmode);
14128 op1 = gen_reg_rtx (XFmode);
14130 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14131 emit_insn (gen_exp2xf2 (op0, op1));
14132 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14136 (define_expand "expm1xf2"
14137 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14139 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14140 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14141 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14142 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14143 (parallel [(set (match_dup 7)
14144 (unspec:XF [(match_dup 6) (match_dup 4)]
14145 UNSPEC_FSCALE_FRACT))
14147 (unspec:XF [(match_dup 6) (match_dup 4)]
14148 UNSPEC_FSCALE_EXP))])
14149 (parallel [(set (match_dup 10)
14150 (unspec:XF [(match_dup 9) (match_dup 8)]
14151 UNSPEC_FSCALE_FRACT))
14152 (set (match_dup 11)
14153 (unspec:XF [(match_dup 9) (match_dup 8)]
14154 UNSPEC_FSCALE_EXP))])
14155 (set (match_dup 12) (minus:XF (match_dup 10)
14156 (float_extend:XF (match_dup 13))))
14157 (set (match_operand:XF 0 "register_operand" "")
14158 (plus:XF (match_dup 12) (match_dup 7)))]
14159 "TARGET_USE_FANCY_MATH_387
14160 && flag_unsafe_math_optimizations"
14164 if (optimize_insn_for_size_p ())
14167 for (i = 2; i < 13; i++)
14168 operands[i] = gen_reg_rtx (XFmode);
14171 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14173 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14176 (define_expand "expm1<mode>2"
14177 [(use (match_operand:MODEF 0 "register_operand" ""))
14178 (use (match_operand:MODEF 1 "general_operand" ""))]
14179 "TARGET_USE_FANCY_MATH_387
14180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14181 || TARGET_MIX_SSE_I387)
14182 && flag_unsafe_math_optimizations"
14186 if (optimize_insn_for_size_p ())
14189 op0 = gen_reg_rtx (XFmode);
14190 op1 = gen_reg_rtx (XFmode);
14192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193 emit_insn (gen_expm1xf2 (op0, op1));
14194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14198 (define_expand "ldexpxf3"
14199 [(set (match_dup 3)
14200 (float:XF (match_operand:SI 2 "register_operand" "")))
14201 (parallel [(set (match_operand:XF 0 " register_operand" "")
14202 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14204 UNSPEC_FSCALE_FRACT))
14206 (unspec:XF [(match_dup 1) (match_dup 3)]
14207 UNSPEC_FSCALE_EXP))])]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14211 if (optimize_insn_for_size_p ())
14214 operands[3] = gen_reg_rtx (XFmode);
14215 operands[4] = gen_reg_rtx (XFmode);
14218 (define_expand "ldexp<mode>3"
14219 [(use (match_operand:MODEF 0 "register_operand" ""))
14220 (use (match_operand:MODEF 1 "general_operand" ""))
14221 (use (match_operand:SI 2 "register_operand" ""))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224 || TARGET_MIX_SSE_I387)
14225 && flag_unsafe_math_optimizations"
14229 if (optimize_insn_for_size_p ())
14232 op0 = gen_reg_rtx (XFmode);
14233 op1 = gen_reg_rtx (XFmode);
14235 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14236 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14237 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14241 (define_expand "scalbxf3"
14242 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14243 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14244 (match_operand:XF 2 "register_operand" "")]
14245 UNSPEC_FSCALE_FRACT))
14247 (unspec:XF [(match_dup 1) (match_dup 2)]
14248 UNSPEC_FSCALE_EXP))])]
14249 "TARGET_USE_FANCY_MATH_387
14250 && flag_unsafe_math_optimizations"
14252 if (optimize_insn_for_size_p ())
14255 operands[3] = gen_reg_rtx (XFmode);
14258 (define_expand "scalb<mode>3"
14259 [(use (match_operand:MODEF 0 "register_operand" ""))
14260 (use (match_operand:MODEF 1 "general_operand" ""))
14261 (use (match_operand:MODEF 2 "general_operand" ""))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14269 if (optimize_insn_for_size_p ())
14272 op0 = gen_reg_rtx (XFmode);
14273 op1 = gen_reg_rtx (XFmode);
14274 op2 = gen_reg_rtx (XFmode);
14276 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14277 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14278 emit_insn (gen_scalbxf3 (op0, op1, op2));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 (define_expand "significandxf2"
14284 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14285 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14286 UNSPEC_XTRACT_FRACT))
14288 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14289 "TARGET_USE_FANCY_MATH_387
14290 && flag_unsafe_math_optimizations"
14291 "operands[2] = gen_reg_rtx (XFmode);")
14293 (define_expand "significand<mode>2"
14294 [(use (match_operand:MODEF 0 "register_operand" ""))
14295 (use (match_operand:MODEF 1 "register_operand" ""))]
14296 "TARGET_USE_FANCY_MATH_387
14297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14298 || TARGET_MIX_SSE_I387)
14299 && flag_unsafe_math_optimizations"
14301 rtx op0 = gen_reg_rtx (XFmode);
14302 rtx op1 = gen_reg_rtx (XFmode);
14304 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14305 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14310 (define_insn "sse4_1_round<mode>2"
14311 [(set (match_operand:MODEF 0 "register_operand" "=x")
14312 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14313 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14316 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14317 [(set_attr "type" "ssecvt")
14318 (set_attr "prefix_extra" "1")
14319 (set_attr "prefix" "maybe_vex")
14320 (set_attr "mode" "<MODE>")])
14322 (define_insn "rintxf2"
14323 [(set (match_operand:XF 0 "register_operand" "=f")
14324 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14326 "TARGET_USE_FANCY_MATH_387
14327 && flag_unsafe_math_optimizations"
14329 [(set_attr "type" "fpspc")
14330 (set_attr "mode" "XF")])
14332 (define_expand "rint<mode>2"
14333 [(use (match_operand:MODEF 0 "register_operand" ""))
14334 (use (match_operand:MODEF 1 "register_operand" ""))]
14335 "(TARGET_USE_FANCY_MATH_387
14336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337 || TARGET_MIX_SSE_I387)
14338 && flag_unsafe_math_optimizations)
14339 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14340 && !flag_trapping_math)"
14342 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14343 && !flag_trapping_math)
14345 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14348 emit_insn (gen_sse4_1_round<mode>2
14349 (operands[0], operands[1], GEN_INT (0x04)));
14351 ix86_expand_rint (operand0, operand1);
14355 rtx op0 = gen_reg_rtx (XFmode);
14356 rtx op1 = gen_reg_rtx (XFmode);
14358 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14359 emit_insn (gen_rintxf2 (op0, op1));
14361 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14366 (define_expand "round<mode>2"
14367 [(match_operand:MODEF 0 "register_operand" "")
14368 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14369 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14370 && !flag_trapping_math && !flag_rounding_math"
14372 if (optimize_insn_for_size_p ())
14374 if (TARGET_64BIT || (<MODE>mode != DFmode))
14375 ix86_expand_round (operand0, operand1);
14377 ix86_expand_rounddf_32 (operand0, operand1);
14381 (define_insn_and_split "*fistdi2_1"
14382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14383 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14385 "TARGET_USE_FANCY_MATH_387
14386 && can_create_pseudo_p ()"
14391 if (memory_operand (operands[0], VOIDmode))
14392 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14395 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14396 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14401 [(set_attr "type" "fpspc")
14402 (set_attr "mode" "DI")])
14404 (define_insn "fistdi2"
14405 [(set (match_operand:DI 0 "memory_operand" "=m")
14406 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14408 (clobber (match_scratch:XF 2 "=&1f"))]
14409 "TARGET_USE_FANCY_MATH_387"
14410 "* return output_fix_trunc (insn, operands, 0);"
14411 [(set_attr "type" "fpspc")
14412 (set_attr "mode" "DI")])
14414 (define_insn "fistdi2_with_temp"
14415 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14416 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14418 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14419 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14420 "TARGET_USE_FANCY_MATH_387"
14422 [(set_attr "type" "fpspc")
14423 (set_attr "mode" "DI")])
14426 [(set (match_operand:DI 0 "register_operand" "")
14427 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429 (clobber (match_operand:DI 2 "memory_operand" ""))
14430 (clobber (match_scratch 3 ""))]
14432 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14433 (clobber (match_dup 3))])
14434 (set (match_dup 0) (match_dup 2))])
14437 [(set (match_operand:DI 0 "memory_operand" "")
14438 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14440 (clobber (match_operand:DI 2 "memory_operand" ""))
14441 (clobber (match_scratch 3 ""))]
14443 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14444 (clobber (match_dup 3))])])
14446 (define_insn_and_split "*fist<mode>2_1"
14447 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14448 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14450 "TARGET_USE_FANCY_MATH_387
14451 && can_create_pseudo_p ()"
14456 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14457 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14461 [(set_attr "type" "fpspc")
14462 (set_attr "mode" "<MODE>")])
14464 (define_insn "fist<mode>2"
14465 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14466 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14468 "TARGET_USE_FANCY_MATH_387"
14469 "* return output_fix_trunc (insn, operands, 0);"
14470 [(set_attr "type" "fpspc")
14471 (set_attr "mode" "<MODE>")])
14473 (define_insn "fist<mode>2_with_temp"
14474 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14475 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14477 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14478 "TARGET_USE_FANCY_MATH_387"
14480 [(set_attr "type" "fpspc")
14481 (set_attr "mode" "<MODE>")])
14484 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14485 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14487 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14489 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14490 (set (match_dup 0) (match_dup 2))])
14493 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14494 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14496 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14498 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14500 (define_expand "lrintxf<mode>2"
14501 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14502 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14504 "TARGET_USE_FANCY_MATH_387")
14506 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14507 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14508 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14509 UNSPEC_FIX_NOTRUNC))]
14510 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14511 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14513 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14514 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14515 (match_operand:MODEF 1 "register_operand" "")]
14516 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14517 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14518 && !flag_trapping_math && !flag_rounding_math"
14520 if (optimize_insn_for_size_p ())
14522 ix86_expand_lround (operand0, operand1);
14526 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14527 (define_insn_and_split "frndintxf2_floor"
14528 [(set (match_operand:XF 0 "register_operand" "")
14529 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14530 UNSPEC_FRNDINT_FLOOR))
14531 (clobber (reg:CC FLAGS_REG))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && flag_unsafe_math_optimizations
14534 && can_create_pseudo_p ()"
14539 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14541 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14542 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14544 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14545 operands[2], operands[3]));
14548 [(set_attr "type" "frndint")
14549 (set_attr "i387_cw" "floor")
14550 (set_attr "mode" "XF")])
14552 (define_insn "frndintxf2_floor_i387"
14553 [(set (match_operand:XF 0 "register_operand" "=f")
14554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14555 UNSPEC_FRNDINT_FLOOR))
14556 (use (match_operand:HI 2 "memory_operand" "m"))
14557 (use (match_operand:HI 3 "memory_operand" "m"))]
14558 "TARGET_USE_FANCY_MATH_387
14559 && flag_unsafe_math_optimizations"
14560 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14561 [(set_attr "type" "frndint")
14562 (set_attr "i387_cw" "floor")
14563 (set_attr "mode" "XF")])
14565 (define_expand "floorxf2"
14566 [(use (match_operand:XF 0 "register_operand" ""))
14567 (use (match_operand:XF 1 "register_operand" ""))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && flag_unsafe_math_optimizations"
14571 if (optimize_insn_for_size_p ())
14573 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14577 (define_expand "floor<mode>2"
14578 [(use (match_operand:MODEF 0 "register_operand" ""))
14579 (use (match_operand:MODEF 1 "register_operand" ""))]
14580 "(TARGET_USE_FANCY_MATH_387
14581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14582 || TARGET_MIX_SSE_I387)
14583 && flag_unsafe_math_optimizations)
14584 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585 && !flag_trapping_math)"
14587 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14588 && !flag_trapping_math
14589 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14591 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14594 emit_insn (gen_sse4_1_round<mode>2
14595 (operands[0], operands[1], GEN_INT (0x01)));
14596 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14597 ix86_expand_floorceil (operand0, operand1, true);
14599 ix86_expand_floorceildf_32 (operand0, operand1, true);
14605 if (optimize_insn_for_size_p ())
14608 op0 = gen_reg_rtx (XFmode);
14609 op1 = gen_reg_rtx (XFmode);
14610 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14611 emit_insn (gen_frndintxf2_floor (op0, op1));
14613 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14618 (define_insn_and_split "*fist<mode>2_floor_1"
14619 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14620 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14621 UNSPEC_FIST_FLOOR))
14622 (clobber (reg:CC FLAGS_REG))]
14623 "TARGET_USE_FANCY_MATH_387
14624 && flag_unsafe_math_optimizations
14625 && can_create_pseudo_p ()"
14630 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14632 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14633 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14634 if (memory_operand (operands[0], VOIDmode))
14635 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14636 operands[2], operands[3]));
14639 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14640 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14641 operands[2], operands[3],
14646 [(set_attr "type" "fistp")
14647 (set_attr "i387_cw" "floor")
14648 (set_attr "mode" "<MODE>")])
14650 (define_insn "fistdi2_floor"
14651 [(set (match_operand:DI 0 "memory_operand" "=m")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14653 UNSPEC_FIST_FLOOR))
14654 (use (match_operand:HI 2 "memory_operand" "m"))
14655 (use (match_operand:HI 3 "memory_operand" "m"))
14656 (clobber (match_scratch:XF 4 "=&1f"))]
14657 "TARGET_USE_FANCY_MATH_387
14658 && flag_unsafe_math_optimizations"
14659 "* return output_fix_trunc (insn, operands, 0);"
14660 [(set_attr "type" "fistp")
14661 (set_attr "i387_cw" "floor")
14662 (set_attr "mode" "DI")])
14664 (define_insn "fistdi2_floor_with_temp"
14665 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14666 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14667 UNSPEC_FIST_FLOOR))
14668 (use (match_operand:HI 2 "memory_operand" "m,m"))
14669 (use (match_operand:HI 3 "memory_operand" "m,m"))
14670 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14671 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_unsafe_math_optimizations"
14675 [(set_attr "type" "fistp")
14676 (set_attr "i387_cw" "floor")
14677 (set_attr "mode" "DI")])
14680 [(set (match_operand:DI 0 "register_operand" "")
14681 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14682 UNSPEC_FIST_FLOOR))
14683 (use (match_operand:HI 2 "memory_operand" ""))
14684 (use (match_operand:HI 3 "memory_operand" ""))
14685 (clobber (match_operand:DI 4 "memory_operand" ""))
14686 (clobber (match_scratch 5 ""))]
14688 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14689 (use (match_dup 2))
14690 (use (match_dup 3))
14691 (clobber (match_dup 5))])
14692 (set (match_dup 0) (match_dup 4))])
14695 [(set (match_operand:DI 0 "memory_operand" "")
14696 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14697 UNSPEC_FIST_FLOOR))
14698 (use (match_operand:HI 2 "memory_operand" ""))
14699 (use (match_operand:HI 3 "memory_operand" ""))
14700 (clobber (match_operand:DI 4 "memory_operand" ""))
14701 (clobber (match_scratch 5 ""))]
14703 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14704 (use (match_dup 2))
14705 (use (match_dup 3))
14706 (clobber (match_dup 5))])])
14708 (define_insn "fist<mode>2_floor"
14709 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14710 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14711 UNSPEC_FIST_FLOOR))
14712 (use (match_operand:HI 2 "memory_operand" "m"))
14713 (use (match_operand:HI 3 "memory_operand" "m"))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && flag_unsafe_math_optimizations"
14716 "* return output_fix_trunc (insn, operands, 0);"
14717 [(set_attr "type" "fistp")
14718 (set_attr "i387_cw" "floor")
14719 (set_attr "mode" "<MODE>")])
14721 (define_insn "fist<mode>2_floor_with_temp"
14722 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14723 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14724 UNSPEC_FIST_FLOOR))
14725 (use (match_operand:HI 2 "memory_operand" "m,m"))
14726 (use (match_operand:HI 3 "memory_operand" "m,m"))
14727 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && flag_unsafe_math_optimizations"
14731 [(set_attr "type" "fistp")
14732 (set_attr "i387_cw" "floor")
14733 (set_attr "mode" "<MODE>")])
14736 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14737 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14738 UNSPEC_FIST_FLOOR))
14739 (use (match_operand:HI 2 "memory_operand" ""))
14740 (use (match_operand:HI 3 "memory_operand" ""))
14741 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14743 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14744 UNSPEC_FIST_FLOOR))
14745 (use (match_dup 2))
14746 (use (match_dup 3))])
14747 (set (match_dup 0) (match_dup 4))])
14750 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14751 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14752 UNSPEC_FIST_FLOOR))
14753 (use (match_operand:HI 2 "memory_operand" ""))
14754 (use (match_operand:HI 3 "memory_operand" ""))
14755 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14757 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14758 UNSPEC_FIST_FLOOR))
14759 (use (match_dup 2))
14760 (use (match_dup 3))])])
14762 (define_expand "lfloorxf<mode>2"
14763 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14764 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14765 UNSPEC_FIST_FLOOR))
14766 (clobber (reg:CC FLAGS_REG))])]
14767 "TARGET_USE_FANCY_MATH_387
14768 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14769 && flag_unsafe_math_optimizations")
14771 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14772 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14773 (match_operand:MODEF 1 "register_operand" "")]
14774 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14775 && !flag_trapping_math"
14777 if (TARGET_64BIT && optimize_insn_for_size_p ())
14779 ix86_expand_lfloorceil (operand0, operand1, true);
14783 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14784 (define_insn_and_split "frndintxf2_ceil"
14785 [(set (match_operand:XF 0 "register_operand" "")
14786 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14787 UNSPEC_FRNDINT_CEIL))
14788 (clobber (reg:CC FLAGS_REG))]
14789 "TARGET_USE_FANCY_MATH_387
14790 && flag_unsafe_math_optimizations
14791 && can_create_pseudo_p ()"
14796 ix86_optimize_mode_switching[I387_CEIL] = 1;
14798 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14799 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14801 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14802 operands[2], operands[3]));
14805 [(set_attr "type" "frndint")
14806 (set_attr "i387_cw" "ceil")
14807 (set_attr "mode" "XF")])
14809 (define_insn "frndintxf2_ceil_i387"
14810 [(set (match_operand:XF 0 "register_operand" "=f")
14811 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14812 UNSPEC_FRNDINT_CEIL))
14813 (use (match_operand:HI 2 "memory_operand" "m"))
14814 (use (match_operand:HI 3 "memory_operand" "m"))]
14815 "TARGET_USE_FANCY_MATH_387
14816 && flag_unsafe_math_optimizations"
14817 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14818 [(set_attr "type" "frndint")
14819 (set_attr "i387_cw" "ceil")
14820 (set_attr "mode" "XF")])
14822 (define_expand "ceilxf2"
14823 [(use (match_operand:XF 0 "register_operand" ""))
14824 (use (match_operand:XF 1 "register_operand" ""))]
14825 "TARGET_USE_FANCY_MATH_387
14826 && flag_unsafe_math_optimizations"
14828 if (optimize_insn_for_size_p ())
14830 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14834 (define_expand "ceil<mode>2"
14835 [(use (match_operand:MODEF 0 "register_operand" ""))
14836 (use (match_operand:MODEF 1 "register_operand" ""))]
14837 "(TARGET_USE_FANCY_MATH_387
14838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14839 || TARGET_MIX_SSE_I387)
14840 && flag_unsafe_math_optimizations)
14841 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14842 && !flag_trapping_math)"
14844 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14845 && !flag_trapping_math
14846 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14849 emit_insn (gen_sse4_1_round<mode>2
14850 (operands[0], operands[1], GEN_INT (0x02)));
14851 else if (optimize_insn_for_size_p ())
14853 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14854 ix86_expand_floorceil (operand0, operand1, false);
14856 ix86_expand_floorceildf_32 (operand0, operand1, false);
14862 if (optimize_insn_for_size_p ())
14865 op0 = gen_reg_rtx (XFmode);
14866 op1 = gen_reg_rtx (XFmode);
14867 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14868 emit_insn (gen_frndintxf2_ceil (op0, op1));
14870 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14875 (define_insn_and_split "*fist<mode>2_ceil_1"
14876 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14877 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14879 (clobber (reg:CC FLAGS_REG))]
14880 "TARGET_USE_FANCY_MATH_387
14881 && flag_unsafe_math_optimizations
14882 && can_create_pseudo_p ()"
14887 ix86_optimize_mode_switching[I387_CEIL] = 1;
14889 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14890 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14891 if (memory_operand (operands[0], VOIDmode))
14892 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14893 operands[2], operands[3]));
14896 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14897 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14898 operands[2], operands[3],
14903 [(set_attr "type" "fistp")
14904 (set_attr "i387_cw" "ceil")
14905 (set_attr "mode" "<MODE>")])
14907 (define_insn "fistdi2_ceil"
14908 [(set (match_operand:DI 0 "memory_operand" "=m")
14909 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14911 (use (match_operand:HI 2 "memory_operand" "m"))
14912 (use (match_operand:HI 3 "memory_operand" "m"))
14913 (clobber (match_scratch:XF 4 "=&1f"))]
14914 "TARGET_USE_FANCY_MATH_387
14915 && flag_unsafe_math_optimizations"
14916 "* return output_fix_trunc (insn, operands, 0);"
14917 [(set_attr "type" "fistp")
14918 (set_attr "i387_cw" "ceil")
14919 (set_attr "mode" "DI")])
14921 (define_insn "fistdi2_ceil_with_temp"
14922 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14923 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14925 (use (match_operand:HI 2 "memory_operand" "m,m"))
14926 (use (match_operand:HI 3 "memory_operand" "m,m"))
14927 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14928 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && flag_unsafe_math_optimizations"
14932 [(set_attr "type" "fistp")
14933 (set_attr "i387_cw" "ceil")
14934 (set_attr "mode" "DI")])
14937 [(set (match_operand:DI 0 "register_operand" "")
14938 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14940 (use (match_operand:HI 2 "memory_operand" ""))
14941 (use (match_operand:HI 3 "memory_operand" ""))
14942 (clobber (match_operand:DI 4 "memory_operand" ""))
14943 (clobber (match_scratch 5 ""))]
14945 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14946 (use (match_dup 2))
14947 (use (match_dup 3))
14948 (clobber (match_dup 5))])
14949 (set (match_dup 0) (match_dup 4))])
14952 [(set (match_operand:DI 0 "memory_operand" "")
14953 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14955 (use (match_operand:HI 2 "memory_operand" ""))
14956 (use (match_operand:HI 3 "memory_operand" ""))
14957 (clobber (match_operand:DI 4 "memory_operand" ""))
14958 (clobber (match_scratch 5 ""))]
14960 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14961 (use (match_dup 2))
14962 (use (match_dup 3))
14963 (clobber (match_dup 5))])])
14965 (define_insn "fist<mode>2_ceil"
14966 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14967 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14969 (use (match_operand:HI 2 "memory_operand" "m"))
14970 (use (match_operand:HI 3 "memory_operand" "m"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14973 "* return output_fix_trunc (insn, operands, 0);"
14974 [(set_attr "type" "fistp")
14975 (set_attr "i387_cw" "ceil")
14976 (set_attr "mode" "<MODE>")])
14978 (define_insn "fist<mode>2_ceil_with_temp"
14979 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14980 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14982 (use (match_operand:HI 2 "memory_operand" "m,m"))
14983 (use (match_operand:HI 3 "memory_operand" "m,m"))
14984 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14985 "TARGET_USE_FANCY_MATH_387
14986 && flag_unsafe_math_optimizations"
14988 [(set_attr "type" "fistp")
14989 (set_attr "i387_cw" "ceil")
14990 (set_attr "mode" "<MODE>")])
14993 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14994 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14996 (use (match_operand:HI 2 "memory_operand" ""))
14997 (use (match_operand:HI 3 "memory_operand" ""))
14998 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15000 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15002 (use (match_dup 2))
15003 (use (match_dup 3))])
15004 (set (match_dup 0) (match_dup 4))])
15007 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15008 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15010 (use (match_operand:HI 2 "memory_operand" ""))
15011 (use (match_operand:HI 3 "memory_operand" ""))
15012 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15014 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15016 (use (match_dup 2))
15017 (use (match_dup 3))])])
15019 (define_expand "lceilxf<mode>2"
15020 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15021 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15023 (clobber (reg:CC FLAGS_REG))])]
15024 "TARGET_USE_FANCY_MATH_387
15025 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15026 && flag_unsafe_math_optimizations")
15028 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15029 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15030 (match_operand:MODEF 1 "register_operand" "")]
15031 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15032 && !flag_trapping_math"
15034 ix86_expand_lfloorceil (operand0, operand1, false);
15038 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15039 (define_insn_and_split "frndintxf2_trunc"
15040 [(set (match_operand:XF 0 "register_operand" "")
15041 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15042 UNSPEC_FRNDINT_TRUNC))
15043 (clobber (reg:CC FLAGS_REG))]
15044 "TARGET_USE_FANCY_MATH_387
15045 && flag_unsafe_math_optimizations
15046 && can_create_pseudo_p ()"
15051 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15053 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15054 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15056 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15057 operands[2], operands[3]));
15060 [(set_attr "type" "frndint")
15061 (set_attr "i387_cw" "trunc")
15062 (set_attr "mode" "XF")])
15064 (define_insn "frndintxf2_trunc_i387"
15065 [(set (match_operand:XF 0 "register_operand" "=f")
15066 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15067 UNSPEC_FRNDINT_TRUNC))
15068 (use (match_operand:HI 2 "memory_operand" "m"))
15069 (use (match_operand:HI 3 "memory_operand" "m"))]
15070 "TARGET_USE_FANCY_MATH_387
15071 && flag_unsafe_math_optimizations"
15072 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15073 [(set_attr "type" "frndint")
15074 (set_attr "i387_cw" "trunc")
15075 (set_attr "mode" "XF")])
15077 (define_expand "btruncxf2"
15078 [(use (match_operand:XF 0 "register_operand" ""))
15079 (use (match_operand:XF 1 "register_operand" ""))]
15080 "TARGET_USE_FANCY_MATH_387
15081 && flag_unsafe_math_optimizations"
15083 if (optimize_insn_for_size_p ())
15085 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15089 (define_expand "btrunc<mode>2"
15090 [(use (match_operand:MODEF 0 "register_operand" ""))
15091 (use (match_operand:MODEF 1 "register_operand" ""))]
15092 "(TARGET_USE_FANCY_MATH_387
15093 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15094 || TARGET_MIX_SSE_I387)
15095 && flag_unsafe_math_optimizations)
15096 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15097 && !flag_trapping_math)"
15099 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15100 && !flag_trapping_math
15101 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15104 emit_insn (gen_sse4_1_round<mode>2
15105 (operands[0], operands[1], GEN_INT (0x03)));
15106 else if (optimize_insn_for_size_p ())
15108 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15109 ix86_expand_trunc (operand0, operand1);
15111 ix86_expand_truncdf_32 (operand0, operand1);
15117 if (optimize_insn_for_size_p ())
15120 op0 = gen_reg_rtx (XFmode);
15121 op1 = gen_reg_rtx (XFmode);
15122 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15123 emit_insn (gen_frndintxf2_trunc (op0, op1));
15125 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15130 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15131 (define_insn_and_split "frndintxf2_mask_pm"
15132 [(set (match_operand:XF 0 "register_operand" "")
15133 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15134 UNSPEC_FRNDINT_MASK_PM))
15135 (clobber (reg:CC FLAGS_REG))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && flag_unsafe_math_optimizations
15138 && can_create_pseudo_p ()"
15143 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15145 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15146 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15148 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15149 operands[2], operands[3]));
15152 [(set_attr "type" "frndint")
15153 (set_attr "i387_cw" "mask_pm")
15154 (set_attr "mode" "XF")])
15156 (define_insn "frndintxf2_mask_pm_i387"
15157 [(set (match_operand:XF 0 "register_operand" "=f")
15158 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15159 UNSPEC_FRNDINT_MASK_PM))
15160 (use (match_operand:HI 2 "memory_operand" "m"))
15161 (use (match_operand:HI 3 "memory_operand" "m"))]
15162 "TARGET_USE_FANCY_MATH_387
15163 && flag_unsafe_math_optimizations"
15164 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15165 [(set_attr "type" "frndint")
15166 (set_attr "i387_cw" "mask_pm")
15167 (set_attr "mode" "XF")])
15169 (define_expand "nearbyintxf2"
15170 [(use (match_operand:XF 0 "register_operand" ""))
15171 (use (match_operand:XF 1 "register_operand" ""))]
15172 "TARGET_USE_FANCY_MATH_387
15173 && flag_unsafe_math_optimizations"
15175 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15179 (define_expand "nearbyint<mode>2"
15180 [(use (match_operand:MODEF 0 "register_operand" ""))
15181 (use (match_operand:MODEF 1 "register_operand" ""))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184 || TARGET_MIX_SSE_I387)
15185 && flag_unsafe_math_optimizations"
15187 rtx op0 = gen_reg_rtx (XFmode);
15188 rtx op1 = gen_reg_rtx (XFmode);
15190 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15191 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15193 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15197 (define_insn "fxam<mode>2_i387"
15198 [(set (match_operand:HI 0 "register_operand" "=a")
15200 [(match_operand:X87MODEF 1 "register_operand" "f")]
15202 "TARGET_USE_FANCY_MATH_387"
15203 "fxam\n\tfnstsw\t%0"
15204 [(set_attr "type" "multi")
15205 (set_attr "length" "4")
15206 (set_attr "unit" "i387")
15207 (set_attr "mode" "<MODE>")])
15209 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15210 [(set (match_operand:HI 0 "register_operand" "")
15212 [(match_operand:MODEF 1 "memory_operand" "")]
15214 "TARGET_USE_FANCY_MATH_387
15215 && can_create_pseudo_p ()"
15218 [(set (match_dup 2)(match_dup 1))
15220 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15222 operands[2] = gen_reg_rtx (<MODE>mode);
15224 MEM_VOLATILE_P (operands[1]) = 1;
15226 [(set_attr "type" "multi")
15227 (set_attr "unit" "i387")
15228 (set_attr "mode" "<MODE>")])
15230 (define_expand "isinfxf2"
15231 [(use (match_operand:SI 0 "register_operand" ""))
15232 (use (match_operand:XF 1 "register_operand" ""))]
15233 "TARGET_USE_FANCY_MATH_387
15234 && TARGET_C99_FUNCTIONS"
15236 rtx mask = GEN_INT (0x45);
15237 rtx val = GEN_INT (0x05);
15241 rtx scratch = gen_reg_rtx (HImode);
15242 rtx res = gen_reg_rtx (QImode);
15244 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15246 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15247 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15248 cond = gen_rtx_fmt_ee (EQ, QImode,
15249 gen_rtx_REG (CCmode, FLAGS_REG),
15251 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15252 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15256 (define_expand "isinf<mode>2"
15257 [(use (match_operand:SI 0 "register_operand" ""))
15258 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15259 "TARGET_USE_FANCY_MATH_387
15260 && TARGET_C99_FUNCTIONS
15261 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15263 rtx mask = GEN_INT (0x45);
15264 rtx val = GEN_INT (0x05);
15268 rtx scratch = gen_reg_rtx (HImode);
15269 rtx res = gen_reg_rtx (QImode);
15271 /* Remove excess precision by forcing value through memory. */
15272 if (memory_operand (operands[1], VOIDmode))
15273 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15276 enum ix86_stack_slot slot = (virtuals_instantiated
15279 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15281 emit_move_insn (temp, operands[1]);
15282 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15285 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15286 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15287 cond = gen_rtx_fmt_ee (EQ, QImode,
15288 gen_rtx_REG (CCmode, FLAGS_REG),
15290 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15291 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15295 (define_expand "signbitxf2"
15296 [(use (match_operand:SI 0 "register_operand" ""))
15297 (use (match_operand:XF 1 "register_operand" ""))]
15298 "TARGET_USE_FANCY_MATH_387"
15300 rtx scratch = gen_reg_rtx (HImode);
15302 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15303 emit_insn (gen_andsi3 (operands[0],
15304 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15308 (define_insn "movmsk_df"
15309 [(set (match_operand:SI 0 "register_operand" "=r")
15311 [(match_operand:DF 1 "register_operand" "x")]
15313 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15314 "%vmovmskpd\t{%1, %0|%0, %1}"
15315 [(set_attr "type" "ssemov")
15316 (set_attr "prefix" "maybe_vex")
15317 (set_attr "mode" "DF")])
15319 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15320 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15321 (define_expand "signbitdf2"
15322 [(use (match_operand:SI 0 "register_operand" ""))
15323 (use (match_operand:DF 1 "register_operand" ""))]
15324 "TARGET_USE_FANCY_MATH_387
15325 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15327 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15329 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15330 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15334 rtx scratch = gen_reg_rtx (HImode);
15336 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15337 emit_insn (gen_andsi3 (operands[0],
15338 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15343 (define_expand "signbitsf2"
15344 [(use (match_operand:SI 0 "register_operand" ""))
15345 (use (match_operand:SF 1 "register_operand" ""))]
15346 "TARGET_USE_FANCY_MATH_387
15347 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15349 rtx scratch = gen_reg_rtx (HImode);
15351 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15352 emit_insn (gen_andsi3 (operands[0],
15353 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15357 ;; Block operation instructions
15360 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15363 [(set_attr "length" "1")
15364 (set_attr "length_immediate" "0")
15365 (set_attr "modrm" "0")])
15367 (define_expand "movmem<mode>"
15368 [(use (match_operand:BLK 0 "memory_operand" ""))
15369 (use (match_operand:BLK 1 "memory_operand" ""))
15370 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15371 (use (match_operand:SWI48 3 "const_int_operand" ""))
15372 (use (match_operand:SI 4 "const_int_operand" ""))
15373 (use (match_operand:SI 5 "const_int_operand" ""))]
15376 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15377 operands[4], operands[5]))
15383 ;; Most CPUs don't like single string operations
15384 ;; Handle this case here to simplify previous expander.
15386 (define_expand "strmov"
15387 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15388 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15389 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15390 (clobber (reg:CC FLAGS_REG))])
15391 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15392 (clobber (reg:CC FLAGS_REG))])]
15395 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15397 /* If .md ever supports :P for Pmode, these can be directly
15398 in the pattern above. */
15399 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15400 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15402 /* Can't use this if the user has appropriated esi or edi. */
15403 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15404 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15406 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15407 operands[2], operands[3],
15408 operands[5], operands[6]));
15412 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15415 (define_expand "strmov_singleop"
15416 [(parallel [(set (match_operand 1 "memory_operand" "")
15417 (match_operand 3 "memory_operand" ""))
15418 (set (match_operand 0 "register_operand" "")
15419 (match_operand 4 "" ""))
15420 (set (match_operand 2 "register_operand" "")
15421 (match_operand 5 "" ""))])]
15423 "ix86_current_function_needs_cld = 1;")
15425 (define_insn "*strmovdi_rex_1"
15426 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15427 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15428 (set (match_operand:DI 0 "register_operand" "=D")
15429 (plus:DI (match_dup 2)
15431 (set (match_operand:DI 1 "register_operand" "=S")
15432 (plus:DI (match_dup 3)
15436 [(set_attr "type" "str")
15437 (set_attr "memory" "both")
15438 (set_attr "mode" "DI")])
15440 (define_insn "*strmovsi_1"
15441 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15442 (mem:SI (match_operand:P 3 "register_operand" "1")))
15443 (set (match_operand:P 0 "register_operand" "=D")
15444 (plus:P (match_dup 2)
15446 (set (match_operand:P 1 "register_operand" "=S")
15447 (plus:P (match_dup 3)
15451 [(set_attr "type" "str")
15452 (set_attr "memory" "both")
15453 (set_attr "mode" "SI")])
15455 (define_insn "*strmovhi_1"
15456 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15457 (mem:HI (match_operand:P 3 "register_operand" "1")))
15458 (set (match_operand:P 0 "register_operand" "=D")
15459 (plus:P (match_dup 2)
15461 (set (match_operand:P 1 "register_operand" "=S")
15462 (plus:P (match_dup 3)
15466 [(set_attr "type" "str")
15467 (set_attr "memory" "both")
15468 (set_attr "mode" "HI")])
15470 (define_insn "*strmovqi_1"
15471 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15472 (mem:QI (match_operand:P 3 "register_operand" "1")))
15473 (set (match_operand:P 0 "register_operand" "=D")
15474 (plus:P (match_dup 2)
15476 (set (match_operand:P 1 "register_operand" "=S")
15477 (plus:P (match_dup 3)
15481 [(set_attr "type" "str")
15482 (set_attr "memory" "both")
15483 (set (attr "prefix_rex")
15485 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15487 (const_string "*")))
15488 (set_attr "mode" "QI")])
15490 (define_expand "rep_mov"
15491 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15492 (set (match_operand 0 "register_operand" "")
15493 (match_operand 5 "" ""))
15494 (set (match_operand 2 "register_operand" "")
15495 (match_operand 6 "" ""))
15496 (set (match_operand 1 "memory_operand" "")
15497 (match_operand 3 "memory_operand" ""))
15498 (use (match_dup 4))])]
15500 "ix86_current_function_needs_cld = 1;")
15502 (define_insn "*rep_movdi_rex64"
15503 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15504 (set (match_operand:DI 0 "register_operand" "=D")
15505 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15507 (match_operand:DI 3 "register_operand" "0")))
15508 (set (match_operand:DI 1 "register_operand" "=S")
15509 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15510 (match_operand:DI 4 "register_operand" "1")))
15511 (set (mem:BLK (match_dup 3))
15512 (mem:BLK (match_dup 4)))
15513 (use (match_dup 5))]
15516 [(set_attr "type" "str")
15517 (set_attr "prefix_rep" "1")
15518 (set_attr "memory" "both")
15519 (set_attr "mode" "DI")])
15521 (define_insn "*rep_movsi"
15522 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15523 (set (match_operand:P 0 "register_operand" "=D")
15524 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15526 (match_operand:P 3 "register_operand" "0")))
15527 (set (match_operand:P 1 "register_operand" "=S")
15528 (plus:P (ashift:P (match_dup 5) (const_int 2))
15529 (match_operand:P 4 "register_operand" "1")))
15530 (set (mem:BLK (match_dup 3))
15531 (mem:BLK (match_dup 4)))
15532 (use (match_dup 5))]
15534 "rep{%;} movs{l|d}"
15535 [(set_attr "type" "str")
15536 (set_attr "prefix_rep" "1")
15537 (set_attr "memory" "both")
15538 (set_attr "mode" "SI")])
15540 (define_insn "*rep_movqi"
15541 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15542 (set (match_operand:P 0 "register_operand" "=D")
15543 (plus:P (match_operand:P 3 "register_operand" "0")
15544 (match_operand:P 5 "register_operand" "2")))
15545 (set (match_operand:P 1 "register_operand" "=S")
15546 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15547 (set (mem:BLK (match_dup 3))
15548 (mem:BLK (match_dup 4)))
15549 (use (match_dup 5))]
15552 [(set_attr "type" "str")
15553 (set_attr "prefix_rep" "1")
15554 (set_attr "memory" "both")
15555 (set_attr "mode" "QI")])
15557 (define_expand "setmem<mode>"
15558 [(use (match_operand:BLK 0 "memory_operand" ""))
15559 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15560 (use (match_operand 2 "const_int_operand" ""))
15561 (use (match_operand 3 "const_int_operand" ""))
15562 (use (match_operand:SI 4 "const_int_operand" ""))
15563 (use (match_operand:SI 5 "const_int_operand" ""))]
15566 if (ix86_expand_setmem (operands[0], operands[1],
15567 operands[2], operands[3],
15568 operands[4], operands[5]))
15574 ;; Most CPUs don't like single string operations
15575 ;; Handle this case here to simplify previous expander.
15577 (define_expand "strset"
15578 [(set (match_operand 1 "memory_operand" "")
15579 (match_operand 2 "register_operand" ""))
15580 (parallel [(set (match_operand 0 "register_operand" "")
15582 (clobber (reg:CC FLAGS_REG))])]
15585 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15586 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15588 /* If .md ever supports :P for Pmode, this can be directly
15589 in the pattern above. */
15590 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15591 GEN_INT (GET_MODE_SIZE (GET_MODE
15593 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15595 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15601 (define_expand "strset_singleop"
15602 [(parallel [(set (match_operand 1 "memory_operand" "")
15603 (match_operand 2 "register_operand" ""))
15604 (set (match_operand 0 "register_operand" "")
15605 (match_operand 3 "" ""))])]
15607 "ix86_current_function_needs_cld = 1;")
15609 (define_insn "*strsetdi_rex_1"
15610 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15611 (match_operand:DI 2 "register_operand" "a"))
15612 (set (match_operand:DI 0 "register_operand" "=D")
15613 (plus:DI (match_dup 1)
15617 [(set_attr "type" "str")
15618 (set_attr "memory" "store")
15619 (set_attr "mode" "DI")])
15621 (define_insn "*strsetsi_1"
15622 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15623 (match_operand:SI 2 "register_operand" "a"))
15624 (set (match_operand:P 0 "register_operand" "=D")
15625 (plus:P (match_dup 1)
15629 [(set_attr "type" "str")
15630 (set_attr "memory" "store")
15631 (set_attr "mode" "SI")])
15633 (define_insn "*strsethi_1"
15634 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15635 (match_operand:HI 2 "register_operand" "a"))
15636 (set (match_operand:P 0 "register_operand" "=D")
15637 (plus:P (match_dup 1)
15641 [(set_attr "type" "str")
15642 (set_attr "memory" "store")
15643 (set_attr "mode" "HI")])
15645 (define_insn "*strsetqi_1"
15646 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15647 (match_operand:QI 2 "register_operand" "a"))
15648 (set (match_operand:P 0 "register_operand" "=D")
15649 (plus:P (match_dup 1)
15653 [(set_attr "type" "str")
15654 (set_attr "memory" "store")
15655 (set (attr "prefix_rex")
15657 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15659 (const_string "*")))
15660 (set_attr "mode" "QI")])
15662 (define_expand "rep_stos"
15663 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15664 (set (match_operand 0 "register_operand" "")
15665 (match_operand 4 "" ""))
15666 (set (match_operand 2 "memory_operand" "") (const_int 0))
15667 (use (match_operand 3 "register_operand" ""))
15668 (use (match_dup 1))])]
15670 "ix86_current_function_needs_cld = 1;")
15672 (define_insn "*rep_stosdi_rex64"
15673 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15674 (set (match_operand:DI 0 "register_operand" "=D")
15675 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15677 (match_operand:DI 3 "register_operand" "0")))
15678 (set (mem:BLK (match_dup 3))
15680 (use (match_operand:DI 2 "register_operand" "a"))
15681 (use (match_dup 4))]
15684 [(set_attr "type" "str")
15685 (set_attr "prefix_rep" "1")
15686 (set_attr "memory" "store")
15687 (set_attr "mode" "DI")])
15689 (define_insn "*rep_stossi"
15690 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15691 (set (match_operand:P 0 "register_operand" "=D")
15692 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15694 (match_operand:P 3 "register_operand" "0")))
15695 (set (mem:BLK (match_dup 3))
15697 (use (match_operand:SI 2 "register_operand" "a"))
15698 (use (match_dup 4))]
15700 "rep{%;} stos{l|d}"
15701 [(set_attr "type" "str")
15702 (set_attr "prefix_rep" "1")
15703 (set_attr "memory" "store")
15704 (set_attr "mode" "SI")])
15706 (define_insn "*rep_stosqi"
15707 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15708 (set (match_operand:P 0 "register_operand" "=D")
15709 (plus:P (match_operand:P 3 "register_operand" "0")
15710 (match_operand:P 4 "register_operand" "1")))
15711 (set (mem:BLK (match_dup 3))
15713 (use (match_operand:QI 2 "register_operand" "a"))
15714 (use (match_dup 4))]
15717 [(set_attr "type" "str")
15718 (set_attr "prefix_rep" "1")
15719 (set_attr "memory" "store")
15720 (set (attr "prefix_rex")
15722 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15724 (const_string "*")))
15725 (set_attr "mode" "QI")])
15727 (define_expand "cmpstrnsi"
15728 [(set (match_operand:SI 0 "register_operand" "")
15729 (compare:SI (match_operand:BLK 1 "general_operand" "")
15730 (match_operand:BLK 2 "general_operand" "")))
15731 (use (match_operand 3 "general_operand" ""))
15732 (use (match_operand 4 "immediate_operand" ""))]
15735 rtx addr1, addr2, out, outlow, count, countreg, align;
15737 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15740 /* Can't use this if the user has appropriated esi or edi. */
15741 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15746 out = gen_reg_rtx (SImode);
15748 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15749 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15750 if (addr1 != XEXP (operands[1], 0))
15751 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15752 if (addr2 != XEXP (operands[2], 0))
15753 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15755 count = operands[3];
15756 countreg = ix86_zero_extend_to_Pmode (count);
15758 /* %%% Iff we are testing strict equality, we can use known alignment
15759 to good advantage. This may be possible with combine, particularly
15760 once cc0 is dead. */
15761 align = operands[4];
15763 if (CONST_INT_P (count))
15765 if (INTVAL (count) == 0)
15767 emit_move_insn (operands[0], const0_rtx);
15770 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15771 operands[1], operands[2]));
15775 rtx (*gen_cmp) (rtx, rtx);
15777 gen_cmp = (TARGET_64BIT
15778 ? gen_cmpdi_1 : gen_cmpsi_1);
15780 emit_insn (gen_cmp (countreg, countreg));
15781 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15782 operands[1], operands[2]));
15785 outlow = gen_lowpart (QImode, out);
15786 emit_insn (gen_cmpintqi (outlow));
15787 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15789 if (operands[0] != out)
15790 emit_move_insn (operands[0], out);
15795 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15797 (define_expand "cmpintqi"
15798 [(set (match_dup 1)
15799 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15801 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15802 (parallel [(set (match_operand:QI 0 "register_operand" "")
15803 (minus:QI (match_dup 1)
15805 (clobber (reg:CC FLAGS_REG))])]
15808 operands[1] = gen_reg_rtx (QImode);
15809 operands[2] = gen_reg_rtx (QImode);
15812 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15813 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15815 (define_expand "cmpstrnqi_nz_1"
15816 [(parallel [(set (reg:CC FLAGS_REG)
15817 (compare:CC (match_operand 4 "memory_operand" "")
15818 (match_operand 5 "memory_operand" "")))
15819 (use (match_operand 2 "register_operand" ""))
15820 (use (match_operand:SI 3 "immediate_operand" ""))
15821 (clobber (match_operand 0 "register_operand" ""))
15822 (clobber (match_operand 1 "register_operand" ""))
15823 (clobber (match_dup 2))])]
15825 "ix86_current_function_needs_cld = 1;")
15827 (define_insn "*cmpstrnqi_nz_1"
15828 [(set (reg:CC FLAGS_REG)
15829 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15830 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15831 (use (match_operand:P 6 "register_operand" "2"))
15832 (use (match_operand:SI 3 "immediate_operand" "i"))
15833 (clobber (match_operand:P 0 "register_operand" "=S"))
15834 (clobber (match_operand:P 1 "register_operand" "=D"))
15835 (clobber (match_operand:P 2 "register_operand" "=c"))]
15838 [(set_attr "type" "str")
15839 (set_attr "mode" "QI")
15840 (set (attr "prefix_rex")
15842 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15844 (const_string "*")))
15845 (set_attr "prefix_rep" "1")])
15847 ;; The same, but the count is not known to not be zero.
15849 (define_expand "cmpstrnqi_1"
15850 [(parallel [(set (reg:CC FLAGS_REG)
15851 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15853 (compare:CC (match_operand 4 "memory_operand" "")
15854 (match_operand 5 "memory_operand" ""))
15856 (use (match_operand:SI 3 "immediate_operand" ""))
15857 (use (reg:CC FLAGS_REG))
15858 (clobber (match_operand 0 "register_operand" ""))
15859 (clobber (match_operand 1 "register_operand" ""))
15860 (clobber (match_dup 2))])]
15862 "ix86_current_function_needs_cld = 1;")
15864 (define_insn "*cmpstrnqi_1"
15865 [(set (reg:CC FLAGS_REG)
15866 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15868 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15869 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15871 (use (match_operand:SI 3 "immediate_operand" "i"))
15872 (use (reg:CC FLAGS_REG))
15873 (clobber (match_operand:P 0 "register_operand" "=S"))
15874 (clobber (match_operand:P 1 "register_operand" "=D"))
15875 (clobber (match_operand:P 2 "register_operand" "=c"))]
15878 [(set_attr "type" "str")
15879 (set_attr "mode" "QI")
15880 (set (attr "prefix_rex")
15882 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15884 (const_string "*")))
15885 (set_attr "prefix_rep" "1")])
15887 (define_expand "strlen<mode>"
15888 [(set (match_operand:SWI48x 0 "register_operand" "")
15889 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15890 (match_operand:QI 2 "immediate_operand" "")
15891 (match_operand 3 "immediate_operand" "")]
15895 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15901 (define_expand "strlenqi_1"
15902 [(parallel [(set (match_operand 0 "register_operand" "")
15903 (match_operand 2 "" ""))
15904 (clobber (match_operand 1 "register_operand" ""))
15905 (clobber (reg:CC FLAGS_REG))])]
15907 "ix86_current_function_needs_cld = 1;")
15909 (define_insn "*strlenqi_1"
15910 [(set (match_operand:P 0 "register_operand" "=&c")
15911 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15912 (match_operand:QI 2 "register_operand" "a")
15913 (match_operand:P 3 "immediate_operand" "i")
15914 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15915 (clobber (match_operand:P 1 "register_operand" "=D"))
15916 (clobber (reg:CC FLAGS_REG))]
15919 [(set_attr "type" "str")
15920 (set_attr "mode" "QI")
15921 (set (attr "prefix_rex")
15923 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15925 (const_string "*")))
15926 (set_attr "prefix_rep" "1")])
15928 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15929 ;; handled in combine, but it is not currently up to the task.
15930 ;; When used for their truth value, the cmpstrn* expanders generate
15939 ;; The intermediate three instructions are unnecessary.
15941 ;; This one handles cmpstrn*_nz_1...
15944 (set (reg:CC FLAGS_REG)
15945 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15946 (mem:BLK (match_operand 5 "register_operand" ""))))
15947 (use (match_operand 6 "register_operand" ""))
15948 (use (match_operand:SI 3 "immediate_operand" ""))
15949 (clobber (match_operand 0 "register_operand" ""))
15950 (clobber (match_operand 1 "register_operand" ""))
15951 (clobber (match_operand 2 "register_operand" ""))])
15952 (set (match_operand:QI 7 "register_operand" "")
15953 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15954 (set (match_operand:QI 8 "register_operand" "")
15955 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15956 (set (reg FLAGS_REG)
15957 (compare (match_dup 7) (match_dup 8)))
15959 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15961 (set (reg:CC FLAGS_REG)
15962 (compare:CC (mem:BLK (match_dup 4))
15963 (mem:BLK (match_dup 5))))
15964 (use (match_dup 6))
15965 (use (match_dup 3))
15966 (clobber (match_dup 0))
15967 (clobber (match_dup 1))
15968 (clobber (match_dup 2))])])
15970 ;; ...and this one handles cmpstrn*_1.
15973 (set (reg:CC FLAGS_REG)
15974 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15976 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15977 (mem:BLK (match_operand 5 "register_operand" "")))
15979 (use (match_operand:SI 3 "immediate_operand" ""))
15980 (use (reg:CC FLAGS_REG))
15981 (clobber (match_operand 0 "register_operand" ""))
15982 (clobber (match_operand 1 "register_operand" ""))
15983 (clobber (match_operand 2 "register_operand" ""))])
15984 (set (match_operand:QI 7 "register_operand" "")
15985 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15986 (set (match_operand:QI 8 "register_operand" "")
15987 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15988 (set (reg FLAGS_REG)
15989 (compare (match_dup 7) (match_dup 8)))
15991 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15993 (set (reg:CC FLAGS_REG)
15994 (if_then_else:CC (ne (match_dup 6)
15996 (compare:CC (mem:BLK (match_dup 4))
15997 (mem:BLK (match_dup 5)))
15999 (use (match_dup 3))
16000 (use (reg:CC FLAGS_REG))
16001 (clobber (match_dup 0))
16002 (clobber (match_dup 1))
16003 (clobber (match_dup 2))])])
16005 ;; Conditional move instructions.
16007 (define_expand "mov<mode>cc"
16008 [(set (match_operand:SWIM 0 "register_operand" "")
16009 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16010 (match_operand:SWIM 2 "general_operand" "")
16011 (match_operand:SWIM 3 "general_operand" "")))]
16013 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16015 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16016 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16017 ;; So just document what we're doing explicitly.
16019 (define_expand "x86_mov<mode>cc_0_m1"
16021 [(set (match_operand:SWI48 0 "register_operand" "")
16022 (if_then_else:SWI48
16023 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16024 [(match_operand 1 "flags_reg_operand" "")
16028 (clobber (reg:CC FLAGS_REG))])])
16030 (define_insn "*x86_mov<mode>cc_0_m1"
16031 [(set (match_operand:SWI48 0 "register_operand" "=r")
16032 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16033 [(reg FLAGS_REG) (const_int 0)])
16036 (clobber (reg:CC FLAGS_REG))]
16038 "sbb{<imodesuffix>}\t%0, %0"
16039 ; Since we don't have the proper number of operands for an alu insn,
16040 ; fill in all the blanks.
16041 [(set_attr "type" "alu")
16042 (set_attr "use_carry" "1")
16043 (set_attr "pent_pair" "pu")
16044 (set_attr "memory" "none")
16045 (set_attr "imm_disp" "false")
16046 (set_attr "mode" "<MODE>")
16047 (set_attr "length_immediate" "0")])
16049 (define_insn "*x86_mov<mode>cc_0_m1_se"
16050 [(set (match_operand:SWI48 0 "register_operand" "=r")
16051 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16052 [(reg FLAGS_REG) (const_int 0)])
16055 (clobber (reg:CC FLAGS_REG))]
16057 "sbb{<imodesuffix>}\t%0, %0"
16058 [(set_attr "type" "alu")
16059 (set_attr "use_carry" "1")
16060 (set_attr "pent_pair" "pu")
16061 (set_attr "memory" "none")
16062 (set_attr "imm_disp" "false")
16063 (set_attr "mode" "<MODE>")
16064 (set_attr "length_immediate" "0")])
16066 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16067 [(set (match_operand:SWI48 0 "register_operand" "=r")
16068 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16069 [(reg FLAGS_REG) (const_int 0)])))]
16071 "sbb{<imodesuffix>}\t%0, %0"
16072 [(set_attr "type" "alu")
16073 (set_attr "use_carry" "1")
16074 (set_attr "pent_pair" "pu")
16075 (set_attr "memory" "none")
16076 (set_attr "imm_disp" "false")
16077 (set_attr "mode" "<MODE>")
16078 (set_attr "length_immediate" "0")])
16080 (define_insn "*mov<mode>cc_noc"
16081 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16082 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16083 [(reg FLAGS_REG) (const_int 0)])
16084 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16085 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16086 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16088 cmov%O2%C1\t{%2, %0|%0, %2}
16089 cmov%O2%c1\t{%3, %0|%0, %3}"
16090 [(set_attr "type" "icmov")
16091 (set_attr "mode" "<MODE>")])
16093 (define_insn_and_split "*movqicc_noc"
16094 [(set (match_operand:QI 0 "register_operand" "=r,r")
16095 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16096 [(match_operand 4 "flags_reg_operand" "")
16098 (match_operand:QI 2 "register_operand" "r,0")
16099 (match_operand:QI 3 "register_operand" "0,r")))]
16100 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16102 "&& reload_completed"
16103 [(set (match_dup 0)
16104 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16107 "operands[0] = gen_lowpart (SImode, operands[0]);
16108 operands[2] = gen_lowpart (SImode, operands[2]);
16109 operands[3] = gen_lowpart (SImode, operands[3]);"
16110 [(set_attr "type" "icmov")
16111 (set_attr "mode" "SI")])
16113 (define_expand "mov<mode>cc"
16114 [(set (match_operand:X87MODEF 0 "register_operand" "")
16115 (if_then_else:X87MODEF
16116 (match_operand 1 "ix86_fp_comparison_operator" "")
16117 (match_operand:X87MODEF 2 "register_operand" "")
16118 (match_operand:X87MODEF 3 "register_operand" "")))]
16119 "(TARGET_80387 && TARGET_CMOVE)
16120 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16121 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16123 (define_insn "*movxfcc_1"
16124 [(set (match_operand:XF 0 "register_operand" "=f,f")
16125 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16126 [(reg FLAGS_REG) (const_int 0)])
16127 (match_operand:XF 2 "register_operand" "f,0")
16128 (match_operand:XF 3 "register_operand" "0,f")))]
16129 "TARGET_80387 && TARGET_CMOVE"
16131 fcmov%F1\t{%2, %0|%0, %2}
16132 fcmov%f1\t{%3, %0|%0, %3}"
16133 [(set_attr "type" "fcmov")
16134 (set_attr "mode" "XF")])
16136 (define_insn "*movdfcc_1_rex64"
16137 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16138 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16139 [(reg FLAGS_REG) (const_int 0)])
16140 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16141 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16142 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16143 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16145 fcmov%F1\t{%2, %0|%0, %2}
16146 fcmov%f1\t{%3, %0|%0, %3}
16147 cmov%O2%C1\t{%2, %0|%0, %2}
16148 cmov%O2%c1\t{%3, %0|%0, %3}"
16149 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16150 (set_attr "mode" "DF,DF,DI,DI")])
16152 (define_insn "*movdfcc_1"
16153 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16154 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16155 [(reg FLAGS_REG) (const_int 0)])
16156 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16157 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16158 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16159 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16161 fcmov%F1\t{%2, %0|%0, %2}
16162 fcmov%f1\t{%3, %0|%0, %3}
16165 [(set_attr "type" "fcmov,fcmov,multi,multi")
16166 (set_attr "mode" "DF,DF,DI,DI")])
16169 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16170 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16171 [(match_operand 4 "flags_reg_operand" "")
16173 (match_operand:DF 2 "nonimmediate_operand" "")
16174 (match_operand:DF 3 "nonimmediate_operand" "")))]
16175 "!TARGET_64BIT && reload_completed"
16176 [(set (match_dup 2)
16177 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16181 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16185 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16186 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16189 (define_insn "*movsfcc_1_387"
16190 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16191 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16192 [(reg FLAGS_REG) (const_int 0)])
16193 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16194 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16195 "TARGET_80387 && TARGET_CMOVE
16196 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16198 fcmov%F1\t{%2, %0|%0, %2}
16199 fcmov%f1\t{%3, %0|%0, %3}
16200 cmov%O2%C1\t{%2, %0|%0, %2}
16201 cmov%O2%c1\t{%3, %0|%0, %3}"
16202 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16203 (set_attr "mode" "SF,SF,SI,SI")])
16205 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16206 ;; the scalar versions to have only XMM registers as operands.
16208 ;; XOP conditional move
16209 (define_insn "*xop_pcmov_<mode>"
16210 [(set (match_operand:MODEF 0 "register_operand" "=x")
16211 (if_then_else:MODEF
16212 (match_operand:MODEF 1 "register_operand" "x")
16213 (match_operand:MODEF 2 "register_operand" "x")
16214 (match_operand:MODEF 3 "register_operand" "x")))]
16216 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16217 [(set_attr "type" "sse4arg")])
16219 ;; These versions of the min/max patterns are intentionally ignorant of
16220 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16221 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16222 ;; are undefined in this condition, we're certain this is correct.
16224 (define_insn "*avx_<code><mode>3"
16225 [(set (match_operand:MODEF 0 "register_operand" "=x")
16227 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16228 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16229 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16230 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16231 [(set_attr "type" "sseadd")
16232 (set_attr "prefix" "vex")
16233 (set_attr "mode" "<MODE>")])
16235 (define_insn "<code><mode>3"
16236 [(set (match_operand:MODEF 0 "register_operand" "=x")
16238 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16239 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16240 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16241 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16242 [(set_attr "type" "sseadd")
16243 (set_attr "mode" "<MODE>")])
16245 ;; These versions of the min/max patterns implement exactly the operations
16246 ;; min = (op1 < op2 ? op1 : op2)
16247 ;; max = (!(op1 < op2) ? op1 : op2)
16248 ;; Their operands are not commutative, and thus they may be used in the
16249 ;; presence of -0.0 and NaN.
16251 (define_insn "*avx_ieee_smin<mode>3"
16252 [(set (match_operand:MODEF 0 "register_operand" "=x")
16254 [(match_operand:MODEF 1 "register_operand" "x")
16255 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16257 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16258 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16259 [(set_attr "type" "sseadd")
16260 (set_attr "prefix" "vex")
16261 (set_attr "mode" "<MODE>")])
16263 (define_insn "*ieee_smin<mode>3"
16264 [(set (match_operand:MODEF 0 "register_operand" "=x")
16266 [(match_operand:MODEF 1 "register_operand" "0")
16267 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16269 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16270 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16271 [(set_attr "type" "sseadd")
16272 (set_attr "mode" "<MODE>")])
16274 (define_insn "*avx_ieee_smax<mode>3"
16275 [(set (match_operand:MODEF 0 "register_operand" "=x")
16277 [(match_operand:MODEF 1 "register_operand" "0")
16278 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16280 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16281 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16282 [(set_attr "type" "sseadd")
16283 (set_attr "prefix" "vex")
16284 (set_attr "mode" "<MODE>")])
16286 (define_insn "*ieee_smax<mode>3"
16287 [(set (match_operand:MODEF 0 "register_operand" "=x")
16289 [(match_operand:MODEF 1 "register_operand" "0")
16290 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16292 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16293 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16294 [(set_attr "type" "sseadd")
16295 (set_attr "mode" "<MODE>")])
16297 ;; Make two stack loads independent:
16299 ;; fld %st(0) -> fld bb
16300 ;; fmul bb fmul %st(1), %st
16302 ;; Actually we only match the last two instructions for simplicity.
16304 [(set (match_operand 0 "fp_register_operand" "")
16305 (match_operand 1 "fp_register_operand" ""))
16307 (match_operator 2 "binary_fp_operator"
16309 (match_operand 3 "memory_operand" "")]))]
16310 "REGNO (operands[0]) != REGNO (operands[1])"
16311 [(set (match_dup 0) (match_dup 3))
16312 (set (match_dup 0) (match_dup 4))]
16314 ;; The % modifier is not operational anymore in peephole2's, so we have to
16315 ;; swap the operands manually in the case of addition and multiplication.
16316 "if (COMMUTATIVE_ARITH_P (operands[2]))
16317 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16318 GET_MODE (operands[2]),
16319 operands[0], operands[1]);
16321 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16322 GET_MODE (operands[2]),
16323 operands[1], operands[0]);")
16325 ;; Conditional addition patterns
16326 (define_expand "add<mode>cc"
16327 [(match_operand:SWI 0 "register_operand" "")
16328 (match_operand 1 "ordered_comparison_operator" "")
16329 (match_operand:SWI 2 "register_operand" "")
16330 (match_operand:SWI 3 "const_int_operand" "")]
16332 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16334 ;; Misc patterns (?)
16336 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16337 ;; Otherwise there will be nothing to keep
16339 ;; [(set (reg ebp) (reg esp))]
16340 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16341 ;; (clobber (eflags)]
16342 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16344 ;; in proper program order.
16346 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16347 [(set (match_operand:P 0 "register_operand" "=r,r")
16348 (plus:P (match_operand:P 1 "register_operand" "0,r")
16349 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16350 (clobber (reg:CC FLAGS_REG))
16351 (clobber (mem:BLK (scratch)))]
16354 switch (get_attr_type (insn))
16357 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16360 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16361 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16362 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16364 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16367 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16368 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16371 [(set (attr "type")
16372 (cond [(and (eq_attr "alternative" "0")
16373 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16374 (const_string "alu")
16375 (match_operand:<MODE> 2 "const0_operand" "")
16376 (const_string "imov")
16378 (const_string "lea")))
16379 (set (attr "length_immediate")
16380 (cond [(eq_attr "type" "imov")
16382 (and (eq_attr "type" "alu")
16383 (match_operand 2 "const128_operand" ""))
16386 (const_string "*")))
16387 (set_attr "mode" "<MODE>")])
16389 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16390 [(set (match_operand:P 0 "register_operand" "=r")
16391 (minus:P (match_operand:P 1 "register_operand" "0")
16392 (match_operand:P 2 "register_operand" "r")))
16393 (clobber (reg:CC FLAGS_REG))
16394 (clobber (mem:BLK (scratch)))]
16396 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16397 [(set_attr "type" "alu")
16398 (set_attr "mode" "<MODE>")])
16400 (define_insn "allocate_stack_worker_probe_<mode>"
16401 [(set (match_operand:P 0 "register_operand" "=a")
16402 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16403 UNSPECV_STACK_PROBE))
16404 (clobber (reg:CC FLAGS_REG))]
16405 "ix86_target_stack_probe ()"
16406 "call\t___chkstk_ms"
16407 [(set_attr "type" "multi")
16408 (set_attr "length" "5")])
16410 (define_expand "allocate_stack"
16411 [(match_operand 0 "register_operand" "")
16412 (match_operand 1 "general_operand" "")]
16413 "ix86_target_stack_probe ()"
16417 #ifndef CHECK_STACK_LIMIT
16418 #define CHECK_STACK_LIMIT 0
16421 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16422 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16424 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16425 stack_pointer_rtx, 0, OPTAB_DIRECT);
16426 if (x != stack_pointer_rtx)
16427 emit_move_insn (stack_pointer_rtx, x);
16431 x = copy_to_mode_reg (Pmode, operands[1]);
16433 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16435 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16436 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16437 stack_pointer_rtx, 0, OPTAB_DIRECT);
16438 if (x != stack_pointer_rtx)
16439 emit_move_insn (stack_pointer_rtx, x);
16442 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16446 ;; Use IOR for stack probes, this is shorter.
16447 (define_expand "probe_stack"
16448 [(match_operand 0 "memory_operand" "")]
16451 rtx (*gen_ior3) (rtx, rtx, rtx);
16453 gen_ior3 = (GET_MODE (operands[0]) == DImode
16454 ? gen_iordi3 : gen_iorsi3);
16456 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16460 (define_insn "adjust_stack_and_probe<mode>"
16461 [(set (match_operand:P 0 "register_operand" "=r")
16462 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16463 UNSPECV_PROBE_STACK_RANGE))
16464 (set (reg:P SP_REG)
16465 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16466 (clobber (reg:CC FLAGS_REG))
16467 (clobber (mem:BLK (scratch)))]
16469 "* return output_adjust_stack_and_probe (operands[0]);"
16470 [(set_attr "type" "multi")])
16472 (define_insn "probe_stack_range<mode>"
16473 [(set (match_operand:P 0 "register_operand" "=r")
16474 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16475 (match_operand:P 2 "const_int_operand" "n")]
16476 UNSPECV_PROBE_STACK_RANGE))
16477 (clobber (reg:CC FLAGS_REG))]
16479 "* return output_probe_stack_range (operands[0], operands[2]);"
16480 [(set_attr "type" "multi")])
16482 (define_expand "builtin_setjmp_receiver"
16483 [(label_ref (match_operand 0 "" ""))]
16484 "!TARGET_64BIT && flag_pic"
16490 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16491 rtx label_rtx = gen_label_rtx ();
16492 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16493 xops[0] = xops[1] = picreg;
16494 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16495 ix86_expand_binary_operator (MINUS, SImode, xops);
16499 emit_insn (gen_set_got (pic_offset_table_rtx));
16503 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16506 [(set (match_operand 0 "register_operand" "")
16507 (match_operator 3 "promotable_binary_operator"
16508 [(match_operand 1 "register_operand" "")
16509 (match_operand 2 "aligned_operand" "")]))
16510 (clobber (reg:CC FLAGS_REG))]
16511 "! TARGET_PARTIAL_REG_STALL && reload_completed
16512 && ((GET_MODE (operands[0]) == HImode
16513 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16514 /* ??? next two lines just !satisfies_constraint_K (...) */
16515 || !CONST_INT_P (operands[2])
16516 || satisfies_constraint_K (operands[2])))
16517 || (GET_MODE (operands[0]) == QImode
16518 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16519 [(parallel [(set (match_dup 0)
16520 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16521 (clobber (reg:CC FLAGS_REG))])]
16522 "operands[0] = gen_lowpart (SImode, operands[0]);
16523 operands[1] = gen_lowpart (SImode, operands[1]);
16524 if (GET_CODE (operands[3]) != ASHIFT)
16525 operands[2] = gen_lowpart (SImode, operands[2]);
16526 PUT_MODE (operands[3], SImode);")
16528 ; Promote the QImode tests, as i386 has encoding of the AND
16529 ; instruction with 32-bit sign-extended immediate and thus the
16530 ; instruction size is unchanged, except in the %eax case for
16531 ; which it is increased by one byte, hence the ! optimize_size.
16533 [(set (match_operand 0 "flags_reg_operand" "")
16534 (match_operator 2 "compare_operator"
16535 [(and (match_operand 3 "aligned_operand" "")
16536 (match_operand 4 "const_int_operand" ""))
16538 (set (match_operand 1 "register_operand" "")
16539 (and (match_dup 3) (match_dup 4)))]
16540 "! TARGET_PARTIAL_REG_STALL && reload_completed
16541 && optimize_insn_for_speed_p ()
16542 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16543 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16544 /* Ensure that the operand will remain sign-extended immediate. */
16545 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16546 [(parallel [(set (match_dup 0)
16547 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16550 (and:SI (match_dup 3) (match_dup 4)))])]
16553 = gen_int_mode (INTVAL (operands[4])
16554 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16555 operands[1] = gen_lowpart (SImode, operands[1]);
16556 operands[3] = gen_lowpart (SImode, operands[3]);
16559 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16560 ; the TEST instruction with 32-bit sign-extended immediate and thus
16561 ; the instruction size would at least double, which is not what we
16562 ; want even with ! optimize_size.
16564 [(set (match_operand 0 "flags_reg_operand" "")
16565 (match_operator 1 "compare_operator"
16566 [(and (match_operand:HI 2 "aligned_operand" "")
16567 (match_operand:HI 3 "const_int_operand" ""))
16569 "! TARGET_PARTIAL_REG_STALL && reload_completed
16570 && ! TARGET_FAST_PREFIX
16571 && optimize_insn_for_speed_p ()
16572 /* Ensure that the operand will remain sign-extended immediate. */
16573 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16574 [(set (match_dup 0)
16575 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16579 = gen_int_mode (INTVAL (operands[3])
16580 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16581 operands[2] = gen_lowpart (SImode, operands[2]);
16585 [(set (match_operand 0 "register_operand" "")
16586 (neg (match_operand 1 "register_operand" "")))
16587 (clobber (reg:CC FLAGS_REG))]
16588 "! TARGET_PARTIAL_REG_STALL && reload_completed
16589 && (GET_MODE (operands[0]) == HImode
16590 || (GET_MODE (operands[0]) == QImode
16591 && (TARGET_PROMOTE_QImode
16592 || optimize_insn_for_size_p ())))"
16593 [(parallel [(set (match_dup 0)
16594 (neg:SI (match_dup 1)))
16595 (clobber (reg:CC FLAGS_REG))])]
16596 "operands[0] = gen_lowpart (SImode, operands[0]);
16597 operands[1] = gen_lowpart (SImode, operands[1]);")
16600 [(set (match_operand 0 "register_operand" "")
16601 (not (match_operand 1 "register_operand" "")))]
16602 "! TARGET_PARTIAL_REG_STALL && reload_completed
16603 && (GET_MODE (operands[0]) == HImode
16604 || (GET_MODE (operands[0]) == QImode
16605 && (TARGET_PROMOTE_QImode
16606 || optimize_insn_for_size_p ())))"
16607 [(set (match_dup 0)
16608 (not:SI (match_dup 1)))]
16609 "operands[0] = gen_lowpart (SImode, operands[0]);
16610 operands[1] = gen_lowpart (SImode, operands[1]);")
16613 [(set (match_operand 0 "register_operand" "")
16614 (if_then_else (match_operator 1 "ordered_comparison_operator"
16615 [(reg FLAGS_REG) (const_int 0)])
16616 (match_operand 2 "register_operand" "")
16617 (match_operand 3 "register_operand" "")))]
16618 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16619 && (GET_MODE (operands[0]) == HImode
16620 || (GET_MODE (operands[0]) == QImode
16621 && (TARGET_PROMOTE_QImode
16622 || optimize_insn_for_size_p ())))"
16623 [(set (match_dup 0)
16624 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16625 "operands[0] = gen_lowpart (SImode, operands[0]);
16626 operands[2] = gen_lowpart (SImode, operands[2]);
16627 operands[3] = gen_lowpart (SImode, operands[3]);")
16629 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16630 ;; transform a complex memory operation into two memory to register operations.
16632 ;; Don't push memory operands
16634 [(set (match_operand:SWI 0 "push_operand" "")
16635 (match_operand:SWI 1 "memory_operand" ""))
16636 (match_scratch:SWI 2 "<r>")]
16637 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16638 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16639 [(set (match_dup 2) (match_dup 1))
16640 (set (match_dup 0) (match_dup 2))])
16642 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16645 [(set (match_operand:SF 0 "push_operand" "")
16646 (match_operand:SF 1 "memory_operand" ""))
16647 (match_scratch:SF 2 "r")]
16648 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16649 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16650 [(set (match_dup 2) (match_dup 1))
16651 (set (match_dup 0) (match_dup 2))])
16653 ;; Don't move an immediate directly to memory when the instruction
16656 [(match_scratch:SWI124 1 "<r>")
16657 (set (match_operand:SWI124 0 "memory_operand" "")
16659 "optimize_insn_for_speed_p ()
16660 && !TARGET_USE_MOV0
16661 && TARGET_SPLIT_LONG_MOVES
16662 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16663 && peep2_regno_dead_p (0, FLAGS_REG)"
16664 [(parallel [(set (match_dup 2) (const_int 0))
16665 (clobber (reg:CC FLAGS_REG))])
16666 (set (match_dup 0) (match_dup 1))]
16667 "operands[2] = gen_lowpart (SImode, operands[1]);")
16670 [(match_scratch:SWI124 2 "<r>")
16671 (set (match_operand:SWI124 0 "memory_operand" "")
16672 (match_operand:SWI124 1 "immediate_operand" ""))]
16673 "optimize_insn_for_speed_p ()
16674 && TARGET_SPLIT_LONG_MOVES
16675 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16676 [(set (match_dup 2) (match_dup 1))
16677 (set (match_dup 0) (match_dup 2))])
16679 ;; Don't compare memory with zero, load and use a test instead.
16681 [(set (match_operand 0 "flags_reg_operand" "")
16682 (match_operator 1 "compare_operator"
16683 [(match_operand:SI 2 "memory_operand" "")
16685 (match_scratch:SI 3 "r")]
16686 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16687 [(set (match_dup 3) (match_dup 2))
16688 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16690 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16691 ;; Don't split NOTs with a displacement operand, because resulting XOR
16692 ;; will not be pairable anyway.
16694 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16695 ;; represented using a modRM byte. The XOR replacement is long decoded,
16696 ;; so this split helps here as well.
16698 ;; Note: Can't do this as a regular split because we can't get proper
16699 ;; lifetime information then.
16702 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16703 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16704 "optimize_insn_for_speed_p ()
16705 && ((TARGET_NOT_UNPAIRABLE
16706 && (!MEM_P (operands[0])
16707 || !memory_displacement_operand (operands[0], <MODE>mode)))
16708 || (TARGET_NOT_VECTORMODE
16709 && long_memory_operand (operands[0], <MODE>mode)))
16710 && peep2_regno_dead_p (0, FLAGS_REG)"
16711 [(parallel [(set (match_dup 0)
16712 (xor:SWI124 (match_dup 1) (const_int -1)))
16713 (clobber (reg:CC FLAGS_REG))])])
16715 ;; Non pairable "test imm, reg" instructions can be translated to
16716 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16717 ;; byte opcode instead of two, have a short form for byte operands),
16718 ;; so do it for other CPUs as well. Given that the value was dead,
16719 ;; this should not create any new dependencies. Pass on the sub-word
16720 ;; versions if we're concerned about partial register stalls.
16723 [(set (match_operand 0 "flags_reg_operand" "")
16724 (match_operator 1 "compare_operator"
16725 [(and:SI (match_operand:SI 2 "register_operand" "")
16726 (match_operand:SI 3 "immediate_operand" ""))
16728 "ix86_match_ccmode (insn, CCNOmode)
16729 && (true_regnum (operands[2]) != AX_REG
16730 || satisfies_constraint_K (operands[3]))
16731 && peep2_reg_dead_p (1, operands[2])"
16733 [(set (match_dup 0)
16734 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16737 (and:SI (match_dup 2) (match_dup 3)))])])
16739 ;; We don't need to handle HImode case, because it will be promoted to SImode
16740 ;; on ! TARGET_PARTIAL_REG_STALL
16743 [(set (match_operand 0 "flags_reg_operand" "")
16744 (match_operator 1 "compare_operator"
16745 [(and:QI (match_operand:QI 2 "register_operand" "")
16746 (match_operand:QI 3 "immediate_operand" ""))
16748 "! TARGET_PARTIAL_REG_STALL
16749 && ix86_match_ccmode (insn, CCNOmode)
16750 && true_regnum (operands[2]) != AX_REG
16751 && peep2_reg_dead_p (1, operands[2])"
16753 [(set (match_dup 0)
16754 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16757 (and:QI (match_dup 2) (match_dup 3)))])])
16760 [(set (match_operand 0 "flags_reg_operand" "")
16761 (match_operator 1 "compare_operator"
16764 (match_operand 2 "ext_register_operand" "")
16767 (match_operand 3 "const_int_operand" ""))
16769 "! TARGET_PARTIAL_REG_STALL
16770 && ix86_match_ccmode (insn, CCNOmode)
16771 && true_regnum (operands[2]) != AX_REG
16772 && peep2_reg_dead_p (1, operands[2])"
16773 [(parallel [(set (match_dup 0)
16782 (set (zero_extract:SI (match_dup 2)
16790 (match_dup 3)))])])
16792 ;; Don't do logical operations with memory inputs.
16794 [(match_scratch:SI 2 "r")
16795 (parallel [(set (match_operand:SI 0 "register_operand" "")
16796 (match_operator:SI 3 "arith_or_logical_operator"
16798 (match_operand:SI 1 "memory_operand" "")]))
16799 (clobber (reg:CC FLAGS_REG))])]
16800 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16801 [(set (match_dup 2) (match_dup 1))
16802 (parallel [(set (match_dup 0)
16803 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16804 (clobber (reg:CC FLAGS_REG))])])
16807 [(match_scratch:SI 2 "r")
16808 (parallel [(set (match_operand:SI 0 "register_operand" "")
16809 (match_operator:SI 3 "arith_or_logical_operator"
16810 [(match_operand:SI 1 "memory_operand" "")
16812 (clobber (reg:CC FLAGS_REG))])]
16813 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16814 [(set (match_dup 2) (match_dup 1))
16815 (parallel [(set (match_dup 0)
16816 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16817 (clobber (reg:CC FLAGS_REG))])])
16819 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16820 ;; refers to the destination of the load!
16823 [(set (match_operand:SI 0 "register_operand" "")
16824 (match_operand:SI 1 "register_operand" ""))
16825 (parallel [(set (match_dup 0)
16826 (match_operator:SI 3 "commutative_operator"
16828 (match_operand:SI 2 "memory_operand" "")]))
16829 (clobber (reg:CC FLAGS_REG))])]
16830 "REGNO (operands[0]) != REGNO (operands[1])
16831 && GENERAL_REGNO_P (REGNO (operands[0]))
16832 && GENERAL_REGNO_P (REGNO (operands[1]))"
16833 [(set (match_dup 0) (match_dup 4))
16834 (parallel [(set (match_dup 0)
16835 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16836 (clobber (reg:CC FLAGS_REG))])]
16837 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16840 [(set (match_operand 0 "register_operand" "")
16841 (match_operand 1 "register_operand" ""))
16843 (match_operator 3 "commutative_operator"
16845 (match_operand 2 "memory_operand" "")]))]
16846 "REGNO (operands[0]) != REGNO (operands[1])
16847 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16848 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16849 [(set (match_dup 0) (match_dup 2))
16851 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16853 ; Don't do logical operations with memory outputs
16855 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16856 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16857 ; the same decoder scheduling characteristics as the original.
16860 [(match_scratch:SI 2 "r")
16861 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16862 (match_operator:SI 3 "arith_or_logical_operator"
16864 (match_operand:SI 1 "nonmemory_operand" "")]))
16865 (clobber (reg:CC FLAGS_REG))])]
16866 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16867 /* Do not split stack checking probes. */
16868 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16869 [(set (match_dup 2) (match_dup 0))
16870 (parallel [(set (match_dup 2)
16871 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16872 (clobber (reg:CC FLAGS_REG))])
16873 (set (match_dup 0) (match_dup 2))])
16876 [(match_scratch:SI 2 "r")
16877 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16878 (match_operator:SI 3 "arith_or_logical_operator"
16879 [(match_operand:SI 1 "nonmemory_operand" "")
16881 (clobber (reg:CC FLAGS_REG))])]
16882 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16883 /* Do not split stack checking probes. */
16884 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16885 [(set (match_dup 2) (match_dup 0))
16886 (parallel [(set (match_dup 2)
16887 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16888 (clobber (reg:CC FLAGS_REG))])
16889 (set (match_dup 0) (match_dup 2))])
16891 ;; Attempt to always use XOR for zeroing registers.
16893 [(set (match_operand 0 "register_operand" "")
16894 (match_operand 1 "const0_operand" ""))]
16895 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16896 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16897 && GENERAL_REG_P (operands[0])
16898 && peep2_regno_dead_p (0, FLAGS_REG)"
16899 [(parallel [(set (match_dup 0) (const_int 0))
16900 (clobber (reg:CC FLAGS_REG))])]
16901 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16904 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16906 "(GET_MODE (operands[0]) == QImode
16907 || GET_MODE (operands[0]) == HImode)
16908 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16909 && peep2_regno_dead_p (0, FLAGS_REG)"
16910 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16911 (clobber (reg:CC FLAGS_REG))])])
16913 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16915 [(set (match_operand:SWI248 0 "register_operand" "")
16917 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16918 && peep2_regno_dead_p (0, FLAGS_REG)"
16919 [(parallel [(set (match_dup 0) (const_int -1))
16920 (clobber (reg:CC FLAGS_REG))])]
16922 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16923 operands[0] = gen_lowpart (SImode, operands[0]);
16926 ;; Attempt to convert simple lea to add/shift.
16927 ;; These can be created by move expanders.
16930 [(set (match_operand:SWI48 0 "register_operand" "")
16931 (plus:SWI48 (match_dup 0)
16932 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16933 "peep2_regno_dead_p (0, FLAGS_REG)"
16934 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16935 (clobber (reg:CC FLAGS_REG))])])
16938 [(set (match_operand:SI 0 "register_operand" "")
16939 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16940 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16942 && peep2_regno_dead_p (0, FLAGS_REG)
16943 && REGNO (operands[0]) == REGNO (operands[1])"
16944 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16945 (clobber (reg:CC FLAGS_REG))])]
16946 "operands[2] = gen_lowpart (SImode, operands[2]);")
16949 [(set (match_operand:SWI48 0 "register_operand" "")
16950 (mult:SWI48 (match_dup 0)
16951 (match_operand:SWI48 1 "const_int_operand" "")))]
16952 "exact_log2 (INTVAL (operands[1])) >= 0
16953 && peep2_regno_dead_p (0, FLAGS_REG)"
16954 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16955 (clobber (reg:CC FLAGS_REG))])]
16956 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16959 [(set (match_operand:SI 0 "register_operand" "")
16960 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16961 (match_operand:DI 2 "const_int_operand" "")) 0))]
16963 && exact_log2 (INTVAL (operands[2])) >= 0
16964 && REGNO (operands[0]) == REGNO (operands[1])
16965 && peep2_regno_dead_p (0, FLAGS_REG)"
16966 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16967 (clobber (reg:CC FLAGS_REG))])]
16968 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16970 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16971 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16972 ;; On many CPUs it is also faster, since special hardware to avoid esp
16973 ;; dependencies is present.
16975 ;; While some of these conversions may be done using splitters, we use
16976 ;; peepholes in order to allow combine_stack_adjustments pass to see
16977 ;; nonobfuscated RTL.
16979 ;; Convert prologue esp subtractions to push.
16980 ;; We need register to push. In order to keep verify_flow_info happy we have
16982 ;; - use scratch and clobber it in order to avoid dependencies
16983 ;; - use already live register
16984 ;; We can't use the second way right now, since there is no reliable way how to
16985 ;; verify that given register is live. First choice will also most likely in
16986 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16987 ;; call clobbered registers are dead. We may want to use base pointer as an
16988 ;; alternative when no register is available later.
16991 [(match_scratch:P 1 "r")
16992 (parallel [(set (reg:P SP_REG)
16993 (plus:P (reg:P SP_REG)
16994 (match_operand:P 0 "const_int_operand" "")))
16995 (clobber (reg:CC FLAGS_REG))
16996 (clobber (mem:BLK (scratch)))])]
16997 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16998 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16999 [(clobber (match_dup 1))
17000 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17001 (clobber (mem:BLK (scratch)))])])
17004 [(match_scratch:P 1 "r")
17005 (parallel [(set (reg:P SP_REG)
17006 (plus:P (reg:P SP_REG)
17007 (match_operand:P 0 "const_int_operand" "")))
17008 (clobber (reg:CC FLAGS_REG))
17009 (clobber (mem:BLK (scratch)))])]
17010 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17011 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17012 [(clobber (match_dup 1))
17013 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17014 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17015 (clobber (mem:BLK (scratch)))])])
17017 ;; Convert esp subtractions to push.
17019 [(match_scratch:P 1 "r")
17020 (parallel [(set (reg:P SP_REG)
17021 (plus:P (reg:P SP_REG)
17022 (match_operand:P 0 "const_int_operand" "")))
17023 (clobber (reg:CC FLAGS_REG))])]
17024 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17025 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17026 [(clobber (match_dup 1))
17027 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17030 [(match_scratch:P 1 "r")
17031 (parallel [(set (reg:P SP_REG)
17032 (plus:P (reg:P SP_REG)
17033 (match_operand:P 0 "const_int_operand" "")))
17034 (clobber (reg:CC FLAGS_REG))])]
17035 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17036 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17037 [(clobber (match_dup 1))
17038 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17039 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17041 ;; Convert epilogue deallocator to pop.
17043 [(match_scratch:P 1 "r")
17044 (parallel [(set (reg:P SP_REG)
17045 (plus:P (reg:P SP_REG)
17046 (match_operand:P 0 "const_int_operand" "")))
17047 (clobber (reg:CC FLAGS_REG))
17048 (clobber (mem:BLK (scratch)))])]
17049 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17050 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17051 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17052 (clobber (mem:BLK (scratch)))])])
17054 ;; Two pops case is tricky, since pop causes dependency
17055 ;; on destination register. We use two registers if available.
17057 [(match_scratch:P 1 "r")
17058 (match_scratch:P 2 "r")
17059 (parallel [(set (reg:P SP_REG)
17060 (plus:P (reg:P SP_REG)
17061 (match_operand:P 0 "const_int_operand" "")))
17062 (clobber (reg:CC FLAGS_REG))
17063 (clobber (mem:BLK (scratch)))])]
17064 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17065 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17066 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17067 (clobber (mem:BLK (scratch)))])
17068 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17071 [(match_scratch:P 1 "r")
17072 (parallel [(set (reg:P SP_REG)
17073 (plus:P (reg:P SP_REG)
17074 (match_operand:P 0 "const_int_operand" "")))
17075 (clobber (reg:CC FLAGS_REG))
17076 (clobber (mem:BLK (scratch)))])]
17077 "optimize_insn_for_size_p ()
17078 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17079 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17080 (clobber (mem:BLK (scratch)))])
17081 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17083 ;; Convert esp additions to pop.
17085 [(match_scratch:P 1 "r")
17086 (parallel [(set (reg:P SP_REG)
17087 (plus:P (reg:P SP_REG)
17088 (match_operand:P 0 "const_int_operand" "")))
17089 (clobber (reg:CC FLAGS_REG))])]
17090 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17091 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17093 ;; Two pops case is tricky, since pop causes dependency
17094 ;; on destination register. We use two registers if available.
17096 [(match_scratch:P 1 "r")
17097 (match_scratch:P 2 "r")
17098 (parallel [(set (reg:P SP_REG)
17099 (plus:P (reg:P SP_REG)
17100 (match_operand:P 0 "const_int_operand" "")))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17103 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17104 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17107 [(match_scratch:P 1 "r")
17108 (parallel [(set (reg:P SP_REG)
17109 (plus:P (reg:P SP_REG)
17110 (match_operand:P 0 "const_int_operand" "")))
17111 (clobber (reg:CC FLAGS_REG))])]
17112 "optimize_insn_for_size_p ()
17113 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17114 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17115 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17117 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17118 ;; required and register dies. Similarly for 128 to -128.
17120 [(set (match_operand 0 "flags_reg_operand" "")
17121 (match_operator 1 "compare_operator"
17122 [(match_operand 2 "register_operand" "")
17123 (match_operand 3 "const_int_operand" "")]))]
17124 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17125 && incdec_operand (operands[3], GET_MODE (operands[3])))
17126 || (!TARGET_FUSE_CMP_AND_BRANCH
17127 && INTVAL (operands[3]) == 128))
17128 && ix86_match_ccmode (insn, CCGCmode)
17129 && peep2_reg_dead_p (1, operands[2])"
17130 [(parallel [(set (match_dup 0)
17131 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17132 (clobber (match_dup 2))])])
17134 ;; Convert imul by three, five and nine into lea
17137 [(set (match_operand:SWI48 0 "register_operand" "")
17138 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17139 (match_operand:SWI48 2 "const_int_operand" "")))
17140 (clobber (reg:CC FLAGS_REG))])]
17141 "INTVAL (operands[2]) == 3
17142 || INTVAL (operands[2]) == 5
17143 || INTVAL (operands[2]) == 9"
17144 [(set (match_dup 0)
17145 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17147 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17151 [(set (match_operand:SWI48 0 "register_operand" "")
17152 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17153 (match_operand:SWI48 2 "const_int_operand" "")))
17154 (clobber (reg:CC FLAGS_REG))])]
17155 "optimize_insn_for_speed_p ()
17156 && (INTVAL (operands[2]) == 3
17157 || INTVAL (operands[2]) == 5
17158 || INTVAL (operands[2]) == 9)"
17159 [(set (match_dup 0) (match_dup 1))
17161 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17163 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17165 ;; imul $32bit_imm, mem, reg is vector decoded, while
17166 ;; imul $32bit_imm, reg, reg is direct decoded.
17168 [(match_scratch:SWI48 3 "r")
17169 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17170 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17171 (match_operand:SWI48 2 "immediate_operand" "")))
17172 (clobber (reg:CC FLAGS_REG))])]
17173 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17174 && !satisfies_constraint_K (operands[2])"
17175 [(set (match_dup 3) (match_dup 1))
17176 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17177 (clobber (reg:CC FLAGS_REG))])])
17180 [(match_scratch:SI 3 "r")
17181 (parallel [(set (match_operand:DI 0 "register_operand" "")
17183 (mult:SI (match_operand:SI 1 "memory_operand" "")
17184 (match_operand:SI 2 "immediate_operand" ""))))
17185 (clobber (reg:CC FLAGS_REG))])]
17187 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17188 && !satisfies_constraint_K (operands[2])"
17189 [(set (match_dup 3) (match_dup 1))
17190 (parallel [(set (match_dup 0)
17191 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17192 (clobber (reg:CC FLAGS_REG))])])
17194 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17195 ;; Convert it into imul reg, reg
17196 ;; It would be better to force assembler to encode instruction using long
17197 ;; immediate, but there is apparently no way to do so.
17199 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17201 (match_operand:SWI248 1 "nonimmediate_operand" "")
17202 (match_operand:SWI248 2 "const_int_operand" "")))
17203 (clobber (reg:CC FLAGS_REG))])
17204 (match_scratch:SWI248 3 "r")]
17205 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17206 && satisfies_constraint_K (operands[2])"
17207 [(set (match_dup 3) (match_dup 2))
17208 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17209 (clobber (reg:CC FLAGS_REG))])]
17211 if (!rtx_equal_p (operands[0], operands[1]))
17212 emit_move_insn (operands[0], operands[1]);
17215 ;; After splitting up read-modify operations, array accesses with memory
17216 ;; operands might end up in form:
17218 ;; movl 4(%esp), %edx
17220 ;; instead of pre-splitting:
17222 ;; addl 4(%esp), %eax
17224 ;; movl 4(%esp), %edx
17225 ;; leal (%edx,%eax,4), %eax
17228 [(match_scratch:P 5 "r")
17229 (parallel [(set (match_operand 0 "register_operand" "")
17230 (ashift (match_operand 1 "register_operand" "")
17231 (match_operand 2 "const_int_operand" "")))
17232 (clobber (reg:CC FLAGS_REG))])
17233 (parallel [(set (match_operand 3 "register_operand" "")
17234 (plus (match_dup 0)
17235 (match_operand 4 "x86_64_general_operand" "")))
17236 (clobber (reg:CC FLAGS_REG))])]
17237 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17238 /* Validate MODE for lea. */
17239 && ((!TARGET_PARTIAL_REG_STALL
17240 && (GET_MODE (operands[0]) == QImode
17241 || GET_MODE (operands[0]) == HImode))
17242 || GET_MODE (operands[0]) == SImode
17243 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17244 && (rtx_equal_p (operands[0], operands[3])
17245 || peep2_reg_dead_p (2, operands[0]))
17246 /* We reorder load and the shift. */
17247 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17248 [(set (match_dup 5) (match_dup 4))
17249 (set (match_dup 0) (match_dup 1))]
17251 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17252 int scale = 1 << INTVAL (operands[2]);
17253 rtx index = gen_lowpart (Pmode, operands[1]);
17254 rtx base = gen_lowpart (Pmode, operands[5]);
17255 rtx dest = gen_lowpart (mode, operands[3]);
17257 operands[1] = gen_rtx_PLUS (Pmode, base,
17258 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17259 operands[5] = base;
17262 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17263 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17265 operands[0] = dest;
17268 ;; Call-value patterns last so that the wildcard operand does not
17269 ;; disrupt insn-recog's switch tables.
17271 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17272 [(set (match_operand 0 "" "")
17273 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17274 (match_operand:SI 2 "" "")))
17275 (set (reg:SI SP_REG)
17276 (plus:SI (reg:SI SP_REG)
17277 (match_operand:SI 3 "immediate_operand" "")))
17278 (unspec [(match_operand 4 "const_int_operand" "")]
17279 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17280 "TARGET_VZEROUPPER && !TARGET_64BIT"
17282 "&& reload_completed"
17284 "ix86_split_call_pop_vzeroupper (curr_insn, operands[4]); DONE;"
17285 [(set_attr "type" "callv")])
17287 (define_insn "*call_value_pop_0"
17288 [(set (match_operand 0 "" "")
17289 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17290 (match_operand:SI 2 "" "")))
17291 (set (reg:SI SP_REG)
17292 (plus:SI (reg:SI SP_REG)
17293 (match_operand:SI 3 "immediate_operand" "")))]
17295 { return ix86_output_call_insn (insn, operands[1], 1); }
17296 [(set_attr "type" "callv")])
17298 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17299 [(set (match_operand 0 "" "")
17300 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17301 (match_operand:SI 2 "" "")))
17302 (set (reg:SI SP_REG)
17303 (plus:SI (reg:SI SP_REG)
17304 (match_operand:SI 3 "immediate_operand" "i")))
17305 (unspec [(match_operand 4 "const_int_operand" "")]
17306 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17307 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17309 "&& reload_completed"
17311 "ix86_split_call_pop_vzeroupper (curr_insn, operands[4]); DONE;"
17312 [(set_attr "type" "callv")])
17314 (define_insn "*call_value_pop_1"
17315 [(set (match_operand 0 "" "")
17316 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17317 (match_operand:SI 2 "" "")))
17318 (set (reg:SI SP_REG)
17319 (plus:SI (reg:SI SP_REG)
17320 (match_operand:SI 3 "immediate_operand" "i")))]
17321 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17322 { return ix86_output_call_insn (insn, operands[1], 1); }
17323 [(set_attr "type" "callv")])
17325 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17326 [(set (match_operand 0 "" "")
17327 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17328 (match_operand:SI 2 "" "")))
17329 (set (reg:SI SP_REG)
17330 (plus:SI (reg:SI SP_REG)
17331 (match_operand:SI 3 "immediate_operand" "i,i")))
17332 (unspec [(match_operand 4 "const_int_operand" "")]
17333 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17334 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17336 "&& reload_completed"
17338 "ix86_split_call_pop_vzeroupper (curr_insn, operands[4]); DONE;"
17339 [(set_attr "type" "callv")])
17341 (define_insn "*sibcall_value_pop_1"
17342 [(set (match_operand 0 "" "")
17343 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17344 (match_operand:SI 2 "" "")))
17345 (set (reg:SI SP_REG)
17346 (plus:SI (reg:SI SP_REG)
17347 (match_operand:SI 3 "immediate_operand" "i,i")))]
17348 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17349 { return ix86_output_call_insn (insn, operands[1], 1); }
17350 [(set_attr "type" "callv")])
17352 (define_insn_and_split "*call_value_0_vzeroupper"
17353 [(set (match_operand 0 "" "")
17354 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17355 (match_operand:SI 2 "" "")))
17356 (unspec [(match_operand 3 "const_int_operand" "")]
17357 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17358 "TARGET_VZEROUPPER && !TARGET_64BIT"
17360 "&& reload_completed"
17362 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17363 [(set_attr "type" "callv")])
17365 (define_insn "*call_value_0"
17366 [(set (match_operand 0 "" "")
17367 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17368 (match_operand:SI 2 "" "")))]
17370 { return ix86_output_call_insn (insn, operands[1], 1); }
17371 [(set_attr "type" "callv")])
17373 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17374 [(set (match_operand 0 "" "")
17375 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17376 (match_operand:DI 2 "const_int_operand" "")))
17377 (unspec [(match_operand 3 "const_int_operand" "")]
17378 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17379 "TARGET_VZEROUPPER && TARGET_64BIT"
17381 "&& reload_completed"
17383 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17384 [(set_attr "type" "callv")])
17386 (define_insn "*call_value_0_rex64"
17387 [(set (match_operand 0 "" "")
17388 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17389 (match_operand:DI 2 "const_int_operand" "")))]
17391 { return ix86_output_call_insn (insn, operands[1], 1); }
17392 [(set_attr "type" "callv")])
17394 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17396 [(set (match_operand 0 "" "")
17397 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17398 (match_operand:DI 2 "const_int_operand" "")))
17399 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17400 (clobber (reg:TI XMM6_REG))
17401 (clobber (reg:TI XMM7_REG))
17402 (clobber (reg:TI XMM8_REG))
17403 (clobber (reg:TI XMM9_REG))
17404 (clobber (reg:TI XMM10_REG))
17405 (clobber (reg:TI XMM11_REG))
17406 (clobber (reg:TI XMM12_REG))
17407 (clobber (reg:TI XMM13_REG))
17408 (clobber (reg:TI XMM14_REG))
17409 (clobber (reg:TI XMM15_REG))
17410 (clobber (reg:DI SI_REG))
17411 (clobber (reg:DI DI_REG))])
17412 (unspec [(match_operand 3 "const_int_operand" "")]
17413 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17414 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17416 "&& reload_completed"
17418 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17419 [(set_attr "type" "callv")])
17421 (define_insn "*call_value_0_rex64_ms_sysv"
17422 [(set (match_operand 0 "" "")
17423 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17424 (match_operand:DI 2 "const_int_operand" "")))
17425 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17426 (clobber (reg:TI XMM6_REG))
17427 (clobber (reg:TI XMM7_REG))
17428 (clobber (reg:TI XMM8_REG))
17429 (clobber (reg:TI XMM9_REG))
17430 (clobber (reg:TI XMM10_REG))
17431 (clobber (reg:TI XMM11_REG))
17432 (clobber (reg:TI XMM12_REG))
17433 (clobber (reg:TI XMM13_REG))
17434 (clobber (reg:TI XMM14_REG))
17435 (clobber (reg:TI XMM15_REG))
17436 (clobber (reg:DI SI_REG))
17437 (clobber (reg:DI DI_REG))]
17438 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17439 { return ix86_output_call_insn (insn, operands[1], 1); }
17440 [(set_attr "type" "callv")])
17442 (define_insn_and_split "*call_value_1_vzeroupper"
17443 [(set (match_operand 0 "" "")
17444 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17445 (match_operand:SI 2 "" "")))
17446 (unspec [(match_operand 3 "const_int_operand" "")]
17447 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17448 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17450 "&& reload_completed"
17452 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17453 [(set_attr "type" "callv")])
17455 (define_insn "*call_value_1"
17456 [(set (match_operand 0 "" "")
17457 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17458 (match_operand:SI 2 "" "")))]
17459 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17460 { return ix86_output_call_insn (insn, operands[1], 1); }
17461 [(set_attr "type" "callv")])
17463 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17464 [(set (match_operand 0 "" "")
17465 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17466 (match_operand:SI 2 "" "")))
17467 (unspec [(match_operand 3 "const_int_operand" "")]
17468 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17469 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17471 "&& reload_completed"
17473 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17474 [(set_attr "type" "callv")])
17476 (define_insn "*sibcall_value_1"
17477 [(set (match_operand 0 "" "")
17478 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17479 (match_operand:SI 2 "" "")))]
17480 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17481 { return ix86_output_call_insn (insn, operands[1], 1); }
17482 [(set_attr "type" "callv")])
17484 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17485 [(set (match_operand 0 "" "")
17486 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17487 (match_operand:DI 2 "" "")))
17488 (unspec [(match_operand 3 "const_int_operand" "")]
17489 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17490 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17491 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17493 "&& reload_completed"
17495 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17496 [(set_attr "type" "callv")])
17498 (define_insn "*call_value_1_rex64"
17499 [(set (match_operand 0 "" "")
17500 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17501 (match_operand:DI 2 "" "")))]
17502 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17503 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17504 { return ix86_output_call_insn (insn, operands[1], 1); }
17505 [(set_attr "type" "callv")])
17507 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17509 [(set (match_operand 0 "" "")
17510 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17511 (match_operand:DI 2 "" "")))
17512 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17513 (clobber (reg:TI XMM6_REG))
17514 (clobber (reg:TI XMM7_REG))
17515 (clobber (reg:TI XMM8_REG))
17516 (clobber (reg:TI XMM9_REG))
17517 (clobber (reg:TI XMM10_REG))
17518 (clobber (reg:TI XMM11_REG))
17519 (clobber (reg:TI XMM12_REG))
17520 (clobber (reg:TI XMM13_REG))
17521 (clobber (reg:TI XMM14_REG))
17522 (clobber (reg:TI XMM15_REG))
17523 (clobber (reg:DI SI_REG))
17524 (clobber (reg:DI DI_REG))])
17525 (unspec [(match_operand 3 "const_int_operand" "")]
17526 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17527 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17529 "&& reload_completed"
17531 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17532 [(set_attr "type" "callv")])
17534 (define_insn "*call_value_1_rex64_ms_sysv"
17535 [(set (match_operand 0 "" "")
17536 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17537 (match_operand:DI 2 "" "")))
17538 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17539 (clobber (reg:TI XMM6_REG))
17540 (clobber (reg:TI XMM7_REG))
17541 (clobber (reg:TI XMM8_REG))
17542 (clobber (reg:TI XMM9_REG))
17543 (clobber (reg:TI XMM10_REG))
17544 (clobber (reg:TI XMM11_REG))
17545 (clobber (reg:TI XMM12_REG))
17546 (clobber (reg:TI XMM13_REG))
17547 (clobber (reg:TI XMM14_REG))
17548 (clobber (reg:TI XMM15_REG))
17549 (clobber (reg:DI SI_REG))
17550 (clobber (reg:DI DI_REG))]
17551 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17552 { return ix86_output_call_insn (insn, operands[1], 1); }
17553 [(set_attr "type" "callv")])
17555 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17556 [(set (match_operand 0 "" "")
17557 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17558 (match_operand:DI 2 "" "")))
17559 (unspec [(match_operand 3 "const_int_operand" "")]
17560 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17561 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17563 "&& reload_completed"
17565 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17566 [(set_attr "type" "callv")])
17568 (define_insn "*call_value_1_rex64_large"
17569 [(set (match_operand 0 "" "")
17570 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17571 (match_operand:DI 2 "" "")))]
17572 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17573 { return ix86_output_call_insn (insn, operands[1], 1); }
17574 [(set_attr "type" "callv")])
17576 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17577 [(set (match_operand 0 "" "")
17578 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17579 (match_operand:DI 2 "" "")))
17580 (unspec [(match_operand 3 "const_int_operand" "")]
17581 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17582 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17584 "&& reload_completed"
17586 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17587 [(set_attr "type" "callv")])
17589 (define_insn "*sibcall_value_1_rex64"
17590 [(set (match_operand 0 "" "")
17591 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17592 (match_operand:DI 2 "" "")))]
17593 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17594 { return ix86_output_call_insn (insn, operands[1], 1); }
17595 [(set_attr "type" "callv")])
17597 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17598 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17599 ;; caught for use by garbage collectors and the like. Using an insn that
17600 ;; maps to SIGILL makes it more likely the program will rightfully die.
17601 ;; Keeping with tradition, "6" is in honor of #UD.
17602 (define_insn "trap"
17603 [(trap_if (const_int 1) (const_int 6))]
17605 { return ASM_SHORT "0x0b0f"; }
17606 [(set_attr "length" "2")])
17608 (define_expand "prefetch"
17609 [(prefetch (match_operand 0 "address_operand" "")
17610 (match_operand:SI 1 "const_int_operand" "")
17611 (match_operand:SI 2 "const_int_operand" ""))]
17612 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17614 int rw = INTVAL (operands[1]);
17615 int locality = INTVAL (operands[2]);
17617 gcc_assert (rw == 0 || rw == 1);
17618 gcc_assert (locality >= 0 && locality <= 3);
17619 gcc_assert (GET_MODE (operands[0]) == Pmode
17620 || GET_MODE (operands[0]) == VOIDmode);
17622 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17623 supported by SSE counterpart or the SSE prefetch is not available
17624 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17626 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17627 operands[2] = GEN_INT (3);
17629 operands[1] = const0_rtx;
17632 (define_insn "*prefetch_sse_<mode>"
17633 [(prefetch (match_operand:P 0 "address_operand" "p")
17635 (match_operand:SI 1 "const_int_operand" ""))]
17636 "TARGET_PREFETCH_SSE"
17638 static const char * const patterns[4] = {
17639 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17642 int locality = INTVAL (operands[1]);
17643 gcc_assert (locality >= 0 && locality <= 3);
17645 return patterns[locality];
17647 [(set_attr "type" "sse")
17648 (set_attr "atom_sse_attr" "prefetch")
17649 (set (attr "length_address")
17650 (symbol_ref "memory_address_length (operands[0])"))
17651 (set_attr "memory" "none")])
17653 (define_insn "*prefetch_3dnow_<mode>"
17654 [(prefetch (match_operand:P 0 "address_operand" "p")
17655 (match_operand:SI 1 "const_int_operand" "n")
17659 if (INTVAL (operands[1]) == 0)
17660 return "prefetch\t%a0";
17662 return "prefetchw\t%a0";
17664 [(set_attr "type" "mmx")
17665 (set (attr "length_address")
17666 (symbol_ref "memory_address_length (operands[0])"))
17667 (set_attr "memory" "none")])
17669 (define_expand "stack_protect_set"
17670 [(match_operand 0 "memory_operand" "")
17671 (match_operand 1 "memory_operand" "")]
17674 rtx (*insn)(rtx, rtx);
17676 #ifdef TARGET_THREAD_SSP_OFFSET
17677 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17678 insn = (TARGET_64BIT
17679 ? gen_stack_tls_protect_set_di
17680 : gen_stack_tls_protect_set_si);
17682 insn = (TARGET_64BIT
17683 ? gen_stack_protect_set_di
17684 : gen_stack_protect_set_si);
17687 emit_insn (insn (operands[0], operands[1]));
17691 (define_insn "stack_protect_set_<mode>"
17692 [(set (match_operand:P 0 "memory_operand" "=m")
17693 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17694 (set (match_scratch:P 2 "=&r") (const_int 0))
17695 (clobber (reg:CC FLAGS_REG))]
17697 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17698 [(set_attr "type" "multi")])
17700 (define_insn "stack_tls_protect_set_<mode>"
17701 [(set (match_operand:P 0 "memory_operand" "=m")
17702 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17703 UNSPEC_SP_TLS_SET))
17704 (set (match_scratch:P 2 "=&r") (const_int 0))
17705 (clobber (reg:CC FLAGS_REG))]
17707 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17708 [(set_attr "type" "multi")])
17710 (define_expand "stack_protect_test"
17711 [(match_operand 0 "memory_operand" "")
17712 (match_operand 1 "memory_operand" "")
17713 (match_operand 2 "" "")]
17716 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17718 rtx (*insn)(rtx, rtx, rtx);
17720 #ifdef TARGET_THREAD_SSP_OFFSET
17721 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17722 insn = (TARGET_64BIT
17723 ? gen_stack_tls_protect_test_di
17724 : gen_stack_tls_protect_test_si);
17726 insn = (TARGET_64BIT
17727 ? gen_stack_protect_test_di
17728 : gen_stack_protect_test_si);
17731 emit_insn (insn (flags, operands[0], operands[1]));
17733 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17734 flags, const0_rtx, operands[2]));
17738 (define_insn "stack_protect_test_<mode>"
17739 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17740 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17741 (match_operand:P 2 "memory_operand" "m")]
17743 (clobber (match_scratch:P 3 "=&r"))]
17745 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17746 [(set_attr "type" "multi")])
17748 (define_insn "stack_tls_protect_test_<mode>"
17749 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17750 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17751 (match_operand:P 2 "const_int_operand" "i")]
17752 UNSPEC_SP_TLS_TEST))
17753 (clobber (match_scratch:P 3 "=r"))]
17755 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17756 [(set_attr "type" "multi")])
17758 (define_insn "sse4_2_crc32<mode>"
17759 [(set (match_operand:SI 0 "register_operand" "=r")
17761 [(match_operand:SI 1 "register_operand" "0")
17762 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17764 "TARGET_SSE4_2 || TARGET_CRC32"
17765 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17766 [(set_attr "type" "sselog1")
17767 (set_attr "prefix_rep" "1")
17768 (set_attr "prefix_extra" "1")
17769 (set (attr "prefix_data16")
17770 (if_then_else (match_operand:HI 2 "" "")
17772 (const_string "*")))
17773 (set (attr "prefix_rex")
17774 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17776 (const_string "*")))
17777 (set_attr "mode" "SI")])
17779 (define_insn "sse4_2_crc32di"
17780 [(set (match_operand:DI 0 "register_operand" "=r")
17782 [(match_operand:DI 1 "register_operand" "0")
17783 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17785 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17786 "crc32{q}\t{%2, %0|%0, %2}"
17787 [(set_attr "type" "sselog1")
17788 (set_attr "prefix_rep" "1")
17789 (set_attr "prefix_extra" "1")
17790 (set_attr "mode" "DI")])
17792 (define_expand "rdpmc"
17793 [(match_operand:DI 0 "register_operand" "")
17794 (match_operand:SI 1 "register_operand" "")]
17797 rtx reg = gen_reg_rtx (DImode);
17800 /* Force operand 1 into ECX. */
17801 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17802 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17803 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17808 rtvec vec = rtvec_alloc (2);
17809 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17810 rtx upper = gen_reg_rtx (DImode);
17811 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17812 gen_rtvec (1, const0_rtx),
17814 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17815 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17817 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17818 NULL, 1, OPTAB_DIRECT);
17819 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17823 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17824 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17828 (define_insn "*rdpmc"
17829 [(set (match_operand:DI 0 "register_operand" "=A")
17830 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17834 [(set_attr "type" "other")
17835 (set_attr "length" "2")])
17837 (define_insn "*rdpmc_rex64"
17838 [(set (match_operand:DI 0 "register_operand" "=a")
17839 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17841 (set (match_operand:DI 1 "register_operand" "=d")
17842 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17845 [(set_attr "type" "other")
17846 (set_attr "length" "2")])
17848 (define_expand "rdtsc"
17849 [(set (match_operand:DI 0 "register_operand" "")
17850 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17855 rtvec vec = rtvec_alloc (2);
17856 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17857 rtx upper = gen_reg_rtx (DImode);
17858 rtx lower = gen_reg_rtx (DImode);
17859 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17860 gen_rtvec (1, const0_rtx),
17862 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17863 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17865 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17866 NULL, 1, OPTAB_DIRECT);
17867 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17874 (define_insn "*rdtsc"
17875 [(set (match_operand:DI 0 "register_operand" "=A")
17876 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17879 [(set_attr "type" "other")
17880 (set_attr "length" "2")])
17882 (define_insn "*rdtsc_rex64"
17883 [(set (match_operand:DI 0 "register_operand" "=a")
17884 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17885 (set (match_operand:DI 1 "register_operand" "=d")
17886 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17889 [(set_attr "type" "other")
17890 (set_attr "length" "2")])
17892 (define_expand "rdtscp"
17893 [(match_operand:DI 0 "register_operand" "")
17894 (match_operand:SI 1 "memory_operand" "")]
17897 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17898 gen_rtvec (1, const0_rtx),
17900 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17901 gen_rtvec (1, const0_rtx),
17903 rtx reg = gen_reg_rtx (DImode);
17904 rtx tmp = gen_reg_rtx (SImode);
17908 rtvec vec = rtvec_alloc (3);
17909 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17910 rtx upper = gen_reg_rtx (DImode);
17911 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17912 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17913 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17915 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17916 NULL, 1, OPTAB_DIRECT);
17917 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17922 rtvec vec = rtvec_alloc (2);
17923 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17924 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17925 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17928 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17929 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17933 (define_insn "*rdtscp"
17934 [(set (match_operand:DI 0 "register_operand" "=A")
17935 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17936 (set (match_operand:SI 1 "register_operand" "=c")
17937 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17940 [(set_attr "type" "other")
17941 (set_attr "length" "3")])
17943 (define_insn "*rdtscp_rex64"
17944 [(set (match_operand:DI 0 "register_operand" "=a")
17945 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17946 (set (match_operand:DI 1 "register_operand" "=d")
17947 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17948 (set (match_operand:SI 2 "register_operand" "=c")
17949 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17952 [(set_attr "type" "other")
17953 (set_attr "length" "3")])
17955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17957 ;; LWP instructions
17959 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17961 (define_expand "lwp_llwpcb"
17962 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17963 UNSPECV_LLWP_INTRINSIC)]
17966 (define_insn "*lwp_llwpcb<mode>1"
17967 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17968 UNSPECV_LLWP_INTRINSIC)]
17971 [(set_attr "type" "lwp")
17972 (set_attr "mode" "<MODE>")
17973 (set_attr "length" "5")])
17975 (define_expand "lwp_slwpcb"
17976 [(set (match_operand 0 "register_operand" "=r")
17977 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17981 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17983 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17987 (define_insn "lwp_slwpcb<mode>"
17988 [(set (match_operand:P 0 "register_operand" "=r")
17989 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17992 [(set_attr "type" "lwp")
17993 (set_attr "mode" "<MODE>")
17994 (set_attr "length" "5")])
17996 (define_expand "lwp_lwpval<mode>3"
17997 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17998 (match_operand:SI 2 "nonimmediate_operand" "rm")
17999 (match_operand:SI 3 "const_int_operand" "i")]
18000 UNSPECV_LWPVAL_INTRINSIC)]
18002 "/* Avoid unused variable warning. */
18005 (define_insn "*lwp_lwpval<mode>3_1"
18006 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18007 (match_operand:SI 1 "nonimmediate_operand" "rm")
18008 (match_operand:SI 2 "const_int_operand" "i")]
18009 UNSPECV_LWPVAL_INTRINSIC)]
18011 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18012 [(set_attr "type" "lwp")
18013 (set_attr "mode" "<MODE>")
18014 (set (attr "length")
18015 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18017 (define_expand "lwp_lwpins<mode>3"
18018 [(set (reg:CCC FLAGS_REG)
18019 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18020 (match_operand:SI 2 "nonimmediate_operand" "rm")
18021 (match_operand:SI 3 "const_int_operand" "i")]
18022 UNSPECV_LWPINS_INTRINSIC))
18023 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18024 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18027 (define_insn "*lwp_lwpins<mode>3_1"
18028 [(set (reg:CCC FLAGS_REG)
18029 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18030 (match_operand:SI 1 "nonimmediate_operand" "rm")
18031 (match_operand:SI 2 "const_int_operand" "i")]
18032 UNSPECV_LWPINS_INTRINSIC))]
18034 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18035 [(set_attr "type" "lwp")
18036 (set_attr "mode" "<MODE>")
18037 (set (attr "length")
18038 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18040 (define_insn "rdfsbase<mode>"
18041 [(set (match_operand:SWI48 0 "register_operand" "=r")
18042 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18043 "TARGET_64BIT && TARGET_FSGSBASE"
18045 [(set_attr "type" "other")
18046 (set_attr "prefix_extra" "2")])
18048 (define_insn "rdgsbase<mode>"
18049 [(set (match_operand:SWI48 0 "register_operand" "=r")
18050 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18051 "TARGET_64BIT && TARGET_FSGSBASE"
18053 [(set_attr "type" "other")
18054 (set_attr "prefix_extra" "2")])
18056 (define_insn "wrfsbase<mode>"
18057 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18059 "TARGET_64BIT && TARGET_FSGSBASE"
18061 [(set_attr "type" "other")
18062 (set_attr "prefix_extra" "2")])
18064 (define_insn "wrgsbase<mode>"
18065 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18067 "TARGET_64BIT && TARGET_FSGSBASE"
18069 [(set_attr "type" "other")
18070 (set_attr "prefix_extra" "2")])
18072 (define_expand "rdrand<mode>"
18073 [(set (match_operand:SWI248 0 "register_operand" "=r")
18074 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18077 rtx retry_label, insn, ccc;
18079 retry_label = gen_label_rtx ();
18081 emit_label (retry_label);
18083 /* Generate rdrand. */
18084 emit_insn (gen_rdrand<mode>_1 (operands[0]));
18086 /* Retry if the carry flag isn't valid. */
18087 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18088 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18089 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18090 gen_rtx_LABEL_REF (VOIDmode, retry_label));
18091 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18092 JUMP_LABEL (insn) = retry_label;
18097 (define_insn "rdrand<mode>_1"
18098 [(set (match_operand:SWI248 0 "register_operand" "=r")
18099 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18102 [(set_attr "type" "other")
18103 (set_attr "prefix_extra" "1")])
18107 (include "sync.md")