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).
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
82 UNSPEC_SSE_PROLOGUE_SAVE
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_SSE_PROLOGUE_SAVE_LOW
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
108 ;; For SSE/MMX support:
126 UNSPEC_MS_TO_SYSV_CALL
128 ;; Generic math support
130 UNSPEC_IEEE_MIN ; not commutative
131 UNSPEC_IEEE_MAX ; not commutative
133 ;; x87 Floating point
149 UNSPEC_FRNDINT_MASK_PM
153 ;; x87 Double output FP
185 ;; For SSE4.1 support
195 ;; For SSE4.2 support
201 UNSPEC_FMA4_INTRINSIC
204 UNSPEC_XOP_UNSIGNED_CMP
215 UNSPEC_AESKEYGENASSIST
217 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
259 ;; Constants to represent pcomtrue/pcomfalse variants
269 ;; Constants used in the XOP pperm instruction
271 [(PPERM_SRC 0x00) /* copy source */
272 (PPERM_INVERT 0x20) /* invert source */
273 (PPERM_REVERSE 0x40) /* bit reverse source */
274 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
275 (PPERM_ZERO 0x80) /* all 0's */
276 (PPERM_ONES 0xa0) /* all 1's */
277 (PPERM_SIGN 0xc0) /* propagate sign bit */
278 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
279 (PPERM_SRC1 0x00) /* use first source byte */
280 (PPERM_SRC2 0x10) /* use second source byte */
283 ;; Registers by name.
336 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
339 ;; In C guard expressions, put expressions which may be compile-time
340 ;; constants first. This allows for better optimization. For
341 ;; example, write "TARGET_64BIT && reload_completed", not
342 ;; "reload_completed && TARGET_64BIT".
346 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 generic64,amdfam10,bdver1"
348 (const (symbol_ref "ix86_schedule")))
350 ;; A basic instruction type. Refinements due to arguments to be
351 ;; provided in other attributes.
354 alu,alu1,negnot,imov,imovx,lea,
355 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356 icmp,test,ibr,setcc,icmov,
357 push,pop,call,callv,leave,
359 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
361 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362 ssemuladd,sse4arg,lwp,
363 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364 (const_string "other"))
366 ;; Main data type used by the insn
368 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369 (const_string "unknown"))
371 ;; The CPU unit operations uses.
372 (define_attr "unit" "integer,i387,sse,mmx,unknown"
373 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374 (const_string "i387")
375 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
379 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
381 (eq_attr "type" "other")
382 (const_string "unknown")]
383 (const_string "integer")))
385 ;; The (bounding maximum) length of an instruction immediate.
386 (define_attr "length_immediate" ""
387 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
390 (eq_attr "unit" "i387,sse,mmx")
392 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
394 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395 (eq_attr "type" "imov,test")
396 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397 (eq_attr "type" "call")
398 (if_then_else (match_operand 0 "constant_call_address_operand" "")
401 (eq_attr "type" "callv")
402 (if_then_else (match_operand 1 "constant_call_address_operand" "")
405 ;; We don't know the size before shorten_branches. Expect
406 ;; the instruction to fit for better scheduling.
407 (eq_attr "type" "ibr")
410 (symbol_ref "/* Update immediate_length and other attributes! */
411 gcc_unreachable (),1")))
413 ;; The (bounding maximum) length of an instruction address.
414 (define_attr "length_address" ""
415 (cond [(eq_attr "type" "str,other,multi,fxch")
417 (and (eq_attr "type" "call")
418 (match_operand 0 "constant_call_address_operand" ""))
420 (and (eq_attr "type" "callv")
421 (match_operand 1 "constant_call_address_operand" ""))
424 (symbol_ref "ix86_attr_length_address_default (insn)")))
426 ;; Set when length prefix is used.
427 (define_attr "prefix_data16" ""
428 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
430 (eq_attr "mode" "HI")
432 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
437 ;; Set when string REP prefix is used.
438 (define_attr "prefix_rep" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
446 ;; Set when 0f opcode prefix is used.
447 (define_attr "prefix_0f" ""
449 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450 (eq_attr "unit" "sse,mmx"))
454 ;; Set when REX opcode prefix is used.
455 (define_attr "prefix_rex" ""
456 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
458 (and (eq_attr "mode" "DI")
459 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460 (eq_attr "unit" "!mmx")))
462 (and (eq_attr "mode" "QI")
463 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
466 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
469 (and (eq_attr "type" "imovx")
470 (match_operand:QI 1 "ext_QIreg_operand" ""))
475 ;; There are also additional prefixes in 3DNOW, SSSE3.
476 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479 (define_attr "prefix_extra" ""
480 (cond [(eq_attr "type" "ssemuladd,sse4arg")
482 (eq_attr "type" "sseiadd1,ssecvt1")
487 ;; Prefix used: original, VEX or maybe VEX.
488 (define_attr "prefix" "orig,vex,maybe_vex"
489 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
491 (const_string "orig")))
493 ;; VEX W bit is used.
494 (define_attr "prefix_vex_w" "" (const_int 0))
496 ;; The length of VEX prefix
497 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
499 ;; still prefix_0f 1, with prefix_extra 1.
500 (define_attr "length_vex" ""
501 (if_then_else (and (eq_attr "prefix_0f" "1")
502 (eq_attr "prefix_extra" "0"))
503 (if_then_else (eq_attr "prefix_vex_w" "1")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506 (if_then_else (eq_attr "prefix_vex_w" "1")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
510 ;; Set when modrm byte is used.
511 (define_attr "modrm" ""
512 (cond [(eq_attr "type" "str,leave")
514 (eq_attr "unit" "i387")
516 (and (eq_attr "type" "incdec")
517 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518 (ior (match_operand:SI 1 "register_operand" "")
519 (match_operand:HI 1 "register_operand" ""))))
521 (and (eq_attr "type" "push")
522 (not (match_operand 1 "memory_operand" "")))
524 (and (eq_attr "type" "pop")
525 (not (match_operand 0 "memory_operand" "")))
527 (and (eq_attr "type" "imov")
528 (and (not (eq_attr "mode" "DI"))
529 (ior (and (match_operand 0 "register_operand" "")
530 (match_operand 1 "immediate_operand" ""))
531 (ior (and (match_operand 0 "ax_reg_operand" "")
532 (match_operand 1 "memory_displacement_only_operand" ""))
533 (and (match_operand 0 "memory_displacement_only_operand" "")
534 (match_operand 1 "ax_reg_operand" ""))))))
536 (and (eq_attr "type" "call")
537 (match_operand 0 "constant_call_address_operand" ""))
539 (and (eq_attr "type" "callv")
540 (match_operand 1 "constant_call_address_operand" ""))
542 (and (eq_attr "type" "alu,alu1,icmp,test")
543 (match_operand 0 "ax_reg_operand" ""))
544 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
548 ;; The (bounding maximum) length of an instruction in bytes.
549 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550 ;; Later we may want to split them and compute proper length as for
552 (define_attr "length" ""
553 (cond [(eq_attr "type" "other,multi,fistp,frndint")
555 (eq_attr "type" "fcmp")
557 (eq_attr "unit" "i387")
559 (plus (attr "prefix_data16")
560 (attr "length_address")))
561 (ior (eq_attr "prefix" "vex")
562 (and (eq_attr "prefix" "maybe_vex")
563 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564 (plus (attr "length_vex")
565 (plus (attr "length_immediate")
567 (attr "length_address"))))]
568 (plus (plus (attr "modrm")
569 (plus (attr "prefix_0f")
570 (plus (attr "prefix_rex")
571 (plus (attr "prefix_extra")
573 (plus (attr "prefix_rep")
574 (plus (attr "prefix_data16")
575 (plus (attr "length_immediate")
576 (attr "length_address")))))))
578 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
579 ;; `store' if there is a simple memory reference therein, or `unknown'
580 ;; if the instruction is complex.
582 (define_attr "memory" "none,load,store,both,unknown"
583 (cond [(eq_attr "type" "other,multi,str,lwp")
584 (const_string "unknown")
585 (eq_attr "type" "lea,fcmov,fpspc")
586 (const_string "none")
587 (eq_attr "type" "fistp,leave")
588 (const_string "both")
589 (eq_attr "type" "frndint")
590 (const_string "load")
591 (eq_attr "type" "push")
592 (if_then_else (match_operand 1 "memory_operand" "")
593 (const_string "both")
594 (const_string "store"))
595 (eq_attr "type" "pop")
596 (if_then_else (match_operand 0 "memory_operand" "")
597 (const_string "both")
598 (const_string "load"))
599 (eq_attr "type" "setcc")
600 (if_then_else (match_operand 0 "memory_operand" "")
601 (const_string "store")
602 (const_string "none"))
603 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604 (if_then_else (ior (match_operand 0 "memory_operand" "")
605 (match_operand 1 "memory_operand" ""))
606 (const_string "load")
607 (const_string "none"))
608 (eq_attr "type" "ibr")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "load")
611 (const_string "none"))
612 (eq_attr "type" "call")
613 (if_then_else (match_operand 0 "constant_call_address_operand" "")
614 (const_string "none")
615 (const_string "load"))
616 (eq_attr "type" "callv")
617 (if_then_else (match_operand 1 "constant_call_address_operand" "")
618 (const_string "none")
619 (const_string "load"))
620 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621 (match_operand 1 "memory_operand" ""))
622 (const_string "both")
623 (and (match_operand 0 "memory_operand" "")
624 (match_operand 1 "memory_operand" ""))
625 (const_string "both")
626 (match_operand 0 "memory_operand" "")
627 (const_string "store")
628 (match_operand 1 "memory_operand" "")
629 (const_string "load")
631 "!alu1,negnot,ishift1,
632 imov,imovx,icmp,test,bitmanip,
634 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636 (match_operand 2 "memory_operand" ""))
637 (const_string "load")
638 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639 (match_operand 3 "memory_operand" ""))
640 (const_string "load")
642 (const_string "none")))
644 ;; Indicates if an instruction has both an immediate and a displacement.
646 (define_attr "imm_disp" "false,true,unknown"
647 (cond [(eq_attr "type" "other,multi")
648 (const_string "unknown")
649 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650 (and (match_operand 0 "memory_displacement_operand" "")
651 (match_operand 1 "immediate_operand" "")))
652 (const_string "true")
653 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654 (and (match_operand 0 "memory_displacement_operand" "")
655 (match_operand 2 "immediate_operand" "")))
656 (const_string "true")
658 (const_string "false")))
660 ;; Indicates if an FP operation has an integer source.
662 (define_attr "fp_int_src" "false,true"
663 (const_string "false"))
665 ;; Defines rounding mode of an FP operation.
667 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668 (const_string "any"))
670 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671 (define_attr "use_carry" "0,1" (const_string "0"))
673 ;; Define attribute to indicate unaligned ssemov insns
674 (define_attr "movu" "0,1" (const_string "0"))
676 ;; Describe a user's asm statement.
677 (define_asm_attributes
678 [(set_attr "length" "128")
679 (set_attr "type" "multi")])
681 ;; All integer comparison codes.
682 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
684 ;; All floating-point comparison codes.
685 (define_code_iterator fp_cond [unordered ordered
686 uneq unge ungt unle unlt ltgt])
688 (define_code_iterator plusminus [plus minus])
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699 [(plus "add") (ss_plus "adds") (us_plus "addus")
700 (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702 [(plus "adc") (minus "sbb")])
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706 (minus "") (ss_minus "") (us_minus "")])
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
714 ;; Mapping of signed/unsigned max and min
715 (define_code_iterator maxmin [smax smin umax umin])
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719 (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758 (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
764 ;; Instruction prefix for signed and unsigned operations.
765 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
766 (div "i") (udiv "")])
768 ;; 64bit single word integer modes.
769 (define_mode_iterator SWI1248x [QI HI SI DI])
771 ;; 64bit single word integer modes without QImode and HImode.
772 (define_mode_iterator SWI48x [SI DI])
774 ;; Single word integer modes.
775 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
777 ;; Single word integer modes without SImode and DImode.
778 (define_mode_iterator SWI12 [QI HI])
780 ;; Single word integer modes without DImode.
781 (define_mode_iterator SWI124 [QI HI SI])
783 ;; Single word integer modes without QImode and DImode.
784 (define_mode_iterator SWI24 [HI SI])
786 ;; Single word integer modes without QImode.
787 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
789 ;; Single word integer modes without QImode and HImode.
790 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
792 ;; All math-dependant single and double word integer modes.
793 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
794 (HI "TARGET_HIMODE_MATH")
795 SI DI (TI "TARGET_64BIT")])
797 ;; Math-dependant single word integer modes.
798 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
799 (HI "TARGET_HIMODE_MATH")
800 SI (DI "TARGET_64BIT")])
802 ;; Math-dependant single word integer modes without DImode.
803 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
804 (HI "TARGET_HIMODE_MATH")
807 ;; Math-dependant single word integer modes without QImode.
808 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
809 SI (DI "TARGET_64BIT")])
811 ;; Double word integer modes.
812 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
813 (TI "TARGET_64BIT")])
815 ;; Double word integer modes as mode attribute.
816 (define_mode_attr DWI [(SI "DI") (DI "TI")])
817 (define_mode_attr dwi [(SI "di") (DI "ti")])
819 ;; Half mode for double word integer modes.
820 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
821 (DI "TARGET_64BIT")])
823 ;; Instruction suffix for integer modes.
824 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
826 ;; Register class for integer modes.
827 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
829 ;; Immediate operand constraint for integer modes.
830 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
832 ;; General operand constraint for word modes.
833 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
835 ;; Immediate operand constraint for double integer modes.
836 (define_mode_attr di [(SI "iF") (DI "e")])
838 ;; Immediate operand constraint for shifts.
839 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
841 ;; General operand predicate for integer modes.
842 (define_mode_attr general_operand
843 [(QI "general_operand")
844 (HI "general_operand")
845 (SI "general_operand")
846 (DI "x86_64_general_operand")
847 (TI "x86_64_general_operand")])
849 ;; General sign/zero extend operand predicate for integer modes.
850 (define_mode_attr general_szext_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "general_operand")
854 (DI "x86_64_szext_general_operand")])
856 ;; Operand predicate for shifts.
857 (define_mode_attr shift_operand
858 [(QI "nonimmediate_operand")
859 (HI "nonimmediate_operand")
860 (SI "nonimmediate_operand")
861 (DI "shiftdi_operand")
862 (TI "register_operand")])
864 ;; Operand predicate for shift argument.
865 (define_mode_attr shift_immediate_operand
866 [(QI "const_1_to_31_operand")
867 (HI "const_1_to_31_operand")
868 (SI "const_1_to_31_operand")
869 (DI "const_1_to_63_operand")])
871 ;; Input operand predicate for arithmetic left shifts.
872 (define_mode_attr ashl_input_operand
873 [(QI "nonimmediate_operand")
874 (HI "nonimmediate_operand")
875 (SI "nonimmediate_operand")
876 (DI "ashldi_input_operand")
877 (TI "reg_or_pm1_operand")])
879 ;; SSE and x87 SFmode and DFmode floating point modes
880 (define_mode_iterator MODEF [SF DF])
882 ;; All x87 floating point modes
883 (define_mode_iterator X87MODEF [SF DF XF])
885 ;; All integer modes handled by x87 fisttp operator.
886 (define_mode_iterator X87MODEI [HI SI DI])
888 ;; All integer modes handled by integer x87 operators.
889 (define_mode_iterator X87MODEI12 [HI SI])
891 ;; All integer modes handled by SSE cvtts?2si* operators.
892 (define_mode_iterator SSEMODEI24 [SI DI])
894 ;; SSE asm suffix for floating point modes
895 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
897 ;; SSE vector mode corresponding to a scalar mode
898 (define_mode_attr ssevecmode
899 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
901 ;; Instruction suffix for REX 64bit operators.
902 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
904 ;; This mode iterator allows :P to be used for patterns that operate on
905 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
906 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
908 ;; Scheduling descriptions
910 (include "pentium.md")
913 (include "athlon.md")
918 ;; Operand and operator predicates and constraints
920 (include "predicates.md")
921 (include "constraints.md")
924 ;; Compare and branch/compare and store instructions.
926 (define_expand "cbranch<mode>4"
927 [(set (reg:CC FLAGS_REG)
928 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
929 (match_operand:SDWIM 2 "<general_operand>" "")))
930 (set (pc) (if_then_else
931 (match_operator 0 "comparison_operator"
932 [(reg:CC FLAGS_REG) (const_int 0)])
933 (label_ref (match_operand 3 "" ""))
937 if (MEM_P (operands[1]) && MEM_P (operands[2]))
938 operands[1] = force_reg (<MODE>mode, operands[1]);
939 ix86_compare_op0 = operands[1];
940 ix86_compare_op1 = operands[2];
941 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
945 (define_expand "cstore<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948 (match_operand:SWIM 3 "<general_operand>" "")))
949 (set (match_operand:QI 0 "register_operand" "")
950 (match_operator 1 "comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)]))]
954 if (MEM_P (operands[2]) && MEM_P (operands[3]))
955 operands[2] = force_reg (<MODE>mode, operands[2]);
956 ix86_compare_op0 = operands[2];
957 ix86_compare_op1 = operands[3];
958 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
962 (define_expand "cmp<mode>_1"
963 [(set (reg:CC FLAGS_REG)
964 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
965 (match_operand:SWI48 1 "<general_operand>" "")))]
969 (define_insn "*cmp<mode>_ccno_1"
970 [(set (reg FLAGS_REG)
971 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
972 (match_operand:SWI 1 "const0_operand" "")))]
973 "ix86_match_ccmode (insn, CCNOmode)"
975 test{<imodesuffix>}\t%0, %0
976 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "test,icmp")
978 (set_attr "length_immediate" "0,1")
979 (set_attr "mode" "<MODE>")])
981 (define_insn "*cmp<mode>_1"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
985 "ix86_match_ccmode (insn, CCmode)"
986 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "icmp")
988 (set_attr "mode" "<MODE>")])
990 (define_insn "*cmp<mode>_minus_1"
991 [(set (reg FLAGS_REG)
993 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
996 "ix86_match_ccmode (insn, CCGOCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1001 (define_insn "*cmpqi_ext_1"
1002 [(set (reg FLAGS_REG)
1004 (match_operand:QI 0 "general_operand" "Qm")
1007 (match_operand 1 "ext_register_operand" "Q")
1009 (const_int 8)) 0)))]
1010 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%h1, %0|%0, %h1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_1_rex64"
1016 [(set (reg FLAGS_REG)
1018 (match_operand:QI 0 "register_operand" "Q")
1021 (match_operand 1 "ext_register_operand" "Q")
1023 (const_int 8)) 0)))]
1024 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025 "cmp{b}\t{%h1, %0|%0, %h1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "QI")])
1029 (define_insn "*cmpqi_ext_2"
1030 [(set (reg FLAGS_REG)
1034 (match_operand 0 "ext_register_operand" "Q")
1037 (match_operand:QI 1 "const0_operand" "")))]
1038 "ix86_match_ccmode (insn, CCNOmode)"
1040 [(set_attr "type" "test")
1041 (set_attr "length_immediate" "0")
1042 (set_attr "mode" "QI")])
1044 (define_expand "cmpqi_ext_3"
1045 [(set (reg:CC FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "")
1052 (match_operand:QI 1 "immediate_operand" "")))]
1056 (define_insn "*cmpqi_ext_3_insn"
1057 [(set (reg FLAGS_REG)
1061 (match_operand 0 "ext_register_operand" "Q")
1064 (match_operand:QI 1 "general_operand" "Qmn")))]
1065 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1066 "cmp{b}\t{%1, %h0|%h0, %1}"
1067 [(set_attr "type" "icmp")
1068 (set_attr "modrm" "1")
1069 (set_attr "mode" "QI")])
1071 (define_insn "*cmpqi_ext_3_insn_rex64"
1072 [(set (reg FLAGS_REG)
1076 (match_operand 0 "ext_register_operand" "Q")
1079 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1080 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1081 "cmp{b}\t{%1, %h0|%h0, %1}"
1082 [(set_attr "type" "icmp")
1083 (set_attr "modrm" "1")
1084 (set_attr "mode" "QI")])
1086 (define_insn "*cmpqi_ext_4"
1087 [(set (reg FLAGS_REG)
1091 (match_operand 0 "ext_register_operand" "Q")
1096 (match_operand 1 "ext_register_operand" "Q")
1098 (const_int 8)) 0)))]
1099 "ix86_match_ccmode (insn, CCmode)"
1100 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1101 [(set_attr "type" "icmp")
1102 (set_attr "mode" "QI")])
1104 ;; These implement float point compares.
1105 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1106 ;; which would allow mix and match FP modes on the compares. Which is what
1107 ;; the old patterns did, but with many more of them.
1109 (define_expand "cbranchxf4"
1110 [(set (reg:CC FLAGS_REG)
1111 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1112 (match_operand:XF 2 "nonmemory_operand" "")))
1113 (set (pc) (if_then_else
1114 (match_operator 0 "ix86_fp_comparison_operator"
1117 (label_ref (match_operand 3 "" ""))
1121 ix86_compare_op0 = operands[1];
1122 ix86_compare_op1 = operands[2];
1123 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1127 (define_expand "cstorexf4"
1128 [(set (reg:CC FLAGS_REG)
1129 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1130 (match_operand:XF 3 "nonmemory_operand" "")))
1131 (set (match_operand:QI 0 "register_operand" "")
1132 (match_operator 1 "ix86_fp_comparison_operator"
1137 ix86_compare_op0 = operands[2];
1138 ix86_compare_op1 = operands[3];
1139 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1143 (define_expand "cbranch<mode>4"
1144 [(set (reg:CC FLAGS_REG)
1145 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1146 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1147 (set (pc) (if_then_else
1148 (match_operator 0 "ix86_fp_comparison_operator"
1151 (label_ref (match_operand 3 "" ""))
1153 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1155 ix86_compare_op0 = operands[1];
1156 ix86_compare_op1 = operands[2];
1157 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1161 (define_expand "cstore<mode>4"
1162 [(set (reg:CC FLAGS_REG)
1163 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1164 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1165 (set (match_operand:QI 0 "register_operand" "")
1166 (match_operator 1 "ix86_fp_comparison_operator"
1169 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1171 ix86_compare_op0 = operands[2];
1172 ix86_compare_op1 = operands[3];
1173 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1177 (define_expand "cbranchcc4"
1178 [(set (pc) (if_then_else
1179 (match_operator 0 "comparison_operator"
1180 [(match_operand 1 "flags_reg_operand" "")
1181 (match_operand 2 "const0_operand" "")])
1182 (label_ref (match_operand 3 "" ""))
1186 ix86_compare_op0 = operands[1];
1187 ix86_compare_op1 = operands[2];
1188 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1192 (define_expand "cstorecc4"
1193 [(set (match_operand:QI 0 "register_operand" "")
1194 (match_operator 1 "comparison_operator"
1195 [(match_operand 2 "flags_reg_operand" "")
1196 (match_operand 3 "const0_operand" "")]))]
1199 ix86_compare_op0 = operands[2];
1200 ix86_compare_op1 = operands[3];
1201 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1206 ;; FP compares, step 1:
1207 ;; Set the FP condition codes.
1209 ;; CCFPmode compare with exceptions
1210 ;; CCFPUmode compare with no exceptions
1212 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1213 ;; used to manage the reg stack popping would not be preserved.
1215 (define_insn "*cmpfp_0"
1216 [(set (match_operand:HI 0 "register_operand" "=a")
1219 (match_operand 1 "register_operand" "f")
1220 (match_operand 2 "const0_operand" ""))]
1222 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1223 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1224 "* return output_fp_compare (insn, operands, 0, 0);"
1225 [(set_attr "type" "multi")
1226 (set_attr "unit" "i387")
1228 (cond [(match_operand:SF 1 "" "")
1230 (match_operand:DF 1 "" "")
1233 (const_string "XF")))])
1235 (define_insn_and_split "*cmpfp_0_cc"
1236 [(set (reg:CCFP FLAGS_REG)
1238 (match_operand 1 "register_operand" "f")
1239 (match_operand 2 "const0_operand" "")))
1240 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1241 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242 && TARGET_SAHF && !TARGET_CMOVE
1243 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1245 "&& reload_completed"
1248 [(compare:CCFP (match_dup 1)(match_dup 2))]
1250 (set (reg:CC FLAGS_REG)
1251 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1253 [(set_attr "type" "multi")
1254 (set_attr "unit" "i387")
1256 (cond [(match_operand:SF 1 "" "")
1258 (match_operand:DF 1 "" "")
1261 (const_string "XF")))])
1263 (define_insn "*cmpfp_xf"
1264 [(set (match_operand:HI 0 "register_operand" "=a")
1267 (match_operand:XF 1 "register_operand" "f")
1268 (match_operand:XF 2 "register_operand" "f"))]
1271 "* return output_fp_compare (insn, operands, 0, 0);"
1272 [(set_attr "type" "multi")
1273 (set_attr "unit" "i387")
1274 (set_attr "mode" "XF")])
1276 (define_insn_and_split "*cmpfp_xf_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand:XF 1 "register_operand" "f")
1280 (match_operand:XF 2 "register_operand" "f")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283 && TARGET_SAHF && !TARGET_CMOVE"
1285 "&& reload_completed"
1288 [(compare:CCFP (match_dup 1)(match_dup 2))]
1290 (set (reg:CC FLAGS_REG)
1291 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293 [(set_attr "type" "multi")
1294 (set_attr "unit" "i387")
1295 (set_attr "mode" "XF")])
1297 (define_insn "*cmpfp_<mode>"
1298 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (match_operand:MODEF 1 "register_operand" "f")
1302 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1305 "* return output_fp_compare (insn, operands, 0, 0);"
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "<MODE>")])
1310 (define_insn_and_split "*cmpfp_<mode>_cc"
1311 [(set (reg:CCFP FLAGS_REG)
1313 (match_operand:MODEF 1 "register_operand" "f")
1314 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1315 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1317 && TARGET_SAHF && !TARGET_CMOVE"
1319 "&& reload_completed"
1322 [(compare:CCFP (match_dup 1)(match_dup 2))]
1324 (set (reg:CC FLAGS_REG)
1325 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1329 (set_attr "mode" "<MODE>")])
1331 (define_insn "*cmpfp_u"
1332 [(set (match_operand:HI 0 "register_operand" "=a")
1335 (match_operand 1 "register_operand" "f")
1336 (match_operand 2 "register_operand" "f"))]
1338 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1339 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1340 "* return output_fp_compare (insn, operands, 0, 1);"
1341 [(set_attr "type" "multi")
1342 (set_attr "unit" "i387")
1344 (cond [(match_operand:SF 1 "" "")
1346 (match_operand:DF 1 "" "")
1349 (const_string "XF")))])
1351 (define_insn_and_split "*cmpfp_u_cc"
1352 [(set (reg:CCFPU FLAGS_REG)
1354 (match_operand 1 "register_operand" "f")
1355 (match_operand 2 "register_operand" "f")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1358 && TARGET_SAHF && !TARGET_CMOVE
1359 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1361 "&& reload_completed"
1364 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1366 (set (reg:CC FLAGS_REG)
1367 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1369 [(set_attr "type" "multi")
1370 (set_attr "unit" "i387")
1372 (cond [(match_operand:SF 1 "" "")
1374 (match_operand:DF 1 "" "")
1377 (const_string "XF")))])
1379 (define_insn "*cmpfp_<mode>"
1380 [(set (match_operand:HI 0 "register_operand" "=a")
1383 (match_operand 1 "register_operand" "f")
1384 (match_operator 3 "float_operator"
1385 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1388 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1389 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1390 "* return output_fp_compare (insn, operands, 0, 0);"
1391 [(set_attr "type" "multi")
1392 (set_attr "unit" "i387")
1393 (set_attr "fp_int_src" "true")
1394 (set_attr "mode" "<MODE>")])
1396 (define_insn_and_split "*cmpfp_<mode>_cc"
1397 [(set (reg:CCFP FLAGS_REG)
1399 (match_operand 1 "register_operand" "f")
1400 (match_operator 3 "float_operator"
1401 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1402 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1404 && TARGET_SAHF && !TARGET_CMOVE
1405 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1406 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1408 "&& reload_completed"
1413 (match_op_dup 3 [(match_dup 2)]))]
1415 (set (reg:CC FLAGS_REG)
1416 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1418 [(set_attr "type" "multi")
1419 (set_attr "unit" "i387")
1420 (set_attr "fp_int_src" "true")
1421 (set_attr "mode" "<MODE>")])
1423 ;; FP compares, step 2
1424 ;; Move the fpsw to ax.
1426 (define_insn "x86_fnstsw_1"
1427 [(set (match_operand:HI 0 "register_operand" "=a")
1428 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1431 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1432 (set_attr "mode" "SI")
1433 (set_attr "unit" "i387")])
1435 ;; FP compares, step 3
1436 ;; Get ax into flags, general case.
1438 (define_insn "x86_sahf_1"
1439 [(set (reg:CC FLAGS_REG)
1440 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1444 #ifndef HAVE_AS_IX86_SAHF
1446 return ASM_BYTE "0x9e";
1451 [(set_attr "length" "1")
1452 (set_attr "athlon_decode" "vector")
1453 (set_attr "amdfam10_decode" "direct")
1454 (set_attr "mode" "SI")])
1456 ;; Pentium Pro can do steps 1 through 3 in one go.
1457 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1458 (define_insn "*cmpfp_i_mixed"
1459 [(set (reg:CCFP FLAGS_REG)
1460 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1461 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1462 "TARGET_MIX_SSE_I387
1463 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1464 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1465 "* return output_fp_compare (insn, operands, 1, 0);"
1466 [(set_attr "type" "fcmp,ssecomi")
1467 (set_attr "prefix" "orig,maybe_vex")
1469 (if_then_else (match_operand:SF 1 "" "")
1471 (const_string "DF")))
1472 (set (attr "prefix_rep")
1473 (if_then_else (eq_attr "type" "ssecomi")
1475 (const_string "*")))
1476 (set (attr "prefix_data16")
1477 (cond [(eq_attr "type" "fcmp")
1479 (eq_attr "mode" "DF")
1482 (const_string "0")))
1483 (set_attr "athlon_decode" "vector")
1484 (set_attr "amdfam10_decode" "direct")])
1486 (define_insn "*cmpfp_i_sse"
1487 [(set (reg:CCFP FLAGS_REG)
1488 (compare:CCFP (match_operand 0 "register_operand" "x")
1489 (match_operand 1 "nonimmediate_operand" "xm")))]
1491 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1492 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1493 "* return output_fp_compare (insn, operands, 1, 0);"
1494 [(set_attr "type" "ssecomi")
1495 (set_attr "prefix" "maybe_vex")
1497 (if_then_else (match_operand:SF 1 "" "")
1499 (const_string "DF")))
1500 (set_attr "prefix_rep" "0")
1501 (set (attr "prefix_data16")
1502 (if_then_else (eq_attr "mode" "DF")
1504 (const_string "0")))
1505 (set_attr "athlon_decode" "vector")
1506 (set_attr "amdfam10_decode" "direct")])
1508 (define_insn "*cmpfp_i_i387"
1509 [(set (reg:CCFP FLAGS_REG)
1510 (compare:CCFP (match_operand 0 "register_operand" "f")
1511 (match_operand 1 "register_operand" "f")))]
1512 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1514 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1515 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1516 "* return output_fp_compare (insn, operands, 1, 0);"
1517 [(set_attr "type" "fcmp")
1519 (cond [(match_operand:SF 1 "" "")
1521 (match_operand:DF 1 "" "")
1524 (const_string "XF")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")])
1528 (define_insn "*cmpfp_iu_mixed"
1529 [(set (reg:CCFPU FLAGS_REG)
1530 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1531 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1532 "TARGET_MIX_SSE_I387
1533 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1534 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1535 "* return output_fp_compare (insn, operands, 1, 1);"
1536 [(set_attr "type" "fcmp,ssecomi")
1537 (set_attr "prefix" "orig,maybe_vex")
1539 (if_then_else (match_operand:SF 1 "" "")
1541 (const_string "DF")))
1542 (set (attr "prefix_rep")
1543 (if_then_else (eq_attr "type" "ssecomi")
1545 (const_string "*")))
1546 (set (attr "prefix_data16")
1547 (cond [(eq_attr "type" "fcmp")
1549 (eq_attr "mode" "DF")
1552 (const_string "0")))
1553 (set_attr "athlon_decode" "vector")
1554 (set_attr "amdfam10_decode" "direct")])
1556 (define_insn "*cmpfp_iu_sse"
1557 [(set (reg:CCFPU FLAGS_REG)
1558 (compare:CCFPU (match_operand 0 "register_operand" "x")
1559 (match_operand 1 "nonimmediate_operand" "xm")))]
1561 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1562 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1563 "* return output_fp_compare (insn, operands, 1, 1);"
1564 [(set_attr "type" "ssecomi")
1565 (set_attr "prefix" "maybe_vex")
1567 (if_then_else (match_operand:SF 1 "" "")
1569 (const_string "DF")))
1570 (set_attr "prefix_rep" "0")
1571 (set (attr "prefix_data16")
1572 (if_then_else (eq_attr "mode" "DF")
1574 (const_string "0")))
1575 (set_attr "athlon_decode" "vector")
1576 (set_attr "amdfam10_decode" "direct")])
1578 (define_insn "*cmpfp_iu_387"
1579 [(set (reg:CCFPU FLAGS_REG)
1580 (compare:CCFPU (match_operand 0 "register_operand" "f")
1581 (match_operand 1 "register_operand" "f")))]
1582 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1584 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1585 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1586 "* return output_fp_compare (insn, operands, 1, 1);"
1587 [(set_attr "type" "fcmp")
1589 (cond [(match_operand:SF 1 "" "")
1591 (match_operand:DF 1 "" "")
1594 (const_string "XF")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")])
1598 ;; Move instructions.
1600 (define_expand "movoi"
1601 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1602 (match_operand:OI 1 "general_operand" ""))]
1604 "ix86_expand_move (OImode, operands); DONE;")
1606 (define_expand "movti"
1607 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1608 (match_operand:TI 1 "nonimmediate_operand" ""))]
1609 "TARGET_64BIT || TARGET_SSE"
1612 ix86_expand_move (TImode, operands);
1613 else if (push_operand (operands[0], TImode))
1614 ix86_expand_push (TImode, operands[1]);
1616 ix86_expand_vector_move (TImode, operands);
1620 ;; This expands to what emit_move_complex would generate if we didn't
1621 ;; have a movti pattern. Having this avoids problems with reload on
1622 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1623 ;; to have around all the time.
1624 (define_expand "movcdi"
1625 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1626 (match_operand:CDI 1 "general_operand" ""))]
1629 if (push_operand (operands[0], CDImode))
1630 emit_move_complex_push (CDImode, operands[0], operands[1]);
1632 emit_move_complex_parts (operands[0], operands[1]);
1636 (define_expand "mov<mode>"
1637 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1638 (match_operand:SWI1248x 1 "general_operand" ""))]
1640 "ix86_expand_move (<MODE>mode, operands); DONE;")
1642 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1645 ;; %%% We don't use a post-inc memory reference because x86 is not a
1646 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1647 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1648 ;; targets without our curiosities, and it is just as easy to represent
1649 ;; this differently.
1651 (define_insn "*pushdi2_rex64"
1652 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1653 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1658 [(set_attr "type" "push,multi")
1659 (set_attr "mode" "DI")])
1661 ;; Convert impossible pushes of immediate to existing instructions.
1662 ;; First try to get scratch register and go through it. In case this
1663 ;; fails, push sign extended lower part first and then overwrite
1664 ;; upper part by 32bit move.
1666 [(match_scratch:DI 2 "r")
1667 (set (match_operand:DI 0 "push_operand" "")
1668 (match_operand:DI 1 "immediate_operand" ""))]
1669 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1670 && !x86_64_immediate_operand (operands[1], DImode)"
1671 [(set (match_dup 2) (match_dup 1))
1672 (set (match_dup 0) (match_dup 2))]
1675 ;; We need to define this as both peepholer and splitter for case
1676 ;; peephole2 pass is not run.
1677 ;; "&& 1" is needed to keep it from matching the previous pattern.
1679 [(set (match_operand:DI 0 "push_operand" "")
1680 (match_operand:DI 1 "immediate_operand" ""))]
1681 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1682 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1683 [(set (match_dup 0) (match_dup 1))
1684 (set (match_dup 2) (match_dup 3))]
1686 split_di (&operands[1], 1, &operands[2], &operands[3]);
1688 operands[1] = gen_lowpart (DImode, operands[2]);
1689 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1694 [(set (match_operand:DI 0 "push_operand" "")
1695 (match_operand:DI 1 "immediate_operand" ""))]
1696 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1697 ? epilogue_completed : reload_completed)
1698 && !symbolic_operand (operands[1], DImode)
1699 && !x86_64_immediate_operand (operands[1], DImode)"
1700 [(set (match_dup 0) (match_dup 1))
1701 (set (match_dup 2) (match_dup 3))]
1703 split_di (&operands[1], 1, &operands[2], &operands[3]);
1705 operands[1] = gen_lowpart (DImode, operands[2]);
1706 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1710 (define_insn "*pushdi2"
1711 [(set (match_operand:DI 0 "push_operand" "=<")
1712 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1722 "ix86_split_long_move (operands); DONE;")
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1736 ;; For 64BIT abi we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1762 (define_insn "popdi1"
1763 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1764 (mem:DI (reg:DI SP_REG)))
1765 (set (reg:DI SP_REG)
1766 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1769 [(set_attr "type" "pop")
1770 (set_attr "mode" "DI")])
1772 (define_insn "popsi1"
1773 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1774 (mem:SI (reg:SI SP_REG)))
1775 (set (reg:SI SP_REG)
1776 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1779 [(set_attr "type" "pop")
1780 (set_attr "mode" "SI")])
1782 (define_insn "*popdi1_epilogue"
1783 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1784 (mem:DI (reg:DI SP_REG)))
1785 (set (reg:DI SP_REG)
1786 (plus:DI (reg:DI SP_REG) (const_int 8)))
1787 (clobber (mem:BLK (scratch)))]
1790 [(set_attr "type" "pop")
1791 (set_attr "mode" "DI")])
1793 (define_insn "*popsi1_epilogue"
1794 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1795 (mem:SI (reg:SI SP_REG)))
1796 (set (reg:SI SP_REG)
1797 (plus:SI (reg:SI SP_REG) (const_int 4)))
1798 (clobber (mem:BLK (scratch)))]
1801 [(set_attr "type" "pop")
1802 (set_attr "mode" "SI")])
1804 (define_insn "*mov<mode>_xor"
1805 [(set (match_operand:SWI48 0 "register_operand" "=r")
1806 (match_operand:SWI48 1 "const0_operand" ""))
1807 (clobber (reg:CC FLAGS_REG))]
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "SI")
1812 (set_attr "length_immediate" "0")])
1814 (define_insn "*mov<mode>_or"
1815 [(set (match_operand:SWI48 0 "register_operand" "=r")
1816 (match_operand:SWI48 1 "const_int_operand" ""))
1817 (clobber (reg:CC FLAGS_REG))]
1819 && operands[1] == constm1_rtx"
1820 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1821 [(set_attr "type" "alu1")
1822 (set_attr "mode" "<MODE>")
1823 (set_attr "length_immediate" "1")])
1825 (define_insn "*movoi_internal_avx"
1826 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1827 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1828 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1830 switch (which_alternative)
1833 return "vxorps\t%0, %0, %0";
1836 if (misaligned_operand (operands[0], OImode)
1837 || misaligned_operand (operands[1], OImode))
1838 return "vmovdqu\t{%1, %0|%0, %1}";
1840 return "vmovdqa\t{%1, %0|%0, %1}";
1845 [(set_attr "type" "sselog1,ssemov,ssemov")
1846 (set_attr "prefix" "vex")
1847 (set_attr "mode" "OI")])
1849 (define_insn "*movti_internal_rex64"
1850 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1851 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1852 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1854 switch (which_alternative)
1860 if (get_attr_mode (insn) == MODE_V4SF)
1861 return "%vxorps\t%0, %d0";
1863 return "%vpxor\t%0, %d0";
1866 /* TDmode values are passed as TImode on the stack. Moving them
1867 to stack may result in unaligned memory access. */
1868 if (misaligned_operand (operands[0], TImode)
1869 || misaligned_operand (operands[1], TImode))
1871 if (get_attr_mode (insn) == MODE_V4SF)
1872 return "%vmovups\t{%1, %0|%0, %1}";
1874 return "%vmovdqu\t{%1, %0|%0, %1}";
1878 if (get_attr_mode (insn) == MODE_V4SF)
1879 return "%vmovaps\t{%1, %0|%0, %1}";
1881 return "%vmovdqa\t{%1, %0|%0, %1}";
1887 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1888 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1890 (cond [(eq_attr "alternative" "2,3")
1892 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1894 (const_string "V4SF")
1895 (const_string "TI"))
1896 (eq_attr "alternative" "4")
1898 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1900 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1902 (const_string "V4SF")
1903 (const_string "TI"))]
1904 (const_string "DI")))])
1907 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1908 (match_operand:TI 1 "general_operand" ""))]
1910 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1912 "ix86_split_long_move (operands); DONE;")
1914 (define_insn "*movti_internal_sse"
1915 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1916 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1917 "TARGET_SSE && !TARGET_64BIT
1918 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920 switch (which_alternative)
1923 if (get_attr_mode (insn) == MODE_V4SF)
1924 return "%vxorps\t%0, %d0";
1926 return "%vpxor\t%0, %d0";
1929 /* TDmode values are passed as TImode on the stack. Moving them
1930 to stack may result in unaligned memory access. */
1931 if (misaligned_operand (operands[0], TImode)
1932 || misaligned_operand (operands[1], TImode))
1934 if (get_attr_mode (insn) == MODE_V4SF)
1935 return "%vmovups\t{%1, %0|%0, %1}";
1937 return "%vmovdqu\t{%1, %0|%0, %1}";
1941 if (get_attr_mode (insn) == MODE_V4SF)
1942 return "%vmovaps\t{%1, %0|%0, %1}";
1944 return "%vmovdqa\t{%1, %0|%0, %1}";
1950 [(set_attr "type" "sselog1,ssemov,ssemov")
1951 (set_attr "prefix" "maybe_vex")
1953 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1954 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1956 (const_string "V4SF")
1957 (and (eq_attr "alternative" "2")
1958 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1960 (const_string "V4SF")]
1961 (const_string "TI")))])
1963 (define_insn "*movdi_internal_rex64"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1966 (match_operand:DI 1 "general_operand"
1967 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1968 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1970 switch (get_attr_type (insn))
1973 if (SSE_REG_P (operands[0]))
1974 return "movq2dq\t{%1, %0|%0, %1}";
1976 return "movdq2q\t{%1, %0|%0, %1}";
1981 if (get_attr_mode (insn) == MODE_TI)
1982 return "vmovdqa\t{%1, %0|%0, %1}";
1984 return "vmovq\t{%1, %0|%0, %1}";
1987 if (get_attr_mode (insn) == MODE_TI)
1988 return "movdqa\t{%1, %0|%0, %1}";
1992 /* Moves from and into integer register is done using movd
1993 opcode with REX prefix. */
1994 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1995 return "movd\t{%1, %0|%0, %1}";
1996 return "movq\t{%1, %0|%0, %1}";
1999 return "%vpxor\t%0, %d0";
2002 return "pxor\t%0, %0";
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2017 return "mov{q}\t{%1, %0|%0, %1}";
2021 (cond [(eq_attr "alternative" "5")
2022 (const_string "mmx")
2023 (eq_attr "alternative" "6,7,8,9,10")
2024 (const_string "mmxmov")
2025 (eq_attr "alternative" "11")
2026 (const_string "sselog1")
2027 (eq_attr "alternative" "12,13,14,15,16")
2028 (const_string "ssemov")
2029 (eq_attr "alternative" "17,18")
2030 (const_string "ssecvt")
2031 (eq_attr "alternative" "4")
2032 (const_string "multi")
2033 (match_operand:DI 1 "pic_32bit_operand" "")
2034 (const_string "lea")
2036 (const_string "imov")))
2039 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2041 (const_string "*")))
2042 (set (attr "length_immediate")
2044 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2046 (const_string "*")))
2047 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2048 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2049 (set (attr "prefix")
2050 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2051 (const_string "maybe_vex")
2052 (const_string "orig")))
2053 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2055 ;; Convert impossible stores of immediate to existing instructions.
2056 ;; First try to get scratch register and go through it. In case this
2057 ;; fails, move by 32bit parts.
2059 [(match_scratch:DI 2 "r")
2060 (set (match_operand:DI 0 "memory_operand" "")
2061 (match_operand:DI 1 "immediate_operand" ""))]
2062 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2063 && !x86_64_immediate_operand (operands[1], DImode)"
2064 [(set (match_dup 2) (match_dup 1))
2065 (set (match_dup 0) (match_dup 2))]
2068 ;; We need to define this as both peepholer and splitter for case
2069 ;; peephole2 pass is not run.
2070 ;; "&& 1" is needed to keep it from matching the previous pattern.
2072 [(set (match_operand:DI 0 "memory_operand" "")
2073 (match_operand:DI 1 "immediate_operand" ""))]
2074 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2075 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2076 [(set (match_dup 2) (match_dup 3))
2077 (set (match_dup 4) (match_dup 5))]
2078 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2081 [(set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2084 ? epilogue_completed : reload_completed)
2085 && !symbolic_operand (operands[1], DImode)
2086 && !x86_64_immediate_operand (operands[1], DImode)"
2087 [(set (match_dup 2) (match_dup 3))
2088 (set (match_dup 4) (match_dup 5))]
2089 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2091 (define_insn "*movdi_internal"
2092 [(set (match_operand:DI 0 "nonimmediate_operand"
2093 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2094 (match_operand:DI 1 "general_operand"
2095 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2096 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2101 movq\t{%1, %0|%0, %1}
2102 movq\t{%1, %0|%0, %1}
2104 %vmovq\t{%1, %0|%0, %1}
2105 %vmovdqa\t{%1, %0|%0, %1}
2106 %vmovq\t{%1, %0|%0, %1}
2108 movlps\t{%1, %0|%0, %1}
2109 movaps\t{%1, %0|%0, %1}
2110 movlps\t{%1, %0|%0, %1}"
2111 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2112 (set (attr "prefix")
2113 (if_then_else (eq_attr "alternative" "5,6,7,8")
2114 (const_string "vex")
2115 (const_string "orig")))
2116 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2119 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2120 (match_operand:DI 1 "general_operand" ""))]
2121 "!TARGET_64BIT && reload_completed
2122 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2123 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2125 "ix86_split_long_move (operands); DONE;")
2127 (define_insn "*movsi_internal"
2128 [(set (match_operand:SI 0 "nonimmediate_operand"
2129 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2130 (match_operand:SI 1 "general_operand"
2131 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2132 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2134 switch (get_attr_type (insn))
2137 if (get_attr_mode (insn) == MODE_TI)
2138 return "%vpxor\t%0, %d0";
2139 return "%vxorps\t%0, %d0";
2142 switch (get_attr_mode (insn))
2145 return "%vmovdqa\t{%1, %0|%0, %1}";
2147 return "%vmovaps\t{%1, %0|%0, %1}";
2149 return "%vmovd\t{%1, %0|%0, %1}";
2151 return "%vmovss\t{%1, %0|%0, %1}";
2157 return "pxor\t%0, %0";
2160 if (get_attr_mode (insn) == MODE_DI)
2161 return "movq\t{%1, %0|%0, %1}";
2162 return "movd\t{%1, %0|%0, %1}";
2165 return "lea{l}\t{%a1, %0|%0, %a1}";
2168 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169 return "mov{l}\t{%1, %0|%0, %1}";
2173 (cond [(eq_attr "alternative" "2")
2174 (const_string "mmx")
2175 (eq_attr "alternative" "3,4,5")
2176 (const_string "mmxmov")
2177 (eq_attr "alternative" "6")
2178 (const_string "sselog1")
2179 (eq_attr "alternative" "7,8,9,10,11")
2180 (const_string "ssemov")
2181 (match_operand:DI 1 "pic_32bit_operand" "")
2182 (const_string "lea")
2184 (const_string "imov")))
2185 (set (attr "prefix")
2186 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2187 (const_string "orig")
2188 (const_string "maybe_vex")))
2189 (set (attr "prefix_data16")
2190 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2192 (const_string "*")))
2194 (cond [(eq_attr "alternative" "2,3")
2196 (eq_attr "alternative" "6,7")
2198 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2199 (const_string "V4SF")
2200 (const_string "TI"))
2201 (and (eq_attr "alternative" "8,9,10,11")
2202 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2205 (const_string "SI")))])
2207 (define_insn "*movhi_internal"
2208 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2209 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2210 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2212 switch (get_attr_type (insn))
2215 /* movzwl is faster than movw on p2 due to partial word stalls,
2216 though not as fast as an aligned movl. */
2217 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2219 if (get_attr_mode (insn) == MODE_SI)
2220 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2222 return "mov{w}\t{%1, %0|%0, %1}";
2226 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2228 (const_string "imov")
2229 (and (eq_attr "alternative" "0")
2230 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2232 (eq (symbol_ref "TARGET_HIMODE_MATH")
2234 (const_string "imov")
2235 (and (eq_attr "alternative" "1,2")
2236 (match_operand:HI 1 "aligned_operand" ""))
2237 (const_string "imov")
2238 (and (ne (symbol_ref "TARGET_MOVX")
2240 (eq_attr "alternative" "0,2"))
2241 (const_string "imovx")
2243 (const_string "imov")))
2245 (cond [(eq_attr "type" "imovx")
2247 (and (eq_attr "alternative" "1,2")
2248 (match_operand:HI 1 "aligned_operand" ""))
2250 (and (eq_attr "alternative" "0")
2251 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2253 (eq (symbol_ref "TARGET_HIMODE_MATH")
2257 (const_string "HI")))])
2259 ;; Situation is quite tricky about when to choose full sized (SImode) move
2260 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2261 ;; partial register dependency machines (such as AMD Athlon), where QImode
2262 ;; moves issue extra dependency and for partial register stalls machines
2263 ;; that don't use QImode patterns (and QImode move cause stall on the next
2266 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2267 ;; register stall machines with, where we use QImode instructions, since
2268 ;; partial register stall can be caused there. Then we use movzx.
2269 (define_insn "*movqi_internal"
2270 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2271 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2272 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2274 switch (get_attr_type (insn))
2277 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2278 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2280 if (get_attr_mode (insn) == MODE_SI)
2281 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2283 return "mov{b}\t{%1, %0|%0, %1}";
2287 (cond [(and (eq_attr "alternative" "5")
2288 (not (match_operand:QI 1 "aligned_operand" "")))
2289 (const_string "imovx")
2290 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2292 (const_string "imov")
2293 (and (eq_attr "alternative" "3")
2294 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2296 (eq (symbol_ref "TARGET_QIMODE_MATH")
2298 (const_string "imov")
2299 (eq_attr "alternative" "3,5")
2300 (const_string "imovx")
2301 (and (ne (symbol_ref "TARGET_MOVX")
2303 (eq_attr "alternative" "2"))
2304 (const_string "imovx")
2306 (const_string "imov")))
2308 (cond [(eq_attr "alternative" "3,4,5")
2310 (eq_attr "alternative" "6")
2312 (eq_attr "type" "imovx")
2314 (and (eq_attr "type" "imov")
2315 (and (eq_attr "alternative" "0,1")
2316 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2318 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2320 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2323 ;; Avoid partial register stalls when not using QImode arithmetic
2324 (and (eq_attr "type" "imov")
2325 (and (eq_attr "alternative" "0,1")
2326 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2328 (eq (symbol_ref "TARGET_QIMODE_MATH")
2332 (const_string "QI")))])
2334 ;; Stores and loads of ax to arbitrary constant address.
2335 ;; We fake an second form of instruction to force reload to load address
2336 ;; into register when rax is not available
2337 (define_insn "*movabs<mode>_1"
2338 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2339 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2340 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2342 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2343 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2344 [(set_attr "type" "imov")
2345 (set_attr "modrm" "0,*")
2346 (set_attr "length_address" "8,0")
2347 (set_attr "length_immediate" "0,*")
2348 (set_attr "memory" "store")
2349 (set_attr "mode" "<MODE>")])
2351 (define_insn "*movabs<mode>_2"
2352 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2353 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2354 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2356 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2357 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2358 [(set_attr "type" "imov")
2359 (set_attr "modrm" "0,*")
2360 (set_attr "length_address" "8,0")
2361 (set_attr "length_immediate" "0")
2362 (set_attr "memory" "load")
2363 (set_attr "mode" "<MODE>")])
2365 (define_insn "*swap<mode>"
2366 [(set (match_operand:SWI48 0 "register_operand" "+r")
2367 (match_operand:SWI48 1 "register_operand" "+r"))
2371 "xchg{<imodesuffix>}\t%1, %0"
2372 [(set_attr "type" "imov")
2373 (set_attr "mode" "<MODE>")
2374 (set_attr "pent_pair" "np")
2375 (set_attr "athlon_decode" "vector")
2376 (set_attr "amdfam10_decode" "double")])
2378 (define_insn "*swap<mode>_1"
2379 [(set (match_operand:SWI12 0 "register_operand" "+r")
2380 (match_operand:SWI12 1 "register_operand" "+r"))
2383 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2385 [(set_attr "type" "imov")
2386 (set_attr "mode" "SI")
2387 (set_attr "pent_pair" "np")
2388 (set_attr "athlon_decode" "vector")
2389 (set_attr "amdfam10_decode" "double")])
2391 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2392 ;; is disabled for AMDFAM10
2393 (define_insn "*swap<mode>_2"
2394 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2395 (match_operand:SWI12 1 "register_operand" "+<r>"))
2398 "TARGET_PARTIAL_REG_STALL"
2399 "xchg{<imodesuffix>}\t%1, %0"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "<MODE>")
2402 (set_attr "pent_pair" "np")
2403 (set_attr "athlon_decode" "vector")])
2405 (define_expand "movstrict<mode>"
2406 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2407 (match_operand:SWI12 1 "general_operand" ""))]
2410 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2412 /* Don't generate memory->memory moves, go through a register */
2413 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2414 operands[1] = force_reg (<MODE>mode, operands[1]);
2417 (define_insn "*movstrict<mode>_1"
2418 [(set (strict_low_part
2419 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2420 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2421 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2423 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "<MODE>")])
2427 (define_insn "*movstrict<mode>_xor"
2428 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2429 (match_operand:SWI12 1 "const0_operand" ""))
2430 (clobber (reg:CC FLAGS_REG))]
2432 "xor{<imodesuffix>}\t%0, %0"
2433 [(set_attr "type" "alu1")
2434 (set_attr "mode" "<MODE>")
2435 (set_attr "length_immediate" "0")])
2437 (define_insn "*mov<mode>_extv_1"
2438 [(set (match_operand:SWI24 0 "register_operand" "=R")
2439 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2443 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2444 [(set_attr "type" "imovx")
2445 (set_attr "mode" "SI")])
2447 (define_insn "*movqi_extv_1_rex64"
2448 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2449 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2454 switch (get_attr_type (insn))
2457 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2459 return "mov{b}\t{%h1, %0|%0, %h1}";
2463 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2464 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2465 (ne (symbol_ref "TARGET_MOVX")
2467 (const_string "imovx")
2468 (const_string "imov")))
2470 (if_then_else (eq_attr "type" "imovx")
2472 (const_string "QI")))])
2474 (define_insn "*movqi_extv_1"
2475 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2476 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2481 switch (get_attr_type (insn))
2484 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2486 return "mov{b}\t{%h1, %0|%0, %h1}";
2490 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492 (ne (symbol_ref "TARGET_MOVX")
2494 (const_string "imovx")
2495 (const_string "imov")))
2497 (if_then_else (eq_attr "type" "imovx")
2499 (const_string "QI")))])
2501 (define_insn "*mov<mode>_extzv_1"
2502 [(set (match_operand:SWI48 0 "register_operand" "=R")
2503 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2507 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2508 [(set_attr "type" "imovx")
2509 (set_attr "mode" "SI")])
2511 (define_insn "*movqi_extzv_2_rex64"
2512 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2514 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2519 switch (get_attr_type (insn))
2522 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2528 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2529 (ne (symbol_ref "TARGET_MOVX")
2531 (const_string "imovx")
2532 (const_string "imov")))
2534 (if_then_else (eq_attr "type" "imovx")
2536 (const_string "QI")))])
2538 (define_insn "*movqi_extzv_2"
2539 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2556 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2557 (ne (symbol_ref "TARGET_MOVX")
2559 (const_string "imovx")
2560 (const_string "imov")))
2562 (if_then_else (eq_attr "type" "imovx")
2564 (const_string "QI")))])
2566 (define_expand "mov<mode>_insv_1"
2567 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2570 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2574 (define_insn "*mov<mode>_insv_1_rex64"
2575 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2578 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2580 "mov{b}\t{%b1, %h0|%h0, %b1}"
2581 [(set_attr "type" "imov")
2582 (set_attr "mode" "QI")])
2584 (define_insn "*movsi_insv_1"
2585 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2588 (match_operand:SI 1 "general_operand" "Qmn"))]
2590 "mov{b}\t{%b1, %h0|%h0, %b1}"
2591 [(set_attr "type" "imov")
2592 (set_attr "mode" "QI")])
2594 (define_insn "*movqi_insv_2"
2595 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2598 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2601 "mov{b}\t{%h1, %h0|%h0, %h1}"
2602 [(set_attr "type" "imov")
2603 (set_attr "mode" "QI")])
2605 ;; Floating point move instructions.
2607 (define_expand "movtf"
2608 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2609 (match_operand:TF 1 "nonimmediate_operand" ""))]
2612 ix86_expand_move (TFmode, operands);
2616 (define_expand "mov<mode>"
2617 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2618 (match_operand:X87MODEF 1 "general_operand" ""))]
2620 "ix86_expand_move (<MODE>mode, operands); DONE;")
2622 (define_insn "*pushtf"
2623 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2624 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2627 /* This insn should be already split before reg-stack. */
2630 [(set_attr "type" "multi")
2631 (set_attr "unit" "sse,*,*")
2632 (set_attr "mode" "TF,SI,SI")])
2635 [(set (match_operand:TF 0 "push_operand" "")
2636 (match_operand:TF 1 "general_operand" ""))]
2637 "TARGET_SSE2 && reload_completed
2638 && !SSE_REG_P (operands[1])"
2640 "ix86_split_long_move (operands); DONE;")
2643 [(set (match_operand:TF 0 "push_operand" "")
2644 (match_operand:TF 1 "any_fp_register_operand" ""))]
2646 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2647 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2650 (define_insn "*pushxf"
2651 [(set (match_operand:XF 0 "push_operand" "=<,<")
2652 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653 "optimize_function_for_speed_p (cfun)"
2655 /* This insn should be already split before reg-stack. */
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*")
2660 (set_attr "mode" "XF,SI")])
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2668 (define_insn "*pushxf_nointeger"
2669 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2671 "optimize_function_for_size_p (cfun)"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*,*")
2678 (set_attr "mode" "XF,SI,SI")])
2681 [(set (match_operand:XF 0 "push_operand" "")
2682 (match_operand:XF 1 "any_fp_register_operand" ""))]
2684 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2685 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2686 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2689 [(set (match_operand:XF 0 "push_operand" "")
2690 (match_operand:XF 1 "general_operand" ""))]
2692 && !ANY_FP_REG_P (operands[1])"
2694 "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*pushdf"
2697 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2698 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2699 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2701 /* This insn should be already split before reg-stack. */
2704 [(set_attr "type" "multi")
2705 (set_attr "unit" "i387,*,*")
2706 (set_attr "mode" "DF,SI,DF")])
2708 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2709 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2710 ;; On the average, pushdf using integers can be still shorter. Allow this
2711 ;; pattern for optimize_size too.
2713 (define_insn "*pushdf_nointeger"
2714 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2715 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2716 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2718 /* This insn should be already split before reg-stack. */
2721 [(set_attr "type" "multi")
2722 (set_attr "unit" "i387,*,*,*")
2723 (set_attr "mode" "DF,SI,SI,DF")])
2725 ;; %%% Kill this when call knows how to work this out.
2727 [(set (match_operand:DF 0 "push_operand" "")
2728 (match_operand:DF 1 "any_fp_register_operand" ""))]
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2731 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2735 [(set (match_operand:DF 0 "push_operand" "")
2736 (match_operand:DF 1 "general_operand" ""))]
2738 && !ANY_FP_REG_P (operands[1])"
2740 "ix86_split_long_move (operands); DONE;")
2742 (define_insn "*pushsf_rex64"
2743 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2744 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2747 /* Anything else should be already split before reg-stack. */
2748 gcc_assert (which_alternative == 1);
2749 return "push{q}\t%q1";
2751 [(set_attr "type" "multi,push,multi")
2752 (set_attr "unit" "i387,*,*")
2753 (set_attr "mode" "SF,DI,SF")])
2755 (define_insn "*pushsf"
2756 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2757 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2760 /* Anything else should be already split before reg-stack. */
2761 gcc_assert (which_alternative == 1);
2762 return "push{l}\t%1";
2764 [(set_attr "type" "multi,push,multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "SF,SI,SF")])
2769 [(set (match_operand:SF 0 "push_operand" "")
2770 (match_operand:SF 1 "memory_operand" ""))]
2772 && MEM_P (operands[1])
2773 && (operands[2] = find_constant_src (insn))"
2777 ;; %%% Kill this when call knows how to work this out.
2779 [(set (match_operand:SF 0 "push_operand" "")
2780 (match_operand:SF 1 "any_fp_register_operand" ""))]
2782 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2783 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2784 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2786 (define_insn "*movtf_internal"
2787 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2788 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2792 switch (which_alternative)
2796 if (get_attr_mode (insn) == MODE_V4SF)
2797 return "%vmovaps\t{%1, %0|%0, %1}";
2799 return "%vmovdqa\t{%1, %0|%0, %1}";
2801 if (get_attr_mode (insn) == MODE_V4SF)
2802 return "%vxorps\t%0, %d0";
2804 return "%vpxor\t%0, %d0";
2812 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2813 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2815 (cond [(eq_attr "alternative" "0,2")
2817 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2819 (const_string "V4SF")
2820 (const_string "TI"))
2821 (eq_attr "alternative" "1")
2823 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2825 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2827 (const_string "V4SF")
2828 (const_string "TI"))]
2829 (const_string "DI")))])
2832 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2833 (match_operand:TF 1 "general_operand" ""))]
2835 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2837 "ix86_split_long_move (operands); DONE;")
2839 (define_insn "*movxf_internal"
2840 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2841 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2842 "optimize_function_for_speed_p (cfun)
2843 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2844 && (reload_in_progress || reload_completed
2845 || GET_CODE (operands[1]) != CONST_DOUBLE
2846 || memory_operand (operands[0], XFmode))"
2848 switch (which_alternative)
2852 return output_387_reg_move (insn, operands);
2855 return standard_80387_constant_opcode (operands[1]);
2864 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2865 (set_attr "mode" "XF,XF,XF,SI,SI")])
2867 ;; Do not use integer registers when optimizing for size
2868 (define_insn "*movxf_internal_nointeger"
2869 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2870 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2871 "optimize_function_for_size_p (cfun)
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && (reload_in_progress || reload_completed
2874 || standard_80387_constant_p (operands[1])
2875 || GET_CODE (operands[1]) != CONST_DOUBLE
2876 || memory_operand (operands[0], XFmode))"
2878 switch (which_alternative)
2882 return output_387_reg_move (insn, operands);
2885 return standard_80387_constant_opcode (operands[1]);
2893 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2894 (set_attr "mode" "XF,XF,XF,SI,SI")])
2897 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2898 (match_operand:XF 1 "general_operand" ""))]
2900 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && ! (ANY_FP_REG_P (operands[0]) ||
2902 (GET_CODE (operands[0]) == SUBREG
2903 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2904 && ! (ANY_FP_REG_P (operands[1]) ||
2905 (GET_CODE (operands[1]) == SUBREG
2906 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2908 "ix86_split_long_move (operands); DONE;")
2910 (define_insn "*movdf_internal_rex64"
2911 [(set (match_operand:DF 0 "nonimmediate_operand"
2912 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2913 (match_operand:DF 1 "general_operand"
2914 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2915 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2916 && (reload_in_progress || reload_completed
2917 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2918 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2919 && optimize_function_for_size_p (cfun)
2920 && standard_80387_constant_p (operands[1]))
2921 || GET_CODE (operands[1]) != CONST_DOUBLE
2922 || memory_operand (operands[0], DFmode))"
2924 switch (which_alternative)
2928 return output_387_reg_move (insn, operands);
2931 return standard_80387_constant_opcode (operands[1]);
2938 switch (get_attr_mode (insn))
2941 return "%vxorps\t%0, %d0";
2943 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2944 return "%vxorps\t%0, %d0";
2946 return "%vxorpd\t%0, %d0";
2948 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2949 return "%vxorps\t%0, %d0";
2951 return "%vpxor\t%0, %d0";
2958 switch (get_attr_mode (insn))
2961 return "%vmovaps\t{%1, %0|%0, %1}";
2963 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2964 return "%vmovaps\t{%1, %0|%0, %1}";
2966 return "%vmovapd\t{%1, %0|%0, %1}";
2968 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2969 return "%vmovaps\t{%1, %0|%0, %1}";
2971 return "%vmovdqa\t{%1, %0|%0, %1}";
2973 return "%vmovq\t{%1, %0|%0, %1}";
2977 if (REG_P (operands[0]) && REG_P (operands[1]))
2978 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2980 return "vmovsd\t{%1, %0|%0, %1}";
2983 return "movsd\t{%1, %0|%0, %1}";
2985 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2987 return "%vmovlps\t{%1, %d0|%d0, %1}";
2994 return "%vmovd\t{%1, %0|%0, %1}";
3000 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3001 (set (attr "prefix")
3002 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3003 (const_string "orig")
3004 (const_string "maybe_vex")))
3005 (set (attr "prefix_data16")
3006 (if_then_else (eq_attr "mode" "V1DF")
3008 (const_string "*")))
3010 (cond [(eq_attr "alternative" "0,1,2")
3012 (eq_attr "alternative" "3,4,9,10")
3015 /* For SSE1, we have many fewer alternatives. */
3016 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3017 (cond [(eq_attr "alternative" "5,6")
3018 (const_string "V4SF")
3020 (const_string "V2SF"))
3022 /* xorps is one byte shorter. */
3023 (eq_attr "alternative" "5")
3024 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3026 (const_string "V4SF")
3027 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3031 (const_string "V2DF"))
3033 /* For architectures resolving dependencies on
3034 whole SSE registers use APD move to break dependency
3035 chains, otherwise use short move to avoid extra work.
3037 movaps encodes one byte shorter. */
3038 (eq_attr "alternative" "6")
3040 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3042 (const_string "V4SF")
3043 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3045 (const_string "V2DF")
3047 (const_string "DF"))
3048 /* For architectures resolving dependencies on register
3049 parts we may avoid extra work to zero out upper part
3051 (eq_attr "alternative" "7")
3053 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3055 (const_string "V1DF")
3056 (const_string "DF"))
3058 (const_string "DF")))])
3060 (define_insn "*movdf_internal"
3061 [(set (match_operand:DF 0 "nonimmediate_operand"
3062 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3063 (match_operand:DF 1 "general_operand"
3064 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3065 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3066 && optimize_function_for_speed_p (cfun)
3067 && TARGET_INTEGER_DFMODE_MOVES
3068 && (reload_in_progress || reload_completed
3069 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3070 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3071 && optimize_function_for_size_p (cfun)
3072 && standard_80387_constant_p (operands[1]))
3073 || GET_CODE (operands[1]) != CONST_DOUBLE
3074 || memory_operand (operands[0], DFmode))"
3076 switch (which_alternative)
3080 return output_387_reg_move (insn, operands);
3083 return standard_80387_constant_opcode (operands[1]);
3090 switch (get_attr_mode (insn))
3093 return "xorps\t%0, %0";
3095 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3096 return "xorps\t%0, %0";
3098 return "xorpd\t%0, %0";
3100 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3101 return "xorps\t%0, %0";
3103 return "pxor\t%0, %0";
3110 switch (get_attr_mode (insn))
3113 return "movaps\t{%1, %0|%0, %1}";
3115 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3116 return "movaps\t{%1, %0|%0, %1}";
3118 return "movapd\t{%1, %0|%0, %1}";
3120 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3121 return "movaps\t{%1, %0|%0, %1}";
3123 return "movdqa\t{%1, %0|%0, %1}";
3125 return "movq\t{%1, %0|%0, %1}";
3127 return "movsd\t{%1, %0|%0, %1}";
3129 return "movlpd\t{%1, %0|%0, %1}";
3131 return "movlps\t{%1, %0|%0, %1}";
3140 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3141 (set (attr "prefix_data16")
3142 (if_then_else (eq_attr "mode" "V1DF")
3144 (const_string "*")))
3146 (cond [(eq_attr "alternative" "0,1,2")
3148 (eq_attr "alternative" "3,4")
3151 /* For SSE1, we have many fewer alternatives. */
3152 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3153 (cond [(eq_attr "alternative" "5,6")
3154 (const_string "V4SF")
3156 (const_string "V2SF"))
3158 /* xorps is one byte shorter. */
3159 (eq_attr "alternative" "5")
3160 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162 (const_string "V4SF")
3163 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3167 (const_string "V2DF"))
3169 /* For architectures resolving dependencies on
3170 whole SSE registers use APD move to break dependency
3171 chains, otherwise use short move to avoid extra work.
3173 movaps encodes one byte shorter. */
3174 (eq_attr "alternative" "6")
3176 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3178 (const_string "V4SF")
3179 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3181 (const_string "V2DF")
3183 (const_string "DF"))
3184 /* For architectures resolving dependencies on register
3185 parts we may avoid extra work to zero out upper part
3187 (eq_attr "alternative" "7")
3189 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3191 (const_string "V1DF")
3192 (const_string "DF"))
3194 (const_string "DF")))])
3196 ;; Moving is usually shorter when only FP registers are used. This separate
3197 ;; movdf pattern avoids the use of integer registers for FP operations
3198 ;; when optimizing for size.
3200 (define_insn "*movdf_internal_nointeger"
3201 [(set (match_operand:DF 0 "nonimmediate_operand"
3202 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3203 (match_operand:DF 1 "general_operand"
3204 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3205 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206 && ((optimize_function_for_size_p (cfun)
3207 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3208 && (reload_in_progress || reload_completed
3209 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211 && optimize_function_for_size_p (cfun)
3212 && !memory_operand (operands[0], DFmode)
3213 && standard_80387_constant_p (operands[1]))
3214 || GET_CODE (operands[1]) != CONST_DOUBLE
3215 || ((optimize_function_for_size_p (cfun)
3216 || !TARGET_MEMORY_MISMATCH_STALL
3217 || reload_in_progress || reload_completed)
3218 && memory_operand (operands[0], DFmode)))"
3220 switch (which_alternative)
3224 return output_387_reg_move (insn, operands);
3227 return standard_80387_constant_opcode (operands[1]);
3233 switch (get_attr_mode (insn))
3236 return "%vxorps\t%0, %d0";
3238 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3239 return "%vxorps\t%0, %d0";
3241 return "%vxorpd\t%0, %d0";
3243 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3244 return "%vxorps\t%0, %d0";
3246 return "%vpxor\t%0, %d0";
3253 switch (get_attr_mode (insn))
3256 return "%vmovaps\t{%1, %0|%0, %1}";
3258 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3259 return "%vmovaps\t{%1, %0|%0, %1}";
3261 return "%vmovapd\t{%1, %0|%0, %1}";
3263 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3264 return "%vmovaps\t{%1, %0|%0, %1}";
3266 return "%vmovdqa\t{%1, %0|%0, %1}";
3268 return "%vmovq\t{%1, %0|%0, %1}";
3272 if (REG_P (operands[0]) && REG_P (operands[1]))
3273 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3275 return "vmovsd\t{%1, %0|%0, %1}";
3278 return "movsd\t{%1, %0|%0, %1}";
3282 if (REG_P (operands[0]))
3283 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3285 return "vmovlpd\t{%1, %0|%0, %1}";
3288 return "movlpd\t{%1, %0|%0, %1}";
3292 if (REG_P (operands[0]))
3293 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3295 return "vmovlps\t{%1, %0|%0, %1}";
3298 return "movlps\t{%1, %0|%0, %1}";
3307 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3308 (set (attr "prefix")
3309 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3310 (const_string "orig")
3311 (const_string "maybe_vex")))
3312 (set (attr "prefix_data16")
3313 (if_then_else (eq_attr "mode" "V1DF")
3315 (const_string "*")))
3317 (cond [(eq_attr "alternative" "0,1,2")
3319 (eq_attr "alternative" "3,4")
3322 /* For SSE1, we have many fewer alternatives. */
3323 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3324 (cond [(eq_attr "alternative" "5,6")
3325 (const_string "V4SF")
3327 (const_string "V2SF"))
3329 /* xorps is one byte shorter. */
3330 (eq_attr "alternative" "5")
3331 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3333 (const_string "V4SF")
3334 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3338 (const_string "V2DF"))
3340 /* For architectures resolving dependencies on
3341 whole SSE registers use APD move to break dependency
3342 chains, otherwise use short move to avoid extra work.
3344 movaps encodes one byte shorter. */
3345 (eq_attr "alternative" "6")
3347 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3349 (const_string "V4SF")
3350 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3352 (const_string "V2DF")
3354 (const_string "DF"))
3355 /* For architectures resolving dependencies on register
3356 parts we may avoid extra work to zero out upper part
3358 (eq_attr "alternative" "7")
3360 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3362 (const_string "V1DF")
3363 (const_string "DF"))
3365 (const_string "DF")))])
3368 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3369 (match_operand:DF 1 "general_operand" ""))]
3371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3372 && ! (ANY_FP_REG_P (operands[0]) ||
3373 (GET_CODE (operands[0]) == SUBREG
3374 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3375 && ! (ANY_FP_REG_P (operands[1]) ||
3376 (GET_CODE (operands[1]) == SUBREG
3377 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3379 "ix86_split_long_move (operands); DONE;")
3381 (define_insn "*movsf_internal"
3382 [(set (match_operand:SF 0 "nonimmediate_operand"
3383 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3384 (match_operand:SF 1 "general_operand"
3385 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3386 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3387 && (reload_in_progress || reload_completed
3388 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3389 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3390 && standard_80387_constant_p (operands[1]))
3391 || GET_CODE (operands[1]) != CONST_DOUBLE
3392 || memory_operand (operands[0], SFmode))"
3394 switch (which_alternative)
3398 return output_387_reg_move (insn, operands);
3401 return standard_80387_constant_opcode (operands[1]);
3405 return "mov{l}\t{%1, %0|%0, %1}";
3407 if (get_attr_mode (insn) == MODE_TI)
3408 return "%vpxor\t%0, %d0";
3410 return "%vxorps\t%0, %d0";
3412 if (get_attr_mode (insn) == MODE_V4SF)
3413 return "%vmovaps\t{%1, %0|%0, %1}";
3415 return "%vmovss\t{%1, %d0|%d0, %1}";
3418 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3419 : "vmovss\t{%1, %0|%0, %1}";
3421 return "movss\t{%1, %0|%0, %1}";
3423 return "%vmovss\t{%1, %0|%0, %1}";
3425 case 9: case 10: case 14: case 15:
3426 return "movd\t{%1, %0|%0, %1}";
3428 return "%vmovd\t{%1, %0|%0, %1}";
3431 return "movq\t{%1, %0|%0, %1}";
3437 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3438 (set (attr "prefix")
3439 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3440 (const_string "maybe_vex")
3441 (const_string "orig")))
3443 (cond [(eq_attr "alternative" "3,4,9,10")
3445 (eq_attr "alternative" "5")
3447 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3449 (ne (symbol_ref "TARGET_SSE2")
3451 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3454 (const_string "V4SF"))
3455 /* For architectures resolving dependencies on
3456 whole SSE registers use APS move to break dependency
3457 chains, otherwise use short move to avoid extra work.
3459 Do the same for architectures resolving dependencies on
3460 the parts. While in DF mode it is better to always handle
3461 just register parts, the SF mode is different due to lack
3462 of instructions to load just part of the register. It is
3463 better to maintain the whole registers in single format
3464 to avoid problems on using packed logical operations. */
3465 (eq_attr "alternative" "6")
3467 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3469 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3471 (const_string "V4SF")
3472 (const_string "SF"))
3473 (eq_attr "alternative" "11")
3474 (const_string "DI")]
3475 (const_string "SF")))])
3478 [(set (match_operand 0 "register_operand" "")
3479 (match_operand 1 "memory_operand" ""))]
3481 && MEM_P (operands[1])
3482 && (GET_MODE (operands[0]) == TFmode
3483 || GET_MODE (operands[0]) == XFmode
3484 || GET_MODE (operands[0]) == DFmode
3485 || GET_MODE (operands[0]) == SFmode)
3486 && (operands[2] = find_constant_src (insn))"
3487 [(set (match_dup 0) (match_dup 2))]
3489 rtx c = operands[2];
3490 rtx r = operands[0];
3492 if (GET_CODE (r) == SUBREG)
3497 if (!standard_sse_constant_p (c))
3500 else if (FP_REG_P (r))
3502 if (!standard_80387_constant_p (c))
3505 else if (MMX_REG_P (r))
3510 [(set (match_operand 0 "register_operand" "")
3511 (float_extend (match_operand 1 "memory_operand" "")))]
3513 && MEM_P (operands[1])
3514 && (GET_MODE (operands[0]) == TFmode
3515 || GET_MODE (operands[0]) == XFmode
3516 || GET_MODE (operands[0]) == DFmode
3517 || GET_MODE (operands[0]) == SFmode)
3518 && (operands[2] = find_constant_src (insn))"
3519 [(set (match_dup 0) (match_dup 2))]
3521 rtx c = operands[2];
3522 rtx r = operands[0];
3524 if (GET_CODE (r) == SUBREG)
3529 if (!standard_sse_constant_p (c))
3532 else if (FP_REG_P (r))
3534 if (!standard_80387_constant_p (c))
3537 else if (MMX_REG_P (r))
3541 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3543 [(set (match_operand:X87MODEF 0 "register_operand" "")
3544 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3545 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3546 && (standard_80387_constant_p (operands[1]) == 8
3547 || standard_80387_constant_p (operands[1]) == 9)"
3548 [(set (match_dup 0)(match_dup 1))
3550 (neg:X87MODEF (match_dup 0)))]
3554 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3555 if (real_isnegzero (&r))
3556 operands[1] = CONST0_RTX (<MODE>mode);
3558 operands[1] = CONST1_RTX (<MODE>mode);
3561 (define_insn "swapxf"
3562 [(set (match_operand:XF 0 "register_operand" "+f")
3563 (match_operand:XF 1 "register_operand" "+f"))
3568 if (STACK_TOP_P (operands[0]))
3573 [(set_attr "type" "fxch")
3574 (set_attr "mode" "XF")])
3576 (define_insn "*swap<mode>"
3577 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3578 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3581 "TARGET_80387 || reload_completed"
3583 if (STACK_TOP_P (operands[0]))
3588 [(set_attr "type" "fxch")
3589 (set_attr "mode" "<MODE>")])
3591 ;; Zero extension instructions
3593 (define_expand "zero_extendhisi2"
3594 [(set (match_operand:SI 0 "register_operand" "")
3595 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3598 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3600 operands[1] = force_reg (HImode, operands[1]);
3601 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3606 (define_insn "zero_extendhisi2_and"
3607 [(set (match_operand:SI 0 "register_operand" "=r")
3608 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3609 (clobber (reg:CC FLAGS_REG))]
3610 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3612 [(set_attr "type" "alu1")
3613 (set_attr "mode" "SI")])
3616 [(set (match_operand:SI 0 "register_operand" "")
3617 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3618 (clobber (reg:CC FLAGS_REG))]
3619 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3620 && optimize_function_for_speed_p (cfun)"
3621 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3622 (clobber (reg:CC FLAGS_REG))])]
3625 (define_insn "*zero_extendhisi2_movzwl"
3626 [(set (match_operand:SI 0 "register_operand" "=r")
3627 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3628 "!TARGET_ZERO_EXTEND_WITH_AND
3629 || optimize_function_for_size_p (cfun)"
3630 "movz{wl|x}\t{%1, %0|%0, %1}"
3631 [(set_attr "type" "imovx")
3632 (set_attr "mode" "SI")])
3634 (define_expand "zero_extendqihi2"
3636 [(set (match_operand:HI 0 "register_operand" "")
3637 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3638 (clobber (reg:CC FLAGS_REG))])]
3642 (define_insn "*zero_extendqihi2_and"
3643 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3644 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3645 (clobber (reg:CC FLAGS_REG))]
3646 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3648 [(set_attr "type" "alu1")
3649 (set_attr "mode" "HI")])
3651 (define_insn "*zero_extendqihi2_movzbw_and"
3652 [(set (match_operand:HI 0 "register_operand" "=r,r")
3653 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3654 (clobber (reg:CC FLAGS_REG))]
3655 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3657 [(set_attr "type" "imovx,alu1")
3658 (set_attr "mode" "HI")])
3660 ; zero extend to SImode here to avoid partial register stalls
3661 (define_insn "*zero_extendqihi2_movzbl"
3662 [(set (match_operand:HI 0 "register_operand" "=r")
3663 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3664 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3665 && reload_completed"
3666 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "SI")])
3670 ;; For the movzbw case strip only the clobber
3672 [(set (match_operand:HI 0 "register_operand" "")
3673 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))]
3676 && (!TARGET_ZERO_EXTEND_WITH_AND
3677 || optimize_function_for_size_p (cfun))
3678 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3679 [(set (match_operand:HI 0 "register_operand" "")
3680 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3682 ;; When source and destination does not overlap, clear destination
3683 ;; first and then do the movb
3685 [(set (match_operand:HI 0 "register_operand" "")
3686 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))]
3689 && ANY_QI_REG_P (operands[0])
3690 && (TARGET_ZERO_EXTEND_WITH_AND
3691 && optimize_function_for_speed_p (cfun))
3692 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3693 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3695 operands[2] = gen_lowpart (QImode, operands[0]);
3696 ix86_expand_clear (operands[0]);
3699 ;; Rest is handled by single and.
3701 [(set (match_operand:HI 0 "register_operand" "")
3702 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3703 (clobber (reg:CC FLAGS_REG))]
3705 && true_regnum (operands[0]) == true_regnum (operands[1])"
3706 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3707 (clobber (reg:CC FLAGS_REG))])]
3710 (define_expand "zero_extendqisi2"
3712 [(set (match_operand:SI 0 "register_operand" "")
3713 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3714 (clobber (reg:CC FLAGS_REG))])]
3718 (define_insn "*zero_extendqisi2_and"
3719 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3720 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3721 (clobber (reg:CC FLAGS_REG))]
3722 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3724 [(set_attr "type" "alu1")
3725 (set_attr "mode" "SI")])
3727 (define_insn "*zero_extendqisi2_movzbl_and"
3728 [(set (match_operand:SI 0 "register_operand" "=r,r")
3729 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3730 (clobber (reg:CC FLAGS_REG))]
3731 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3733 [(set_attr "type" "imovx,alu1")
3734 (set_attr "mode" "SI")])
3736 (define_insn "*zero_extendqisi2_movzbl"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3740 && reload_completed"
3741 "movz{bl|x}\t{%1, %0|%0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")])
3745 ;; For the movzbl case strip only the clobber
3747 [(set (match_operand:SI 0 "register_operand" "")
3748 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3749 (clobber (reg:CC FLAGS_REG))]
3751 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3752 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3754 (zero_extend:SI (match_dup 1)))])
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3759 [(set (match_operand:SI 0 "register_operand" "")
3760 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3761 (clobber (reg:CC FLAGS_REG))]
3763 && ANY_QI_REG_P (operands[0])
3764 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3765 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3766 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3769 operands[2] = gen_lowpart (QImode, operands[0]);
3770 ix86_expand_clear (operands[0]);
3773 ;; Rest is handled by single and.
3775 [(set (match_operand:SI 0 "register_operand" "")
3776 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3777 (clobber (reg:CC FLAGS_REG))]
3779 && true_regnum (operands[0]) == true_regnum (operands[1])"
3780 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3781 (clobber (reg:CC FLAGS_REG))])]
3784 ;; %%% Kill me once multi-word ops are sane.
3785 (define_expand "zero_extendsidi2"
3786 [(set (match_operand:DI 0 "register_operand" "")
3787 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3792 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3797 (define_insn "zero_extendsidi2_32"
3798 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3800 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3801 (clobber (reg:CC FLAGS_REG))]
3807 movd\t{%1, %0|%0, %1}
3808 movd\t{%1, %0|%0, %1}
3809 %vmovd\t{%1, %0|%0, %1}
3810 %vmovd\t{%1, %0|%0, %1}"
3811 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3812 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3813 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3815 (define_insn "zero_extendsidi2_rex64"
3816 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3818 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3821 mov\t{%k1, %k0|%k0, %k1}
3823 movd\t{%1, %0|%0, %1}
3824 movd\t{%1, %0|%0, %1}
3825 %vmovd\t{%1, %0|%0, %1}
3826 %vmovd\t{%1, %0|%0, %1}"
3827 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3828 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3829 (set_attr "prefix_0f" "0,*,*,*,*,*")
3830 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3833 [(set (match_operand:DI 0 "memory_operand" "")
3834 (zero_extend:DI (match_dup 0)))]
3836 [(set (match_dup 4) (const_int 0))]
3837 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3840 [(set (match_operand:DI 0 "register_operand" "")
3841 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3842 (clobber (reg:CC FLAGS_REG))]
3843 "!TARGET_64BIT && reload_completed
3844 && true_regnum (operands[0]) == true_regnum (operands[1])"
3845 [(set (match_dup 4) (const_int 0))]
3846 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3849 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3850 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3851 (clobber (reg:CC FLAGS_REG))]
3852 "!TARGET_64BIT && reload_completed
3853 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3854 [(set (match_dup 3) (match_dup 1))
3855 (set (match_dup 4) (const_int 0))]
3856 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3858 (define_insn "zero_extendhidi2"
3859 [(set (match_operand:DI 0 "register_operand" "=r")
3860 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3862 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3863 [(set_attr "type" "imovx")
3864 (set_attr "mode" "SI")])
3866 (define_insn "zero_extendqidi2"
3867 [(set (match_operand:DI 0 "register_operand" "=r")
3868 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3870 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3871 [(set_attr "type" "imovx")
3872 (set_attr "mode" "SI")])
3874 ;; Sign extension instructions
3876 (define_expand "extendsidi2"
3877 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3878 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3879 (clobber (reg:CC FLAGS_REG))
3880 (clobber (match_scratch:SI 2 ""))])]
3885 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3890 (define_insn "*extendsidi2_1"
3891 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3892 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3893 (clobber (reg:CC FLAGS_REG))
3894 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3898 (define_insn "extendsidi2_rex64"
3899 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3900 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3904 movs{lq|x}\t{%1, %0|%0, %1}"
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "DI")
3907 (set_attr "prefix_0f" "0")
3908 (set_attr "modrm" "0,1")])
3910 (define_insn "extendhidi2"
3911 [(set (match_operand:DI 0 "register_operand" "=r")
3912 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3914 "movs{wq|x}\t{%1, %0|%0, %1}"
3915 [(set_attr "type" "imovx")
3916 (set_attr "mode" "DI")])
3918 (define_insn "extendqidi2"
3919 [(set (match_operand:DI 0 "register_operand" "=r")
3920 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3922 "movs{bq|x}\t{%1, %0|%0, %1}"
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "DI")])
3926 ;; Extend to memory case when source register does die.
3928 [(set (match_operand:DI 0 "memory_operand" "")
3929 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3930 (clobber (reg:CC FLAGS_REG))
3931 (clobber (match_operand:SI 2 "register_operand" ""))]
3933 && dead_or_set_p (insn, operands[1])
3934 && !reg_mentioned_p (operands[1], operands[0]))"
3935 [(set (match_dup 3) (match_dup 1))
3936 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3937 (clobber (reg:CC FLAGS_REG))])
3938 (set (match_dup 4) (match_dup 1))]
3939 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3941 ;; Extend to memory case when source register does not die.
3943 [(set (match_operand:DI 0 "memory_operand" "")
3944 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3945 (clobber (reg:CC FLAGS_REG))
3946 (clobber (match_operand:SI 2 "register_operand" ""))]
3950 split_di (&operands[0], 1, &operands[3], &operands[4]);
3952 emit_move_insn (operands[3], operands[1]);
3954 /* Generate a cltd if possible and doing so it profitable. */
3955 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3956 && true_regnum (operands[1]) == AX_REG
3957 && true_regnum (operands[2]) == DX_REG)
3959 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3963 emit_move_insn (operands[2], operands[1]);
3964 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3966 emit_move_insn (operands[4], operands[2]);
3970 ;; Extend to register case. Optimize case where source and destination
3971 ;; registers match and cases where we can use cltd.
3973 [(set (match_operand:DI 0 "register_operand" "")
3974 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3975 (clobber (reg:CC FLAGS_REG))
3976 (clobber (match_scratch:SI 2 ""))]
3980 split_di (&operands[0], 1, &operands[3], &operands[4]);
3982 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3983 emit_move_insn (operands[3], operands[1]);
3985 /* Generate a cltd if possible and doing so it profitable. */
3986 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3987 && true_regnum (operands[3]) == AX_REG
3988 && true_regnum (operands[4]) == DX_REG)
3990 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3994 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3995 emit_move_insn (operands[4], operands[1]);
3997 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4001 (define_insn "extendhisi2"
4002 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4003 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4006 switch (get_attr_prefix_0f (insn))
4009 return "{cwtl|cwde}";
4011 return "movs{wl|x}\t{%1, %0|%0, %1}";
4014 [(set_attr "type" "imovx")
4015 (set_attr "mode" "SI")
4016 (set (attr "prefix_0f")
4017 ;; movsx is short decodable while cwtl is vector decoded.
4018 (if_then_else (and (eq_attr "cpu" "!k6")
4019 (eq_attr "alternative" "0"))
4021 (const_string "1")))
4023 (if_then_else (eq_attr "prefix_0f" "0")
4025 (const_string "1")))])
4027 (define_insn "*extendhisi2_zext"
4028 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4030 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4033 switch (get_attr_prefix_0f (insn))
4036 return "{cwtl|cwde}";
4038 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4041 [(set_attr "type" "imovx")
4042 (set_attr "mode" "SI")
4043 (set (attr "prefix_0f")
4044 ;; movsx is short decodable while cwtl is vector decoded.
4045 (if_then_else (and (eq_attr "cpu" "!k6")
4046 (eq_attr "alternative" "0"))
4048 (const_string "1")))
4050 (if_then_else (eq_attr "prefix_0f" "0")
4052 (const_string "1")))])
4054 (define_insn "extendqihi2"
4055 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4056 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4059 switch (get_attr_prefix_0f (insn))
4062 return "{cbtw|cbw}";
4064 return "movs{bw|x}\t{%1, %0|%0, %1}";
4067 [(set_attr "type" "imovx")
4068 (set_attr "mode" "HI")
4069 (set (attr "prefix_0f")
4070 ;; movsx is short decodable while cwtl is vector decoded.
4071 (if_then_else (and (eq_attr "cpu" "!k6")
4072 (eq_attr "alternative" "0"))
4074 (const_string "1")))
4076 (if_then_else (eq_attr "prefix_0f" "0")
4078 (const_string "1")))])
4080 (define_insn "extendqisi2"
4081 [(set (match_operand:SI 0 "register_operand" "=r")
4082 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4084 "movs{bl|x}\t{%1, %0|%0, %1}"
4085 [(set_attr "type" "imovx")
4086 (set_attr "mode" "SI")])
4088 (define_insn "*extendqisi2_zext"
4089 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4093 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4094 [(set_attr "type" "imovx")
4095 (set_attr "mode" "SI")])
4097 ;; Conversions between float and double.
4099 ;; These are all no-ops in the model used for the 80387. So just
4102 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4103 (define_insn "*dummy_extendsfdf2"
4104 [(set (match_operand:DF 0 "push_operand" "=<")
4105 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4110 [(set (match_operand:DF 0 "push_operand" "")
4111 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4113 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4114 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4116 (define_insn "*dummy_extendsfxf2"
4117 [(set (match_operand:XF 0 "push_operand" "=<")
4118 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4123 [(set (match_operand:XF 0 "push_operand" "")
4124 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4126 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4127 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4128 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4131 [(set (match_operand:XF 0 "push_operand" "")
4132 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4134 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4135 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4136 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4138 (define_expand "extendsfdf2"
4139 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4140 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4141 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4143 /* ??? Needed for compress_float_constant since all fp constants
4144 are LEGITIMATE_CONSTANT_P. */
4145 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4147 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4148 && standard_80387_constant_p (operands[1]) > 0)
4150 operands[1] = simplify_const_unary_operation
4151 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4152 emit_move_insn_1 (operands[0], operands[1]);
4155 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4159 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4161 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4163 We do the conversion post reload to avoid producing of 128bit spills
4164 that might lead to ICE on 32bit target. The sequence unlikely combine
4167 [(set (match_operand:DF 0 "register_operand" "")
4169 (match_operand:SF 1 "nonimmediate_operand" "")))]
4170 "TARGET_USE_VECTOR_FP_CONVERTS
4171 && optimize_insn_for_speed_p ()
4172 && reload_completed && SSE_REG_P (operands[0])"
4177 (parallel [(const_int 0) (const_int 1)]))))]
4179 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4180 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4181 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4182 Try to avoid move when unpacking can be done in source. */
4183 if (REG_P (operands[1]))
4185 /* If it is unsafe to overwrite upper half of source, we need
4186 to move to destination and unpack there. */
4187 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4188 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4189 && true_regnum (operands[0]) != true_regnum (operands[1]))
4191 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4192 emit_move_insn (tmp, operands[1]);
4195 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4196 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4200 emit_insn (gen_vec_setv4sf_0 (operands[3],
4201 CONST0_RTX (V4SFmode), operands[1]));
4204 (define_insn "*extendsfdf2_mixed"
4205 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4207 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4208 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4210 switch (which_alternative)
4214 return output_387_reg_move (insn, operands);
4217 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4223 [(set_attr "type" "fmov,fmov,ssecvt")
4224 (set_attr "prefix" "orig,orig,maybe_vex")
4225 (set_attr "mode" "SF,XF,DF")])
4227 (define_insn "*extendsfdf2_sse"
4228 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4229 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4230 "TARGET_SSE2 && TARGET_SSE_MATH"
4231 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4232 [(set_attr "type" "ssecvt")
4233 (set_attr "prefix" "maybe_vex")
4234 (set_attr "mode" "DF")])
4236 (define_insn "*extendsfdf2_i387"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4238 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4240 "* return output_387_reg_move (insn, operands);"
4241 [(set_attr "type" "fmov")
4242 (set_attr "mode" "SF,XF")])
4244 (define_expand "extend<mode>xf2"
4245 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4246 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4249 /* ??? Needed for compress_float_constant since all fp constants
4250 are LEGITIMATE_CONSTANT_P. */
4251 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4253 if (standard_80387_constant_p (operands[1]) > 0)
4255 operands[1] = simplify_const_unary_operation
4256 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4257 emit_move_insn_1 (operands[0], operands[1]);
4260 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4264 (define_insn "*extend<mode>xf2_i387"
4265 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4267 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4269 "* return output_387_reg_move (insn, operands);"
4270 [(set_attr "type" "fmov")
4271 (set_attr "mode" "<MODE>,XF")])
4273 ;; %%% This seems bad bad news.
4274 ;; This cannot output into an f-reg because there is no way to be sure
4275 ;; of truncating in that case. Otherwise this is just like a simple move
4276 ;; insn. So we pretend we can output to a reg in order to get better
4277 ;; register preferencing, but we really use a stack slot.
4279 ;; Conversion from DFmode to SFmode.
4281 (define_expand "truncdfsf2"
4282 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4284 (match_operand:DF 1 "nonimmediate_operand" "")))]
4285 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4287 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4289 else if (flag_unsafe_math_optimizations)
4293 enum ix86_stack_slot slot = (virtuals_instantiated
4296 rtx temp = assign_386_stack_local (SFmode, slot);
4297 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4302 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4304 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4306 We do the conversion post reload to avoid producing of 128bit spills
4307 that might lead to ICE on 32bit target. The sequence unlikely combine
4310 [(set (match_operand:SF 0 "register_operand" "")
4312 (match_operand:DF 1 "nonimmediate_operand" "")))]
4313 "TARGET_USE_VECTOR_FP_CONVERTS
4314 && optimize_insn_for_speed_p ()
4315 && reload_completed && SSE_REG_P (operands[0])"
4318 (float_truncate:V2SF
4322 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4323 operands[3] = CONST0_RTX (V2SFmode);
4324 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4325 /* Use movsd for loading from memory, unpcklpd for registers.
4326 Try to avoid move when unpacking can be done in source, or SSE3
4327 movddup is available. */
4328 if (REG_P (operands[1]))
4331 && true_regnum (operands[0]) != true_regnum (operands[1])
4332 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4333 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4335 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4336 emit_move_insn (tmp, operands[1]);
4339 else if (!TARGET_SSE3)
4340 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4341 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4344 emit_insn (gen_sse2_loadlpd (operands[4],
4345 CONST0_RTX (V2DFmode), operands[1]));
4348 (define_expand "truncdfsf2_with_temp"
4349 [(parallel [(set (match_operand:SF 0 "" "")
4350 (float_truncate:SF (match_operand:DF 1 "" "")))
4351 (clobber (match_operand:SF 2 "" ""))])]
4354 (define_insn "*truncdfsf_fast_mixed"
4355 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4357 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4358 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4360 switch (which_alternative)
4363 return output_387_reg_move (insn, operands);
4365 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4370 [(set_attr "type" "fmov,ssecvt")
4371 (set_attr "prefix" "orig,maybe_vex")
4372 (set_attr "mode" "SF")])
4374 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4375 ;; because nothing we do here is unsafe.
4376 (define_insn "*truncdfsf_fast_sse"
4377 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4379 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4380 "TARGET_SSE2 && TARGET_SSE_MATH"
4381 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4382 [(set_attr "type" "ssecvt")
4383 (set_attr "prefix" "maybe_vex")
4384 (set_attr "mode" "SF")])
4386 (define_insn "*truncdfsf_fast_i387"
4387 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4389 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4390 "TARGET_80387 && flag_unsafe_math_optimizations"
4391 "* return output_387_reg_move (insn, operands);"
4392 [(set_attr "type" "fmov")
4393 (set_attr "mode" "SF")])
4395 (define_insn "*truncdfsf_mixed"
4396 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4398 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4399 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4400 "TARGET_MIX_SSE_I387"
4402 switch (which_alternative)
4405 return output_387_reg_move (insn, operands);
4407 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4413 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4414 (set_attr "unit" "*,*,i387,i387,i387")
4415 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4416 (set_attr "mode" "SF")])
4418 (define_insn "*truncdfsf_i387"
4419 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4421 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4422 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4425 switch (which_alternative)
4428 return output_387_reg_move (insn, operands);
4434 [(set_attr "type" "fmov,multi,multi,multi")
4435 (set_attr "unit" "*,i387,i387,i387")
4436 (set_attr "mode" "SF")])
4438 (define_insn "*truncdfsf2_i387_1"
4439 [(set (match_operand:SF 0 "memory_operand" "=m")
4441 (match_operand:DF 1 "register_operand" "f")))]
4443 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4444 && !TARGET_MIX_SSE_I387"
4445 "* return output_387_reg_move (insn, operands);"
4446 [(set_attr "type" "fmov")
4447 (set_attr "mode" "SF")])
4450 [(set (match_operand:SF 0 "register_operand" "")
4452 (match_operand:DF 1 "fp_register_operand" "")))
4453 (clobber (match_operand 2 "" ""))]
4455 [(set (match_dup 2) (match_dup 1))
4456 (set (match_dup 0) (match_dup 2))]
4458 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4461 ;; Conversion from XFmode to {SF,DF}mode
4463 (define_expand "truncxf<mode>2"
4464 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4465 (float_truncate:MODEF
4466 (match_operand:XF 1 "register_operand" "")))
4467 (clobber (match_dup 2))])]
4470 if (flag_unsafe_math_optimizations)
4472 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4473 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4474 if (reg != operands[0])
4475 emit_move_insn (operands[0], reg);
4480 enum ix86_stack_slot slot = (virtuals_instantiated
4483 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4487 (define_insn "*truncxfsf2_mixed"
4488 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4490 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4491 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4494 gcc_assert (!which_alternative);
4495 return output_387_reg_move (insn, operands);
4497 [(set_attr "type" "fmov,multi,multi,multi")
4498 (set_attr "unit" "*,i387,i387,i387")
4499 (set_attr "mode" "SF")])
4501 (define_insn "*truncxfdf2_mixed"
4502 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4504 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4505 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4508 gcc_assert (!which_alternative);
4509 return output_387_reg_move (insn, operands);
4511 [(set_attr "type" "fmov,multi,multi,multi")
4512 (set_attr "unit" "*,i387,i387,i387")
4513 (set_attr "mode" "DF")])
4515 (define_insn "truncxf<mode>2_i387_noop"
4516 [(set (match_operand:MODEF 0 "register_operand" "=f")
4517 (float_truncate:MODEF
4518 (match_operand:XF 1 "register_operand" "f")))]
4519 "TARGET_80387 && flag_unsafe_math_optimizations"
4520 "* return output_387_reg_move (insn, operands);"
4521 [(set_attr "type" "fmov")
4522 (set_attr "mode" "<MODE>")])
4524 (define_insn "*truncxf<mode>2_i387"
4525 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4526 (float_truncate:MODEF
4527 (match_operand:XF 1 "register_operand" "f")))]
4529 "* return output_387_reg_move (insn, operands);"
4530 [(set_attr "type" "fmov")
4531 (set_attr "mode" "<MODE>")])
4534 [(set (match_operand:MODEF 0 "register_operand" "")
4535 (float_truncate:MODEF
4536 (match_operand:XF 1 "register_operand" "")))
4537 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4538 "TARGET_80387 && reload_completed"
4539 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4540 (set (match_dup 0) (match_dup 2))]
4544 [(set (match_operand:MODEF 0 "memory_operand" "")
4545 (float_truncate:MODEF
4546 (match_operand:XF 1 "register_operand" "")))
4547 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4549 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4552 ;; Signed conversion to DImode.
4554 (define_expand "fix_truncxfdi2"
4555 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4556 (fix:DI (match_operand:XF 1 "register_operand" "")))
4557 (clobber (reg:CC FLAGS_REG))])]
4562 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4567 (define_expand "fix_trunc<mode>di2"
4568 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4569 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4570 (clobber (reg:CC FLAGS_REG))])]
4571 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4574 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4576 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4579 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4581 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4582 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4583 if (out != operands[0])
4584 emit_move_insn (operands[0], out);
4589 ;; Signed conversion to SImode.
4591 (define_expand "fix_truncxfsi2"
4592 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4593 (fix:SI (match_operand:XF 1 "register_operand" "")))
4594 (clobber (reg:CC FLAGS_REG))])]
4599 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4604 (define_expand "fix_trunc<mode>si2"
4605 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4606 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4607 (clobber (reg:CC FLAGS_REG))])]
4608 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4611 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4613 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4616 if (SSE_FLOAT_MODE_P (<MODE>mode))
4618 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4619 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4620 if (out != operands[0])
4621 emit_move_insn (operands[0], out);
4626 ;; Signed conversion to HImode.
4628 (define_expand "fix_trunc<mode>hi2"
4629 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4630 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4631 (clobber (reg:CC FLAGS_REG))])]
4633 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4637 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4642 ;; Unsigned conversion to SImode.
4644 (define_expand "fixuns_trunc<mode>si2"
4646 [(set (match_operand:SI 0 "register_operand" "")
4648 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4650 (clobber (match_scratch:<ssevecmode> 3 ""))
4651 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4652 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4654 enum machine_mode mode = <MODE>mode;
4655 enum machine_mode vecmode = <ssevecmode>mode;
4656 REAL_VALUE_TYPE TWO31r;
4659 if (optimize_insn_for_size_p ())
4662 real_ldexp (&TWO31r, &dconst1, 31);
4663 two31 = const_double_from_real_value (TWO31r, mode);
4664 two31 = ix86_build_const_vector (mode, true, two31);
4665 operands[2] = force_reg (vecmode, two31);
4668 (define_insn_and_split "*fixuns_trunc<mode>_1"
4669 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4671 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4672 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4673 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4674 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4675 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4676 && optimize_function_for_speed_p (cfun)"
4678 "&& reload_completed"
4681 ix86_split_convert_uns_si_sse (operands);
4685 ;; Unsigned conversion to HImode.
4686 ;; Without these patterns, we'll try the unsigned SI conversion which
4687 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4689 (define_expand "fixuns_trunc<mode>hi2"
4691 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4692 (set (match_operand:HI 0 "nonimmediate_operand" "")
4693 (subreg:HI (match_dup 2) 0))]
4694 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4695 "operands[2] = gen_reg_rtx (SImode);")
4697 ;; When SSE is available, it is always faster to use it!
4698 (define_insn "fix_trunc<mode>di_sse"
4699 [(set (match_operand:DI 0 "register_operand" "=r,r")
4700 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4701 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4702 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4703 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4704 [(set_attr "type" "sseicvt")
4705 (set_attr "prefix" "maybe_vex")
4706 (set_attr "prefix_rex" "1")
4707 (set_attr "mode" "<MODE>")
4708 (set_attr "athlon_decode" "double,vector")
4709 (set_attr "amdfam10_decode" "double,double")])
4711 (define_insn "fix_trunc<mode>si_sse"
4712 [(set (match_operand:SI 0 "register_operand" "=r,r")
4713 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4714 "SSE_FLOAT_MODE_P (<MODE>mode)
4715 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4716 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4717 [(set_attr "type" "sseicvt")
4718 (set_attr "prefix" "maybe_vex")
4719 (set_attr "mode" "<MODE>")
4720 (set_attr "athlon_decode" "double,vector")
4721 (set_attr "amdfam10_decode" "double,double")])
4723 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4725 [(set (match_operand:MODEF 0 "register_operand" "")
4726 (match_operand:MODEF 1 "memory_operand" ""))
4727 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4728 (fix:SSEMODEI24 (match_dup 0)))]
4729 "TARGET_SHORTEN_X87_SSE
4730 && peep2_reg_dead_p (2, operands[0])"
4731 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4734 ;; Avoid vector decoded forms of the instruction.
4736 [(match_scratch:DF 2 "Y2")
4737 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4738 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4739 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4740 [(set (match_dup 2) (match_dup 1))
4741 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4745 [(match_scratch:SF 2 "x")
4746 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4747 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4748 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4749 [(set (match_dup 2) (match_dup 1))
4750 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4753 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4754 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4755 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4756 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4758 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4759 && (TARGET_64BIT || <MODE>mode != DImode))
4761 && can_create_pseudo_p ()"
4766 if (memory_operand (operands[0], VOIDmode))
4767 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4770 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4771 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4777 [(set_attr "type" "fisttp")
4778 (set_attr "mode" "<MODE>")])
4780 (define_insn "fix_trunc<mode>_i387_fisttp"
4781 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4782 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4783 (clobber (match_scratch:XF 2 "=&1f"))]
4784 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4786 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && (TARGET_64BIT || <MODE>mode != DImode))
4788 && TARGET_SSE_MATH)"
4789 "* return output_fix_trunc (insn, operands, 1);"
4790 [(set_attr "type" "fisttp")
4791 (set_attr "mode" "<MODE>")])
4793 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4794 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4795 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4796 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4797 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4798 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4800 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4801 && (TARGET_64BIT || <MODE>mode != DImode))
4802 && TARGET_SSE_MATH)"
4804 [(set_attr "type" "fisttp")
4805 (set_attr "mode" "<MODE>")])
4808 [(set (match_operand:X87MODEI 0 "register_operand" "")
4809 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4810 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4811 (clobber (match_scratch 3 ""))]
4813 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4814 (clobber (match_dup 3))])
4815 (set (match_dup 0) (match_dup 2))]
4819 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4820 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4821 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4822 (clobber (match_scratch 3 ""))]
4824 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4825 (clobber (match_dup 3))])]
4828 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4829 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4830 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4831 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4832 ;; function in i386.c.
4833 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4834 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4835 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4836 (clobber (reg:CC FLAGS_REG))]
4837 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4839 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4840 && (TARGET_64BIT || <MODE>mode != DImode))
4841 && can_create_pseudo_p ()"
4846 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4848 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4849 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4850 if (memory_operand (operands[0], VOIDmode))
4851 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4852 operands[2], operands[3]));
4855 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4856 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4857 operands[2], operands[3],
4862 [(set_attr "type" "fistp")
4863 (set_attr "i387_cw" "trunc")
4864 (set_attr "mode" "<MODE>")])
4866 (define_insn "fix_truncdi_i387"
4867 [(set (match_operand:DI 0 "memory_operand" "=m")
4868 (fix:DI (match_operand 1 "register_operand" "f")))
4869 (use (match_operand:HI 2 "memory_operand" "m"))
4870 (use (match_operand:HI 3 "memory_operand" "m"))
4871 (clobber (match_scratch:XF 4 "=&1f"))]
4872 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4874 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4875 "* return output_fix_trunc (insn, operands, 0);"
4876 [(set_attr "type" "fistp")
4877 (set_attr "i387_cw" "trunc")
4878 (set_attr "mode" "DI")])
4880 (define_insn "fix_truncdi_i387_with_temp"
4881 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4882 (fix:DI (match_operand 1 "register_operand" "f,f")))
4883 (use (match_operand:HI 2 "memory_operand" "m,m"))
4884 (use (match_operand:HI 3 "memory_operand" "m,m"))
4885 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4886 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4887 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4889 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4891 [(set_attr "type" "fistp")
4892 (set_attr "i387_cw" "trunc")
4893 (set_attr "mode" "DI")])
4896 [(set (match_operand:DI 0 "register_operand" "")
4897 (fix:DI (match_operand 1 "register_operand" "")))
4898 (use (match_operand:HI 2 "memory_operand" ""))
4899 (use (match_operand:HI 3 "memory_operand" ""))
4900 (clobber (match_operand:DI 4 "memory_operand" ""))
4901 (clobber (match_scratch 5 ""))]
4903 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4906 (clobber (match_dup 5))])
4907 (set (match_dup 0) (match_dup 4))]
4911 [(set (match_operand:DI 0 "memory_operand" "")
4912 (fix:DI (match_operand 1 "register_operand" "")))
4913 (use (match_operand:HI 2 "memory_operand" ""))
4914 (use (match_operand:HI 3 "memory_operand" ""))
4915 (clobber (match_operand:DI 4 "memory_operand" ""))
4916 (clobber (match_scratch 5 ""))]
4918 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4921 (clobber (match_dup 5))])]
4924 (define_insn "fix_trunc<mode>_i387"
4925 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4926 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4927 (use (match_operand:HI 2 "memory_operand" "m"))
4928 (use (match_operand:HI 3 "memory_operand" "m"))]
4929 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4931 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4932 "* return output_fix_trunc (insn, operands, 0);"
4933 [(set_attr "type" "fistp")
4934 (set_attr "i387_cw" "trunc")
4935 (set_attr "mode" "<MODE>")])
4937 (define_insn "fix_trunc<mode>_i387_with_temp"
4938 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4939 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4940 (use (match_operand:HI 2 "memory_operand" "m,m"))
4941 (use (match_operand:HI 3 "memory_operand" "m,m"))
4942 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4943 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4945 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4947 [(set_attr "type" "fistp")
4948 (set_attr "i387_cw" "trunc")
4949 (set_attr "mode" "<MODE>")])
4952 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4953 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4954 (use (match_operand:HI 2 "memory_operand" ""))
4955 (use (match_operand:HI 3 "memory_operand" ""))
4956 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4958 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4960 (use (match_dup 3))])
4961 (set (match_dup 0) (match_dup 4))]
4965 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4966 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4967 (use (match_operand:HI 2 "memory_operand" ""))
4968 (use (match_operand:HI 3 "memory_operand" ""))
4969 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4971 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4973 (use (match_dup 3))])]
4976 (define_insn "x86_fnstcw_1"
4977 [(set (match_operand:HI 0 "memory_operand" "=m")
4978 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4981 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4982 (set_attr "mode" "HI")
4983 (set_attr "unit" "i387")])
4985 (define_insn "x86_fldcw_1"
4986 [(set (reg:HI FPCR_REG)
4987 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4990 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4991 (set_attr "mode" "HI")
4992 (set_attr "unit" "i387")
4993 (set_attr "athlon_decode" "vector")
4994 (set_attr "amdfam10_decode" "vector")])
4996 ;; Conversion between fixed point and floating point.
4998 ;; Even though we only accept memory inputs, the backend _really_
4999 ;; wants to be able to do this between registers.
5001 (define_expand "floathi<mode>2"
5002 [(set (match_operand:X87MODEF 0 "register_operand" "")
5003 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5006 || TARGET_MIX_SSE_I387)"
5009 ;; Pre-reload splitter to add memory clobber to the pattern.
5010 (define_insn_and_split "*floathi<mode>2_1"
5011 [(set (match_operand:X87MODEF 0 "register_operand" "")
5012 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5015 || TARGET_MIX_SSE_I387)
5016 && can_create_pseudo_p ()"
5019 [(parallel [(set (match_dup 0)
5020 (float:X87MODEF (match_dup 1)))
5021 (clobber (match_dup 2))])]
5022 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5024 (define_insn "*floathi<mode>2_i387_with_temp"
5025 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5026 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5027 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5030 || TARGET_MIX_SSE_I387)"
5032 [(set_attr "type" "fmov,multi")
5033 (set_attr "mode" "<MODE>")
5034 (set_attr "unit" "*,i387")
5035 (set_attr "fp_int_src" "true")])
5037 (define_insn "*floathi<mode>2_i387"
5038 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5039 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5042 || TARGET_MIX_SSE_I387)"
5044 [(set_attr "type" "fmov")
5045 (set_attr "mode" "<MODE>")
5046 (set_attr "fp_int_src" "true")])
5049 [(set (match_operand:X87MODEF 0 "register_operand" "")
5050 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5051 (clobber (match_operand:HI 2 "memory_operand" ""))]
5053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5054 || TARGET_MIX_SSE_I387)
5055 && reload_completed"
5056 [(set (match_dup 2) (match_dup 1))
5057 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5061 [(set (match_operand:X87MODEF 0 "register_operand" "")
5062 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5063 (clobber (match_operand:HI 2 "memory_operand" ""))]
5065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5066 || TARGET_MIX_SSE_I387)
5067 && reload_completed"
5068 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5071 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5072 [(set (match_operand:X87MODEF 0 "register_operand" "")
5074 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5076 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5077 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5079 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5080 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5081 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5083 rtx reg = gen_reg_rtx (XFmode);
5086 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5088 if (<X87MODEF:MODE>mode == SFmode)
5089 insn = gen_truncxfsf2 (operands[0], reg);
5090 else if (<X87MODEF:MODE>mode == DFmode)
5091 insn = gen_truncxfdf2 (operands[0], reg);
5100 ;; Pre-reload splitter to add memory clobber to the pattern.
5101 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5102 [(set (match_operand:X87MODEF 0 "register_operand" "")
5103 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5105 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5106 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5107 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5108 || TARGET_MIX_SSE_I387))
5109 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5110 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5111 && ((<SSEMODEI24:MODE>mode == SImode
5112 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5113 && optimize_function_for_speed_p (cfun)
5114 && flag_trapping_math)
5115 || !(TARGET_INTER_UNIT_CONVERSIONS
5116 || optimize_function_for_size_p (cfun)))))
5117 && can_create_pseudo_p ()"
5120 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5121 (clobber (match_dup 2))])]
5123 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5125 /* Avoid store forwarding (partial memory) stall penalty
5126 by passing DImode value through XMM registers. */
5127 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5128 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5129 && optimize_function_for_speed_p (cfun))
5131 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5138 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5139 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5141 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5142 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5143 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5144 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5146 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5147 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5148 (set_attr "unit" "*,i387,*,*,*")
5149 (set_attr "athlon_decode" "*,*,double,direct,double")
5150 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5151 (set_attr "fp_int_src" "true")])
5153 (define_insn "*floatsi<mode>2_vector_mixed"
5154 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5155 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5156 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5157 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5161 [(set_attr "type" "fmov,sseicvt")
5162 (set_attr "mode" "<MODE>,<ssevecmode>")
5163 (set_attr "unit" "i387,*")
5164 (set_attr "athlon_decode" "*,direct")
5165 (set_attr "amdfam10_decode" "*,double")
5166 (set_attr "fp_int_src" "true")])
5168 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5169 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5171 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5172 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5173 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5174 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5176 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5177 (set_attr "mode" "<MODEF:MODE>")
5178 (set_attr "unit" "*,i387,*,*")
5179 (set_attr "athlon_decode" "*,*,double,direct")
5180 (set_attr "amdfam10_decode" "*,*,vector,double")
5181 (set_attr "fp_int_src" "true")])
5184 [(set (match_operand:MODEF 0 "register_operand" "")
5185 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5186 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5187 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5189 && TARGET_INTER_UNIT_CONVERSIONS
5191 && (SSE_REG_P (operands[0])
5192 || (GET_CODE (operands[0]) == SUBREG
5193 && SSE_REG_P (operands[0])))"
5194 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5198 [(set (match_operand:MODEF 0 "register_operand" "")
5199 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5200 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5201 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5203 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5205 && (SSE_REG_P (operands[0])
5206 || (GET_CODE (operands[0]) == SUBREG
5207 && SSE_REG_P (operands[0])))"
5208 [(set (match_dup 2) (match_dup 1))
5209 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5212 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5213 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5215 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5216 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5217 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5218 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5221 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5222 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5223 [(set_attr "type" "fmov,sseicvt,sseicvt")
5224 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5225 (set_attr "mode" "<MODEF:MODE>")
5226 (set (attr "prefix_rex")
5228 (and (eq_attr "prefix" "maybe_vex")
5229 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5231 (const_string "*")))
5232 (set_attr "unit" "i387,*,*")
5233 (set_attr "athlon_decode" "*,double,direct")
5234 (set_attr "amdfam10_decode" "*,vector,double")
5235 (set_attr "fp_int_src" "true")])
5237 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5238 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5240 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5241 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5243 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5246 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5247 [(set_attr "type" "fmov,sseicvt")
5248 (set_attr "prefix" "orig,maybe_vex")
5249 (set_attr "mode" "<MODEF:MODE>")
5250 (set (attr "prefix_rex")
5252 (and (eq_attr "prefix" "maybe_vex")
5253 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5255 (const_string "*")))
5256 (set_attr "athlon_decode" "*,direct")
5257 (set_attr "amdfam10_decode" "*,double")
5258 (set_attr "fp_int_src" "true")])
5260 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5261 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5263 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5264 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5265 "TARGET_SSE2 && TARGET_SSE_MATH
5266 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5268 [(set_attr "type" "sseicvt")
5269 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5270 (set_attr "athlon_decode" "double,direct,double")
5271 (set_attr "amdfam10_decode" "vector,double,double")
5272 (set_attr "fp_int_src" "true")])
5274 (define_insn "*floatsi<mode>2_vector_sse"
5275 [(set (match_operand:MODEF 0 "register_operand" "=x")
5276 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5277 "TARGET_SSE2 && TARGET_SSE_MATH
5278 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5280 [(set_attr "type" "sseicvt")
5281 (set_attr "mode" "<MODE>")
5282 (set_attr "athlon_decode" "direct")
5283 (set_attr "amdfam10_decode" "double")
5284 (set_attr "fp_int_src" "true")])
5287 [(set (match_operand:MODEF 0 "register_operand" "")
5288 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5289 (clobber (match_operand:SI 2 "memory_operand" ""))]
5290 "TARGET_SSE2 && TARGET_SSE_MATH
5291 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5293 && (SSE_REG_P (operands[0])
5294 || (GET_CODE (operands[0]) == SUBREG
5295 && SSE_REG_P (operands[0])))"
5298 rtx op1 = operands[1];
5300 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5302 if (GET_CODE (op1) == SUBREG)
5303 op1 = SUBREG_REG (op1);
5305 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5307 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5308 emit_insn (gen_sse2_loadld (operands[4],
5309 CONST0_RTX (V4SImode), operands[1]));
5311 /* We can ignore possible trapping value in the
5312 high part of SSE register for non-trapping math. */
5313 else if (SSE_REG_P (op1) && !flag_trapping_math)
5314 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5317 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5318 emit_move_insn (operands[2], operands[1]);
5319 emit_insn (gen_sse2_loadld (operands[4],
5320 CONST0_RTX (V4SImode), operands[2]));
5323 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5328 [(set (match_operand:MODEF 0 "register_operand" "")
5329 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5330 (clobber (match_operand:SI 2 "memory_operand" ""))]
5331 "TARGET_SSE2 && TARGET_SSE_MATH
5332 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5334 && (SSE_REG_P (operands[0])
5335 || (GET_CODE (operands[0]) == SUBREG
5336 && SSE_REG_P (operands[0])))"
5339 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5341 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5343 emit_insn (gen_sse2_loadld (operands[4],
5344 CONST0_RTX (V4SImode), operands[1]));
5346 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5351 [(set (match_operand:MODEF 0 "register_operand" "")
5352 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5353 "TARGET_SSE2 && TARGET_SSE_MATH
5354 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5356 && (SSE_REG_P (operands[0])
5357 || (GET_CODE (operands[0]) == SUBREG
5358 && SSE_REG_P (operands[0])))"
5361 rtx op1 = operands[1];
5363 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5365 if (GET_CODE (op1) == SUBREG)
5366 op1 = SUBREG_REG (op1);
5368 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5370 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5371 emit_insn (gen_sse2_loadld (operands[4],
5372 CONST0_RTX (V4SImode), operands[1]));
5374 /* We can ignore possible trapping value in the
5375 high part of SSE register for non-trapping math. */
5376 else if (SSE_REG_P (op1) && !flag_trapping_math)
5377 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5381 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5386 [(set (match_operand:MODEF 0 "register_operand" "")
5387 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5388 "TARGET_SSE2 && TARGET_SSE_MATH
5389 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5391 && (SSE_REG_P (operands[0])
5392 || (GET_CODE (operands[0]) == SUBREG
5393 && SSE_REG_P (operands[0])))"
5396 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5398 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5400 emit_insn (gen_sse2_loadld (operands[4],
5401 CONST0_RTX (V4SImode), operands[1]));
5403 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5407 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5408 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5410 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5411 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5412 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5413 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5415 [(set_attr "type" "sseicvt")
5416 (set_attr "mode" "<MODEF:MODE>")
5417 (set_attr "athlon_decode" "double,direct")
5418 (set_attr "amdfam10_decode" "vector,double")
5419 (set_attr "fp_int_src" "true")])
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5422 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5424 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5425 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5426 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5427 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5428 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5429 [(set_attr "type" "sseicvt")
5430 (set_attr "prefix" "maybe_vex")
5431 (set_attr "mode" "<MODEF:MODE>")
5432 (set (attr "prefix_rex")
5434 (and (eq_attr "prefix" "maybe_vex")
5435 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5437 (const_string "*")))
5438 (set_attr "athlon_decode" "double,direct")
5439 (set_attr "amdfam10_decode" "vector,double")
5440 (set_attr "fp_int_src" "true")])
5443 [(set (match_operand:MODEF 0 "register_operand" "")
5444 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5445 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5446 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5447 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5448 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5450 && (SSE_REG_P (operands[0])
5451 || (GET_CODE (operands[0]) == SUBREG
5452 && SSE_REG_P (operands[0])))"
5453 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5456 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5457 [(set (match_operand:MODEF 0 "register_operand" "=x")
5459 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5460 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5462 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5463 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5464 [(set_attr "type" "sseicvt")
5465 (set_attr "prefix" "maybe_vex")
5466 (set_attr "mode" "<MODEF:MODE>")
5467 (set (attr "prefix_rex")
5469 (and (eq_attr "prefix" "maybe_vex")
5470 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5472 (const_string "*")))
5473 (set_attr "athlon_decode" "direct")
5474 (set_attr "amdfam10_decode" "double")
5475 (set_attr "fp_int_src" "true")])
5478 [(set (match_operand:MODEF 0 "register_operand" "")
5479 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5480 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5481 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5482 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5483 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5485 && (SSE_REG_P (operands[0])
5486 || (GET_CODE (operands[0]) == SUBREG
5487 && SSE_REG_P (operands[0])))"
5488 [(set (match_dup 2) (match_dup 1))
5489 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5493 [(set (match_operand:MODEF 0 "register_operand" "")
5494 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5495 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5496 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5497 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5499 && (SSE_REG_P (operands[0])
5500 || (GET_CODE (operands[0]) == SUBREG
5501 && SSE_REG_P (operands[0])))"
5502 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5505 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5506 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5508 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5509 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5511 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5515 [(set_attr "type" "fmov,multi")
5516 (set_attr "mode" "<X87MODEF:MODE>")
5517 (set_attr "unit" "*,i387")
5518 (set_attr "fp_int_src" "true")])
5520 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5521 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5523 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5525 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5527 [(set_attr "type" "fmov")
5528 (set_attr "mode" "<X87MODEF:MODE>")
5529 (set_attr "fp_int_src" "true")])
5532 [(set (match_operand:X87MODEF 0 "register_operand" "")
5533 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5534 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5536 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5538 && FP_REG_P (operands[0])"
5539 [(set (match_dup 2) (match_dup 1))
5540 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5544 [(set (match_operand:X87MODEF 0 "register_operand" "")
5545 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5546 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5548 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5550 && FP_REG_P (operands[0])"
5551 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5554 ;; Avoid store forwarding (partial memory) stall penalty
5555 ;; by passing DImode value through XMM registers. */
5557 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5558 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5560 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5561 (clobber (match_scratch:V4SI 3 "=X,x"))
5562 (clobber (match_scratch:V4SI 4 "=X,x"))
5563 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5564 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5565 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5566 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5568 [(set_attr "type" "multi")
5569 (set_attr "mode" "<X87MODEF:MODE>")
5570 (set_attr "unit" "i387")
5571 (set_attr "fp_int_src" "true")])
5574 [(set (match_operand:X87MODEF 0 "register_operand" "")
5575 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5576 (clobber (match_scratch:V4SI 3 ""))
5577 (clobber (match_scratch:V4SI 4 ""))
5578 (clobber (match_operand:DI 2 "memory_operand" ""))]
5579 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5580 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5581 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5583 && FP_REG_P (operands[0])"
5584 [(set (match_dup 2) (match_dup 3))
5585 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5587 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5588 Assemble the 64-bit DImode value in an xmm register. */
5589 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5590 gen_rtx_SUBREG (SImode, operands[1], 0)));
5591 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5592 gen_rtx_SUBREG (SImode, operands[1], 4)));
5593 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5596 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5600 [(set (match_operand:X87MODEF 0 "register_operand" "")
5601 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5602 (clobber (match_scratch:V4SI 3 ""))
5603 (clobber (match_scratch:V4SI 4 ""))
5604 (clobber (match_operand:DI 2 "memory_operand" ""))]
5605 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5606 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5607 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5609 && FP_REG_P (operands[0])"
5610 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5613 ;; Avoid store forwarding (partial memory) stall penalty by extending
5614 ;; SImode value to DImode through XMM register instead of pushing two
5615 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5616 ;; targets benefit from this optimization. Also note that fild
5617 ;; loads from memory only.
5619 (define_insn "*floatunssi<mode>2_1"
5620 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5621 (unsigned_float:X87MODEF
5622 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5623 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5624 (clobber (match_scratch:SI 3 "=X,x"))]
5626 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5629 [(set_attr "type" "multi")
5630 (set_attr "mode" "<MODE>")])
5633 [(set (match_operand:X87MODEF 0 "register_operand" "")
5634 (unsigned_float:X87MODEF
5635 (match_operand:SI 1 "register_operand" "")))
5636 (clobber (match_operand:DI 2 "memory_operand" ""))
5637 (clobber (match_scratch:SI 3 ""))]
5639 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5641 && reload_completed"
5642 [(set (match_dup 2) (match_dup 1))
5644 (float:X87MODEF (match_dup 2)))]
5645 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5648 [(set (match_operand:X87MODEF 0 "register_operand" "")
5649 (unsigned_float:X87MODEF
5650 (match_operand:SI 1 "memory_operand" "")))
5651 (clobber (match_operand:DI 2 "memory_operand" ""))
5652 (clobber (match_scratch:SI 3 ""))]
5654 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5656 && reload_completed"
5657 [(set (match_dup 2) (match_dup 3))
5659 (float:X87MODEF (match_dup 2)))]
5661 emit_move_insn (operands[3], operands[1]);
5662 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5665 (define_expand "floatunssi<mode>2"
5667 [(set (match_operand:X87MODEF 0 "register_operand" "")
5668 (unsigned_float:X87MODEF
5669 (match_operand:SI 1 "nonimmediate_operand" "")))
5670 (clobber (match_dup 2))
5671 (clobber (match_scratch:SI 3 ""))])]
5673 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5675 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5677 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5679 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5684 enum ix86_stack_slot slot = (virtuals_instantiated
5687 operands[2] = assign_386_stack_local (DImode, slot);
5691 (define_expand "floatunsdisf2"
5692 [(use (match_operand:SF 0 "register_operand" ""))
5693 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5694 "TARGET_64BIT && TARGET_SSE_MATH"
5695 "x86_emit_floatuns (operands); DONE;")
5697 (define_expand "floatunsdidf2"
5698 [(use (match_operand:DF 0 "register_operand" ""))
5699 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5700 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5701 && TARGET_SSE2 && TARGET_SSE_MATH"
5704 x86_emit_floatuns (operands);
5706 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5712 (define_expand "add<mode>3"
5713 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5714 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5715 (match_operand:SDWIM 2 "<general_operand>" "")))]
5717 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5719 (define_insn_and_split "*add<dwi>3_doubleword"
5720 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5722 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5723 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5724 (clobber (reg:CC FLAGS_REG))]
5725 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5728 [(parallel [(set (reg:CC FLAGS_REG)
5729 (unspec:CC [(match_dup 1) (match_dup 2)]
5732 (plus:DWIH (match_dup 1) (match_dup 2)))])
5733 (parallel [(set (match_dup 3)
5737 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5739 (clobber (reg:CC FLAGS_REG))])]
5740 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5742 (define_insn "*add<mode>3_cc"
5743 [(set (reg:CC FLAGS_REG)
5745 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5746 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5748 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5749 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5750 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5751 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5752 [(set_attr "type" "alu")
5753 (set_attr "mode" "<MODE>")])
5755 (define_insn "addqi3_cc"
5756 [(set (reg:CC FLAGS_REG)
5758 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5759 (match_operand:QI 2 "general_operand" "qn,qm")]
5761 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5762 (plus:QI (match_dup 1) (match_dup 2)))]
5763 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5764 "add{b}\t{%2, %0|%0, %2}"
5765 [(set_attr "type" "alu")
5766 (set_attr "mode" "QI")])
5768 (define_insn "*lea_1"
5769 [(set (match_operand:DWIH 0 "register_operand" "=r")
5770 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5772 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5773 [(set_attr "type" "lea")
5774 (set_attr "mode" "<MODE>")])
5776 (define_insn "*lea_2"
5777 [(set (match_operand:SI 0 "register_operand" "=r")
5778 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5780 "lea{l}\t{%a1, %0|%0, %a1}"
5781 [(set_attr "type" "lea")
5782 (set_attr "mode" "SI")])
5784 (define_insn "*lea_2_zext"
5785 [(set (match_operand:DI 0 "register_operand" "=r")
5787 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5789 "lea{l}\t{%a1, %k0|%k0, %a1}"
5790 [(set_attr "type" "lea")
5791 (set_attr "mode" "SI")])
5793 (define_insn "*add<mode>_1"
5794 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5796 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5797 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5798 (clobber (reg:CC FLAGS_REG))]
5799 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5801 switch (get_attr_type (insn))
5804 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5805 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (operands[2] == const1_rtx)
5810 return "inc{<imodesuffix>}\t%0";
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{<imodesuffix>}\t%0";
5818 /* Use add as much as possible to replace lea for AGU optimization. */
5819 if (which_alternative == 2 && TARGET_OPT_AGU)
5820 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
5822 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5823 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5824 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5826 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5830 (cond [(and (eq_attr "alternative" "2")
5831 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
5832 (const_string "lea")
5833 (eq_attr "alternative" "3")
5834 (const_string "lea")
5835 (match_operand:SWI48 2 "incdec_operand" "")
5836 (const_string "incdec")
5838 (const_string "alu")))
5839 (set (attr "length_immediate")
5841 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5843 (const_string "*")))
5844 (set_attr "mode" "<MODE>")])
5846 ;; It may seem that nonimmediate operand is proper one for operand 1.
5847 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5848 ;; we take care in ix86_binary_operator_ok to not allow two memory
5849 ;; operands so proper swapping will be done in reload. This allow
5850 ;; patterns constructed from addsi_1 to match.
5852 (define_insn "*addsi_1_zext"
5853 [(set (match_operand:DI 0 "register_operand" "=r,r")
5855 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5856 (match_operand:SI 2 "general_operand" "g,li"))))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5860 switch (get_attr_type (insn))
5863 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
5864 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5867 if (operands[2] == const1_rtx)
5868 return "inc{l}\t%k0";
5871 gcc_assert (operands[2] == constm1_rtx);
5872 return "dec{l}\t%k0";
5876 if (x86_maybe_negate_const_int (&operands[2], SImode))
5877 return "sub{l}\t{%2, %k0|%k0, %2}";
5879 return "add{l}\t{%2, %k0|%k0, %2}";
5883 (cond [(eq_attr "alternative" "1")
5884 (const_string "lea")
5885 (match_operand:SI 2 "incdec_operand" "")
5886 (const_string "incdec")
5888 (const_string "alu")))
5889 (set (attr "length_immediate")
5891 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5893 (const_string "*")))
5894 (set_attr "mode" "SI")])
5896 (define_insn "*addhi_1"
5897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5898 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5899 (match_operand:HI 2 "general_operand" "rn,rm")))
5900 (clobber (reg:CC FLAGS_REG))]
5901 "TARGET_PARTIAL_REG_STALL
5902 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5904 switch (get_attr_type (insn))
5907 if (operands[2] == const1_rtx)
5908 return "inc{w}\t%0";
5911 gcc_assert (operands[2] == constm1_rtx);
5912 return "dec{w}\t%0";
5916 if (x86_maybe_negate_const_int (&operands[2], HImode))
5917 return "sub{w}\t{%2, %0|%0, %2}";
5919 return "add{w}\t{%2, %0|%0, %2}";
5923 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5924 (const_string "incdec")
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5930 (const_string "*")))
5931 (set_attr "mode" "HI")])
5933 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5934 ;; type optimizations enabled by define-splits. This is not important
5935 ;; for PII, and in fact harmful because of partial register stalls.
5937 (define_insn "*addhi_1_lea"
5938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5939 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5940 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
5941 (clobber (reg:CC FLAGS_REG))]
5942 "!TARGET_PARTIAL_REG_STALL
5943 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5945 switch (get_attr_type (insn))
5951 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5952 if (operands[2] == const1_rtx)
5953 return "inc{w}\t%0";
5956 gcc_assert (operands[2] == constm1_rtx);
5957 return "dec{w}\t%0";
5961 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962 if (x86_maybe_negate_const_int (&operands[2], HImode))
5963 return "sub{w}\t{%2, %0|%0, %2}";
5965 return "add{w}\t{%2, %0|%0, %2}";
5969 (if_then_else (eq_attr "alternative" "2")
5970 (const_string "lea")
5971 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5972 (const_string "incdec")
5973 (const_string "alu"))))
5974 (set (attr "length_immediate")
5976 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5978 (const_string "*")))
5979 (set_attr "mode" "HI,HI,SI")])
5981 (define_insn "*addqi_1"
5982 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5983 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5984 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5985 (clobber (reg:CC FLAGS_REG))]
5986 "TARGET_PARTIAL_REG_STALL
5987 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5989 int widen = (which_alternative == 2);
5990 switch (get_attr_type (insn))
5993 if (operands[2] == const1_rtx)
5994 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5997 gcc_assert (operands[2] == constm1_rtx);
5998 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6002 if (x86_maybe_negate_const_int (&operands[2], QImode))
6005 return "sub{l}\t{%2, %k0|%k0, %2}";
6007 return "sub{b}\t{%2, %0|%0, %2}";
6010 return "add{l}\t{%k2, %k0|%k0, %k2}";
6012 return "add{b}\t{%2, %0|%0, %2}";
6016 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6017 (const_string "incdec")
6018 (const_string "alu")))
6019 (set (attr "length_immediate")
6021 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6023 (const_string "*")))
6024 (set_attr "mode" "QI,QI,SI")])
6026 ;; %%% Potential partial reg stall on alternative 2. What to do?
6027 (define_insn "*addqi_1_lea"
6028 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6029 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6030 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "!TARGET_PARTIAL_REG_STALL
6033 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6035 int widen = (which_alternative == 2);
6036 switch (get_attr_type (insn))
6042 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043 if (operands[2] == const1_rtx)
6044 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6047 gcc_assert (operands[2] == constm1_rtx);
6048 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053 if (x86_maybe_negate_const_int (&operands[2], QImode))
6056 return "sub{l}\t{%2, %k0|%k0, %2}";
6058 return "sub{b}\t{%2, %0|%0, %2}";
6061 return "add{l}\t{%k2, %k0|%k0, %k2}";
6063 return "add{b}\t{%2, %0|%0, %2}";
6067 (if_then_else (eq_attr "alternative" "3")
6068 (const_string "lea")
6069 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu"))))
6072 (set (attr "length_immediate")
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6076 (const_string "*")))
6077 (set_attr "mode" "QI,QI,SI,SI")])
6079 (define_insn "*addqi_1_slp"
6080 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6081 (plus:QI (match_dup 0)
6082 (match_operand:QI 1 "general_operand" "qn,qnm")))
6083 (clobber (reg:CC FLAGS_REG))]
6084 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6085 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6087 switch (get_attr_type (insn))
6090 if (operands[1] == const1_rtx)
6091 return "inc{b}\t%0";
6094 gcc_assert (operands[1] == constm1_rtx);
6095 return "dec{b}\t%0";
6099 if (x86_maybe_negate_const_int (&operands[1], QImode))
6100 return "sub{b}\t{%1, %0|%0, %1}";
6102 return "add{b}\t{%1, %0|%0, %1}";
6106 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6107 (const_string "incdec")
6108 (const_string "alu1")))
6109 (set (attr "memory")
6110 (if_then_else (match_operand 1 "memory_operand" "")
6111 (const_string "load")
6112 (const_string "none")))
6113 (set_attr "mode" "QI")])
6115 (define_insn "*add<mode>_2"
6116 [(set (reg FLAGS_REG)
6119 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6120 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6122 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6123 (plus:SWI (match_dup 1) (match_dup 2)))]
6124 "ix86_match_ccmode (insn, CCGOCmode)
6125 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6127 switch (get_attr_type (insn))
6130 if (operands[2] == const1_rtx)
6131 return "inc{<imodesuffix>}\t%0";
6134 gcc_assert (operands[2] == constm1_rtx);
6135 return "dec{<imodesuffix>}\t%0";
6139 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6140 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6142 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6146 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6147 (const_string "incdec")
6148 (const_string "alu")))
6149 (set (attr "length_immediate")
6151 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6153 (const_string "*")))
6154 (set_attr "mode" "<MODE>")])
6156 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6157 (define_insn "*addsi_2_zext"
6158 [(set (reg FLAGS_REG)
6160 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6161 (match_operand:SI 2 "general_operand" "g"))
6163 (set (match_operand:DI 0 "register_operand" "=r")
6164 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6165 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6166 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6168 switch (get_attr_type (insn))
6171 if (operands[2] == const1_rtx)
6172 return "inc{l}\t%k0";
6175 gcc_assert (operands[2] == constm1_rtx);
6176 return "dec{l}\t%k0";
6180 if (x86_maybe_negate_const_int (&operands[2], SImode))
6181 return "sub{l}\t{%2, %k0|%k0, %2}";
6183 return "add{l}\t{%2, %k0|%k0, %2}";
6187 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set (attr "length_immediate")
6192 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6194 (const_string "*")))
6195 (set_attr "mode" "SI")])
6197 (define_insn "*add<mode>_3"
6198 [(set (reg FLAGS_REG)
6200 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6201 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6202 (clobber (match_scratch:SWI 0 "=<r>"))]
6203 "ix86_match_ccmode (insn, CCZmode)
6204 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6206 switch (get_attr_type (insn))
6209 if (operands[2] == const1_rtx)
6210 return "inc{<imodesuffix>}\t%0";
6213 gcc_assert (operands[2] == constm1_rtx);
6214 return "dec{<imodesuffix>}\t%0";
6218 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6219 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6221 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6225 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set (attr "length_immediate")
6230 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6232 (const_string "*")))
6233 (set_attr "mode" "<MODE>")])
6235 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6236 (define_insn "*addsi_3_zext"
6237 [(set (reg FLAGS_REG)
6239 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6240 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6241 (set (match_operand:DI 0 "register_operand" "=r")
6242 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6243 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6244 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6246 switch (get_attr_type (insn))
6249 if (operands[2] == const1_rtx)
6250 return "inc{l}\t%k0";
6253 gcc_assert (operands[2] == constm1_rtx);
6254 return "dec{l}\t%k0";
6258 if (x86_maybe_negate_const_int (&operands[2], SImode))
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6261 return "add{l}\t{%2, %k0|%k0, %2}";
6265 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6272 (const_string "*")))
6273 (set_attr "mode" "SI")])
6275 ; For comparisons against 1, -1 and 128, we may generate better code
6276 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6277 ; is matched then. We can't accept general immediate, because for
6278 ; case of overflows, the result is messed up.
6279 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6280 ; only for comparisons not depending on it.
6282 (define_insn "*adddi_4"
6283 [(set (reg FLAGS_REG)
6285 (match_operand:DI 1 "nonimmediate_operand" "0")
6286 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6287 (clobber (match_scratch:DI 0 "=rm"))]
6289 && ix86_match_ccmode (insn, CCGCmode)"
6291 switch (get_attr_type (insn))
6294 if (operands[2] == constm1_rtx)
6295 return "inc{q}\t%0";
6298 gcc_assert (operands[2] == const1_rtx);
6299 return "dec{q}\t%0";
6303 if (x86_maybe_negate_const_int (&operands[2], DImode))
6304 return "add{q}\t{%2, %0|%0, %2}";
6306 return "sub{q}\t{%2, %0|%0, %2}";
6310 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6311 (const_string "incdec")
6312 (const_string "alu")))
6313 (set (attr "length_immediate")
6315 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6317 (const_string "*")))
6318 (set_attr "mode" "DI")])
6320 ; For comparisons against 1, -1 and 128, we may generate better code
6321 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6322 ; is matched then. We can't accept general immediate, because for
6323 ; case of overflows, the result is messed up.
6324 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6325 ; only for comparisons not depending on it.
6327 (define_insn "*add<mode>_4"
6328 [(set (reg FLAGS_REG)
6330 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6331 (match_operand:SWI124 2 "const_int_operand" "n")))
6332 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6333 "ix86_match_ccmode (insn, CCGCmode)"
6335 switch (get_attr_type (insn))
6338 if (operands[2] == constm1_rtx)
6339 return "inc{<imodesuffix>}\t%0";
6342 gcc_assert (operands[2] == const1_rtx);
6343 return "dec{<imodesuffix>}\t%0";
6347 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6348 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6350 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6354 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6355 (const_string "incdec")
6356 (const_string "alu")))
6357 (set (attr "length_immediate")
6359 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6361 (const_string "*")))
6362 (set_attr "mode" "<MODE>")])
6364 (define_insn "*add<mode>_5"
6365 [(set (reg FLAGS_REG)
6368 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6369 (match_operand:SWI 2 "<general_operand>" "<g>"))
6371 (clobber (match_scratch:SWI 0 "=<r>"))]
6372 "ix86_match_ccmode (insn, CCGOCmode)
6373 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6375 switch (get_attr_type (insn))
6378 if (operands[2] == const1_rtx)
6379 return "inc{<imodesuffix>}\t%0";
6382 gcc_assert (operands[2] == constm1_rtx);
6383 return "dec{<imodesuffix>}\t%0";
6387 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6388 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6390 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6394 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6395 (const_string "incdec")
6396 (const_string "alu")))
6397 (set (attr "length_immediate")
6399 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6401 (const_string "*")))
6402 (set_attr "mode" "<MODE>")])
6404 (define_insn "*addqi_ext_1_rex64"
6405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6410 (match_operand 1 "ext_register_operand" "0")
6413 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6414 (clobber (reg:CC FLAGS_REG))]
6417 switch (get_attr_type (insn))
6420 if (operands[2] == const1_rtx)
6421 return "inc{b}\t%h0";
6424 gcc_assert (operands[2] == constm1_rtx);
6425 return "dec{b}\t%h0";
6429 return "add{b}\t{%2, %h0|%h0, %2}";
6433 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6434 (const_string "incdec")
6435 (const_string "alu")))
6436 (set_attr "modrm" "1")
6437 (set_attr "mode" "QI")])
6439 (define_insn "addqi_ext_1"
6440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6445 (match_operand 1 "ext_register_operand" "0")
6448 (match_operand:QI 2 "general_operand" "Qmn")))
6449 (clobber (reg:CC FLAGS_REG))]
6452 switch (get_attr_type (insn))
6455 if (operands[2] == const1_rtx)
6456 return "inc{b}\t%h0";
6459 gcc_assert (operands[2] == constm1_rtx);
6460 return "dec{b}\t%h0";
6464 return "add{b}\t{%2, %h0|%h0, %2}";
6468 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6469 (const_string "incdec")
6470 (const_string "alu")))
6471 (set_attr "modrm" "1")
6472 (set_attr "mode" "QI")])
6474 (define_insn "*addqi_ext_2"
6475 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6480 (match_operand 1 "ext_register_operand" "%0")
6484 (match_operand 2 "ext_register_operand" "Q")
6487 (clobber (reg:CC FLAGS_REG))]
6489 "add{b}\t{%h2, %h0|%h0, %h2}"
6490 [(set_attr "type" "alu")
6491 (set_attr "mode" "QI")])
6493 ;; The lea patterns for non-Pmodes needs to be matched by
6494 ;; several insns converted to real lea by splitters.
6496 (define_insn_and_split "*lea_general_1"
6497 [(set (match_operand 0 "register_operand" "=r")
6498 (plus (plus (match_operand 1 "index_register_operand" "l")
6499 (match_operand 2 "register_operand" "r"))
6500 (match_operand 3 "immediate_operand" "i")))]
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[2])
6506 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6507 || GET_MODE (operands[3]) == VOIDmode)"
6509 "&& reload_completed"
6513 operands[0] = gen_lowpart (SImode, operands[0]);
6514 operands[1] = gen_lowpart (Pmode, operands[1]);
6515 operands[2] = gen_lowpart (Pmode, operands[2]);
6516 operands[3] = gen_lowpart (Pmode, operands[3]);
6517 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6519 if (Pmode != SImode)
6520 pat = gen_rtx_SUBREG (SImode, pat, 0);
6521 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6524 [(set_attr "type" "lea")
6525 (set_attr "mode" "SI")])
6527 (define_insn_and_split "*lea_general_1_zext"
6528 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (match_operand:SI 1 "index_register_operand" "l")
6532 (match_operand:SI 2 "register_operand" "r"))
6533 (match_operand:SI 3 "immediate_operand" "i"))))]
6536 "&& reload_completed"
6538 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6540 (match_dup 3)) 0)))]
6542 operands[1] = gen_lowpart (Pmode, operands[1]);
6543 operands[2] = gen_lowpart (Pmode, operands[2]);
6544 operands[3] = gen_lowpart (Pmode, operands[3]);
6546 [(set_attr "type" "lea")
6547 (set_attr "mode" "SI")])
6549 (define_insn_and_split "*lea_general_2"
6550 [(set (match_operand 0 "register_operand" "=r")
6551 (plus (mult (match_operand 1 "index_register_operand" "l")
6552 (match_operand 2 "const248_operand" "i"))
6553 (match_operand 3 "nonmemory_operand" "ri")))]
6554 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6555 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6556 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6557 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6558 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6559 || GET_MODE (operands[3]) == VOIDmode)"
6561 "&& reload_completed"
6565 operands[0] = gen_lowpart (SImode, operands[0]);
6566 operands[1] = gen_lowpart (Pmode, operands[1]);
6567 operands[3] = gen_lowpart (Pmode, operands[3]);
6568 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6570 if (Pmode != SImode)
6571 pat = gen_rtx_SUBREG (SImode, pat, 0);
6572 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6575 [(set_attr "type" "lea")
6576 (set_attr "mode" "SI")])
6578 (define_insn_and_split "*lea_general_2_zext"
6579 [(set (match_operand:DI 0 "register_operand" "=r")
6582 (match_operand:SI 1 "index_register_operand" "l")
6583 (match_operand:SI 2 "const248_operand" "n"))
6584 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6587 "&& reload_completed"
6589 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6591 (match_dup 3)) 0)))]
6593 operands[1] = gen_lowpart (Pmode, operands[1]);
6594 operands[3] = gen_lowpart (Pmode, operands[3]);
6596 [(set_attr "type" "lea")
6597 (set_attr "mode" "SI")])
6599 (define_insn_and_split "*lea_general_3"
6600 [(set (match_operand 0 "register_operand" "=r")
6601 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6602 (match_operand 2 "const248_operand" "i"))
6603 (match_operand 3 "register_operand" "r"))
6604 (match_operand 4 "immediate_operand" "i")))]
6605 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6606 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6607 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6608 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6609 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6611 "&& reload_completed"
6615 operands[0] = gen_lowpart (SImode, operands[0]);
6616 operands[1] = gen_lowpart (Pmode, operands[1]);
6617 operands[3] = gen_lowpart (Pmode, operands[3]);
6618 operands[4] = gen_lowpart (Pmode, operands[4]);
6619 pat = gen_rtx_PLUS (Pmode,
6620 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6624 if (Pmode != SImode)
6625 pat = gen_rtx_SUBREG (SImode, pat, 0);
6626 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6629 [(set_attr "type" "lea")
6630 (set_attr "mode" "SI")])
6632 (define_insn_and_split "*lea_general_3_zext"
6633 [(set (match_operand:DI 0 "register_operand" "=r")
6637 (match_operand:SI 1 "index_register_operand" "l")
6638 (match_operand:SI 2 "const248_operand" "n"))
6639 (match_operand:SI 3 "register_operand" "r"))
6640 (match_operand:SI 4 "immediate_operand" "i"))))]
6643 "&& reload_completed"
6645 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6648 (match_dup 4)) 0)))]
6650 operands[1] = gen_lowpart (Pmode, operands[1]);
6651 operands[3] = gen_lowpart (Pmode, operands[3]);
6652 operands[4] = gen_lowpart (Pmode, operands[4]);
6654 [(set_attr "type" "lea")
6655 (set_attr "mode" "SI")])
6657 ;; Convert lea to the lea pattern to avoid flags dependency.
6659 [(set (match_operand:DI 0 "register_operand" "")
6660 (plus:DI (match_operand:DI 1 "register_operand" "")
6661 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6662 (clobber (reg:CC FLAGS_REG))]
6663 "TARGET_64BIT && reload_completed
6664 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6666 (plus:DI (match_dup 1)
6670 ;; Convert lea to the lea pattern to avoid flags dependency.
6672 [(set (match_operand 0 "register_operand" "")
6673 (plus (match_operand 1 "register_operand" "")
6674 (match_operand 2 "nonmemory_operand" "")))
6675 (clobber (reg:CC FLAGS_REG))]
6676 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6680 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6681 may confuse gen_lowpart. */
6682 if (GET_MODE (operands[0]) != Pmode)
6684 operands[1] = gen_lowpart (Pmode, operands[1]);
6685 operands[2] = gen_lowpart (Pmode, operands[2]);
6687 operands[0] = gen_lowpart (SImode, operands[0]);
6688 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6689 if (Pmode != SImode)
6690 pat = gen_rtx_SUBREG (SImode, pat, 0);
6691 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6695 ;; Convert lea to the lea pattern to avoid flags dependency.
6697 [(set (match_operand:DI 0 "register_operand" "")
6699 (plus:SI (match_operand:SI 1 "register_operand" "")
6700 (match_operand:SI 2 "nonmemory_operand" ""))))
6701 (clobber (reg:CC FLAGS_REG))]
6702 "TARGET_64BIT && reload_completed
6703 && true_regnum (operands[0]) != true_regnum (operands[1])"
6705 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6707 operands[1] = gen_lowpart (Pmode, operands[1]);
6708 operands[2] = gen_lowpart (Pmode, operands[2]);
6711 ;; Subtract instructions
6713 (define_expand "sub<mode>3"
6714 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6715 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6716 (match_operand:SDWIM 2 "<general_operand>" "")))]
6718 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6720 (define_insn_and_split "*sub<dwi>3_doubleword"
6721 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6723 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6724 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6725 (clobber (reg:CC FLAGS_REG))]
6726 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6729 [(parallel [(set (reg:CC FLAGS_REG)
6730 (compare:CC (match_dup 1) (match_dup 2)))
6732 (minus:DWIH (match_dup 1) (match_dup 2)))])
6733 (parallel [(set (match_dup 3)
6737 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6739 (clobber (reg:CC FLAGS_REG))])]
6740 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6742 (define_insn "*sub<mode>_1"
6743 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6745 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6746 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6747 (clobber (reg:CC FLAGS_REG))]
6748 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6749 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "mode" "<MODE>")])
6753 (define_insn "*subsi_1_zext"
6754 [(set (match_operand:DI 0 "register_operand" "=r")
6756 (minus:SI (match_operand:SI 1 "register_operand" "0")
6757 (match_operand:SI 2 "general_operand" "g"))))
6758 (clobber (reg:CC FLAGS_REG))]
6759 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6760 "sub{l}\t{%2, %k0|%k0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "SI")])
6764 (define_insn "*subqi_1_slp"
6765 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6766 (minus:QI (match_dup 0)
6767 (match_operand:QI 1 "general_operand" "qn,qm")))
6768 (clobber (reg:CC FLAGS_REG))]
6769 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6771 "sub{b}\t{%1, %0|%0, %1}"
6772 [(set_attr "type" "alu1")
6773 (set_attr "mode" "QI")])
6775 (define_insn "*sub<mode>_2"
6776 [(set (reg FLAGS_REG)
6779 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6782 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6783 (minus:SWI (match_dup 1) (match_dup 2)))]
6784 "ix86_match_ccmode (insn, CCGOCmode)
6785 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6786 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6787 [(set_attr "type" "alu")
6788 (set_attr "mode" "<MODE>")])
6790 (define_insn "*subsi_2_zext"
6791 [(set (reg FLAGS_REG)
6793 (minus:SI (match_operand:SI 1 "register_operand" "0")
6794 (match_operand:SI 2 "general_operand" "g"))
6796 (set (match_operand:DI 0 "register_operand" "=r")
6798 (minus:SI (match_dup 1)
6800 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6801 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6802 "sub{l}\t{%2, %k0|%k0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "SI")])
6806 (define_insn "*sub<mode>_3"
6807 [(set (reg FLAGS_REG)
6808 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6809 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6810 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6811 (minus:SWI (match_dup 1) (match_dup 2)))]
6812 "ix86_match_ccmode (insn, CCmode)
6813 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6814 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6815 [(set_attr "type" "alu")
6816 (set_attr "mode" "<MODE>")])
6818 (define_insn "*subsi_3_zext"
6819 [(set (reg FLAGS_REG)
6820 (compare (match_operand:SI 1 "register_operand" "0")
6821 (match_operand:SI 2 "general_operand" "g")))
6822 (set (match_operand:DI 0 "register_operand" "=r")
6824 (minus:SI (match_dup 1)
6826 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6827 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6828 "sub{l}\t{%2, %1|%1, %2}"
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "SI")])
6832 ;; Add with carry and subtract with borrow
6834 (define_expand "<plusminus_insn><mode>3_carry"
6836 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6838 (match_operand:SWI 1 "nonimmediate_operand" "")
6839 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6840 [(match_operand 3 "flags_reg_operand" "")
6842 (match_operand:SWI 2 "<general_operand>" ""))))
6843 (clobber (reg:CC FLAGS_REG))])]
6844 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6847 (define_insn "*<plusminus_insn><mode>3_carry"
6848 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6850 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6852 (match_operator 3 "ix86_carry_flag_operator"
6853 [(reg FLAGS_REG) (const_int 0)])
6854 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6855 (clobber (reg:CC FLAGS_REG))]
6856 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6857 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6858 [(set_attr "type" "alu")
6859 (set_attr "use_carry" "1")
6860 (set_attr "pent_pair" "pu")
6861 (set_attr "mode" "<MODE>")])
6863 (define_insn "*addsi3_carry_zext"
6864 [(set (match_operand:DI 0 "register_operand" "=r")
6866 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6867 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6868 [(reg FLAGS_REG) (const_int 0)])
6869 (match_operand:SI 2 "general_operand" "g")))))
6870 (clobber (reg:CC FLAGS_REG))]
6871 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6872 "adc{l}\t{%2, %k0|%k0, %2}"
6873 [(set_attr "type" "alu")
6874 (set_attr "use_carry" "1")
6875 (set_attr "pent_pair" "pu")
6876 (set_attr "mode" "SI")])
6878 (define_insn "*subsi3_carry_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r")
6881 (minus:SI (match_operand:SI 1 "register_operand" "0")
6882 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6883 [(reg FLAGS_REG) (const_int 0)])
6884 (match_operand:SI 2 "general_operand" "g")))))
6885 (clobber (reg:CC FLAGS_REG))]
6886 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6887 "sbb{l}\t{%2, %k0|%k0, %2}"
6888 [(set_attr "type" "alu")
6889 (set_attr "pent_pair" "pu")
6890 (set_attr "mode" "SI")])
6892 ;; Overflow setting add and subtract instructions
6894 (define_insn "*add<mode>3_cconly_overflow"
6895 [(set (reg:CCC FLAGS_REG)
6898 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6899 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6901 (clobber (match_scratch:SWI 0 "=<r>"))]
6902 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6903 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6904 [(set_attr "type" "alu")
6905 (set_attr "mode" "<MODE>")])
6907 (define_insn "*sub<mode>3_cconly_overflow"
6908 [(set (reg:CCC FLAGS_REG)
6911 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6912 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6915 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6916 [(set_attr "type" "icmp")
6917 (set_attr "mode" "<MODE>")])
6919 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6920 [(set (reg:CCC FLAGS_REG)
6923 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6924 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6926 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6927 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6928 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6929 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "alu")
6931 (set_attr "mode" "<MODE>")])
6933 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6934 [(set (reg:CCC FLAGS_REG)
6937 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6938 (match_operand:SI 2 "general_operand" "g"))
6940 (set (match_operand:DI 0 "register_operand" "=r")
6941 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6942 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6943 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6944 [(set_attr "type" "alu")
6945 (set_attr "mode" "SI")])
6947 ;; The patterns that match these are at the end of this file.
6949 (define_expand "<plusminus_insn>xf3"
6950 [(set (match_operand:XF 0 "register_operand" "")
6952 (match_operand:XF 1 "register_operand" "")
6953 (match_operand:XF 2 "register_operand" "")))]
6957 (define_expand "<plusminus_insn><mode>3"
6958 [(set (match_operand:MODEF 0 "register_operand" "")
6960 (match_operand:MODEF 1 "register_operand" "")
6961 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6962 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6963 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6966 ;; Multiply instructions
6968 (define_expand "mul<mode>3"
6969 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6971 (match_operand:SWIM248 1 "register_operand" "")
6972 (match_operand:SWIM248 2 "<general_operand>" "")))
6973 (clobber (reg:CC FLAGS_REG))])]
6977 (define_expand "mulqi3"
6978 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6980 (match_operand:QI 1 "register_operand" "")
6981 (match_operand:QI 2 "nonimmediate_operand" "")))
6982 (clobber (reg:CC FLAGS_REG))])]
6983 "TARGET_QIMODE_MATH"
6987 ;; IMUL reg32/64, reg32/64, imm8 Direct
6988 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6989 ;; IMUL reg32/64, reg32/64, imm32 Direct
6990 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6991 ;; IMUL reg32/64, reg32/64 Direct
6992 ;; IMUL reg32/64, mem32/64 Direct
6994 (define_insn "*mul<mode>3_1"
6995 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6997 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6998 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6999 (clobber (reg:CC FLAGS_REG))]
7000 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7003 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7004 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7005 [(set_attr "type" "imul")
7006 (set_attr "prefix_0f" "0,0,1")
7007 (set (attr "athlon_decode")
7008 (cond [(eq_attr "cpu" "athlon")
7009 (const_string "vector")
7010 (eq_attr "alternative" "1")
7011 (const_string "vector")
7012 (and (eq_attr "alternative" "2")
7013 (match_operand 1 "memory_operand" ""))
7014 (const_string "vector")]
7015 (const_string "direct")))
7016 (set (attr "amdfam10_decode")
7017 (cond [(and (eq_attr "alternative" "0,1")
7018 (match_operand 1 "memory_operand" ""))
7019 (const_string "vector")]
7020 (const_string "direct")))
7021 (set_attr "mode" "<MODE>")])
7023 (define_insn "*mulsi3_1_zext"
7024 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7026 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7027 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7028 (clobber (reg:CC FLAGS_REG))]
7030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7032 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7033 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7034 imul{l}\t{%2, %k0|%k0, %2}"
7035 [(set_attr "type" "imul")
7036 (set_attr "prefix_0f" "0,0,1")
7037 (set (attr "athlon_decode")
7038 (cond [(eq_attr "cpu" "athlon")
7039 (const_string "vector")
7040 (eq_attr "alternative" "1")
7041 (const_string "vector")
7042 (and (eq_attr "alternative" "2")
7043 (match_operand 1 "memory_operand" ""))
7044 (const_string "vector")]
7045 (const_string "direct")))
7046 (set (attr "amdfam10_decode")
7047 (cond [(and (eq_attr "alternative" "0,1")
7048 (match_operand 1 "memory_operand" ""))
7049 (const_string "vector")]
7050 (const_string "direct")))
7051 (set_attr "mode" "SI")])
7054 ;; IMUL reg16, reg16, imm8 VectorPath
7055 ;; IMUL reg16, mem16, imm8 VectorPath
7056 ;; IMUL reg16, reg16, imm16 VectorPath
7057 ;; IMUL reg16, mem16, imm16 VectorPath
7058 ;; IMUL reg16, reg16 Direct
7059 ;; IMUL reg16, mem16 Direct
7061 (define_insn "*mulhi3_1"
7062 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7063 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7064 (match_operand:HI 2 "general_operand" "K,n,mr")))
7065 (clobber (reg:CC FLAGS_REG))]
7067 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7069 imul{w}\t{%2, %1, %0|%0, %1, %2}
7070 imul{w}\t{%2, %1, %0|%0, %1, %2}
7071 imul{w}\t{%2, %0|%0, %2}"
7072 [(set_attr "type" "imul")
7073 (set_attr "prefix_0f" "0,0,1")
7074 (set (attr "athlon_decode")
7075 (cond [(eq_attr "cpu" "athlon")
7076 (const_string "vector")
7077 (eq_attr "alternative" "1,2")
7078 (const_string "vector")]
7079 (const_string "direct")))
7080 (set (attr "amdfam10_decode")
7081 (cond [(eq_attr "alternative" "0,1")
7082 (const_string "vector")]
7083 (const_string "direct")))
7084 (set_attr "mode" "HI")])
7090 (define_insn "*mulqi3_1"
7091 [(set (match_operand:QI 0 "register_operand" "=a")
7092 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7093 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7094 (clobber (reg:CC FLAGS_REG))]
7096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098 [(set_attr "type" "imul")
7099 (set_attr "length_immediate" "0")
7100 (set (attr "athlon_decode")
7101 (if_then_else (eq_attr "cpu" "athlon")
7102 (const_string "vector")
7103 (const_string "direct")))
7104 (set_attr "amdfam10_decode" "direct")
7105 (set_attr "mode" "QI")])
7107 (define_expand "<u>mul<mode><dwi>3"
7108 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7111 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7113 (match_operand:DWIH 2 "register_operand" ""))))
7114 (clobber (reg:CC FLAGS_REG))])]
7118 (define_expand "<u>mulqihi3"
7119 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7122 (match_operand:QI 1 "nonimmediate_operand" ""))
7124 (match_operand:QI 2 "register_operand" ""))))
7125 (clobber (reg:CC FLAGS_REG))])]
7126 "TARGET_QIMODE_MATH"
7129 (define_insn "*<u>mul<mode><dwi>3_1"
7130 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7133 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7135 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7136 (clobber (reg:CC FLAGS_REG))]
7137 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138 "<sgnprefix>mul{<imodesuffix>}\t%2"
7139 [(set_attr "type" "imul")
7140 (set_attr "length_immediate" "0")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "double")))
7145 (set_attr "amdfam10_decode" "double")
7146 (set_attr "mode" "<MODE>")])
7148 (define_insn "*<u>mulqihi3_1"
7149 [(set (match_operand:HI 0 "register_operand" "=a")
7152 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7154 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7155 (clobber (reg:CC FLAGS_REG))]
7157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7158 "<sgnprefix>mul{b}\t%2"
7159 [(set_attr "type" "imul")
7160 (set_attr "length_immediate" "0")
7161 (set (attr "athlon_decode")
7162 (if_then_else (eq_attr "cpu" "athlon")
7163 (const_string "vector")
7164 (const_string "direct")))
7165 (set_attr "amdfam10_decode" "direct")
7166 (set_attr "mode" "QI")])
7168 (define_expand "<s>mul<mode>3_highpart"
7169 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7174 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7176 (match_operand:SWI48 2 "register_operand" "")))
7178 (clobber (match_scratch:SWI48 3 ""))
7179 (clobber (reg:CC FLAGS_REG))])]
7181 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7183 (define_insn "*<s>muldi3_highpart_1"
7184 [(set (match_operand:DI 0 "register_operand" "=d")
7189 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7191 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7193 (clobber (match_scratch:DI 3 "=1"))
7194 (clobber (reg:CC FLAGS_REG))]
7196 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7197 "<sgnprefix>mul{q}\t%2"
7198 [(set_attr "type" "imul")
7199 (set_attr "length_immediate" "0")
7200 (set (attr "athlon_decode")
7201 (if_then_else (eq_attr "cpu" "athlon")
7202 (const_string "vector")
7203 (const_string "double")))
7204 (set_attr "amdfam10_decode" "double")
7205 (set_attr "mode" "DI")])
7207 (define_insn "*<s>mulsi3_highpart_1"
7208 [(set (match_operand:SI 0 "register_operand" "=d")
7213 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7215 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7217 (clobber (match_scratch:SI 3 "=1"))
7218 (clobber (reg:CC FLAGS_REG))]
7219 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7220 "<sgnprefix>mul{l}\t%2"
7221 [(set_attr "type" "imul")
7222 (set_attr "length_immediate" "0")
7223 (set (attr "athlon_decode")
7224 (if_then_else (eq_attr "cpu" "athlon")
7225 (const_string "vector")
7226 (const_string "double")))
7227 (set_attr "amdfam10_decode" "double")
7228 (set_attr "mode" "SI")])
7230 (define_insn "*<s>mulsi3_highpart_zext"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7232 (zero_extend:DI (truncate:SI
7234 (mult:DI (any_extend:DI
7235 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7237 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7239 (clobber (match_scratch:SI 3 "=1"))
7240 (clobber (reg:CC FLAGS_REG))]
7242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7243 "<sgnprefix>mul{l}\t%2"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "amdfam10_decode" "double")
7251 (set_attr "mode" "SI")])
7253 ;; The patterns that match these are at the end of this file.
7255 (define_expand "mulxf3"
7256 [(set (match_operand:XF 0 "register_operand" "")
7257 (mult:XF (match_operand:XF 1 "register_operand" "")
7258 (match_operand:XF 2 "register_operand" "")))]
7262 (define_expand "mul<mode>3"
7263 [(set (match_operand:MODEF 0 "register_operand" "")
7264 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7265 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7266 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7267 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7270 ;; Divide instructions
7272 (define_insn "<u>divqi3"
7273 [(set (match_operand:QI 0 "register_operand" "=a")
7275 (match_operand:HI 1 "register_operand" "0")
7276 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "TARGET_QIMODE_MATH"
7279 "<sgnprefix>div{b}\t%2"
7280 [(set_attr "type" "idiv")
7281 (set_attr "mode" "QI")])
7283 ;; The patterns that match these are at the end of this file.
7285 (define_expand "divxf3"
7286 [(set (match_operand:XF 0 "register_operand" "")
7287 (div:XF (match_operand:XF 1 "register_operand" "")
7288 (match_operand:XF 2 "register_operand" "")))]
7292 (define_expand "divdf3"
7293 [(set (match_operand:DF 0 "register_operand" "")
7294 (div:DF (match_operand:DF 1 "register_operand" "")
7295 (match_operand:DF 2 "nonimmediate_operand" "")))]
7296 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7297 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7300 (define_expand "divsf3"
7301 [(set (match_operand:SF 0 "register_operand" "")
7302 (div:SF (match_operand:SF 1 "register_operand" "")
7303 (match_operand:SF 2 "nonimmediate_operand" "")))]
7304 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7307 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7308 && flag_finite_math_only && !flag_trapping_math
7309 && flag_unsafe_math_optimizations)
7311 ix86_emit_swdivsf (operands[0], operands[1],
7312 operands[2], SFmode);
7317 ;; Divmod instructions.
7319 (define_expand "divmod<mode>4"
7320 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7322 (match_operand:SWIM248 1 "register_operand" "")
7323 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7324 (set (match_operand:SWIM248 3 "register_operand" "")
7325 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7326 (clobber (reg:CC FLAGS_REG))])]
7330 (define_insn_and_split "*divmod<mode>4"
7331 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7332 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7333 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7334 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7335 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7336 (clobber (reg:CC FLAGS_REG))]
7340 [(parallel [(set (match_dup 1)
7341 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7342 (clobber (reg:CC FLAGS_REG))])
7343 (parallel [(set (match_dup 0)
7344 (div:SWIM248 (match_dup 2) (match_dup 3)))
7346 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7348 (clobber (reg:CC FLAGS_REG))])]
7350 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7352 if (<MODE>mode != HImode
7353 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7354 operands[4] = operands[2];
7357 /* Avoid use of cltd in favor of a mov+shift. */
7358 emit_move_insn (operands[1], operands[2]);
7359 operands[4] = operands[1];
7362 [(set_attr "type" "multi")
7363 (set_attr "mode" "<MODE>")])
7365 (define_insn "*divmod<mode>4_noext"
7366 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7367 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7368 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7369 (set (match_operand:SWIM248 1 "register_operand" "=d")
7370 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7371 (use (match_operand:SWIM248 4 "register_operand" "1"))
7372 (clobber (reg:CC FLAGS_REG))]
7374 "idiv{<imodesuffix>}\t%3"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "<MODE>")])
7378 (define_expand "udivmod<mode>4"
7379 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7381 (match_operand:SWIM248 1 "register_operand" "")
7382 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7383 (set (match_operand:SWIM248 3 "register_operand" "")
7384 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7385 (clobber (reg:CC FLAGS_REG))])]
7389 (define_insn_and_split "*udivmod<mode>4"
7390 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7391 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7392 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7393 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7394 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7395 (clobber (reg:CC FLAGS_REG))]
7399 [(set (match_dup 1) (const_int 0))
7400 (parallel [(set (match_dup 0)
7401 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7403 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7405 (clobber (reg:CC FLAGS_REG))])]
7407 [(set_attr "type" "multi")
7408 (set_attr "mode" "<MODE>")])
7410 (define_insn "*udivmod<mode>4_noext"
7411 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7412 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7413 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7414 (set (match_operand:SWIM248 1 "register_operand" "=d")
7415 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7416 (use (match_operand:SWIM248 4 "register_operand" "1"))
7417 (clobber (reg:CC FLAGS_REG))]
7419 "div{<imodesuffix>}\t%3"
7420 [(set_attr "type" "idiv")
7421 (set_attr "mode" "<MODE>")])
7423 ;; We cannot use div/idiv for double division, because it causes
7424 ;; "division by zero" on the overflow and that's not what we expect
7425 ;; from truncate. Because true (non truncating) double division is
7426 ;; never generated, we can't create this insn anyway.
7429 ; [(set (match_operand:SI 0 "register_operand" "=a")
7431 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7433 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7434 ; (set (match_operand:SI 3 "register_operand" "=d")
7436 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7437 ; (clobber (reg:CC FLAGS_REG))]
7439 ; "div{l}\t{%2, %0|%0, %2}"
7440 ; [(set_attr "type" "idiv")])
7442 ;;- Logical AND instructions
7444 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7445 ;; Note that this excludes ah.
7447 (define_expand "testsi_ccno_1"
7448 [(set (reg:CCNO FLAGS_REG)
7450 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7451 (match_operand:SI 1 "nonmemory_operand" ""))
7456 (define_expand "testqi_ccz_1"
7457 [(set (reg:CCZ FLAGS_REG)
7458 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7459 (match_operand:QI 1 "nonmemory_operand" ""))
7464 (define_insn "*testdi_1"
7465 [(set (reg FLAGS_REG)
7468 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7469 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7472 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7474 test{l}\t{%k1, %k0|%k0, %k1}
7475 test{l}\t{%k1, %k0|%k0, %k1}
7476 test{q}\t{%1, %0|%0, %1}
7477 test{q}\t{%1, %0|%0, %1}
7478 test{q}\t{%1, %0|%0, %1}"
7479 [(set_attr "type" "test")
7480 (set_attr "modrm" "0,1,0,1,1")
7481 (set_attr "mode" "SI,SI,DI,DI,DI")])
7483 (define_insn "*testqi_1_maybe_si"
7484 [(set (reg FLAGS_REG)
7487 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7488 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7490 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7491 && ix86_match_ccmode (insn,
7492 CONST_INT_P (operands[1])
7493 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7495 if (which_alternative == 3)
7497 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7498 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7499 return "test{l}\t{%1, %k0|%k0, %1}";
7501 return "test{b}\t{%1, %0|%0, %1}";
7503 [(set_attr "type" "test")
7504 (set_attr "modrm" "0,1,1,1")
7505 (set_attr "mode" "QI,QI,QI,SI")
7506 (set_attr "pent_pair" "uv,np,uv,np")])
7508 (define_insn "*test<mode>_1"
7509 [(set (reg FLAGS_REG)
7512 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7513 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7515 "ix86_match_ccmode (insn, CCNOmode)
7516 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7517 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7518 [(set_attr "type" "test")
7519 (set_attr "modrm" "0,1,1")
7520 (set_attr "mode" "<MODE>")
7521 (set_attr "pent_pair" "uv,np,uv")])
7523 (define_expand "testqi_ext_ccno_0"
7524 [(set (reg:CCNO FLAGS_REG)
7528 (match_operand 0 "ext_register_operand" "")
7531 (match_operand 1 "const_int_operand" ""))
7536 (define_insn "*testqi_ext_0"
7537 [(set (reg FLAGS_REG)
7541 (match_operand 0 "ext_register_operand" "Q")
7544 (match_operand 1 "const_int_operand" "n"))
7546 "ix86_match_ccmode (insn, CCNOmode)"
7547 "test{b}\t{%1, %h0|%h0, %1}"
7548 [(set_attr "type" "test")
7549 (set_attr "mode" "QI")
7550 (set_attr "length_immediate" "1")
7551 (set_attr "modrm" "1")
7552 (set_attr "pent_pair" "np")])
7554 (define_insn "*testqi_ext_1_rex64"
7555 [(set (reg FLAGS_REG)
7559 (match_operand 0 "ext_register_operand" "Q")
7563 (match_operand:QI 1 "register_operand" "Q")))
7565 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7566 "test{b}\t{%1, %h0|%h0, %1}"
7567 [(set_attr "type" "test")
7568 (set_attr "mode" "QI")])
7570 (define_insn "*testqi_ext_1"
7571 [(set (reg FLAGS_REG)
7575 (match_operand 0 "ext_register_operand" "Q")
7579 (match_operand:QI 1 "general_operand" "Qm")))
7581 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7582 "test{b}\t{%1, %h0|%h0, %1}"
7583 [(set_attr "type" "test")
7584 (set_attr "mode" "QI")])
7586 (define_insn "*testqi_ext_2"
7587 [(set (reg FLAGS_REG)
7591 (match_operand 0 "ext_register_operand" "Q")
7595 (match_operand 1 "ext_register_operand" "Q")
7599 "ix86_match_ccmode (insn, CCNOmode)"
7600 "test{b}\t{%h1, %h0|%h0, %h1}"
7601 [(set_attr "type" "test")
7602 (set_attr "mode" "QI")])
7604 (define_insn "*testqi_ext_3_rex64"
7605 [(set (reg FLAGS_REG)
7606 (compare (zero_extract:DI
7607 (match_operand 0 "nonimmediate_operand" "rm")
7608 (match_operand:DI 1 "const_int_operand" "")
7609 (match_operand:DI 2 "const_int_operand" ""))
7612 && ix86_match_ccmode (insn, CCNOmode)
7613 && INTVAL (operands[1]) > 0
7614 && INTVAL (operands[2]) >= 0
7615 /* Ensure that resulting mask is zero or sign extended operand. */
7616 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7617 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7618 && INTVAL (operands[1]) > 32))
7619 && (GET_MODE (operands[0]) == SImode
7620 || GET_MODE (operands[0]) == DImode
7621 || GET_MODE (operands[0]) == HImode
7622 || GET_MODE (operands[0]) == QImode)"
7625 ;; Combine likes to form bit extractions for some tests. Humor it.
7626 (define_insn "*testqi_ext_3"
7627 [(set (reg FLAGS_REG)
7628 (compare (zero_extract:SI
7629 (match_operand 0 "nonimmediate_operand" "rm")
7630 (match_operand:SI 1 "const_int_operand" "")
7631 (match_operand:SI 2 "const_int_operand" ""))
7633 "ix86_match_ccmode (insn, CCNOmode)
7634 && INTVAL (operands[1]) > 0
7635 && INTVAL (operands[2]) >= 0
7636 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7637 && (GET_MODE (operands[0]) == SImode
7638 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7639 || GET_MODE (operands[0]) == HImode
7640 || GET_MODE (operands[0]) == QImode)"
7644 [(set (match_operand 0 "flags_reg_operand" "")
7645 (match_operator 1 "compare_operator"
7647 (match_operand 2 "nonimmediate_operand" "")
7648 (match_operand 3 "const_int_operand" "")
7649 (match_operand 4 "const_int_operand" ""))
7651 "ix86_match_ccmode (insn, CCNOmode)"
7652 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7654 rtx val = operands[2];
7655 HOST_WIDE_INT len = INTVAL (operands[3]);
7656 HOST_WIDE_INT pos = INTVAL (operands[4]);
7658 enum machine_mode mode, submode;
7660 mode = GET_MODE (val);
7663 /* ??? Combine likes to put non-volatile mem extractions in QImode
7664 no matter the size of the test. So find a mode that works. */
7665 if (! MEM_VOLATILE_P (val))
7667 mode = smallest_mode_for_size (pos + len, MODE_INT);
7668 val = adjust_address (val, mode, 0);
7671 else if (GET_CODE (val) == SUBREG
7672 && (submode = GET_MODE (SUBREG_REG (val)),
7673 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7674 && pos + len <= GET_MODE_BITSIZE (submode)
7675 && GET_MODE_CLASS (submode) == MODE_INT)
7677 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7679 val = SUBREG_REG (val);
7681 else if (mode == HImode && pos + len <= 8)
7683 /* Small HImode tests can be converted to QImode. */
7685 val = gen_lowpart (QImode, val);
7688 if (len == HOST_BITS_PER_WIDE_INT)
7691 mask = ((HOST_WIDE_INT)1 << len) - 1;
7694 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7697 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7698 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7699 ;; this is relatively important trick.
7700 ;; Do the conversion only post-reload to avoid limiting of the register class
7703 [(set (match_operand 0 "flags_reg_operand" "")
7704 (match_operator 1 "compare_operator"
7705 [(and (match_operand 2 "register_operand" "")
7706 (match_operand 3 "const_int_operand" ""))
7709 && QI_REG_P (operands[2])
7710 && GET_MODE (operands[2]) != QImode
7711 && ((ix86_match_ccmode (insn, CCZmode)
7712 && !(INTVAL (operands[3]) & ~(255 << 8)))
7713 || (ix86_match_ccmode (insn, CCNOmode)
7714 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7717 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7720 "operands[2] = gen_lowpart (SImode, operands[2]);
7721 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7724 [(set (match_operand 0 "flags_reg_operand" "")
7725 (match_operator 1 "compare_operator"
7726 [(and (match_operand 2 "nonimmediate_operand" "")
7727 (match_operand 3 "const_int_operand" ""))
7730 && GET_MODE (operands[2]) != QImode
7731 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7732 && ((ix86_match_ccmode (insn, CCZmode)
7733 && !(INTVAL (operands[3]) & ~255))
7734 || (ix86_match_ccmode (insn, CCNOmode)
7735 && !(INTVAL (operands[3]) & ~127)))"
7737 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7739 "operands[2] = gen_lowpart (QImode, operands[2]);
7740 operands[3] = gen_lowpart (QImode, operands[3]);")
7742 ;; %%% This used to optimize known byte-wide and operations to memory,
7743 ;; and sometimes to QImode registers. If this is considered useful,
7744 ;; it should be done with splitters.
7746 (define_expand "and<mode>3"
7747 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7748 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7749 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7751 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7753 (define_insn "*anddi_1"
7754 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7756 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7757 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7758 (clobber (reg:CC FLAGS_REG))]
7759 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7761 switch (get_attr_type (insn))
7765 enum machine_mode mode;
7767 gcc_assert (CONST_INT_P (operands[2]));
7768 if (INTVAL (operands[2]) == 0xff)
7772 gcc_assert (INTVAL (operands[2]) == 0xffff);
7776 operands[1] = gen_lowpart (mode, operands[1]);
7778 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7780 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7785 if (get_attr_mode (insn) == MODE_SI)
7786 return "and{l}\t{%k2, %k0|%k0, %k2}";
7788 return "and{q}\t{%2, %0|%0, %2}";
7791 [(set_attr "type" "alu,alu,alu,imovx")
7792 (set_attr "length_immediate" "*,*,*,0")
7793 (set (attr "prefix_rex")
7795 (and (eq_attr "type" "imovx")
7796 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7797 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7799 (const_string "*")))
7800 (set_attr "mode" "SI,DI,DI,SI")])
7802 (define_insn "*andsi_1"
7803 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7804 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7805 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "ix86_binary_operator_ok (AND, SImode, operands)"
7809 switch (get_attr_type (insn))
7813 enum machine_mode mode;
7815 gcc_assert (CONST_INT_P (operands[2]));
7816 if (INTVAL (operands[2]) == 0xff)
7820 gcc_assert (INTVAL (operands[2]) == 0xffff);
7824 operands[1] = gen_lowpart (mode, operands[1]);
7826 return "movz{bl|x}\t{%1, %0|%0, %1}";
7828 return "movz{wl|x}\t{%1, %0|%0, %1}";
7832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7833 return "and{l}\t{%2, %0|%0, %2}";
7836 [(set_attr "type" "alu,alu,imovx")
7837 (set (attr "prefix_rex")
7839 (and (eq_attr "type" "imovx")
7840 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7841 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7843 (const_string "*")))
7844 (set_attr "length_immediate" "*,*,0")
7845 (set_attr "mode" "SI")])
7847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7848 (define_insn "*andsi_1_zext"
7849 [(set (match_operand:DI 0 "register_operand" "=r")
7851 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7852 (match_operand:SI 2 "general_operand" "g"))))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7855 "and{l}\t{%2, %k0|%k0, %2}"
7856 [(set_attr "type" "alu")
7857 (set_attr "mode" "SI")])
7859 (define_insn "*andhi_1"
7860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7861 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7862 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7863 (clobber (reg:CC FLAGS_REG))]
7864 "ix86_binary_operator_ok (AND, HImode, operands)"
7866 switch (get_attr_type (insn))
7869 gcc_assert (CONST_INT_P (operands[2]));
7870 gcc_assert (INTVAL (operands[2]) == 0xff);
7871 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7874 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7876 return "and{w}\t{%2, %0|%0, %2}";
7879 [(set_attr "type" "alu,alu,imovx")
7880 (set_attr "length_immediate" "*,*,0")
7881 (set (attr "prefix_rex")
7883 (and (eq_attr "type" "imovx")
7884 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7886 (const_string "*")))
7887 (set_attr "mode" "HI,HI,SI")])
7889 ;; %%% Potential partial reg stall on alternative 2. What to do?
7890 (define_insn "*andqi_1"
7891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7892 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "ix86_binary_operator_ok (AND, QImode, operands)"
7897 and{b}\t{%2, %0|%0, %2}
7898 and{b}\t{%2, %0|%0, %2}
7899 and{l}\t{%k2, %k0|%k0, %k2}"
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "QI,QI,SI")])
7903 (define_insn "*andqi_1_slp"
7904 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7905 (and:QI (match_dup 0)
7906 (match_operand:QI 1 "general_operand" "qn,qmn")))
7907 (clobber (reg:CC FLAGS_REG))]
7908 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7910 "and{b}\t{%1, %0|%0, %1}"
7911 [(set_attr "type" "alu1")
7912 (set_attr "mode" "QI")])
7915 [(set (match_operand 0 "register_operand" "")
7917 (const_int -65536)))
7918 (clobber (reg:CC FLAGS_REG))]
7919 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7920 || optimize_function_for_size_p (cfun)"
7921 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7922 "operands[1] = gen_lowpart (HImode, operands[0]);")
7925 [(set (match_operand 0 "ext_register_operand" "")
7928 (clobber (reg:CC FLAGS_REG))]
7929 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7930 && reload_completed"
7931 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7932 "operands[1] = gen_lowpart (QImode, operands[0]);")
7935 [(set (match_operand 0 "ext_register_operand" "")
7937 (const_int -65281)))
7938 (clobber (reg:CC FLAGS_REG))]
7939 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940 && reload_completed"
7941 [(parallel [(set (zero_extract:SI (match_dup 0)
7945 (zero_extract:SI (match_dup 0)
7948 (zero_extract:SI (match_dup 0)
7951 (clobber (reg:CC FLAGS_REG))])]
7952 "operands[0] = gen_lowpart (SImode, operands[0]);")
7954 (define_insn "*anddi_2"
7955 [(set (reg FLAGS_REG)
7958 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7959 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7961 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7962 (and:DI (match_dup 1) (match_dup 2)))]
7963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7964 && ix86_binary_operator_ok (AND, DImode, operands)"
7966 and{l}\t{%k2, %k0|%k0, %k2}
7967 and{q}\t{%2, %0|%0, %2}
7968 and{q}\t{%2, %0|%0, %2}"
7969 [(set_attr "type" "alu")
7970 (set_attr "mode" "SI,DI,DI")])
7972 (define_insn "*andqi_2_maybe_si"
7973 [(set (reg FLAGS_REG)
7975 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7976 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7978 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7979 (and:QI (match_dup 1) (match_dup 2)))]
7980 "ix86_binary_operator_ok (AND, QImode, operands)
7981 && ix86_match_ccmode (insn,
7982 CONST_INT_P (operands[2])
7983 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7985 if (which_alternative == 2)
7987 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7988 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7989 return "and{l}\t{%2, %k0|%k0, %2}";
7991 return "and{b}\t{%2, %0|%0, %2}";
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "QI,QI,SI")])
7996 (define_insn "*and<mode>_2"
7997 [(set (reg FLAGS_REG)
7998 (compare (and:SWI124
7999 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8000 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8002 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8003 (and:SWI124 (match_dup 1) (match_dup 2)))]
8004 "ix86_match_ccmode (insn, CCNOmode)
8005 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8006 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8007 [(set_attr "type" "alu")
8008 (set_attr "mode" "<MODE>")])
8010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8011 (define_insn "*andsi_2_zext"
8012 [(set (reg FLAGS_REG)
8014 (match_operand:SI 1 "nonimmediate_operand" "%0")
8015 (match_operand:SI 2 "general_operand" "g"))
8017 (set (match_operand:DI 0 "register_operand" "=r")
8018 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8019 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8020 && ix86_binary_operator_ok (AND, SImode, operands)"
8021 "and{l}\t{%2, %k0|%k0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "SI")])
8025 (define_insn "*andqi_2_slp"
8026 [(set (reg FLAGS_REG)
8028 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8029 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8031 (set (strict_low_part (match_dup 0))
8032 (and:QI (match_dup 0) (match_dup 1)))]
8033 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034 && ix86_match_ccmode (insn, CCNOmode)
8035 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8036 "and{b}\t{%1, %0|%0, %1}"
8037 [(set_attr "type" "alu1")
8038 (set_attr "mode" "QI")])
8040 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8041 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8042 ;; for a QImode operand, which of course failed.
8043 (define_insn "andqi_ext_0"
8044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8049 (match_operand 1 "ext_register_operand" "0")
8052 (match_operand 2 "const_int_operand" "n")))
8053 (clobber (reg:CC FLAGS_REG))]
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "1")
8058 (set_attr "modrm" "1")
8059 (set_attr "mode" "QI")])
8061 ;; Generated by peephole translating test to and. This shows up
8062 ;; often in fp comparisons.
8063 (define_insn "*andqi_ext_0_cc"
8064 [(set (reg FLAGS_REG)
8068 (match_operand 1 "ext_register_operand" "0")
8071 (match_operand 2 "const_int_operand" "n"))
8073 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8082 "ix86_match_ccmode (insn, CCNOmode)"
8083 "and{b}\t{%2, %h0|%h0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "length_immediate" "1")
8086 (set_attr "modrm" "1")
8087 (set_attr "mode" "QI")])
8089 (define_insn "*andqi_ext_1_rex64"
8090 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8095 (match_operand 1 "ext_register_operand" "0")
8099 (match_operand 2 "ext_register_operand" "Q"))))
8100 (clobber (reg:CC FLAGS_REG))]
8102 "and{b}\t{%2, %h0|%h0, %2}"
8103 [(set_attr "type" "alu")
8104 (set_attr "length_immediate" "0")
8105 (set_attr "mode" "QI")])
8107 (define_insn "*andqi_ext_1"
8108 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8113 (match_operand 1 "ext_register_operand" "0")
8117 (match_operand:QI 2 "general_operand" "Qm"))))
8118 (clobber (reg:CC FLAGS_REG))]
8120 "and{b}\t{%2, %h0|%h0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "length_immediate" "0")
8123 (set_attr "mode" "QI")])
8125 (define_insn "*andqi_ext_2"
8126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8131 (match_operand 1 "ext_register_operand" "%0")
8135 (match_operand 2 "ext_register_operand" "Q")
8138 (clobber (reg:CC FLAGS_REG))]
8140 "and{b}\t{%h2, %h0|%h0, %h2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "length_immediate" "0")
8143 (set_attr "mode" "QI")])
8145 ;; Convert wide AND instructions with immediate operand to shorter QImode
8146 ;; equivalents when possible.
8147 ;; Don't do the splitting with memory operands, since it introduces risk
8148 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8149 ;; for size, but that can (should?) be handled by generic code instead.
8151 [(set (match_operand 0 "register_operand" "")
8152 (and (match_operand 1 "register_operand" "")
8153 (match_operand 2 "const_int_operand" "")))
8154 (clobber (reg:CC FLAGS_REG))]
8156 && QI_REG_P (operands[0])
8157 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158 && !(~INTVAL (operands[2]) & ~(255 << 8))
8159 && GET_MODE (operands[0]) != QImode"
8160 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8161 (and:SI (zero_extract:SI (match_dup 1)
8162 (const_int 8) (const_int 8))
8164 (clobber (reg:CC FLAGS_REG))])]
8165 "operands[0] = gen_lowpart (SImode, operands[0]);
8166 operands[1] = gen_lowpart (SImode, operands[1]);
8167 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8169 ;; Since AND can be encoded with sign extended immediate, this is only
8170 ;; profitable when 7th bit is not set.
8172 [(set (match_operand 0 "register_operand" "")
8173 (and (match_operand 1 "general_operand" "")
8174 (match_operand 2 "const_int_operand" "")))
8175 (clobber (reg:CC FLAGS_REG))]
8177 && ANY_QI_REG_P (operands[0])
8178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8179 && !(~INTVAL (operands[2]) & ~255)
8180 && !(INTVAL (operands[2]) & 128)
8181 && GET_MODE (operands[0]) != QImode"
8182 [(parallel [(set (strict_low_part (match_dup 0))
8183 (and:QI (match_dup 1)
8185 (clobber (reg:CC FLAGS_REG))])]
8186 "operands[0] = gen_lowpart (QImode, operands[0]);
8187 operands[1] = gen_lowpart (QImode, operands[1]);
8188 operands[2] = gen_lowpart (QImode, operands[2]);")
8190 ;; Logical inclusive and exclusive OR instructions
8192 ;; %%% This used to optimize known byte-wide and operations to memory.
8193 ;; If this is considered useful, it should be done with splitters.
8195 (define_expand "<code><mode>3"
8196 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8197 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8198 (match_operand:SWIM 2 "<general_operand>" "")))]
8200 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8202 (define_insn "*<code><mode>_1"
8203 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8205 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8206 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8207 (clobber (reg:CC FLAGS_REG))]
8208 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8209 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8210 [(set_attr "type" "alu")
8211 (set_attr "mode" "<MODE>")])
8213 ;; %%% Potential partial reg stall on alternative 2. What to do?
8214 (define_insn "*<code>qi_1"
8215 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8216 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8217 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8218 (clobber (reg:CC FLAGS_REG))]
8219 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8221 <logic>{b}\t{%2, %0|%0, %2}
8222 <logic>{b}\t{%2, %0|%0, %2}
8223 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "mode" "QI,QI,SI")])
8227 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8228 (define_insn "*<code>si_1_zext"
8229 [(set (match_operand:DI 0 "register_operand" "=r")
8231 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8232 (match_operand:SI 2 "general_operand" "g"))))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8235 "<logic>{l}\t{%2, %k0|%k0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "SI")])
8239 (define_insn "*<code>si_1_zext_imm"
8240 [(set (match_operand:DI 0 "register_operand" "=r")
8242 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8243 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8246 "<logic>{l}\t{%2, %k0|%k0, %2}"
8247 [(set_attr "type" "alu")
8248 (set_attr "mode" "SI")])
8250 (define_insn "*<code>qi_1_slp"
8251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8252 (any_or:QI (match_dup 0)
8253 (match_operand:QI 1 "general_operand" "qmn,qn")))
8254 (clobber (reg:CC FLAGS_REG))]
8255 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8256 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8257 "<logic>{b}\t{%1, %0|%0, %1}"
8258 [(set_attr "type" "alu1")
8259 (set_attr "mode" "QI")])
8261 (define_insn "*<code><mode>_2"
8262 [(set (reg FLAGS_REG)
8263 (compare (any_or:SWI
8264 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8265 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8267 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8268 (any_or:SWI (match_dup 1) (match_dup 2)))]
8269 "ix86_match_ccmode (insn, CCNOmode)
8270 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8271 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "mode" "<MODE>")])
8275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8276 ;; ??? Special case for immediate operand is missing - it is tricky.
8277 (define_insn "*<code>si_2_zext"
8278 [(set (reg FLAGS_REG)
8279 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8280 (match_operand:SI 2 "general_operand" "g"))
8282 (set (match_operand:DI 0 "register_operand" "=r")
8283 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8284 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8285 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8286 "<logic>{l}\t{%2, %k0|%k0, %2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "SI")])
8290 (define_insn "*<code>si_2_zext_imm"
8291 [(set (reg FLAGS_REG)
8293 (match_operand:SI 1 "nonimmediate_operand" "%0")
8294 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8296 (set (match_operand:DI 0 "register_operand" "=r")
8297 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8298 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8299 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8300 "<logic>{l}\t{%2, %k0|%k0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "SI")])
8304 (define_insn "*<code>qi_2_slp"
8305 [(set (reg FLAGS_REG)
8306 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8307 (match_operand:QI 1 "general_operand" "qmn,qn"))
8309 (set (strict_low_part (match_dup 0))
8310 (any_or:QI (match_dup 0) (match_dup 1)))]
8311 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8312 && ix86_match_ccmode (insn, CCNOmode)
8313 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8314 "<logic>{b}\t{%1, %0|%0, %1}"
8315 [(set_attr "type" "alu1")
8316 (set_attr "mode" "QI")])
8318 (define_insn "*<code><mode>_3"
8319 [(set (reg FLAGS_REG)
8320 (compare (any_or:SWI
8321 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8322 (match_operand:SWI 2 "<general_operand>" "<g>"))
8324 (clobber (match_scratch:SWI 0 "=<r>"))]
8325 "ix86_match_ccmode (insn, CCNOmode)
8326 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8327 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "<MODE>")])
8331 (define_insn "*<code>qi_ext_0"
8332 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8337 (match_operand 1 "ext_register_operand" "0")
8340 (match_operand 2 "const_int_operand" "n")))
8341 (clobber (reg:CC FLAGS_REG))]
8342 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8343 "<logic>{b}\t{%2, %h0|%h0, %2}"
8344 [(set_attr "type" "alu")
8345 (set_attr "length_immediate" "1")
8346 (set_attr "modrm" "1")
8347 (set_attr "mode" "QI")])
8349 (define_insn "*<code>qi_ext_1_rex64"
8350 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8355 (match_operand 1 "ext_register_operand" "0")
8359 (match_operand 2 "ext_register_operand" "Q"))))
8360 (clobber (reg:CC FLAGS_REG))]
8362 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8363 "<logic>{b}\t{%2, %h0|%h0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "length_immediate" "0")
8366 (set_attr "mode" "QI")])
8368 (define_insn "*<code>qi_ext_1"
8369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374 (match_operand 1 "ext_register_operand" "0")
8378 (match_operand:QI 2 "general_operand" "Qm"))))
8379 (clobber (reg:CC FLAGS_REG))]
8381 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8382 "<logic>{b}\t{%2, %h0|%h0, %2}"
8383 [(set_attr "type" "alu")
8384 (set_attr "length_immediate" "0")
8385 (set_attr "mode" "QI")])
8387 (define_insn "*<code>qi_ext_2"
8388 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8392 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8395 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8398 (clobber (reg:CC FLAGS_REG))]
8399 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8400 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8401 [(set_attr "type" "alu")
8402 (set_attr "length_immediate" "0")
8403 (set_attr "mode" "QI")])
8406 [(set (match_operand 0 "register_operand" "")
8407 (any_or (match_operand 1 "register_operand" "")
8408 (match_operand 2 "const_int_operand" "")))
8409 (clobber (reg:CC FLAGS_REG))]
8411 && QI_REG_P (operands[0])
8412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413 && !(INTVAL (operands[2]) & ~(255 << 8))
8414 && GET_MODE (operands[0]) != QImode"
8415 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8416 (any_or:SI (zero_extract:SI (match_dup 1)
8417 (const_int 8) (const_int 8))
8419 (clobber (reg:CC FLAGS_REG))])]
8420 "operands[0] = gen_lowpart (SImode, operands[0]);
8421 operands[1] = gen_lowpart (SImode, operands[1]);
8422 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8424 ;; Since OR can be encoded with sign extended immediate, this is only
8425 ;; profitable when 7th bit is set.
8427 [(set (match_operand 0 "register_operand" "")
8428 (any_or (match_operand 1 "general_operand" "")
8429 (match_operand 2 "const_int_operand" "")))
8430 (clobber (reg:CC FLAGS_REG))]
8432 && ANY_QI_REG_P (operands[0])
8433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && !(INTVAL (operands[2]) & ~255)
8435 && (INTVAL (operands[2]) & 128)
8436 && GET_MODE (operands[0]) != QImode"
8437 [(parallel [(set (strict_low_part (match_dup 0))
8438 (any_or:QI (match_dup 1)
8440 (clobber (reg:CC FLAGS_REG))])]
8441 "operands[0] = gen_lowpart (QImode, operands[0]);
8442 operands[1] = gen_lowpart (QImode, operands[1]);
8443 operands[2] = gen_lowpart (QImode, operands[2]);")
8445 (define_expand "xorqi_cc_ext_1"
8447 (set (reg:CCNO FLAGS_REG)
8451 (match_operand 1 "ext_register_operand" "")
8454 (match_operand:QI 2 "general_operand" ""))
8456 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8468 (define_insn "*xorqi_cc_ext_1_rex64"
8469 [(set (reg FLAGS_REG)
8473 (match_operand 1 "ext_register_operand" "0")
8476 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8478 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8488 "xor{b}\t{%2, %h0|%h0, %2}"
8489 [(set_attr "type" "alu")
8490 (set_attr "modrm" "1")
8491 (set_attr "mode" "QI")])
8493 (define_insn "*xorqi_cc_ext_1"
8494 [(set (reg FLAGS_REG)
8498 (match_operand 1 "ext_register_operand" "0")
8501 (match_operand:QI 2 "general_operand" "qmn"))
8503 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8512 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8513 "xor{b}\t{%2, %h0|%h0, %2}"
8514 [(set_attr "type" "alu")
8515 (set_attr "modrm" "1")
8516 (set_attr "mode" "QI")])
8518 ;; Negation instructions
8520 (define_expand "neg<mode>2"
8521 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8522 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8524 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8526 (define_insn_and_split "*neg<dwi>2_doubleword"
8527 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8528 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8529 (clobber (reg:CC FLAGS_REG))]
8530 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8534 [(set (reg:CCZ FLAGS_REG)
8535 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8536 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8539 (plus:DWIH (match_dup 3)
8540 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8542 (clobber (reg:CC FLAGS_REG))])
8545 (neg:DWIH (match_dup 2)))
8546 (clobber (reg:CC FLAGS_REG))])]
8547 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8549 (define_insn "*neg<mode>2_1"
8550 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8551 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8552 (clobber (reg:CC FLAGS_REG))]
8553 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8554 "neg{<imodesuffix>}\t%0"
8555 [(set_attr "type" "negnot")
8556 (set_attr "mode" "<MODE>")])
8558 ;; Combine is quite creative about this pattern.
8559 (define_insn "*negsi2_1_zext"
8560 [(set (match_operand:DI 0 "register_operand" "=r")
8562 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8565 (clobber (reg:CC FLAGS_REG))]
8566 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8568 [(set_attr "type" "negnot")
8569 (set_attr "mode" "SI")])
8571 ;; The problem with neg is that it does not perform (compare x 0),
8572 ;; it really performs (compare 0 x), which leaves us with the zero
8573 ;; flag being the only useful item.
8575 (define_insn "*neg<mode>2_cmpz"
8576 [(set (reg:CCZ FLAGS_REG)
8578 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8580 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8581 (neg:SWI (match_dup 1)))]
8582 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8583 "neg{<imodesuffix>}\t%0"
8584 [(set_attr "type" "negnot")
8585 (set_attr "mode" "<MODE>")])
8587 (define_insn "*negsi2_cmpz_zext"
8588 [(set (reg:CCZ FLAGS_REG)
8592 (match_operand:DI 1 "register_operand" "0")
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8600 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8602 [(set_attr "type" "negnot")
8603 (set_attr "mode" "SI")])
8605 ;; Changing of sign for FP values is doable using integer unit too.
8607 (define_expand "<code><mode>2"
8608 [(set (match_operand:X87MODEF 0 "register_operand" "")
8609 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8610 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8611 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8613 (define_insn "*absneg<mode>2_mixed"
8614 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8615 (match_operator:MODEF 3 "absneg_operator"
8616 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8617 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8622 (define_insn "*absneg<mode>2_sse"
8623 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8624 (match_operator:MODEF 3 "absneg_operator"
8625 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8626 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8627 (clobber (reg:CC FLAGS_REG))]
8628 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8631 (define_insn "*absneg<mode>2_i387"
8632 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8633 (match_operator:X87MODEF 3 "absneg_operator"
8634 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8635 (use (match_operand 2 "" ""))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8640 (define_expand "<code>tf2"
8641 [(set (match_operand:TF 0 "register_operand" "")
8642 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8644 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8646 (define_insn "*absnegtf2_sse"
8647 [(set (match_operand:TF 0 "register_operand" "=x,x")
8648 (match_operator:TF 3 "absneg_operator"
8649 [(match_operand:TF 1 "register_operand" "0,x")]))
8650 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8651 (clobber (reg:CC FLAGS_REG))]
8655 ;; Splitters for fp abs and neg.
8658 [(set (match_operand 0 "fp_register_operand" "")
8659 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8660 (use (match_operand 2 "" ""))
8661 (clobber (reg:CC FLAGS_REG))]
8663 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8666 [(set (match_operand 0 "register_operand" "")
8667 (match_operator 3 "absneg_operator"
8668 [(match_operand 1 "register_operand" "")]))
8669 (use (match_operand 2 "nonimmediate_operand" ""))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "reload_completed && SSE_REG_P (operands[0])"
8672 [(set (match_dup 0) (match_dup 3))]
8674 enum machine_mode mode = GET_MODE (operands[0]);
8675 enum machine_mode vmode = GET_MODE (operands[2]);
8678 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8679 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8680 if (operands_match_p (operands[0], operands[2]))
8683 operands[1] = operands[2];
8686 if (GET_CODE (operands[3]) == ABS)
8687 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8689 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8694 [(set (match_operand:SF 0 "register_operand" "")
8695 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8696 (use (match_operand:V4SF 2 "" ""))
8697 (clobber (reg:CC FLAGS_REG))]
8699 [(parallel [(set (match_dup 0) (match_dup 1))
8700 (clobber (reg:CC FLAGS_REG))])]
8703 operands[0] = gen_lowpart (SImode, operands[0]);
8704 if (GET_CODE (operands[1]) == ABS)
8706 tmp = gen_int_mode (0x7fffffff, SImode);
8707 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8711 tmp = gen_int_mode (0x80000000, SImode);
8712 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8718 [(set (match_operand:DF 0 "register_operand" "")
8719 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8720 (use (match_operand 2 "" ""))
8721 (clobber (reg:CC FLAGS_REG))]
8723 [(parallel [(set (match_dup 0) (match_dup 1))
8724 (clobber (reg:CC FLAGS_REG))])]
8729 tmp = gen_lowpart (DImode, operands[0]);
8730 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8733 if (GET_CODE (operands[1]) == ABS)
8736 tmp = gen_rtx_NOT (DImode, tmp);
8740 operands[0] = gen_highpart (SImode, operands[0]);
8741 if (GET_CODE (operands[1]) == ABS)
8743 tmp = gen_int_mode (0x7fffffff, SImode);
8744 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8748 tmp = gen_int_mode (0x80000000, SImode);
8749 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756 [(set (match_operand:XF 0 "register_operand" "")
8757 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8758 (use (match_operand 2 "" ""))
8759 (clobber (reg:CC FLAGS_REG))]
8761 [(parallel [(set (match_dup 0) (match_dup 1))
8762 (clobber (reg:CC FLAGS_REG))])]
8765 operands[0] = gen_rtx_REG (SImode,
8766 true_regnum (operands[0])
8767 + (TARGET_64BIT ? 1 : 2));
8768 if (GET_CODE (operands[1]) == ABS)
8770 tmp = GEN_INT (0x7fff);
8771 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8775 tmp = GEN_INT (0x8000);
8776 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8781 ;; Conditionalize these after reload. If they match before reload, we
8782 ;; lose the clobber and ability to use integer instructions.
8784 (define_insn "*<code><mode>2_1"
8785 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8786 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8788 && (reload_completed
8789 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8790 "f<absneg_mnemonic>"
8791 [(set_attr "type" "fsgn")
8792 (set_attr "mode" "<MODE>")])
8794 (define_insn "*<code>extendsfdf2"
8795 [(set (match_operand:DF 0 "register_operand" "=f")
8796 (absneg:DF (float_extend:DF
8797 (match_operand:SF 1 "register_operand" "0"))))]
8798 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8799 "f<absneg_mnemonic>"
8800 [(set_attr "type" "fsgn")
8801 (set_attr "mode" "DF")])
8803 (define_insn "*<code>extendsfxf2"
8804 [(set (match_operand:XF 0 "register_operand" "=f")
8805 (absneg:XF (float_extend:XF
8806 (match_operand:SF 1 "register_operand" "0"))))]
8808 "f<absneg_mnemonic>"
8809 [(set_attr "type" "fsgn")
8810 (set_attr "mode" "XF")])
8812 (define_insn "*<code>extenddfxf2"
8813 [(set (match_operand:XF 0 "register_operand" "=f")
8814 (absneg:XF (float_extend:XF
8815 (match_operand:DF 1 "register_operand" "0"))))]
8817 "f<absneg_mnemonic>"
8818 [(set_attr "type" "fsgn")
8819 (set_attr "mode" "XF")])
8821 ;; Copysign instructions
8823 (define_mode_iterator CSGNMODE [SF DF TF])
8824 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8826 (define_expand "copysign<mode>3"
8827 [(match_operand:CSGNMODE 0 "register_operand" "")
8828 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8829 (match_operand:CSGNMODE 2 "register_operand" "")]
8830 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8831 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8833 ix86_expand_copysign (operands);
8837 (define_insn_and_split "copysign<mode>3_const"
8838 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8840 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8841 (match_operand:CSGNMODE 2 "register_operand" "0")
8842 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8844 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8845 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8847 "&& reload_completed"
8850 ix86_split_copysign_const (operands);
8854 (define_insn "copysign<mode>3_var"
8855 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8857 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8858 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8859 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8860 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8862 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8863 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8864 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8868 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8870 [(match_operand:CSGNMODE 2 "register_operand" "")
8871 (match_operand:CSGNMODE 3 "register_operand" "")
8872 (match_operand:<CSGNVMODE> 4 "" "")
8873 (match_operand:<CSGNVMODE> 5 "" "")]
8875 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8876 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8877 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8878 && reload_completed"
8881 ix86_split_copysign_var (operands);
8885 ;; One complement instructions
8887 (define_expand "one_cmpl<mode>2"
8888 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8889 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8891 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8893 (define_insn "*one_cmpl<mode>2_1"
8894 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8895 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8896 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8897 "not{<imodesuffix>}\t%0"
8898 [(set_attr "type" "negnot")
8899 (set_attr "mode" "<MODE>")])
8901 ;; %%% Potential partial reg stall on alternative 1. What to do?
8902 (define_insn "*one_cmplqi2_1"
8903 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8904 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8905 "ix86_unary_operator_ok (NOT, QImode, operands)"
8909 [(set_attr "type" "negnot")
8910 (set_attr "mode" "QI,SI")])
8912 ;; ??? Currently never generated - xor is used instead.
8913 (define_insn "*one_cmplsi2_1_zext"
8914 [(set (match_operand:DI 0 "register_operand" "=r")
8916 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8917 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8919 [(set_attr "type" "negnot")
8920 (set_attr "mode" "SI")])
8922 (define_insn "*one_cmpl<mode>2_2"
8923 [(set (reg FLAGS_REG)
8924 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8926 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8927 (not:SWI (match_dup 1)))]
8928 "ix86_match_ccmode (insn, CCNOmode)
8929 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8931 [(set_attr "type" "alu1")
8932 (set_attr "mode" "<MODE>")])
8935 [(set (match_operand 0 "flags_reg_operand" "")
8936 (match_operator 2 "compare_operator"
8937 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8939 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8940 (not:SWI (match_dup 3)))]
8941 "ix86_match_ccmode (insn, CCNOmode)"
8942 [(parallel [(set (match_dup 0)
8943 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8946 (xor:SWI (match_dup 3) (const_int -1)))])]
8949 ;; ??? Currently never generated - xor is used instead.
8950 (define_insn "*one_cmplsi2_2_zext"
8951 [(set (reg FLAGS_REG)
8952 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8954 (set (match_operand:DI 0 "register_operand" "=r")
8955 (zero_extend:DI (not:SI (match_dup 1))))]
8956 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8957 && ix86_unary_operator_ok (NOT, SImode, operands)"
8959 [(set_attr "type" "alu1")
8960 (set_attr "mode" "SI")])
8963 [(set (match_operand 0 "flags_reg_operand" "")
8964 (match_operator 2 "compare_operator"
8965 [(not:SI (match_operand:SI 3 "register_operand" ""))
8967 (set (match_operand:DI 1 "register_operand" "")
8968 (zero_extend:DI (not:SI (match_dup 3))))]
8969 "ix86_match_ccmode (insn, CCNOmode)"
8970 [(parallel [(set (match_dup 0)
8971 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8974 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
8977 ;; Shift instructions
8979 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8980 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8981 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8982 ;; from the assembler input.
8984 ;; This instruction shifts the target reg/mem as usual, but instead of
8985 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8986 ;; is a left shift double, bits are taken from the high order bits of
8987 ;; reg, else if the insn is a shift right double, bits are taken from the
8988 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8989 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8991 ;; Since sh[lr]d does not change the `reg' operand, that is done
8992 ;; separately, making all shifts emit pairs of shift double and normal
8993 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8994 ;; support a 63 bit shift, each shift where the count is in a reg expands
8995 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8997 ;; If the shift count is a constant, we need never emit more than one
8998 ;; shift pair, instead using moves and sign extension for counts greater
9001 (define_expand "ashl<mode>3"
9002 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9003 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9004 (match_operand:QI 2 "nonmemory_operand" "")))]
9006 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9008 (define_insn "*ashl<mode>3_doubleword"
9009 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9010 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9011 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9012 (clobber (reg:CC FLAGS_REG))]
9015 [(set_attr "type" "multi")])
9018 [(set (match_operand:DWI 0 "register_operand" "")
9019 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9020 (match_operand:QI 2 "nonmemory_operand" "")))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9024 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9026 ;; By default we don't ask for a scratch register, because when DWImode
9027 ;; values are manipulated, registers are already at a premium. But if
9028 ;; we have one handy, we won't turn it away.
9031 [(match_scratch:DWIH 3 "r")
9032 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9034 (match_operand:<DWI> 1 "nonmemory_operand" "")
9035 (match_operand:QI 2 "nonmemory_operand" "")))
9036 (clobber (reg:CC FLAGS_REG))])
9040 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9042 (define_insn "x86_64_shld"
9043 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9044 (ior:DI (ashift:DI (match_dup 0)
9045 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9046 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9047 (minus:QI (const_int 64) (match_dup 2)))))
9048 (clobber (reg:CC FLAGS_REG))]
9050 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9051 [(set_attr "type" "ishift")
9052 (set_attr "prefix_0f" "1")
9053 (set_attr "mode" "DI")
9054 (set_attr "athlon_decode" "vector")
9055 (set_attr "amdfam10_decode" "vector")])
9057 (define_insn "x86_shld"
9058 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9059 (ior:SI (ashift:SI (match_dup 0)
9060 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9061 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9062 (minus:QI (const_int 32) (match_dup 2)))))
9063 (clobber (reg:CC FLAGS_REG))]
9065 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9066 [(set_attr "type" "ishift")
9067 (set_attr "prefix_0f" "1")
9068 (set_attr "mode" "SI")
9069 (set_attr "pent_pair" "np")
9070 (set_attr "athlon_decode" "vector")
9071 (set_attr "amdfam10_decode" "vector")])
9073 (define_expand "x86_shift<mode>_adj_1"
9074 [(set (reg:CCZ FLAGS_REG)
9075 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9078 (set (match_operand:SWI48 0 "register_operand" "")
9079 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9080 (match_operand:SWI48 1 "register_operand" "")
9083 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9084 (match_operand:SWI48 3 "register_operand" "r")
9087 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9089 (define_expand "x86_shift<mode>_adj_2"
9090 [(use (match_operand:SWI48 0 "register_operand" ""))
9091 (use (match_operand:SWI48 1 "register_operand" ""))
9092 (use (match_operand:QI 2 "register_operand" ""))]
9095 rtx label = gen_label_rtx ();
9098 emit_insn (gen_testqi_ccz_1 (operands[2],
9099 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9101 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9102 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9103 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9104 gen_rtx_LABEL_REF (VOIDmode, label),
9106 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9107 JUMP_LABEL (tmp) = label;
9109 emit_move_insn (operands[0], operands[1]);
9110 ix86_expand_clear (operands[1]);
9113 LABEL_NUSES (label) = 1;
9118 (define_insn "*ashl<mode>3_1"
9119 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9120 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9121 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9122 (clobber (reg:CC FLAGS_REG))]
9123 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9125 switch (get_attr_type (insn))
9131 gcc_assert (operands[2] == const1_rtx);
9132 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9133 return "add{<imodesuffix>}\t%0, %0";
9136 if (operands[2] == const1_rtx
9137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9138 return "sal{<imodesuffix>}\t%0";
9140 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9144 (cond [(eq_attr "alternative" "1")
9145 (const_string "lea")
9146 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9148 (match_operand 0 "register_operand" ""))
9149 (match_operand 2 "const1_operand" ""))
9150 (const_string "alu")
9152 (const_string "ishift")))
9153 (set (attr "length_immediate")
9155 (ior (eq_attr "type" "alu")
9156 (and (eq_attr "type" "ishift")
9157 (and (match_operand 2 "const1_operand" "")
9158 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9161 (const_string "*")))
9162 (set_attr "mode" "<MODE>")])
9164 (define_insn "*ashlsi3_1_zext"
9165 [(set (match_operand:DI 0 "register_operand" "=r,r")
9167 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9168 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9172 switch (get_attr_type (insn))
9178 gcc_assert (operands[2] == const1_rtx);
9179 return "add{l}\t%k0, %k0";
9182 if (operands[2] == const1_rtx
9183 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9184 return "sal{l}\t%k0";
9186 return "sal{l}\t{%2, %k0|%k0, %2}";
9190 (cond [(eq_attr "alternative" "1")
9191 (const_string "lea")
9192 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9194 (match_operand 2 "const1_operand" ""))
9195 (const_string "alu")
9197 (const_string "ishift")))
9198 (set (attr "length_immediate")
9200 (ior (eq_attr "type" "alu")
9201 (and (eq_attr "type" "ishift")
9202 (and (match_operand 2 "const1_operand" "")
9203 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9206 (const_string "*")))
9207 (set_attr "mode" "SI")])
9209 (define_insn "*ashlhi3_1"
9210 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9211 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9212 (match_operand:QI 2 "nonmemory_operand" "cI")))
9213 (clobber (reg:CC FLAGS_REG))]
9214 "TARGET_PARTIAL_REG_STALL
9215 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9217 switch (get_attr_type (insn))
9220 gcc_assert (operands[2] == const1_rtx);
9221 return "add{w}\t%0, %0";
9224 if (operands[2] == const1_rtx
9225 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9226 return "sal{w}\t%0";
9228 return "sal{w}\t{%2, %0|%0, %2}";
9232 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9234 (match_operand 0 "register_operand" ""))
9235 (match_operand 2 "const1_operand" ""))
9236 (const_string "alu")
9238 (const_string "ishift")))
9239 (set (attr "length_immediate")
9241 (ior (eq_attr "type" "alu")
9242 (and (eq_attr "type" "ishift")
9243 (and (match_operand 2 "const1_operand" "")
9244 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9247 (const_string "*")))
9248 (set_attr "mode" "HI")])
9250 (define_insn "*ashlhi3_1_lea"
9251 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9252 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9253 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9254 (clobber (reg:CC FLAGS_REG))]
9255 "!TARGET_PARTIAL_REG_STALL
9256 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9258 switch (get_attr_type (insn))
9264 gcc_assert (operands[2] == const1_rtx);
9265 return "add{w}\t%0, %0";
9268 if (operands[2] == const1_rtx
9269 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9270 return "sal{w}\t%0";
9272 return "sal{w}\t{%2, %0|%0, %2}";
9276 (cond [(eq_attr "alternative" "1")
9277 (const_string "lea")
9278 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9280 (match_operand 0 "register_operand" ""))
9281 (match_operand 2 "const1_operand" ""))
9282 (const_string "alu")
9284 (const_string "ishift")))
9285 (set (attr "length_immediate")
9287 (ior (eq_attr "type" "alu")
9288 (and (eq_attr "type" "ishift")
9289 (and (match_operand 2 "const1_operand" "")
9290 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9293 (const_string "*")))
9294 (set_attr "mode" "HI,SI")])
9296 (define_insn "*ashlqi3_1"
9297 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9298 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9299 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9300 (clobber (reg:CC FLAGS_REG))]
9301 "TARGET_PARTIAL_REG_STALL
9302 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9304 switch (get_attr_type (insn))
9307 gcc_assert (operands[2] == const1_rtx);
9308 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9309 return "add{l}\t%k0, %k0";
9311 return "add{b}\t%0, %0";
9314 if (operands[2] == const1_rtx
9315 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9317 if (get_attr_mode (insn) == MODE_SI)
9318 return "sal{l}\t%k0";
9320 return "sal{b}\t%0";
9324 if (get_attr_mode (insn) == MODE_SI)
9325 return "sal{l}\t{%2, %k0|%k0, %2}";
9327 return "sal{b}\t{%2, %0|%0, %2}";
9332 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9334 (match_operand 0 "register_operand" ""))
9335 (match_operand 2 "const1_operand" ""))
9336 (const_string "alu")
9338 (const_string "ishift")))
9339 (set (attr "length_immediate")
9341 (ior (eq_attr "type" "alu")
9342 (and (eq_attr "type" "ishift")
9343 (and (match_operand 2 "const1_operand" "")
9344 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9347 (const_string "*")))
9348 (set_attr "mode" "QI,SI")])
9350 ;; %%% Potential partial reg stall on alternative 2. What to do?
9351 (define_insn "*ashlqi3_1_lea"
9352 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9353 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9354 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9355 (clobber (reg:CC FLAGS_REG))]
9356 "!TARGET_PARTIAL_REG_STALL
9357 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9359 switch (get_attr_type (insn))
9365 gcc_assert (operands[2] == const1_rtx);
9366 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9367 return "add{l}\t%k0, %k0";
9369 return "add{b}\t%0, %0";
9372 if (operands[2] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9375 if (get_attr_mode (insn) == MODE_SI)
9376 return "sal{l}\t%k0";
9378 return "sal{b}\t%0";
9382 if (get_attr_mode (insn) == MODE_SI)
9383 return "sal{l}\t{%2, %k0|%k0, %2}";
9385 return "sal{b}\t{%2, %0|%0, %2}";
9390 (cond [(eq_attr "alternative" "2")
9391 (const_string "lea")
9392 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9394 (match_operand 0 "register_operand" ""))
9395 (match_operand 2 "const1_operand" ""))
9396 (const_string "alu")
9398 (const_string "ishift")))
9399 (set (attr "length_immediate")
9401 (ior (eq_attr "type" "alu")
9402 (and (eq_attr "type" "ishift")
9403 (and (match_operand 2 "const1_operand" "")
9404 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9407 (const_string "*")))
9408 (set_attr "mode" "QI,SI,SI")])
9410 (define_insn "*ashlqi3_1_slp"
9411 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9412 (ashift:QI (match_dup 0)
9413 (match_operand:QI 1 "nonmemory_operand" "cI")))
9414 (clobber (reg:CC FLAGS_REG))]
9415 "(optimize_function_for_size_p (cfun)
9416 || !TARGET_PARTIAL_FLAG_REG_STALL
9417 || (operands[1] == const1_rtx
9419 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9421 switch (get_attr_type (insn))
9424 gcc_assert (operands[1] == const1_rtx);
9425 return "add{b}\t%0, %0";
9428 if (operands[1] == const1_rtx
9429 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9430 return "sal{b}\t%0";
9432 return "sal{b}\t{%1, %0|%0, %1}";
9436 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9438 (match_operand 0 "register_operand" ""))
9439 (match_operand 1 "const1_operand" ""))
9440 (const_string "alu")
9442 (const_string "ishift1")))
9443 (set (attr "length_immediate")
9445 (ior (eq_attr "type" "alu")
9446 (and (eq_attr "type" "ishift1")
9447 (and (match_operand 1 "const1_operand" "")
9448 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9451 (const_string "*")))
9452 (set_attr "mode" "QI")])
9454 ;; Convert lea to the lea pattern to avoid flags dependency.
9456 [(set (match_operand:DI 0 "register_operand" "")
9457 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9458 (match_operand:QI 2 "const_int_operand" "")))
9459 (clobber (reg:CC FLAGS_REG))]
9460 "TARGET_64BIT && reload_completed
9461 && true_regnum (operands[0]) != true_regnum (operands[1])"
9463 (mult:DI (match_dup 1)
9465 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9467 ;; Convert lea to the lea pattern to avoid flags dependency.
9469 [(set (match_operand 0 "register_operand" "")
9470 (ashift (match_operand 1 "index_register_operand" "")
9471 (match_operand:QI 2 "const_int_operand" "")))
9472 (clobber (reg:CC FLAGS_REG))]
9474 && true_regnum (operands[0]) != true_regnum (operands[1])
9475 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9479 enum machine_mode mode = GET_MODE (operands[0]);
9481 if (GET_MODE_SIZE (mode) < 4)
9482 operands[0] = gen_lowpart (SImode, operands[0]);
9484 operands[1] = gen_lowpart (Pmode, operands[1]);
9485 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9487 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9488 if (Pmode != SImode)
9489 pat = gen_rtx_SUBREG (SImode, pat, 0);
9490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9494 ;; Rare case of shifting RSP is handled by generating move and shift
9496 [(set (match_operand 0 "register_operand" "")
9497 (ashift (match_operand 1 "register_operand" "")
9498 (match_operand:QI 2 "const_int_operand" "")))
9499 (clobber (reg:CC FLAGS_REG))]
9501 && true_regnum (operands[0]) != true_regnum (operands[1])"
9505 emit_move_insn (operands[0], operands[1]);
9506 pat = gen_rtx_SET (VOIDmode, operands[0],
9507 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9508 operands[0], operands[2]));
9509 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9510 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9514 ;; Convert lea to the lea pattern to avoid flags dependency.
9516 [(set (match_operand:DI 0 "register_operand" "")
9518 (ashift:SI (match_operand:SI 1 "register_operand" "")
9519 (match_operand:QI 2 "const_int_operand" ""))))
9520 (clobber (reg:CC FLAGS_REG))]
9521 "TARGET_64BIT && reload_completed
9522 && true_regnum (operands[0]) != true_regnum (operands[1])"
9524 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9526 operands[1] = gen_lowpart (Pmode, operands[1]);
9527 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9530 ;; This pattern can't accept a variable shift count, since shifts by
9531 ;; zero don't affect the flags. We assume that shifts by constant
9532 ;; zero are optimized away.
9533 (define_insn "*ashl<mode>3_cmp"
9534 [(set (reg FLAGS_REG)
9536 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9537 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9539 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9540 (ashift:SWI (match_dup 1) (match_dup 2)))]
9541 "(optimize_function_for_size_p (cfun)
9542 || !TARGET_PARTIAL_FLAG_REG_STALL
9543 || (operands[2] == const1_rtx
9545 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9546 && ix86_match_ccmode (insn, CCGOCmode)
9547 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9549 switch (get_attr_type (insn))
9552 gcc_assert (operands[2] == const1_rtx);
9553 return "add{<imodesuffix>}\t%0, %0";
9556 if (operands[2] == const1_rtx
9557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558 return "sal{<imodesuffix>}\t%0";
9560 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9564 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9566 (match_operand 0 "register_operand" ""))
9567 (match_operand 2 "const1_operand" ""))
9568 (const_string "alu")
9570 (const_string "ishift")))
9571 (set (attr "length_immediate")
9573 (ior (eq_attr "type" "alu")
9574 (and (eq_attr "type" "ishift")
9575 (and (match_operand 2 "const1_operand" "")
9576 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9579 (const_string "*")))
9580 (set_attr "mode" "<MODE>")])
9582 (define_insn "*ashlsi3_cmp_zext"
9583 [(set (reg FLAGS_REG)
9585 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9588 (set (match_operand:DI 0 "register_operand" "=r")
9589 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9591 && (optimize_function_for_size_p (cfun)
9592 || !TARGET_PARTIAL_FLAG_REG_STALL
9593 || (operands[2] == const1_rtx
9595 || TARGET_DOUBLE_WITH_ADD)))
9596 && ix86_match_ccmode (insn, CCGOCmode)
9597 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9599 switch (get_attr_type (insn))
9602 gcc_assert (operands[2] == const1_rtx);
9603 return "add{l}\t%k0, %k0";
9606 if (operands[2] == const1_rtx
9607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9608 return "sal{l}\t%k0";
9610 return "sal{l}\t{%2, %k0|%k0, %2}";
9614 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9616 (match_operand 2 "const1_operand" ""))
9617 (const_string "alu")
9619 (const_string "ishift")))
9620 (set (attr "length_immediate")
9622 (ior (eq_attr "type" "alu")
9623 (and (eq_attr "type" "ishift")
9624 (and (match_operand 2 "const1_operand" "")
9625 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9628 (const_string "*")))
9629 (set_attr "mode" "SI")])
9631 (define_insn "*ashl<mode>3_cconly"
9632 [(set (reg FLAGS_REG)
9634 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9635 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9637 (clobber (match_scratch:SWI 0 "=<r>"))]
9638 "(optimize_function_for_size_p (cfun)
9639 || !TARGET_PARTIAL_FLAG_REG_STALL
9640 || (operands[2] == const1_rtx
9642 || TARGET_DOUBLE_WITH_ADD)))
9643 && ix86_match_ccmode (insn, CCGOCmode)
9644 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9646 switch (get_attr_type (insn))
9649 gcc_assert (operands[2] == const1_rtx);
9650 return "add{<imodesuffix>}\t%0, %0";
9653 if (operands[2] == const1_rtx
9654 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9655 return "sal{<imodesuffix>}\t%0";
9657 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9661 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9663 (match_operand 0 "register_operand" ""))
9664 (match_operand 2 "const1_operand" ""))
9665 (const_string "alu")
9667 (const_string "ishift")))
9668 (set (attr "length_immediate")
9670 (ior (eq_attr "type" "alu")
9671 (and (eq_attr "type" "ishift")
9672 (and (match_operand 2 "const1_operand" "")
9673 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9676 (const_string "*")))
9677 (set_attr "mode" "<MODE>")])
9679 ;; See comment above `ashl<mode>3' about how this works.
9681 (define_expand "<shiftrt_insn><mode>3"
9682 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9683 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9684 (match_operand:QI 2 "nonmemory_operand" "")))]
9686 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9688 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9689 [(set (match_operand:DWI 0 "register_operand" "=r")
9690 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9691 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9692 (clobber (reg:CC FLAGS_REG))]
9695 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9697 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9698 [(set_attr "type" "multi")])
9700 ;; By default we don't ask for a scratch register, because when DWImode
9701 ;; values are manipulated, registers are already at a premium. But if
9702 ;; we have one handy, we won't turn it away.
9705 [(match_scratch:DWIH 3 "r")
9706 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9708 (match_operand:<DWI> 1 "register_operand" "")
9709 (match_operand:QI 2 "nonmemory_operand" "")))
9710 (clobber (reg:CC FLAGS_REG))])
9714 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9716 (define_insn "x86_64_shrd"
9717 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9718 (ior:DI (ashiftrt:DI (match_dup 0)
9719 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9720 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9721 (minus:QI (const_int 64) (match_dup 2)))))
9722 (clobber (reg:CC FLAGS_REG))]
9724 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9725 [(set_attr "type" "ishift")
9726 (set_attr "prefix_0f" "1")
9727 (set_attr "mode" "DI")
9728 (set_attr "athlon_decode" "vector")
9729 (set_attr "amdfam10_decode" "vector")])
9731 (define_insn "x86_shrd"
9732 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9733 (ior:SI (ashiftrt:SI (match_dup 0)
9734 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9735 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9736 (minus:QI (const_int 32) (match_dup 2)))))
9737 (clobber (reg:CC FLAGS_REG))]
9739 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9740 [(set_attr "type" "ishift")
9741 (set_attr "prefix_0f" "1")
9742 (set_attr "mode" "SI")
9743 (set_attr "pent_pair" "np")
9744 (set_attr "athlon_decode" "vector")
9745 (set_attr "amdfam10_decode" "vector")])
9747 (define_insn "ashrdi3_cvt"
9748 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9749 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9750 (match_operand:QI 2 "const_int_operand" "")))
9751 (clobber (reg:CC FLAGS_REG))]
9752 "TARGET_64BIT && INTVAL (operands[2]) == 63
9753 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9754 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9757 sar{q}\t{%2, %0|%0, %2}"
9758 [(set_attr "type" "imovx,ishift")
9759 (set_attr "prefix_0f" "0,*")
9760 (set_attr "length_immediate" "0,*")
9761 (set_attr "modrm" "0,1")
9762 (set_attr "mode" "DI")])
9764 (define_insn "ashrsi3_cvt"
9765 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9766 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9767 (match_operand:QI 2 "const_int_operand" "")))
9768 (clobber (reg:CC FLAGS_REG))]
9769 "INTVAL (operands[2]) == 31
9770 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9771 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9774 sar{l}\t{%2, %0|%0, %2}"
9775 [(set_attr "type" "imovx,ishift")
9776 (set_attr "prefix_0f" "0,*")
9777 (set_attr "length_immediate" "0,*")
9778 (set_attr "modrm" "0,1")
9779 (set_attr "mode" "SI")])
9781 (define_insn "*ashrsi3_cvt_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9784 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9785 (match_operand:QI 2 "const_int_operand" ""))))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && INTVAL (operands[2]) == 31
9788 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9789 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9792 sar{l}\t{%2, %k0|%k0, %2}"
9793 [(set_attr "type" "imovx,ishift")
9794 (set_attr "prefix_0f" "0,*")
9795 (set_attr "length_immediate" "0,*")
9796 (set_attr "modrm" "0,1")
9797 (set_attr "mode" "SI")])
9799 (define_expand "x86_shift<mode>_adj_3"
9800 [(use (match_operand:SWI48 0 "register_operand" ""))
9801 (use (match_operand:SWI48 1 "register_operand" ""))
9802 (use (match_operand:QI 2 "register_operand" ""))]
9805 rtx label = gen_label_rtx ();
9808 emit_insn (gen_testqi_ccz_1 (operands[2],
9809 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9811 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9812 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9813 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9814 gen_rtx_LABEL_REF (VOIDmode, label),
9816 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9817 JUMP_LABEL (tmp) = label;
9819 emit_move_insn (operands[0], operands[1]);
9820 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9821 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9823 LABEL_NUSES (label) = 1;
9828 (define_insn "*<shiftrt_insn><mode>3_1"
9829 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9830 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9831 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9832 (clobber (reg:CC FLAGS_REG))]
9833 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9835 if (operands[2] == const1_rtx
9836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837 return "<shiftrt>{<imodesuffix>}\t%0";
9839 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9841 [(set_attr "type" "ishift")
9842 (set (attr "length_immediate")
9844 (and (match_operand 2 "const1_operand" "")
9845 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9848 (const_string "*")))
9849 (set_attr "mode" "<MODE>")])
9851 (define_insn "*<shiftrt_insn>si3_1_zext"
9852 [(set (match_operand:DI 0 "register_operand" "=r")
9854 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9855 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9859 if (operands[2] == const1_rtx
9860 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9861 return "<shiftrt>{l}\t%k0";
9863 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9865 [(set_attr "type" "ishift")
9866 (set (attr "length_immediate")
9868 (and (match_operand 2 "const1_operand" "")
9869 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9872 (const_string "*")))
9873 (set_attr "mode" "SI")])
9875 (define_insn "*<shiftrt_insn>qi3_1_slp"
9876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9877 (any_shiftrt:QI (match_dup 0)
9878 (match_operand:QI 1 "nonmemory_operand" "cI")))
9879 (clobber (reg:CC FLAGS_REG))]
9880 "(optimize_function_for_size_p (cfun)
9881 || !TARGET_PARTIAL_REG_STALL
9882 || (operands[1] == const1_rtx
9885 if (operands[1] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<shiftrt>{b}\t%0";
9889 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9891 [(set_attr "type" "ishift1")
9892 (set (attr "length_immediate")
9894 (and (match_operand 1 "const1_operand" "")
9895 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9898 (const_string "*")))
9899 (set_attr "mode" "QI")])
9901 ;; This pattern can't accept a variable shift count, since shifts by
9902 ;; zero don't affect the flags. We assume that shifts by constant
9903 ;; zero are optimized away.
9904 (define_insn "*<shiftrt_insn><mode>3_cmp"
9905 [(set (reg FLAGS_REG)
9908 (match_operand:SWI 1 "nonimmediate_operand" "0")
9909 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9911 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9912 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9913 "(optimize_function_for_size_p (cfun)
9914 || !TARGET_PARTIAL_FLAG_REG_STALL
9915 || (operands[2] == const1_rtx
9917 && ix86_match_ccmode (insn, CCGOCmode)
9918 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9920 if (operands[2] == const1_rtx
9921 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9922 return "<shiftrt>{<imodesuffix>}\t%0";
9924 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9926 [(set_attr "type" "ishift")
9927 (set (attr "length_immediate")
9929 (and (match_operand 2 "const1_operand" "")
9930 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9933 (const_string "*")))
9934 (set_attr "mode" "<MODE>")])
9936 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9937 [(set (reg FLAGS_REG)
9939 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9940 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9942 (set (match_operand:DI 0 "register_operand" "=r")
9943 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9945 && (optimize_function_for_size_p (cfun)
9946 || !TARGET_PARTIAL_FLAG_REG_STALL
9947 || (operands[2] == const1_rtx
9949 && ix86_match_ccmode (insn, CCGOCmode)
9950 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9952 if (operands[2] == const1_rtx
9953 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9954 return "<shiftrt>{l}\t%k0";
9956 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9958 [(set_attr "type" "ishift")
9959 (set (attr "length_immediate")
9961 (and (match_operand 2 "const1_operand" "")
9962 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9965 (const_string "*")))
9966 (set_attr "mode" "SI")])
9968 (define_insn "*<shiftrt_insn><mode>3_cconly"
9969 [(set (reg FLAGS_REG)
9972 (match_operand:SWI 1 "nonimmediate_operand" "0")
9973 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9975 (clobber (match_scratch:SWI 0 "=<r>"))]
9976 "(optimize_function_for_size_p (cfun)
9977 || !TARGET_PARTIAL_FLAG_REG_STALL
9978 || (operands[2] == const1_rtx
9980 && ix86_match_ccmode (insn, CCGOCmode)
9981 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9983 if (operands[2] == const1_rtx
9984 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9985 return "<shiftrt>{<imodesuffix>}\t%0";
9987 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9989 [(set_attr "type" "ishift")
9990 (set (attr "length_immediate")
9992 (and (match_operand 2 "const1_operand" "")
9993 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9996 (const_string "*")))
9997 (set_attr "mode" "<MODE>")])
9999 ;; Rotate instructions
10001 (define_expand "<rotate_insn>ti3"
10002 [(set (match_operand:TI 0 "register_operand" "")
10003 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10004 (match_operand:QI 2 "nonmemory_operand" "")))]
10007 if (const_1_to_63_operand (operands[2], VOIDmode))
10008 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10009 (operands[0], operands[1], operands[2]));
10016 (define_expand "<rotate_insn>di3"
10017 [(set (match_operand:DI 0 "shiftdi_operand" "")
10018 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10019 (match_operand:QI 2 "nonmemory_operand" "")))]
10023 ix86_expand_binary_operator (<CODE>, DImode, operands);
10024 else if (const_1_to_31_operand (operands[2], VOIDmode))
10025 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10026 (operands[0], operands[1], operands[2]));
10033 (define_expand "<rotate_insn><mode>3"
10034 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10035 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10036 (match_operand:QI 2 "nonmemory_operand" "")))]
10038 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10040 ;; Implement rotation using two double-precision
10041 ;; shift instructions and a scratch register.
10043 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10044 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10045 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10046 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10047 (clobber (reg:CC FLAGS_REG))
10048 (clobber (match_scratch:DWIH 3 "=&r"))]
10052 [(set (match_dup 3) (match_dup 4))
10054 [(set (match_dup 4)
10055 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10056 (lshiftrt:DWIH (match_dup 5)
10057 (minus:QI (match_dup 6) (match_dup 2)))))
10058 (clobber (reg:CC FLAGS_REG))])
10060 [(set (match_dup 5)
10061 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10062 (lshiftrt:DWIH (match_dup 3)
10063 (minus:QI (match_dup 6) (match_dup 2)))))
10064 (clobber (reg:CC FLAGS_REG))])]
10066 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10068 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10071 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10072 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10073 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10074 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10075 (clobber (reg:CC FLAGS_REG))
10076 (clobber (match_scratch:DWIH 3 "=&r"))]
10080 [(set (match_dup 3) (match_dup 4))
10082 [(set (match_dup 4)
10083 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10084 (ashift:DWIH (match_dup 5)
10085 (minus:QI (match_dup 6) (match_dup 2)))))
10086 (clobber (reg:CC FLAGS_REG))])
10088 [(set (match_dup 5)
10089 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10090 (ashift:DWIH (match_dup 3)
10091 (minus:QI (match_dup 6) (match_dup 2)))))
10092 (clobber (reg:CC FLAGS_REG))])]
10094 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10096 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10099 (define_insn "*<rotate_insn><mode>3_1"
10100 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10101 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10102 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10106 if (operands[2] == const1_rtx
10107 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10108 return "<rotate>{<imodesuffix>}\t%0";
10110 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10112 [(set_attr "type" "rotate")
10113 (set (attr "length_immediate")
10115 (and (match_operand 2 "const1_operand" "")
10116 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10119 (const_string "*")))
10120 (set_attr "mode" "<MODE>")])
10122 (define_insn "*<rotate_insn>si3_1_zext"
10123 [(set (match_operand:DI 0 "register_operand" "=r")
10125 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10126 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10127 (clobber (reg:CC FLAGS_REG))]
10128 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10130 if (operands[2] == const1_rtx
10131 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10132 return "<rotate>{l}\t%k0";
10134 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10136 [(set_attr "type" "rotate")
10137 (set (attr "length_immediate")
10139 (and (match_operand 2 "const1_operand" "")
10140 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10143 (const_string "*")))
10144 (set_attr "mode" "SI")])
10146 (define_insn "*<rotate_insn>qi3_1_slp"
10147 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10148 (any_rotate:QI (match_dup 0)
10149 (match_operand:QI 1 "nonmemory_operand" "cI")))
10150 (clobber (reg:CC FLAGS_REG))]
10151 "(optimize_function_for_size_p (cfun)
10152 || !TARGET_PARTIAL_REG_STALL
10153 || (operands[1] == const1_rtx
10154 && TARGET_SHIFT1))"
10156 if (operands[1] == const1_rtx
10157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10158 return "<rotate>{b}\t%0";
10160 return "<rotate>{b}\t{%1, %0|%0, %1}";
10162 [(set_attr "type" "rotate1")
10163 (set (attr "length_immediate")
10165 (and (match_operand 1 "const1_operand" "")
10166 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10169 (const_string "*")))
10170 (set_attr "mode" "QI")])
10173 [(set (match_operand:HI 0 "register_operand" "")
10174 (any_rotate:HI (match_dup 0) (const_int 8)))
10175 (clobber (reg:CC FLAGS_REG))]
10177 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10178 [(parallel [(set (strict_low_part (match_dup 0))
10179 (bswap:HI (match_dup 0)))
10180 (clobber (reg:CC FLAGS_REG))])]
10183 ;; Bit set / bit test instructions
10185 (define_expand "extv"
10186 [(set (match_operand:SI 0 "register_operand" "")
10187 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10188 (match_operand:SI 2 "const8_operand" "")
10189 (match_operand:SI 3 "const8_operand" "")))]
10192 /* Handle extractions from %ah et al. */
10193 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10196 /* From mips.md: extract_bit_field doesn't verify that our source
10197 matches the predicate, so check it again here. */
10198 if (! ext_register_operand (operands[1], VOIDmode))
10202 (define_expand "extzv"
10203 [(set (match_operand:SI 0 "register_operand" "")
10204 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10205 (match_operand:SI 2 "const8_operand" "")
10206 (match_operand:SI 3 "const8_operand" "")))]
10209 /* Handle extractions from %ah et al. */
10210 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10213 /* From mips.md: extract_bit_field doesn't verify that our source
10214 matches the predicate, so check it again here. */
10215 if (! ext_register_operand (operands[1], VOIDmode))
10219 (define_expand "insv"
10220 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10221 (match_operand 1 "const8_operand" "")
10222 (match_operand 2 "const8_operand" ""))
10223 (match_operand 3 "register_operand" ""))]
10226 /* Handle insertions to %ah et al. */
10227 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10230 /* From mips.md: insert_bit_field doesn't verify that our source
10231 matches the predicate, so check it again here. */
10232 if (! ext_register_operand (operands[0], VOIDmode))
10236 emit_insn (gen_movdi_insv_1 (operands[0], operands[3]));
10238 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10243 ;; %%% bts, btr, btc, bt.
10244 ;; In general these instructions are *slow* when applied to memory,
10245 ;; since they enforce atomic operation. When applied to registers,
10246 ;; it depends on the cpu implementation. They're never faster than
10247 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10248 ;; no point. But in 64-bit, we can't hold the relevant immediates
10249 ;; within the instruction itself, so operating on bits in the high
10250 ;; 32-bits of a register becomes easier.
10252 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10253 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10254 ;; negdf respectively, so they can never be disabled entirely.
10256 (define_insn "*btsq"
10257 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10259 (match_operand:DI 1 "const_0_to_63_operand" ""))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10263 "bts{q}\t{%1, %0|%0, %1}"
10264 [(set_attr "type" "alu1")
10265 (set_attr "prefix_0f" "1")
10266 (set_attr "mode" "DI")])
10268 (define_insn "*btrq"
10269 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10271 (match_operand:DI 1 "const_0_to_63_operand" ""))
10273 (clobber (reg:CC FLAGS_REG))]
10274 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10275 "btr{q}\t{%1, %0|%0, %1}"
10276 [(set_attr "type" "alu1")
10277 (set_attr "prefix_0f" "1")
10278 (set_attr "mode" "DI")])
10280 (define_insn "*btcq"
10281 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10283 (match_operand:DI 1 "const_0_to_63_operand" ""))
10284 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10285 (clobber (reg:CC FLAGS_REG))]
10286 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10287 "btc{q}\t{%1, %0|%0, %1}"
10288 [(set_attr "type" "alu1")
10289 (set_attr "prefix_0f" "1")
10290 (set_attr "mode" "DI")])
10292 ;; Allow Nocona to avoid these instructions if a register is available.
10295 [(match_scratch:DI 2 "r")
10296 (parallel [(set (zero_extract:DI
10297 (match_operand:DI 0 "register_operand" "")
10299 (match_operand:DI 1 "const_0_to_63_operand" ""))
10301 (clobber (reg:CC FLAGS_REG))])]
10302 "TARGET_64BIT && !TARGET_USE_BT"
10305 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10308 if (HOST_BITS_PER_WIDE_INT >= 64)
10309 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10310 else if (i < HOST_BITS_PER_WIDE_INT)
10311 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10313 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10315 op1 = immed_double_const (lo, hi, DImode);
10318 emit_move_insn (operands[2], op1);
10322 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10327 [(match_scratch:DI 2 "r")
10328 (parallel [(set (zero_extract:DI
10329 (match_operand:DI 0 "register_operand" "")
10331 (match_operand:DI 1 "const_0_to_63_operand" ""))
10333 (clobber (reg:CC FLAGS_REG))])]
10334 "TARGET_64BIT && !TARGET_USE_BT"
10337 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10340 if (HOST_BITS_PER_WIDE_INT >= 64)
10341 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10342 else if (i < HOST_BITS_PER_WIDE_INT)
10343 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10345 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10347 op1 = immed_double_const (~lo, ~hi, DImode);
10350 emit_move_insn (operands[2], op1);
10354 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10359 [(match_scratch:DI 2 "r")
10360 (parallel [(set (zero_extract:DI
10361 (match_operand:DI 0 "register_operand" "")
10363 (match_operand:DI 1 "const_0_to_63_operand" ""))
10364 (not:DI (zero_extract:DI
10365 (match_dup 0) (const_int 1) (match_dup 1))))
10366 (clobber (reg:CC FLAGS_REG))])]
10367 "TARGET_64BIT && !TARGET_USE_BT"
10370 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10373 if (HOST_BITS_PER_WIDE_INT >= 64)
10374 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10375 else if (i < HOST_BITS_PER_WIDE_INT)
10376 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10378 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10380 op1 = immed_double_const (lo, hi, DImode);
10383 emit_move_insn (operands[2], op1);
10387 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10391 (define_insn "*bt<mode>"
10392 [(set (reg:CCC FLAGS_REG)
10394 (zero_extract:SWI48
10395 (match_operand:SWI48 0 "register_operand" "r")
10397 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10399 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10400 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10401 [(set_attr "type" "alu1")
10402 (set_attr "prefix_0f" "1")
10403 (set_attr "mode" "<MODE>")])
10405 ;; Store-flag instructions.
10407 ;; For all sCOND expanders, also expand the compare or test insn that
10408 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10410 (define_insn_and_split "*setcc_di_1"
10411 [(set (match_operand:DI 0 "register_operand" "=q")
10412 (match_operator:DI 1 "ix86_comparison_operator"
10413 [(reg FLAGS_REG) (const_int 0)]))]
10414 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10416 "&& reload_completed"
10417 [(set (match_dup 2) (match_dup 1))
10418 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10420 PUT_MODE (operands[1], QImode);
10421 operands[2] = gen_lowpart (QImode, operands[0]);
10424 (define_insn_and_split "*setcc_si_1_and"
10425 [(set (match_operand:SI 0 "register_operand" "=q")
10426 (match_operator:SI 1 "ix86_comparison_operator"
10427 [(reg FLAGS_REG) (const_int 0)]))
10428 (clobber (reg:CC FLAGS_REG))]
10429 "!TARGET_PARTIAL_REG_STALL
10430 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10432 "&& reload_completed"
10433 [(set (match_dup 2) (match_dup 1))
10434 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10435 (clobber (reg:CC FLAGS_REG))])]
10437 PUT_MODE (operands[1], QImode);
10438 operands[2] = gen_lowpart (QImode, operands[0]);
10441 (define_insn_and_split "*setcc_si_1_movzbl"
10442 [(set (match_operand:SI 0 "register_operand" "=q")
10443 (match_operator:SI 1 "ix86_comparison_operator"
10444 [(reg FLAGS_REG) (const_int 0)]))]
10445 "!TARGET_PARTIAL_REG_STALL
10446 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10448 "&& reload_completed"
10449 [(set (match_dup 2) (match_dup 1))
10450 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10452 PUT_MODE (operands[1], QImode);
10453 operands[2] = gen_lowpart (QImode, operands[0]);
10456 (define_insn "*setcc_qi"
10457 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10458 (match_operator:QI 1 "ix86_comparison_operator"
10459 [(reg FLAGS_REG) (const_int 0)]))]
10462 [(set_attr "type" "setcc")
10463 (set_attr "mode" "QI")])
10465 (define_insn "*setcc_qi_slp"
10466 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10467 (match_operator:QI 1 "ix86_comparison_operator"
10468 [(reg FLAGS_REG) (const_int 0)]))]
10471 [(set_attr "type" "setcc")
10472 (set_attr "mode" "QI")])
10474 ;; In general it is not safe to assume too much about CCmode registers,
10475 ;; so simplify-rtx stops when it sees a second one. Under certain
10476 ;; conditions this is safe on x86, so help combine not create
10483 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10484 (ne:QI (match_operator 1 "ix86_comparison_operator"
10485 [(reg FLAGS_REG) (const_int 0)])
10488 [(set (match_dup 0) (match_dup 1))]
10490 PUT_MODE (operands[1], QImode);
10494 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10495 (ne:QI (match_operator 1 "ix86_comparison_operator"
10496 [(reg FLAGS_REG) (const_int 0)])
10499 [(set (match_dup 0) (match_dup 1))]
10501 PUT_MODE (operands[1], QImode);
10505 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10506 (eq:QI (match_operator 1 "ix86_comparison_operator"
10507 [(reg FLAGS_REG) (const_int 0)])
10510 [(set (match_dup 0) (match_dup 1))]
10512 rtx new_op1 = copy_rtx (operands[1]);
10513 operands[1] = new_op1;
10514 PUT_MODE (new_op1, QImode);
10515 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10516 GET_MODE (XEXP (new_op1, 0))));
10518 /* Make sure that (a) the CCmode we have for the flags is strong
10519 enough for the reversed compare or (b) we have a valid FP compare. */
10520 if (! ix86_comparison_operator (new_op1, VOIDmode))
10525 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10526 (eq:QI (match_operator 1 "ix86_comparison_operator"
10527 [(reg FLAGS_REG) (const_int 0)])
10530 [(set (match_dup 0) (match_dup 1))]
10532 rtx new_op1 = copy_rtx (operands[1]);
10533 operands[1] = new_op1;
10534 PUT_MODE (new_op1, QImode);
10535 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10536 GET_MODE (XEXP (new_op1, 0))));
10538 /* Make sure that (a) the CCmode we have for the flags is strong
10539 enough for the reversed compare or (b) we have a valid FP compare. */
10540 if (! ix86_comparison_operator (new_op1, VOIDmode))
10544 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10545 ;; subsequent logical operations are used to imitate conditional moves.
10546 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10549 (define_insn "*avx_setcc<mode>"
10550 [(set (match_operand:MODEF 0 "register_operand" "=x")
10551 (match_operator:MODEF 1 "avx_comparison_float_operator"
10552 [(match_operand:MODEF 2 "register_operand" "x")
10553 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10555 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10556 [(set_attr "type" "ssecmp")
10557 (set_attr "prefix" "vex")
10558 (set_attr "length_immediate" "1")
10559 (set_attr "mode" "<MODE>")])
10561 (define_insn "*sse_setcc<mode>"
10562 [(set (match_operand:MODEF 0 "register_operand" "=x")
10563 (match_operator:MODEF 1 "sse_comparison_operator"
10564 [(match_operand:MODEF 2 "register_operand" "0")
10565 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10566 "SSE_FLOAT_MODE_P (<MODE>mode)"
10567 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10568 [(set_attr "type" "ssecmp")
10569 (set_attr "length_immediate" "1")
10570 (set_attr "mode" "<MODE>")])
10572 ;; Basic conditional jump instructions.
10573 ;; We ignore the overflow flag for signed branch instructions.
10575 (define_insn "*jcc_1"
10577 (if_then_else (match_operator 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)])
10579 (label_ref (match_operand 0 "" ""))
10583 [(set_attr "type" "ibr")
10584 (set_attr "modrm" "0")
10585 (set (attr "length")
10586 (if_then_else (and (ge (minus (match_dup 0) (pc))
10588 (lt (minus (match_dup 0) (pc))
10593 (define_insn "*jcc_2"
10595 (if_then_else (match_operator 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)])
10598 (label_ref (match_operand 0 "" ""))))]
10601 [(set_attr "type" "ibr")
10602 (set_attr "modrm" "0")
10603 (set (attr "length")
10604 (if_then_else (and (ge (minus (match_dup 0) (pc))
10606 (lt (minus (match_dup 0) (pc))
10611 ;; In general it is not safe to assume too much about CCmode registers,
10612 ;; so simplify-rtx stops when it sees a second one. Under certain
10613 ;; conditions this is safe on x86, so help combine not create
10621 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10622 [(reg FLAGS_REG) (const_int 0)])
10624 (label_ref (match_operand 1 "" ""))
10628 (if_then_else (match_dup 0)
10629 (label_ref (match_dup 1))
10632 PUT_MODE (operands[0], VOIDmode);
10637 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10638 [(reg FLAGS_REG) (const_int 0)])
10640 (label_ref (match_operand 1 "" ""))
10644 (if_then_else (match_dup 0)
10645 (label_ref (match_dup 1))
10648 rtx new_op0 = copy_rtx (operands[0]);
10649 operands[0] = new_op0;
10650 PUT_MODE (new_op0, VOIDmode);
10651 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10652 GET_MODE (XEXP (new_op0, 0))));
10654 /* Make sure that (a) the CCmode we have for the flags is strong
10655 enough for the reversed compare or (b) we have a valid FP compare. */
10656 if (! ix86_comparison_operator (new_op0, VOIDmode))
10660 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10661 ;; pass generates from shift insn with QImode operand. Actually, the mode
10662 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10663 ;; appropriate modulo of the bit offset value.
10665 (define_insn_and_split "*jcc_bt<mode>"
10667 (if_then_else (match_operator 0 "bt_comparison_operator"
10668 [(zero_extract:SWI48
10669 (match_operand:SWI48 1 "register_operand" "r")
10672 (match_operand:QI 2 "register_operand" "r")))
10674 (label_ref (match_operand 3 "" ""))
10676 (clobber (reg:CC FLAGS_REG))]
10677 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10680 [(set (reg:CCC FLAGS_REG)
10682 (zero_extract:SWI48
10688 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10689 (label_ref (match_dup 3))
10692 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10694 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10697 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10698 ;; also for DImode, this is what combine produces.
10699 (define_insn_and_split "*jcc_bt<mode>_mask"
10701 (if_then_else (match_operator 0 "bt_comparison_operator"
10702 [(zero_extract:SWI48
10703 (match_operand:SWI48 1 "register_operand" "r")
10706 (match_operand:SI 2 "register_operand" "r")
10707 (match_operand:SI 3 "const_int_operand" "n")))])
10708 (label_ref (match_operand 4 "" ""))
10710 (clobber (reg:CC FLAGS_REG))]
10711 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10712 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10713 == GET_MODE_BITSIZE (<MODE>mode)-1"
10716 [(set (reg:CCC FLAGS_REG)
10718 (zero_extract:SWI48
10724 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10725 (label_ref (match_dup 4))
10728 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10730 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10733 (define_insn_and_split "*jcc_btsi_1"
10735 (if_then_else (match_operator 0 "bt_comparison_operator"
10738 (match_operand:SI 1 "register_operand" "r")
10739 (match_operand:QI 2 "register_operand" "r"))
10742 (label_ref (match_operand 3 "" ""))
10744 (clobber (reg:CC FLAGS_REG))]
10745 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10748 [(set (reg:CCC FLAGS_REG)
10756 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10757 (label_ref (match_dup 3))
10760 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10762 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10765 ;; avoid useless masking of bit offset operand
10766 (define_insn_and_split "*jcc_btsi_mask_1"
10769 (match_operator 0 "bt_comparison_operator"
10772 (match_operand:SI 1 "register_operand" "r")
10775 (match_operand:SI 2 "register_operand" "r")
10776 (match_operand:SI 3 "const_int_operand" "n")) 0))
10779 (label_ref (match_operand 4 "" ""))
10781 (clobber (reg:CC FLAGS_REG))]
10782 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10783 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10786 [(set (reg:CCC FLAGS_REG)
10794 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10795 (label_ref (match_dup 4))
10797 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10799 ;; Define combination compare-and-branch fp compare instructions to help
10802 (define_insn "*fp_jcc_1_387"
10804 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10805 [(match_operand 1 "register_operand" "f")
10806 (match_operand 2 "nonimmediate_operand" "fm")])
10807 (label_ref (match_operand 3 "" ""))
10809 (clobber (reg:CCFP FPSR_REG))
10810 (clobber (reg:CCFP FLAGS_REG))
10811 (clobber (match_scratch:HI 4 "=a"))]
10813 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10814 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10815 && SELECT_CC_MODE (GET_CODE (operands[0]),
10816 operands[1], operands[2]) == CCFPmode
10820 (define_insn "*fp_jcc_1r_387"
10822 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10823 [(match_operand 1 "register_operand" "f")
10824 (match_operand 2 "nonimmediate_operand" "fm")])
10826 (label_ref (match_operand 3 "" ""))))
10827 (clobber (reg:CCFP FPSR_REG))
10828 (clobber (reg:CCFP FLAGS_REG))
10829 (clobber (match_scratch:HI 4 "=a"))]
10831 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10832 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10833 && SELECT_CC_MODE (GET_CODE (operands[0]),
10834 operands[1], operands[2]) == CCFPmode
10838 (define_insn "*fp_jcc_2_387"
10840 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10841 [(match_operand 1 "register_operand" "f")
10842 (match_operand 2 "register_operand" "f")])
10843 (label_ref (match_operand 3 "" ""))
10845 (clobber (reg:CCFP FPSR_REG))
10846 (clobber (reg:CCFP FLAGS_REG))
10847 (clobber (match_scratch:HI 4 "=a"))]
10848 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10849 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10853 (define_insn "*fp_jcc_2r_387"
10855 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10856 [(match_operand 1 "register_operand" "f")
10857 (match_operand 2 "register_operand" "f")])
10859 (label_ref (match_operand 3 "" ""))))
10860 (clobber (reg:CCFP FPSR_REG))
10861 (clobber (reg:CCFP FLAGS_REG))
10862 (clobber (match_scratch:HI 4 "=a"))]
10863 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10864 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10868 (define_insn "*fp_jcc_3_387"
10870 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10871 [(match_operand 1 "register_operand" "f")
10872 (match_operand 2 "const0_operand" "")])
10873 (label_ref (match_operand 3 "" ""))
10875 (clobber (reg:CCFP FPSR_REG))
10876 (clobber (reg:CCFP FLAGS_REG))
10877 (clobber (match_scratch:HI 4 "=a"))]
10878 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10879 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10880 && SELECT_CC_MODE (GET_CODE (operands[0]),
10881 operands[1], operands[2]) == CCFPmode
10887 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10888 [(match_operand 1 "register_operand" "")
10889 (match_operand 2 "nonimmediate_operand" "")])
10890 (match_operand 3 "" "")
10891 (match_operand 4 "" "")))
10892 (clobber (reg:CCFP FPSR_REG))
10893 (clobber (reg:CCFP FLAGS_REG))]
10897 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10898 operands[3], operands[4], NULL_RTX, NULL_RTX);
10904 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10905 [(match_operand 1 "register_operand" "")
10906 (match_operand 2 "general_operand" "")])
10907 (match_operand 3 "" "")
10908 (match_operand 4 "" "")))
10909 (clobber (reg:CCFP FPSR_REG))
10910 (clobber (reg:CCFP FLAGS_REG))
10911 (clobber (match_scratch:HI 5 "=a"))]
10915 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10916 operands[3], operands[4], operands[5], NULL_RTX);
10920 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10921 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10922 ;; with a precedence over other operators and is always put in the first
10923 ;; place. Swap condition and operands to match ficom instruction.
10925 (define_insn "*fp_jcc_4_<mode>_387"
10928 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10929 [(match_operator 1 "float_operator"
10930 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10931 (match_operand 3 "register_operand" "f,f")])
10932 (label_ref (match_operand 4 "" ""))
10934 (clobber (reg:CCFP FPSR_REG))
10935 (clobber (reg:CCFP FLAGS_REG))
10936 (clobber (match_scratch:HI 5 "=a,a"))]
10937 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10938 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10939 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10940 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10947 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10948 [(match_operator 1 "float_operator"
10949 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10950 (match_operand 3 "register_operand" "")])
10951 (match_operand 4 "" "")
10952 (match_operand 5 "" "")))
10953 (clobber (reg:CCFP FPSR_REG))
10954 (clobber (reg:CCFP FLAGS_REG))
10955 (clobber (match_scratch:HI 6 "=a"))]
10959 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10961 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10962 operands[3], operands[7],
10963 operands[4], operands[5], operands[6], NULL_RTX);
10967 ;; %%% Kill this when reload knows how to do it.
10971 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10972 [(match_operator 1 "float_operator"
10973 [(match_operand:X87MODEI12 2 "register_operand" "")])
10974 (match_operand 3 "register_operand" "")])
10975 (match_operand 4 "" "")
10976 (match_operand 5 "" "")))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 6 "=a"))]
10983 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10984 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10986 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10987 operands[3], operands[7],
10988 operands[4], operands[5], operands[6], operands[2]);
10992 ;; Unconditional and other jump instructions
10994 (define_insn "jump"
10996 (label_ref (match_operand 0 "" "")))]
10999 [(set_attr "type" "ibr")
11000 (set (attr "length")
11001 (if_then_else (and (ge (minus (match_dup 0) (pc))
11003 (lt (minus (match_dup 0) (pc))
11007 (set_attr "modrm" "0")])
11009 (define_expand "indirect_jump"
11010 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11014 (define_insn "*indirect_jump"
11015 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11018 [(set_attr "type" "ibr")
11019 (set_attr "length_immediate" "0")])
11021 (define_expand "tablejump"
11022 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11023 (use (label_ref (match_operand 1 "" "")))])]
11026 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11027 relative. Convert the relative address to an absolute address. */
11031 enum rtx_code code;
11033 /* We can't use @GOTOFF for text labels on VxWorks;
11034 see gotoff_operand. */
11035 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11039 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11041 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11045 op1 = pic_offset_table_rtx;
11050 op0 = pic_offset_table_rtx;
11054 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11059 (define_insn "*tablejump_1"
11060 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11061 (use (label_ref (match_operand 1 "" "")))]
11064 [(set_attr "type" "ibr")
11065 (set_attr "length_immediate" "0")])
11067 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11070 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11071 (set (match_operand:QI 1 "register_operand" "")
11072 (match_operator:QI 2 "ix86_comparison_operator"
11073 [(reg FLAGS_REG) (const_int 0)]))
11074 (set (match_operand 3 "q_regs_operand" "")
11075 (zero_extend (match_dup 1)))]
11076 "(peep2_reg_dead_p (3, operands[1])
11077 || operands_match_p (operands[1], operands[3]))
11078 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11079 [(set (match_dup 4) (match_dup 0))
11080 (set (strict_low_part (match_dup 5))
11083 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11084 operands[5] = gen_lowpart (QImode, operands[3]);
11085 ix86_expand_clear (operands[3]);
11088 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11091 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11092 (set (match_operand:QI 1 "register_operand" "")
11093 (match_operator:QI 2 "ix86_comparison_operator"
11094 [(reg FLAGS_REG) (const_int 0)]))
11095 (parallel [(set (match_operand 3 "q_regs_operand" "")
11096 (zero_extend (match_dup 1)))
11097 (clobber (reg:CC FLAGS_REG))])]
11098 "(peep2_reg_dead_p (3, operands[1])
11099 || operands_match_p (operands[1], operands[3]))
11100 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11101 [(set (match_dup 4) (match_dup 0))
11102 (set (strict_low_part (match_dup 5))
11105 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11106 operands[5] = gen_lowpart (QImode, operands[3]);
11107 ix86_expand_clear (operands[3]);
11110 ;; Call instructions.
11112 ;; The predicates normally associated with named expanders are not properly
11113 ;; checked for calls. This is a bug in the generic code, but it isn't that
11114 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11116 ;; P6 processors will jump to the address after the decrement when %esp
11117 ;; is used as a call operand, so they will execute return address as a code.
11118 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11120 ;; Call subroutine returning no value.
11122 (define_expand "call_pop"
11123 [(parallel [(call (match_operand:QI 0 "" "")
11124 (match_operand:SI 1 "" ""))
11125 (set (reg:SI SP_REG)
11126 (plus:SI (reg:SI SP_REG)
11127 (match_operand:SI 3 "" "")))])]
11130 ix86_expand_call (NULL, operands[0], operands[1],
11131 operands[2], operands[3], 0);
11135 (define_insn "*call_pop_0"
11136 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11137 (match_operand:SI 1 "" ""))
11138 (set (reg:SI SP_REG)
11139 (plus:SI (reg:SI SP_REG)
11140 (match_operand:SI 2 "immediate_operand" "")))]
11143 if (SIBLING_CALL_P (insn))
11146 return "call\t%P0";
11148 [(set_attr "type" "call")])
11150 (define_insn "*call_pop_1"
11151 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11152 (match_operand:SI 1 "" ""))
11153 (set (reg:SI SP_REG)
11154 (plus:SI (reg:SI SP_REG)
11155 (match_operand:SI 2 "immediate_operand" "i")))]
11156 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11158 if (constant_call_address_operand (operands[0], Pmode))
11159 return "call\t%P0";
11160 return "call\t%A0";
11162 [(set_attr "type" "call")])
11164 (define_insn "*sibcall_pop_1"
11165 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11166 (match_operand:SI 1 "" ""))
11167 (set (reg:SI SP_REG)
11168 (plus:SI (reg:SI SP_REG)
11169 (match_operand:SI 2 "immediate_operand" "i,i")))]
11170 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11174 [(set_attr "type" "call")])
11176 (define_expand "call"
11177 [(call (match_operand:QI 0 "" "")
11178 (match_operand 1 "" ""))
11179 (use (match_operand 2 "" ""))]
11182 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11186 (define_expand "sibcall"
11187 [(call (match_operand:QI 0 "" "")
11188 (match_operand 1 "" ""))
11189 (use (match_operand 2 "" ""))]
11192 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11196 (define_insn "*call_0"
11197 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11198 (match_operand 1 "" ""))]
11201 if (SIBLING_CALL_P (insn))
11204 return "call\t%P0";
11206 [(set_attr "type" "call")])
11208 (define_insn "*call_1"
11209 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11210 (match_operand 1 "" ""))]
11211 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11213 if (constant_call_address_operand (operands[0], Pmode))
11214 return "call\t%P0";
11215 return "call\t%A0";
11217 [(set_attr "type" "call")])
11219 (define_insn "*sibcall_1"
11220 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11221 (match_operand 1 "" ""))]
11222 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11226 [(set_attr "type" "call")])
11228 (define_insn "*call_1_rex64"
11229 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11230 (match_operand 1 "" ""))]
11231 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11232 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11234 if (constant_call_address_operand (operands[0], Pmode))
11235 return "call\t%P0";
11236 return "call\t%A0";
11238 [(set_attr "type" "call")])
11240 (define_insn "*call_1_rex64_ms_sysv"
11241 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11242 (match_operand 1 "" ""))
11243 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11244 (clobber (reg:TI XMM6_REG))
11245 (clobber (reg:TI XMM7_REG))
11246 (clobber (reg:TI XMM8_REG))
11247 (clobber (reg:TI XMM9_REG))
11248 (clobber (reg:TI XMM10_REG))
11249 (clobber (reg:TI XMM11_REG))
11250 (clobber (reg:TI XMM12_REG))
11251 (clobber (reg:TI XMM13_REG))
11252 (clobber (reg:TI XMM14_REG))
11253 (clobber (reg:TI XMM15_REG))
11254 (clobber (reg:DI SI_REG))
11255 (clobber (reg:DI DI_REG))]
11256 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11258 if (constant_call_address_operand (operands[0], Pmode))
11259 return "call\t%P0";
11260 return "call\t%A0";
11262 [(set_attr "type" "call")])
11264 (define_insn "*call_1_rex64_large"
11265 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11266 (match_operand 1 "" ""))]
11267 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11269 [(set_attr "type" "call")])
11271 (define_insn "*sibcall_1_rex64"
11272 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11273 (match_operand 1 "" ""))]
11274 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11278 [(set_attr "type" "call")])
11280 ;; Call subroutine, returning value in operand 0
11281 (define_expand "call_value_pop"
11282 [(parallel [(set (match_operand 0 "" "")
11283 (call (match_operand:QI 1 "" "")
11284 (match_operand:SI 2 "" "")))
11285 (set (reg:SI SP_REG)
11286 (plus:SI (reg:SI SP_REG)
11287 (match_operand:SI 4 "" "")))])]
11290 ix86_expand_call (operands[0], operands[1], operands[2],
11291 operands[3], operands[4], 0);
11295 (define_expand "call_value"
11296 [(set (match_operand 0 "" "")
11297 (call (match_operand:QI 1 "" "")
11298 (match_operand:SI 2 "" "")))
11299 (use (match_operand:SI 3 "" ""))]
11300 ;; Operand 3 is not used on the i386.
11303 ix86_expand_call (operands[0], operands[1], operands[2],
11304 operands[3], NULL, 0);
11308 (define_expand "sibcall_value"
11309 [(set (match_operand 0 "" "")
11310 (call (match_operand:QI 1 "" "")
11311 (match_operand:SI 2 "" "")))
11312 (use (match_operand:SI 3 "" ""))]
11313 ;; Operand 3 is not used on the i386.
11316 ix86_expand_call (operands[0], operands[1], operands[2],
11317 operands[3], NULL, 1);
11321 ;; Call subroutine returning any type.
11323 (define_expand "untyped_call"
11324 [(parallel [(call (match_operand 0 "" "")
11326 (match_operand 1 "" "")
11327 (match_operand 2 "" "")])]
11332 /* In order to give reg-stack an easier job in validating two
11333 coprocessor registers as containing a possible return value,
11334 simply pretend the untyped call returns a complex long double
11337 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11338 and should have the default ABI. */
11340 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11341 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11342 operands[0], const0_rtx,
11343 GEN_INT ((TARGET_64BIT
11344 ? (ix86_abi == SYSV_ABI
11345 ? X86_64_SSE_REGPARM_MAX
11346 : X86_64_MS_SSE_REGPARM_MAX)
11347 : X86_32_SSE_REGPARM_MAX)
11351 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11353 rtx set = XVECEXP (operands[2], 0, i);
11354 emit_move_insn (SET_DEST (set), SET_SRC (set));
11357 /* The optimizer does not know that the call sets the function value
11358 registers we stored in the result block. We avoid problems by
11359 claiming that all hard registers are used and clobbered at this
11361 emit_insn (gen_blockage ());
11366 ;; Prologue and epilogue instructions
11368 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11369 ;; all of memory. This blocks insns from being moved across this point.
11371 (define_insn "blockage"
11372 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11375 [(set_attr "length" "0")])
11377 ;; Do not schedule instructions accessing memory across this point.
11379 (define_expand "memory_blockage"
11380 [(set (match_dup 0)
11381 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11384 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11385 MEM_VOLATILE_P (operands[0]) = 1;
11388 (define_insn "*memory_blockage"
11389 [(set (match_operand:BLK 0 "" "")
11390 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11393 [(set_attr "length" "0")])
11395 ;; As USE insns aren't meaningful after reload, this is used instead
11396 ;; to prevent deleting instructions setting registers for PIC code
11397 (define_insn "prologue_use"
11398 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11401 [(set_attr "length" "0")])
11403 ;; Insn emitted into the body of a function to return from a function.
11404 ;; This is only done if the function's epilogue is known to be simple.
11405 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11407 (define_expand "return"
11409 "ix86_can_use_return_insn_p ()"
11411 if (crtl->args.pops_args)
11413 rtx popc = GEN_INT (crtl->args.pops_args);
11414 emit_jump_insn (gen_return_pop_internal (popc));
11419 (define_insn "return_internal"
11423 [(set_attr "length" "1")
11424 (set_attr "atom_unit" "jeu")
11425 (set_attr "length_immediate" "0")
11426 (set_attr "modrm" "0")])
11428 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11429 ;; instruction Athlon and K8 have.
11431 (define_insn "return_internal_long"
11433 (unspec [(const_int 0)] UNSPEC_REP)]
11436 [(set_attr "length" "2")
11437 (set_attr "atom_unit" "jeu")
11438 (set_attr "length_immediate" "0")
11439 (set_attr "prefix_rep" "1")
11440 (set_attr "modrm" "0")])
11442 (define_insn "return_pop_internal"
11444 (use (match_operand:SI 0 "const_int_operand" ""))]
11447 [(set_attr "length" "3")
11448 (set_attr "atom_unit" "jeu")
11449 (set_attr "length_immediate" "2")
11450 (set_attr "modrm" "0")])
11452 (define_insn "return_indirect_internal"
11454 (use (match_operand:SI 0 "register_operand" "r"))]
11457 [(set_attr "type" "ibr")
11458 (set_attr "length_immediate" "0")])
11464 [(set_attr "length" "1")
11465 (set_attr "length_immediate" "0")
11466 (set_attr "modrm" "0")])
11468 (define_insn "vswapmov"
11469 [(set (match_operand:SI 0 "register_operand" "=r")
11470 (match_operand:SI 1 "register_operand" "r"))
11471 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11473 "movl.s\t{%1, %0|%0, %1}"
11474 [(set_attr "length" "2")
11475 (set_attr "length_immediate" "0")
11476 (set_attr "modrm" "0")])
11478 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11479 ;; branch prediction penalty for the third jump in a 16-byte
11483 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11486 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11487 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11489 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11490 The align insn is used to avoid 3 jump instructions in the row to improve
11491 branch prediction and the benefits hardly outweigh the cost of extra 8
11492 nops on the average inserted by full alignment pseudo operation. */
11496 [(set_attr "length" "16")])
11498 (define_expand "prologue"
11501 "ix86_expand_prologue (); DONE;")
11503 (define_insn "set_got"
11504 [(set (match_operand:SI 0 "register_operand" "=r")
11505 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11506 (clobber (reg:CC FLAGS_REG))]
11508 { return output_set_got (operands[0], NULL_RTX); }
11509 [(set_attr "type" "multi")
11510 (set_attr "length" "12")])
11512 (define_insn "set_got_labelled"
11513 [(set (match_operand:SI 0 "register_operand" "=r")
11514 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11516 (clobber (reg:CC FLAGS_REG))]
11518 { return output_set_got (operands[0], operands[1]); }
11519 [(set_attr "type" "multi")
11520 (set_attr "length" "12")])
11522 (define_insn "set_got_rex64"
11523 [(set (match_operand:DI 0 "register_operand" "=r")
11524 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11526 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11527 [(set_attr "type" "lea")
11528 (set_attr "length_address" "4")
11529 (set_attr "mode" "DI")])
11531 (define_insn "set_rip_rex64"
11532 [(set (match_operand:DI 0 "register_operand" "=r")
11533 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11535 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11536 [(set_attr "type" "lea")
11537 (set_attr "length_address" "4")
11538 (set_attr "mode" "DI")])
11540 (define_insn "set_got_offset_rex64"
11541 [(set (match_operand:DI 0 "register_operand" "=r")
11543 [(label_ref (match_operand 1 "" ""))]
11544 UNSPEC_SET_GOT_OFFSET))]
11546 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11547 [(set_attr "type" "imov")
11548 (set_attr "length_immediate" "0")
11549 (set_attr "length_address" "8")
11550 (set_attr "mode" "DI")])
11552 (define_expand "epilogue"
11555 "ix86_expand_epilogue (1); DONE;")
11557 (define_expand "sibcall_epilogue"
11560 "ix86_expand_epilogue (0); DONE;")
11562 (define_expand "eh_return"
11563 [(use (match_operand 0 "register_operand" ""))]
11566 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11568 /* Tricky bit: we write the address of the handler to which we will
11569 be returning into someone else's stack frame, one word below the
11570 stack address we wish to restore. */
11571 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11572 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11573 tmp = gen_rtx_MEM (Pmode, tmp);
11574 emit_move_insn (tmp, ra);
11576 emit_jump_insn (gen_eh_return_internal ());
11581 (define_insn_and_split "eh_return_internal"
11585 "epilogue_completed"
11587 "ix86_expand_epilogue (2); DONE;")
11589 (define_insn "leave"
11590 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11591 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11592 (clobber (mem:BLK (scratch)))]
11595 [(set_attr "type" "leave")])
11597 (define_insn "leave_rex64"
11598 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11599 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11600 (clobber (mem:BLK (scratch)))]
11603 [(set_attr "type" "leave")])
11605 ;; Bit manipulation instructions.
11607 (define_expand "ffs<mode>2"
11608 [(set (match_dup 2) (const_int -1))
11609 (parallel [(set (reg:CCZ FLAGS_REG)
11611 (match_operand:SWI48 1 "nonimmediate_operand" "")
11613 (set (match_operand:SWI48 0 "register_operand" "")
11614 (ctz:SWI48 (match_dup 1)))])
11615 (set (match_dup 0) (if_then_else:SWI48
11616 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11619 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11620 (clobber (reg:CC FLAGS_REG))])]
11623 if (<MODE>mode == SImode && !TARGET_CMOVE)
11625 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11628 operands[2] = gen_reg_rtx (<MODE>mode);
11631 (define_insn_and_split "ffssi2_no_cmove"
11632 [(set (match_operand:SI 0 "register_operand" "=r")
11633 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11634 (clobber (match_scratch:SI 2 "=&q"))
11635 (clobber (reg:CC FLAGS_REG))]
11638 "&& reload_completed"
11639 [(parallel [(set (reg:CCZ FLAGS_REG)
11640 (compare:CCZ (match_dup 1) (const_int 0)))
11641 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11642 (set (strict_low_part (match_dup 3))
11643 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11644 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11645 (clobber (reg:CC FLAGS_REG))])
11646 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11647 (clobber (reg:CC FLAGS_REG))])
11648 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11649 (clobber (reg:CC FLAGS_REG))])]
11651 operands[3] = gen_lowpart (QImode, operands[2]);
11652 ix86_expand_clear (operands[2]);
11655 (define_insn "*ffs<mode>_1"
11656 [(set (reg:CCZ FLAGS_REG)
11657 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11659 (set (match_operand:SWI48 0 "register_operand" "=r")
11660 (ctz:SWI48 (match_dup 1)))]
11662 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11663 [(set_attr "type" "alu1")
11664 (set_attr "prefix_0f" "1")
11665 (set_attr "mode" "<MODE>")])
11667 (define_insn "ctz<mode>2"
11668 [(set (match_operand:SWI48 0 "register_operand" "=r")
11669 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11670 (clobber (reg:CC FLAGS_REG))]
11672 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11673 [(set_attr "type" "alu1")
11674 (set_attr "prefix_0f" "1")
11675 (set_attr "mode" "<MODE>")])
11677 (define_expand "clz<mode>2"
11679 [(set (match_operand:SWI248 0 "register_operand" "")
11682 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11683 (clobber (reg:CC FLAGS_REG))])
11685 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11686 (clobber (reg:CC FLAGS_REG))])]
11691 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11694 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11697 (define_insn "clz<mode>2_abm"
11698 [(set (match_operand:SWI248 0 "register_operand" "=r")
11699 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11700 (clobber (reg:CC FLAGS_REG))]
11702 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11703 [(set_attr "prefix_rep" "1")
11704 (set_attr "type" "bitmanip")
11705 (set_attr "mode" "<MODE>")])
11707 (define_insn "bsr_rex64"
11708 [(set (match_operand:DI 0 "register_operand" "=r")
11709 (minus:DI (const_int 63)
11710 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11711 (clobber (reg:CC FLAGS_REG))]
11713 "bsr{q}\t{%1, %0|%0, %1}"
11714 [(set_attr "type" "alu1")
11715 (set_attr "prefix_0f" "1")
11716 (set_attr "mode" "DI")])
11719 [(set (match_operand:SI 0 "register_operand" "=r")
11720 (minus:SI (const_int 31)
11721 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11722 (clobber (reg:CC FLAGS_REG))]
11724 "bsr{l}\t{%1, %0|%0, %1}"
11725 [(set_attr "type" "alu1")
11726 (set_attr "prefix_0f" "1")
11727 (set_attr "mode" "SI")])
11729 (define_insn "*bsrhi"
11730 [(set (match_operand:HI 0 "register_operand" "=r")
11731 (minus:HI (const_int 15)
11732 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11733 (clobber (reg:CC FLAGS_REG))]
11735 "bsr{w}\t{%1, %0|%0, %1}"
11736 [(set_attr "type" "alu1")
11737 (set_attr "prefix_0f" "1")
11738 (set_attr "mode" "HI")])
11740 (define_insn "popcount<mode>2"
11741 [(set (match_operand:SWI248 0 "register_operand" "=r")
11743 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11744 (clobber (reg:CC FLAGS_REG))]
11748 return "popcnt\t{%1, %0|%0, %1}";
11750 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11753 [(set_attr "prefix_rep" "1")
11754 (set_attr "type" "bitmanip")
11755 (set_attr "mode" "<MODE>")])
11757 (define_insn "*popcount<mode>2_cmp"
11758 [(set (reg FLAGS_REG)
11761 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11763 (set (match_operand:SWI248 0 "register_operand" "=r")
11764 (popcount:SWI248 (match_dup 1)))]
11765 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11768 return "popcnt\t{%1, %0|%0, %1}";
11770 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11773 [(set_attr "prefix_rep" "1")
11774 (set_attr "type" "bitmanip")
11775 (set_attr "mode" "<MODE>")])
11777 (define_insn "*popcountsi2_cmp_zext"
11778 [(set (reg FLAGS_REG)
11780 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11782 (set (match_operand:DI 0 "register_operand" "=r")
11783 (zero_extend:DI(popcount:SI (match_dup 1))))]
11784 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11787 return "popcnt\t{%1, %0|%0, %1}";
11789 return "popcnt{l}\t{%1, %0|%0, %1}";
11792 [(set_attr "prefix_rep" "1")
11793 (set_attr "type" "bitmanip")
11794 (set_attr "mode" "SI")])
11796 (define_expand "bswap<mode>2"
11797 [(set (match_operand:SWI48 0 "register_operand" "")
11798 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11801 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11803 rtx x = operands[0];
11805 emit_move_insn (x, operands[1]);
11806 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11807 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11808 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11813 (define_insn "*bswap<mode>2_movbe"
11814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11815 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11820 movbe\t{%1, %0|%0, %1}
11821 movbe\t{%1, %0|%0, %1}"
11822 [(set_attr "type" "bitmanip,imov,imov")
11823 (set_attr "modrm" "0,1,1")
11824 (set_attr "prefix_0f" "*,1,1")
11825 (set_attr "prefix_extra" "*,1,1")
11826 (set_attr "mode" "<MODE>")])
11828 (define_insn "*bswap<mode>2_1"
11829 [(set (match_operand:SWI48 0 "register_operand" "=r")
11830 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11833 [(set_attr "type" "bitmanip")
11834 (set_attr "modrm" "0")
11835 (set_attr "mode" "<MODE>")])
11837 (define_insn "*bswaphi_lowpart_1"
11838 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11839 (bswap:HI (match_dup 0)))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11843 xchg{b}\t{%h0, %b0|%b0, %h0}
11844 rol{w}\t{$8, %0|%0, 8}"
11845 [(set_attr "length" "2,4")
11846 (set_attr "mode" "QI,HI")])
11848 (define_insn "bswaphi_lowpart"
11849 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11850 (bswap:HI (match_dup 0)))
11851 (clobber (reg:CC FLAGS_REG))]
11853 "rol{w}\t{$8, %0|%0, 8}"
11854 [(set_attr "length" "4")
11855 (set_attr "mode" "HI")])
11857 (define_expand "paritydi2"
11858 [(set (match_operand:DI 0 "register_operand" "")
11859 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11862 rtx scratch = gen_reg_rtx (QImode);
11865 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11866 NULL_RTX, operands[1]));
11868 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11869 gen_rtx_REG (CCmode, FLAGS_REG),
11871 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11874 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11877 rtx tmp = gen_reg_rtx (SImode);
11879 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11880 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11885 (define_expand "paritysi2"
11886 [(set (match_operand:SI 0 "register_operand" "")
11887 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11890 rtx scratch = gen_reg_rtx (QImode);
11893 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11895 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11896 gen_rtx_REG (CCmode, FLAGS_REG),
11898 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11900 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11904 (define_insn_and_split "paritydi2_cmp"
11905 [(set (reg:CC FLAGS_REG)
11906 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11908 (clobber (match_scratch:DI 0 "=r"))
11909 (clobber (match_scratch:SI 1 "=&r"))
11910 (clobber (match_scratch:HI 2 "=Q"))]
11913 "&& reload_completed"
11915 [(set (match_dup 1)
11916 (xor:SI (match_dup 1) (match_dup 4)))
11917 (clobber (reg:CC FLAGS_REG))])
11919 [(set (reg:CC FLAGS_REG)
11920 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11921 (clobber (match_dup 1))
11922 (clobber (match_dup 2))])]
11924 operands[4] = gen_lowpart (SImode, operands[3]);
11928 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11929 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11932 operands[1] = gen_highpart (SImode, operands[3]);
11935 (define_insn_and_split "paritysi2_cmp"
11936 [(set (reg:CC FLAGS_REG)
11937 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11939 (clobber (match_scratch:SI 0 "=r"))
11940 (clobber (match_scratch:HI 1 "=&Q"))]
11943 "&& reload_completed"
11945 [(set (match_dup 1)
11946 (xor:HI (match_dup 1) (match_dup 3)))
11947 (clobber (reg:CC FLAGS_REG))])
11949 [(set (reg:CC FLAGS_REG)
11950 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11951 (clobber (match_dup 1))])]
11953 operands[3] = gen_lowpart (HImode, operands[2]);
11955 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11956 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11959 (define_insn "*parityhi2_cmp"
11960 [(set (reg:CC FLAGS_REG)
11961 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11963 (clobber (match_scratch:HI 0 "=Q"))]
11965 "xor{b}\t{%h0, %b0|%b0, %h0}"
11966 [(set_attr "length" "2")
11967 (set_attr "mode" "HI")])
11969 ;; Thread-local storage patterns for ELF.
11971 ;; Note that these code sequences must appear exactly as shown
11972 ;; in order to allow linker relaxation.
11974 (define_insn "*tls_global_dynamic_32_gnu"
11975 [(set (match_operand:SI 0 "register_operand" "=a")
11976 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11977 (match_operand:SI 2 "tls_symbolic_operand" "")
11978 (match_operand:SI 3 "call_insn_operand" "")]
11980 (clobber (match_scratch:SI 4 "=d"))
11981 (clobber (match_scratch:SI 5 "=c"))
11982 (clobber (reg:CC FLAGS_REG))]
11983 "!TARGET_64BIT && TARGET_GNU_TLS"
11984 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11985 [(set_attr "type" "multi")
11986 (set_attr "length" "12")])
11988 (define_expand "tls_global_dynamic_32"
11989 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11992 (match_operand:SI 1 "tls_symbolic_operand" "")
11995 (clobber (match_scratch:SI 4 ""))
11996 (clobber (match_scratch:SI 5 ""))
11997 (clobber (reg:CC FLAGS_REG))])]
12001 operands[2] = pic_offset_table_rtx;
12004 operands[2] = gen_reg_rtx (Pmode);
12005 emit_insn (gen_set_got (operands[2]));
12007 if (TARGET_GNU2_TLS)
12009 emit_insn (gen_tls_dynamic_gnu2_32
12010 (operands[0], operands[1], operands[2]));
12013 operands[3] = ix86_tls_get_addr ();
12016 (define_insn "*tls_global_dynamic_64"
12017 [(set (match_operand:DI 0 "register_operand" "=a")
12018 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12019 (match_operand:DI 3 "" "")))
12020 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12023 { 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"; }
12024 [(set_attr "type" "multi")
12025 (set_attr "length" "16")])
12027 (define_expand "tls_global_dynamic_64"
12028 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12029 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12030 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12034 if (TARGET_GNU2_TLS)
12036 emit_insn (gen_tls_dynamic_gnu2_64
12037 (operands[0], operands[1]));
12040 operands[2] = ix86_tls_get_addr ();
12043 (define_insn "*tls_local_dynamic_base_32_gnu"
12044 [(set (match_operand:SI 0 "register_operand" "=a")
12045 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046 (match_operand:SI 2 "call_insn_operand" "")]
12047 UNSPEC_TLS_LD_BASE))
12048 (clobber (match_scratch:SI 3 "=d"))
12049 (clobber (match_scratch:SI 4 "=c"))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "!TARGET_64BIT && TARGET_GNU_TLS"
12052 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12053 [(set_attr "type" "multi")
12054 (set_attr "length" "11")])
12056 (define_expand "tls_local_dynamic_base_32"
12057 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12058 (unspec:SI [(match_dup 1) (match_dup 2)]
12059 UNSPEC_TLS_LD_BASE))
12060 (clobber (match_scratch:SI 3 ""))
12061 (clobber (match_scratch:SI 4 ""))
12062 (clobber (reg:CC FLAGS_REG))])]
12066 operands[1] = pic_offset_table_rtx;
12069 operands[1] = gen_reg_rtx (Pmode);
12070 emit_insn (gen_set_got (operands[1]));
12072 if (TARGET_GNU2_TLS)
12074 emit_insn (gen_tls_dynamic_gnu2_32
12075 (operands[0], ix86_tls_module_base (), operands[1]));
12078 operands[2] = ix86_tls_get_addr ();
12081 (define_insn "*tls_local_dynamic_base_64"
12082 [(set (match_operand:DI 0 "register_operand" "=a")
12083 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12084 (match_operand:DI 2 "" "")))
12085 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12087 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12088 [(set_attr "type" "multi")
12089 (set_attr "length" "12")])
12091 (define_expand "tls_local_dynamic_base_64"
12092 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12093 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12094 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12097 if (TARGET_GNU2_TLS)
12099 emit_insn (gen_tls_dynamic_gnu2_64
12100 (operands[0], ix86_tls_module_base ()));
12103 operands[1] = ix86_tls_get_addr ();
12106 ;; Local dynamic of a single variable is a lose. Show combine how
12107 ;; to convert that back to global dynamic.
12109 (define_insn_and_split "*tls_local_dynamic_32_once"
12110 [(set (match_operand:SI 0 "register_operand" "=a")
12111 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12112 (match_operand:SI 2 "call_insn_operand" "")]
12113 UNSPEC_TLS_LD_BASE)
12114 (const:SI (unspec:SI
12115 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12117 (clobber (match_scratch:SI 4 "=d"))
12118 (clobber (match_scratch:SI 5 "=c"))
12119 (clobber (reg:CC FLAGS_REG))]
12123 [(parallel [(set (match_dup 0)
12124 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12126 (clobber (match_dup 4))
12127 (clobber (match_dup 5))
12128 (clobber (reg:CC FLAGS_REG))])]
12131 ;; Load and add the thread base pointer from %gs:0.
12133 (define_insn "*load_tp_si"
12134 [(set (match_operand:SI 0 "register_operand" "=r")
12135 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12137 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12138 [(set_attr "type" "imov")
12139 (set_attr "modrm" "0")
12140 (set_attr "length" "7")
12141 (set_attr "memory" "load")
12142 (set_attr "imm_disp" "false")])
12144 (define_insn "*add_tp_si"
12145 [(set (match_operand:SI 0 "register_operand" "=r")
12146 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12147 (match_operand:SI 1 "register_operand" "0")))
12148 (clobber (reg:CC FLAGS_REG))]
12150 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12151 [(set_attr "type" "alu")
12152 (set_attr "modrm" "0")
12153 (set_attr "length" "7")
12154 (set_attr "memory" "load")
12155 (set_attr "imm_disp" "false")])
12157 (define_insn "*load_tp_di"
12158 [(set (match_operand:DI 0 "register_operand" "=r")
12159 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12161 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12162 [(set_attr "type" "imov")
12163 (set_attr "modrm" "0")
12164 (set_attr "length" "7")
12165 (set_attr "memory" "load")
12166 (set_attr "imm_disp" "false")])
12168 (define_insn "*add_tp_di"
12169 [(set (match_operand:DI 0 "register_operand" "=r")
12170 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12171 (match_operand:DI 1 "register_operand" "0")))
12172 (clobber (reg:CC FLAGS_REG))]
12174 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12175 [(set_attr "type" "alu")
12176 (set_attr "modrm" "0")
12177 (set_attr "length" "7")
12178 (set_attr "memory" "load")
12179 (set_attr "imm_disp" "false")])
12181 ;; GNU2 TLS patterns can be split.
12183 (define_expand "tls_dynamic_gnu2_32"
12184 [(set (match_dup 3)
12185 (plus:SI (match_operand:SI 2 "register_operand" "")
12187 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12190 [(set (match_operand:SI 0 "register_operand" "")
12191 (unspec:SI [(match_dup 1) (match_dup 3)
12192 (match_dup 2) (reg:SI SP_REG)]
12194 (clobber (reg:CC FLAGS_REG))])]
12195 "!TARGET_64BIT && TARGET_GNU2_TLS"
12197 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12198 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12201 (define_insn "*tls_dynamic_lea_32"
12202 [(set (match_operand:SI 0 "register_operand" "=r")
12203 (plus:SI (match_operand:SI 1 "register_operand" "b")
12205 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12206 UNSPEC_TLSDESC))))]
12207 "!TARGET_64BIT && TARGET_GNU2_TLS"
12208 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12209 [(set_attr "type" "lea")
12210 (set_attr "mode" "SI")
12211 (set_attr "length" "6")
12212 (set_attr "length_address" "4")])
12214 (define_insn "*tls_dynamic_call_32"
12215 [(set (match_operand:SI 0 "register_operand" "=a")
12216 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12217 (match_operand:SI 2 "register_operand" "0")
12218 ;; we have to make sure %ebx still points to the GOT
12219 (match_operand:SI 3 "register_operand" "b")
12222 (clobber (reg:CC FLAGS_REG))]
12223 "!TARGET_64BIT && TARGET_GNU2_TLS"
12224 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12225 [(set_attr "type" "call")
12226 (set_attr "length" "2")
12227 (set_attr "length_address" "0")])
12229 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12230 [(set (match_operand:SI 0 "register_operand" "=&a")
12232 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12233 (match_operand:SI 4 "" "")
12234 (match_operand:SI 2 "register_operand" "b")
12237 (const:SI (unspec:SI
12238 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12240 (clobber (reg:CC FLAGS_REG))]
12241 "!TARGET_64BIT && TARGET_GNU2_TLS"
12244 [(set (match_dup 0) (match_dup 5))]
12246 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12247 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12250 (define_expand "tls_dynamic_gnu2_64"
12251 [(set (match_dup 2)
12252 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12255 [(set (match_operand:DI 0 "register_operand" "")
12256 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12258 (clobber (reg:CC FLAGS_REG))])]
12259 "TARGET_64BIT && TARGET_GNU2_TLS"
12261 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12262 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12265 (define_insn "*tls_dynamic_lea_64"
12266 [(set (match_operand:DI 0 "register_operand" "=r")
12267 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12269 "TARGET_64BIT && TARGET_GNU2_TLS"
12270 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12271 [(set_attr "type" "lea")
12272 (set_attr "mode" "DI")
12273 (set_attr "length" "7")
12274 (set_attr "length_address" "4")])
12276 (define_insn "*tls_dynamic_call_64"
12277 [(set (match_operand:DI 0 "register_operand" "=a")
12278 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12279 (match_operand:DI 2 "register_operand" "0")
12282 (clobber (reg:CC FLAGS_REG))]
12283 "TARGET_64BIT && TARGET_GNU2_TLS"
12284 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12285 [(set_attr "type" "call")
12286 (set_attr "length" "2")
12287 (set_attr "length_address" "0")])
12289 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12290 [(set (match_operand:DI 0 "register_operand" "=&a")
12292 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12293 (match_operand:DI 3 "" "")
12296 (const:DI (unspec:DI
12297 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12299 (clobber (reg:CC FLAGS_REG))]
12300 "TARGET_64BIT && TARGET_GNU2_TLS"
12303 [(set (match_dup 0) (match_dup 4))]
12305 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12306 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12311 ;; These patterns match the binary 387 instructions for addM3, subM3,
12312 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12313 ;; SFmode. The first is the normal insn, the second the same insn but
12314 ;; with one operand a conversion, and the third the same insn but with
12315 ;; the other operand a conversion. The conversion may be SFmode or
12316 ;; SImode if the target mode DFmode, but only SImode if the target mode
12319 ;; Gcc is slightly more smart about handling normal two address instructions
12320 ;; so use special patterns for add and mull.
12322 (define_insn "*fop_<mode>_comm_mixed_avx"
12323 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12324 (match_operator:MODEF 3 "binary_fp_operator"
12325 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12326 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12327 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12328 && COMMUTATIVE_ARITH_P (operands[3])
12329 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12330 "* return output_387_binary_op (insn, operands);"
12331 [(set (attr "type")
12332 (if_then_else (eq_attr "alternative" "1")
12333 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12334 (const_string "ssemul")
12335 (const_string "sseadd"))
12336 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12337 (const_string "fmul")
12338 (const_string "fop"))))
12339 (set_attr "prefix" "orig,maybe_vex")
12340 (set_attr "mode" "<MODE>")])
12342 (define_insn "*fop_<mode>_comm_mixed"
12343 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12344 (match_operator:MODEF 3 "binary_fp_operator"
12345 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12346 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12347 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12348 && COMMUTATIVE_ARITH_P (operands[3])
12349 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12350 "* return output_387_binary_op (insn, operands);"
12351 [(set (attr "type")
12352 (if_then_else (eq_attr "alternative" "1")
12353 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12354 (const_string "ssemul")
12355 (const_string "sseadd"))
12356 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12357 (const_string "fmul")
12358 (const_string "fop"))))
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "*fop_<mode>_comm_avx"
12362 [(set (match_operand:MODEF 0 "register_operand" "=x")
12363 (match_operator:MODEF 3 "binary_fp_operator"
12364 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12365 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12366 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12367 && COMMUTATIVE_ARITH_P (operands[3])
12368 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12369 "* return output_387_binary_op (insn, operands);"
12370 [(set (attr "type")
12371 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12372 (const_string "ssemul")
12373 (const_string "sseadd")))
12374 (set_attr "prefix" "vex")
12375 (set_attr "mode" "<MODE>")])
12377 (define_insn "*fop_<mode>_comm_sse"
12378 [(set (match_operand:MODEF 0 "register_operand" "=x")
12379 (match_operator:MODEF 3 "binary_fp_operator"
12380 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12381 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12382 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12383 && COMMUTATIVE_ARITH_P (operands[3])
12384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12385 "* return output_387_binary_op (insn, operands);"
12386 [(set (attr "type")
12387 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12388 (const_string "ssemul")
12389 (const_string "sseadd")))
12390 (set_attr "mode" "<MODE>")])
12392 (define_insn "*fop_<mode>_comm_i387"
12393 [(set (match_operand:MODEF 0 "register_operand" "=f")
12394 (match_operator:MODEF 3 "binary_fp_operator"
12395 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12396 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12397 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12398 && COMMUTATIVE_ARITH_P (operands[3])
12399 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12400 "* return output_387_binary_op (insn, operands);"
12401 [(set (attr "type")
12402 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12403 (const_string "fmul")
12404 (const_string "fop")))
12405 (set_attr "mode" "<MODE>")])
12407 (define_insn "*fop_<mode>_1_mixed_avx"
12408 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12409 (match_operator:MODEF 3 "binary_fp_operator"
12410 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12411 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12412 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12413 && !COMMUTATIVE_ARITH_P (operands[3])
12414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12415 "* return output_387_binary_op (insn, operands);"
12416 [(set (attr "type")
12417 (cond [(and (eq_attr "alternative" "2")
12418 (match_operand:MODEF 3 "mult_operator" ""))
12419 (const_string "ssemul")
12420 (and (eq_attr "alternative" "2")
12421 (match_operand:MODEF 3 "div_operator" ""))
12422 (const_string "ssediv")
12423 (eq_attr "alternative" "2")
12424 (const_string "sseadd")
12425 (match_operand:MODEF 3 "mult_operator" "")
12426 (const_string "fmul")
12427 (match_operand:MODEF 3 "div_operator" "")
12428 (const_string "fdiv")
12430 (const_string "fop")))
12431 (set_attr "prefix" "orig,orig,maybe_vex")
12432 (set_attr "mode" "<MODE>")])
12434 (define_insn "*fop_<mode>_1_mixed"
12435 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12436 (match_operator:MODEF 3 "binary_fp_operator"
12437 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12438 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12439 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12440 && !COMMUTATIVE_ARITH_P (operands[3])
12441 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12442 "* return output_387_binary_op (insn, operands);"
12443 [(set (attr "type")
12444 (cond [(and (eq_attr "alternative" "2")
12445 (match_operand:MODEF 3 "mult_operator" ""))
12446 (const_string "ssemul")
12447 (and (eq_attr "alternative" "2")
12448 (match_operand:MODEF 3 "div_operator" ""))
12449 (const_string "ssediv")
12450 (eq_attr "alternative" "2")
12451 (const_string "sseadd")
12452 (match_operand:MODEF 3 "mult_operator" "")
12453 (const_string "fmul")
12454 (match_operand:MODEF 3 "div_operator" "")
12455 (const_string "fdiv")
12457 (const_string "fop")))
12458 (set_attr "mode" "<MODE>")])
12460 (define_insn "*rcpsf2_sse"
12461 [(set (match_operand:SF 0 "register_operand" "=x")
12462 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12465 "%vrcpss\t{%1, %d0|%d0, %1}"
12466 [(set_attr "type" "sse")
12467 (set_attr "atom_sse_attr" "rcp")
12468 (set_attr "prefix" "maybe_vex")
12469 (set_attr "mode" "SF")])
12471 (define_insn "*fop_<mode>_1_avx"
12472 [(set (match_operand:MODEF 0 "register_operand" "=x")
12473 (match_operator:MODEF 3 "binary_fp_operator"
12474 [(match_operand:MODEF 1 "register_operand" "x")
12475 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12476 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12477 && !COMMUTATIVE_ARITH_P (operands[3])"
12478 "* return output_387_binary_op (insn, operands);"
12479 [(set (attr "type")
12480 (cond [(match_operand:MODEF 3 "mult_operator" "")
12481 (const_string "ssemul")
12482 (match_operand:MODEF 3 "div_operator" "")
12483 (const_string "ssediv")
12485 (const_string "sseadd")))
12486 (set_attr "prefix" "vex")
12487 (set_attr "mode" "<MODE>")])
12489 (define_insn "*fop_<mode>_1_sse"
12490 [(set (match_operand:MODEF 0 "register_operand" "=x")
12491 (match_operator:MODEF 3 "binary_fp_operator"
12492 [(match_operand:MODEF 1 "register_operand" "0")
12493 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12494 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12495 && !COMMUTATIVE_ARITH_P (operands[3])"
12496 "* return output_387_binary_op (insn, operands);"
12497 [(set (attr "type")
12498 (cond [(match_operand:MODEF 3 "mult_operator" "")
12499 (const_string "ssemul")
12500 (match_operand:MODEF 3 "div_operator" "")
12501 (const_string "ssediv")
12503 (const_string "sseadd")))
12504 (set_attr "mode" "<MODE>")])
12506 ;; This pattern is not fully shadowed by the pattern above.
12507 (define_insn "*fop_<mode>_1_i387"
12508 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12509 (match_operator:MODEF 3 "binary_fp_operator"
12510 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12511 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12512 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12513 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12514 && !COMMUTATIVE_ARITH_P (operands[3])
12515 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12516 "* return output_387_binary_op (insn, operands);"
12517 [(set (attr "type")
12518 (cond [(match_operand:MODEF 3 "mult_operator" "")
12519 (const_string "fmul")
12520 (match_operand:MODEF 3 "div_operator" "")
12521 (const_string "fdiv")
12523 (const_string "fop")))
12524 (set_attr "mode" "<MODE>")])
12526 ;; ??? Add SSE splitters for these!
12527 (define_insn "*fop_<MODEF:mode>_2_i387"
12528 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12529 (match_operator:MODEF 3 "binary_fp_operator"
12531 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12532 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12533 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12534 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12535 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12536 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12537 [(set (attr "type")
12538 (cond [(match_operand:MODEF 3 "mult_operator" "")
12539 (const_string "fmul")
12540 (match_operand:MODEF 3 "div_operator" "")
12541 (const_string "fdiv")
12543 (const_string "fop")))
12544 (set_attr "fp_int_src" "true")
12545 (set_attr "mode" "<X87MODEI12:MODE>")])
12547 (define_insn "*fop_<MODEF:mode>_3_i387"
12548 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12549 (match_operator:MODEF 3 "binary_fp_operator"
12550 [(match_operand:MODEF 1 "register_operand" "0,0")
12552 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12553 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12554 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12555 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12556 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12557 [(set (attr "type")
12558 (cond [(match_operand:MODEF 3 "mult_operator" "")
12559 (const_string "fmul")
12560 (match_operand:MODEF 3 "div_operator" "")
12561 (const_string "fdiv")
12563 (const_string "fop")))
12564 (set_attr "fp_int_src" "true")
12565 (set_attr "mode" "<MODE>")])
12567 (define_insn "*fop_df_4_i387"
12568 [(set (match_operand:DF 0 "register_operand" "=f,f")
12569 (match_operator:DF 3 "binary_fp_operator"
12571 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12572 (match_operand:DF 2 "register_operand" "0,f")]))]
12573 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12574 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12575 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12576 "* return output_387_binary_op (insn, operands);"
12577 [(set (attr "type")
12578 (cond [(match_operand:DF 3 "mult_operator" "")
12579 (const_string "fmul")
12580 (match_operand:DF 3 "div_operator" "")
12581 (const_string "fdiv")
12583 (const_string "fop")))
12584 (set_attr "mode" "SF")])
12586 (define_insn "*fop_df_5_i387"
12587 [(set (match_operand:DF 0 "register_operand" "=f,f")
12588 (match_operator:DF 3 "binary_fp_operator"
12589 [(match_operand:DF 1 "register_operand" "0,f")
12591 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12592 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12593 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12594 "* return output_387_binary_op (insn, operands);"
12595 [(set (attr "type")
12596 (cond [(match_operand:DF 3 "mult_operator" "")
12597 (const_string "fmul")
12598 (match_operand:DF 3 "div_operator" "")
12599 (const_string "fdiv")
12601 (const_string "fop")))
12602 (set_attr "mode" "SF")])
12604 (define_insn "*fop_df_6_i387"
12605 [(set (match_operand:DF 0 "register_operand" "=f,f")
12606 (match_operator:DF 3 "binary_fp_operator"
12608 (match_operand:SF 1 "register_operand" "0,f"))
12610 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12611 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12612 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12613 "* return output_387_binary_op (insn, operands);"
12614 [(set (attr "type")
12615 (cond [(match_operand:DF 3 "mult_operator" "")
12616 (const_string "fmul")
12617 (match_operand:DF 3 "div_operator" "")
12618 (const_string "fdiv")
12620 (const_string "fop")))
12621 (set_attr "mode" "SF")])
12623 (define_insn "*fop_xf_comm_i387"
12624 [(set (match_operand:XF 0 "register_operand" "=f")
12625 (match_operator:XF 3 "binary_fp_operator"
12626 [(match_operand:XF 1 "register_operand" "%0")
12627 (match_operand:XF 2 "register_operand" "f")]))]
12629 && COMMUTATIVE_ARITH_P (operands[3])"
12630 "* return output_387_binary_op (insn, operands);"
12631 [(set (attr "type")
12632 (if_then_else (match_operand:XF 3 "mult_operator" "")
12633 (const_string "fmul")
12634 (const_string "fop")))
12635 (set_attr "mode" "XF")])
12637 (define_insn "*fop_xf_1_i387"
12638 [(set (match_operand:XF 0 "register_operand" "=f,f")
12639 (match_operator:XF 3 "binary_fp_operator"
12640 [(match_operand:XF 1 "register_operand" "0,f")
12641 (match_operand:XF 2 "register_operand" "f,0")]))]
12643 && !COMMUTATIVE_ARITH_P (operands[3])"
12644 "* return output_387_binary_op (insn, operands);"
12645 [(set (attr "type")
12646 (cond [(match_operand:XF 3 "mult_operator" "")
12647 (const_string "fmul")
12648 (match_operand:XF 3 "div_operator" "")
12649 (const_string "fdiv")
12651 (const_string "fop")))
12652 (set_attr "mode" "XF")])
12654 (define_insn "*fop_xf_2_i387"
12655 [(set (match_operand:XF 0 "register_operand" "=f,f")
12656 (match_operator:XF 3 "binary_fp_operator"
12658 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12659 (match_operand:XF 2 "register_operand" "0,0")]))]
12660 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12661 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12662 [(set (attr "type")
12663 (cond [(match_operand:XF 3 "mult_operator" "")
12664 (const_string "fmul")
12665 (match_operand:XF 3 "div_operator" "")
12666 (const_string "fdiv")
12668 (const_string "fop")))
12669 (set_attr "fp_int_src" "true")
12670 (set_attr "mode" "<MODE>")])
12672 (define_insn "*fop_xf_3_i387"
12673 [(set (match_operand:XF 0 "register_operand" "=f,f")
12674 (match_operator:XF 3 "binary_fp_operator"
12675 [(match_operand:XF 1 "register_operand" "0,0")
12677 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12678 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12679 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12680 [(set (attr "type")
12681 (cond [(match_operand:XF 3 "mult_operator" "")
12682 (const_string "fmul")
12683 (match_operand:XF 3 "div_operator" "")
12684 (const_string "fdiv")
12686 (const_string "fop")))
12687 (set_attr "fp_int_src" "true")
12688 (set_attr "mode" "<MODE>")])
12690 (define_insn "*fop_xf_4_i387"
12691 [(set (match_operand:XF 0 "register_operand" "=f,f")
12692 (match_operator:XF 3 "binary_fp_operator"
12694 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12695 (match_operand:XF 2 "register_operand" "0,f")]))]
12697 "* return output_387_binary_op (insn, operands);"
12698 [(set (attr "type")
12699 (cond [(match_operand:XF 3 "mult_operator" "")
12700 (const_string "fmul")
12701 (match_operand:XF 3 "div_operator" "")
12702 (const_string "fdiv")
12704 (const_string "fop")))
12705 (set_attr "mode" "<MODE>")])
12707 (define_insn "*fop_xf_5_i387"
12708 [(set (match_operand:XF 0 "register_operand" "=f,f")
12709 (match_operator:XF 3 "binary_fp_operator"
12710 [(match_operand:XF 1 "register_operand" "0,f")
12712 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12714 "* return output_387_binary_op (insn, operands);"
12715 [(set (attr "type")
12716 (cond [(match_operand:XF 3 "mult_operator" "")
12717 (const_string "fmul")
12718 (match_operand:XF 3 "div_operator" "")
12719 (const_string "fdiv")
12721 (const_string "fop")))
12722 (set_attr "mode" "<MODE>")])
12724 (define_insn "*fop_xf_6_i387"
12725 [(set (match_operand:XF 0 "register_operand" "=f,f")
12726 (match_operator:XF 3 "binary_fp_operator"
12728 (match_operand:MODEF 1 "register_operand" "0,f"))
12730 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12732 "* return output_387_binary_op (insn, operands);"
12733 [(set (attr "type")
12734 (cond [(match_operand:XF 3 "mult_operator" "")
12735 (const_string "fmul")
12736 (match_operand:XF 3 "div_operator" "")
12737 (const_string "fdiv")
12739 (const_string "fop")))
12740 (set_attr "mode" "<MODE>")])
12743 [(set (match_operand 0 "register_operand" "")
12744 (match_operator 3 "binary_fp_operator"
12745 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12746 (match_operand 2 "register_operand" "")]))]
12748 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12749 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12752 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12753 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12754 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12755 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12756 GET_MODE (operands[3]),
12759 ix86_free_from_memory (GET_MODE (operands[1]));
12764 [(set (match_operand 0 "register_operand" "")
12765 (match_operator 3 "binary_fp_operator"
12766 [(match_operand 1 "register_operand" "")
12767 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12769 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12770 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12773 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12774 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12775 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12776 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12777 GET_MODE (operands[3]),
12780 ix86_free_from_memory (GET_MODE (operands[2]));
12784 ;; FPU special functions.
12786 ;; This pattern implements a no-op XFmode truncation for
12787 ;; all fancy i386 XFmode math functions.
12789 (define_insn "truncxf<mode>2_i387_noop_unspec"
12790 [(set (match_operand:MODEF 0 "register_operand" "=f")
12791 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12792 UNSPEC_TRUNC_NOOP))]
12793 "TARGET_USE_FANCY_MATH_387"
12794 "* return output_387_reg_move (insn, operands);"
12795 [(set_attr "type" "fmov")
12796 (set_attr "mode" "<MODE>")])
12798 (define_insn "sqrtxf2"
12799 [(set (match_operand:XF 0 "register_operand" "=f")
12800 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12801 "TARGET_USE_FANCY_MATH_387"
12803 [(set_attr "type" "fpspc")
12804 (set_attr "mode" "XF")
12805 (set_attr "athlon_decode" "direct")
12806 (set_attr "amdfam10_decode" "direct")])
12808 (define_insn "sqrt_extend<mode>xf2_i387"
12809 [(set (match_operand:XF 0 "register_operand" "=f")
12812 (match_operand:MODEF 1 "register_operand" "0"))))]
12813 "TARGET_USE_FANCY_MATH_387"
12815 [(set_attr "type" "fpspc")
12816 (set_attr "mode" "XF")
12817 (set_attr "athlon_decode" "direct")
12818 (set_attr "amdfam10_decode" "direct")])
12820 (define_insn "*rsqrtsf2_sse"
12821 [(set (match_operand:SF 0 "register_operand" "=x")
12822 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12825 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12826 [(set_attr "type" "sse")
12827 (set_attr "atom_sse_attr" "rcp")
12828 (set_attr "prefix" "maybe_vex")
12829 (set_attr "mode" "SF")])
12831 (define_expand "rsqrtsf2"
12832 [(set (match_operand:SF 0 "register_operand" "")
12833 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12837 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12841 (define_insn "*sqrt<mode>2_sse"
12842 [(set (match_operand:MODEF 0 "register_operand" "=x")
12844 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12845 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12846 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12847 [(set_attr "type" "sse")
12848 (set_attr "atom_sse_attr" "sqrt")
12849 (set_attr "prefix" "maybe_vex")
12850 (set_attr "mode" "<MODE>")
12851 (set_attr "athlon_decode" "*")
12852 (set_attr "amdfam10_decode" "*")])
12854 (define_expand "sqrt<mode>2"
12855 [(set (match_operand:MODEF 0 "register_operand" "")
12857 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12858 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12859 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12861 if (<MODE>mode == SFmode
12862 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12863 && flag_finite_math_only && !flag_trapping_math
12864 && flag_unsafe_math_optimizations)
12866 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12870 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12872 rtx op0 = gen_reg_rtx (XFmode);
12873 rtx op1 = force_reg (<MODE>mode, operands[1]);
12875 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12876 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12881 (define_insn "fpremxf4_i387"
12882 [(set (match_operand:XF 0 "register_operand" "=f")
12883 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12884 (match_operand:XF 3 "register_operand" "1")]
12886 (set (match_operand:XF 1 "register_operand" "=u")
12887 (unspec:XF [(match_dup 2) (match_dup 3)]
12889 (set (reg:CCFP FPSR_REG)
12890 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12892 "TARGET_USE_FANCY_MATH_387"
12894 [(set_attr "type" "fpspc")
12895 (set_attr "mode" "XF")])
12897 (define_expand "fmodxf3"
12898 [(use (match_operand:XF 0 "register_operand" ""))
12899 (use (match_operand:XF 1 "general_operand" ""))
12900 (use (match_operand:XF 2 "general_operand" ""))]
12901 "TARGET_USE_FANCY_MATH_387"
12903 rtx label = gen_label_rtx ();
12905 rtx op1 = gen_reg_rtx (XFmode);
12906 rtx op2 = gen_reg_rtx (XFmode);
12908 emit_move_insn (op2, operands[2]);
12909 emit_move_insn (op1, operands[1]);
12911 emit_label (label);
12912 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12913 ix86_emit_fp_unordered_jump (label);
12914 LABEL_NUSES (label) = 1;
12916 emit_move_insn (operands[0], op1);
12920 (define_expand "fmod<mode>3"
12921 [(use (match_operand:MODEF 0 "register_operand" ""))
12922 (use (match_operand:MODEF 1 "general_operand" ""))
12923 (use (match_operand:MODEF 2 "general_operand" ""))]
12924 "TARGET_USE_FANCY_MATH_387"
12926 rtx label = gen_label_rtx ();
12928 rtx op1 = gen_reg_rtx (XFmode);
12929 rtx op2 = gen_reg_rtx (XFmode);
12931 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12932 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12934 emit_label (label);
12935 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12936 ix86_emit_fp_unordered_jump (label);
12937 LABEL_NUSES (label) = 1;
12939 /* Truncate the result properly for strict SSE math. */
12940 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12941 && !TARGET_MIX_SSE_I387)
12942 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
12944 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
12949 (define_insn "fprem1xf4_i387"
12950 [(set (match_operand:XF 0 "register_operand" "=f")
12951 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12952 (match_operand:XF 3 "register_operand" "1")]
12954 (set (match_operand:XF 1 "register_operand" "=u")
12955 (unspec:XF [(match_dup 2) (match_dup 3)]
12957 (set (reg:CCFP FPSR_REG)
12958 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12960 "TARGET_USE_FANCY_MATH_387"
12962 [(set_attr "type" "fpspc")
12963 (set_attr "mode" "XF")])
12965 (define_expand "remainderxf3"
12966 [(use (match_operand:XF 0 "register_operand" ""))
12967 (use (match_operand:XF 1 "general_operand" ""))
12968 (use (match_operand:XF 2 "general_operand" ""))]
12969 "TARGET_USE_FANCY_MATH_387"
12971 rtx label = gen_label_rtx ();
12973 rtx op1 = gen_reg_rtx (XFmode);
12974 rtx op2 = gen_reg_rtx (XFmode);
12976 emit_move_insn (op2, operands[2]);
12977 emit_move_insn (op1, operands[1]);
12979 emit_label (label);
12980 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12981 ix86_emit_fp_unordered_jump (label);
12982 LABEL_NUSES (label) = 1;
12984 emit_move_insn (operands[0], op1);
12988 (define_expand "remainder<mode>3"
12989 [(use (match_operand:MODEF 0 "register_operand" ""))
12990 (use (match_operand:MODEF 1 "general_operand" ""))
12991 (use (match_operand:MODEF 2 "general_operand" ""))]
12992 "TARGET_USE_FANCY_MATH_387"
12994 rtx label = gen_label_rtx ();
12996 rtx op1 = gen_reg_rtx (XFmode);
12997 rtx op2 = gen_reg_rtx (XFmode);
12999 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13000 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13002 emit_label (label);
13004 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13005 ix86_emit_fp_unordered_jump (label);
13006 LABEL_NUSES (label) = 1;
13008 /* Truncate the result properly for strict SSE math. */
13009 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13010 && !TARGET_MIX_SSE_I387)
13011 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13013 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13018 (define_insn "*sinxf2_i387"
13019 [(set (match_operand:XF 0 "register_operand" "=f")
13020 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13021 "TARGET_USE_FANCY_MATH_387
13022 && flag_unsafe_math_optimizations"
13024 [(set_attr "type" "fpspc")
13025 (set_attr "mode" "XF")])
13027 (define_insn "*sin_extend<mode>xf2_i387"
13028 [(set (match_operand:XF 0 "register_operand" "=f")
13029 (unspec:XF [(float_extend:XF
13030 (match_operand:MODEF 1 "register_operand" "0"))]
13032 "TARGET_USE_FANCY_MATH_387
13033 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13034 || TARGET_MIX_SSE_I387)
13035 && flag_unsafe_math_optimizations"
13037 [(set_attr "type" "fpspc")
13038 (set_attr "mode" "XF")])
13040 (define_insn "*cosxf2_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f")
13042 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13043 "TARGET_USE_FANCY_MATH_387
13044 && flag_unsafe_math_optimizations"
13046 [(set_attr "type" "fpspc")
13047 (set_attr "mode" "XF")])
13049 (define_insn "*cos_extend<mode>xf2_i387"
13050 [(set (match_operand:XF 0 "register_operand" "=f")
13051 (unspec:XF [(float_extend:XF
13052 (match_operand:MODEF 1 "register_operand" "0"))]
13054 "TARGET_USE_FANCY_MATH_387
13055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13056 || TARGET_MIX_SSE_I387)
13057 && flag_unsafe_math_optimizations"
13059 [(set_attr "type" "fpspc")
13060 (set_attr "mode" "XF")])
13062 ;; When sincos pattern is defined, sin and cos builtin functions will be
13063 ;; expanded to sincos pattern with one of its outputs left unused.
13064 ;; CSE pass will figure out if two sincos patterns can be combined,
13065 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13066 ;; depending on the unused output.
13068 (define_insn "sincosxf3"
13069 [(set (match_operand:XF 0 "register_operand" "=f")
13070 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13071 UNSPEC_SINCOS_COS))
13072 (set (match_operand:XF 1 "register_operand" "=u")
13073 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13074 "TARGET_USE_FANCY_MATH_387
13075 && flag_unsafe_math_optimizations"
13077 [(set_attr "type" "fpspc")
13078 (set_attr "mode" "XF")])
13081 [(set (match_operand:XF 0 "register_operand" "")
13082 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13083 UNSPEC_SINCOS_COS))
13084 (set (match_operand:XF 1 "register_operand" "")
13085 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13086 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13087 && !(reload_completed || reload_in_progress)"
13088 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13092 [(set (match_operand:XF 0 "register_operand" "")
13093 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13094 UNSPEC_SINCOS_COS))
13095 (set (match_operand:XF 1 "register_operand" "")
13096 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13097 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13098 && !(reload_completed || reload_in_progress)"
13099 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13102 (define_insn "sincos_extend<mode>xf3_i387"
13103 [(set (match_operand:XF 0 "register_operand" "=f")
13104 (unspec:XF [(float_extend:XF
13105 (match_operand:MODEF 2 "register_operand" "0"))]
13106 UNSPEC_SINCOS_COS))
13107 (set (match_operand:XF 1 "register_operand" "=u")
13108 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13109 "TARGET_USE_FANCY_MATH_387
13110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13111 || TARGET_MIX_SSE_I387)
13112 && flag_unsafe_math_optimizations"
13114 [(set_attr "type" "fpspc")
13115 (set_attr "mode" "XF")])
13118 [(set (match_operand:XF 0 "register_operand" "")
13119 (unspec:XF [(float_extend:XF
13120 (match_operand:MODEF 2 "register_operand" ""))]
13121 UNSPEC_SINCOS_COS))
13122 (set (match_operand:XF 1 "register_operand" "")
13123 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13124 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13125 && !(reload_completed || reload_in_progress)"
13126 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13130 [(set (match_operand:XF 0 "register_operand" "")
13131 (unspec:XF [(float_extend:XF
13132 (match_operand:MODEF 2 "register_operand" ""))]
13133 UNSPEC_SINCOS_COS))
13134 (set (match_operand:XF 1 "register_operand" "")
13135 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13136 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13137 && !(reload_completed || reload_in_progress)"
13138 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13141 (define_expand "sincos<mode>3"
13142 [(use (match_operand:MODEF 0 "register_operand" ""))
13143 (use (match_operand:MODEF 1 "register_operand" ""))
13144 (use (match_operand:MODEF 2 "register_operand" ""))]
13145 "TARGET_USE_FANCY_MATH_387
13146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13147 || TARGET_MIX_SSE_I387)
13148 && flag_unsafe_math_optimizations"
13150 rtx op0 = gen_reg_rtx (XFmode);
13151 rtx op1 = gen_reg_rtx (XFmode);
13153 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13155 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13159 (define_insn "fptanxf4_i387"
13160 [(set (match_operand:XF 0 "register_operand" "=f")
13161 (match_operand:XF 3 "const_double_operand" "F"))
13162 (set (match_operand:XF 1 "register_operand" "=u")
13163 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13165 "TARGET_USE_FANCY_MATH_387
13166 && flag_unsafe_math_optimizations
13167 && standard_80387_constant_p (operands[3]) == 2"
13169 [(set_attr "type" "fpspc")
13170 (set_attr "mode" "XF")])
13172 (define_insn "fptan_extend<mode>xf4_i387"
13173 [(set (match_operand:MODEF 0 "register_operand" "=f")
13174 (match_operand:MODEF 3 "const_double_operand" "F"))
13175 (set (match_operand:XF 1 "register_operand" "=u")
13176 (unspec:XF [(float_extend:XF
13177 (match_operand:MODEF 2 "register_operand" "0"))]
13179 "TARGET_USE_FANCY_MATH_387
13180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13181 || TARGET_MIX_SSE_I387)
13182 && flag_unsafe_math_optimizations
13183 && standard_80387_constant_p (operands[3]) == 2"
13185 [(set_attr "type" "fpspc")
13186 (set_attr "mode" "XF")])
13188 (define_expand "tanxf2"
13189 [(use (match_operand:XF 0 "register_operand" ""))
13190 (use (match_operand:XF 1 "register_operand" ""))]
13191 "TARGET_USE_FANCY_MATH_387
13192 && flag_unsafe_math_optimizations"
13194 rtx one = gen_reg_rtx (XFmode);
13195 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13197 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13201 (define_expand "tan<mode>2"
13202 [(use (match_operand:MODEF 0 "register_operand" ""))
13203 (use (match_operand:MODEF 1 "register_operand" ""))]
13204 "TARGET_USE_FANCY_MATH_387
13205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13206 || TARGET_MIX_SSE_I387)
13207 && flag_unsafe_math_optimizations"
13209 rtx op0 = gen_reg_rtx (XFmode);
13211 rtx one = gen_reg_rtx (<MODE>mode);
13212 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13214 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13215 operands[1], op2));
13216 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13220 (define_insn "*fpatanxf3_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f")
13222 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13223 (match_operand:XF 2 "register_operand" "u")]
13225 (clobber (match_scratch:XF 3 "=2"))]
13226 "TARGET_USE_FANCY_MATH_387
13227 && flag_unsafe_math_optimizations"
13229 [(set_attr "type" "fpspc")
13230 (set_attr "mode" "XF")])
13232 (define_insn "fpatan_extend<mode>xf3_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f")
13234 (unspec:XF [(float_extend:XF
13235 (match_operand:MODEF 1 "register_operand" "0"))
13237 (match_operand:MODEF 2 "register_operand" "u"))]
13239 (clobber (match_scratch:XF 3 "=2"))]
13240 "TARGET_USE_FANCY_MATH_387
13241 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13242 || TARGET_MIX_SSE_I387)
13243 && flag_unsafe_math_optimizations"
13245 [(set_attr "type" "fpspc")
13246 (set_attr "mode" "XF")])
13248 (define_expand "atan2xf3"
13249 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13250 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13251 (match_operand:XF 1 "register_operand" "")]
13253 (clobber (match_scratch:XF 3 ""))])]
13254 "TARGET_USE_FANCY_MATH_387
13255 && flag_unsafe_math_optimizations"
13258 (define_expand "atan2<mode>3"
13259 [(use (match_operand:MODEF 0 "register_operand" ""))
13260 (use (match_operand:MODEF 1 "register_operand" ""))
13261 (use (match_operand:MODEF 2 "register_operand" ""))]
13262 "TARGET_USE_FANCY_MATH_387
13263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13264 || TARGET_MIX_SSE_I387)
13265 && flag_unsafe_math_optimizations"
13267 rtx op0 = gen_reg_rtx (XFmode);
13269 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13270 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13274 (define_expand "atanxf2"
13275 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13276 (unspec:XF [(match_dup 2)
13277 (match_operand:XF 1 "register_operand" "")]
13279 (clobber (match_scratch:XF 3 ""))])]
13280 "TARGET_USE_FANCY_MATH_387
13281 && flag_unsafe_math_optimizations"
13283 operands[2] = gen_reg_rtx (XFmode);
13284 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13287 (define_expand "atan<mode>2"
13288 [(use (match_operand:MODEF 0 "register_operand" ""))
13289 (use (match_operand:MODEF 1 "register_operand" ""))]
13290 "TARGET_USE_FANCY_MATH_387
13291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13292 || TARGET_MIX_SSE_I387)
13293 && flag_unsafe_math_optimizations"
13295 rtx op0 = gen_reg_rtx (XFmode);
13297 rtx op2 = gen_reg_rtx (<MODE>mode);
13298 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13300 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13305 (define_expand "asinxf2"
13306 [(set (match_dup 2)
13307 (mult:XF (match_operand:XF 1 "register_operand" "")
13309 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13310 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13311 (parallel [(set (match_operand:XF 0 "register_operand" "")
13312 (unspec:XF [(match_dup 5) (match_dup 1)]
13314 (clobber (match_scratch:XF 6 ""))])]
13315 "TARGET_USE_FANCY_MATH_387
13316 && flag_unsafe_math_optimizations"
13320 if (optimize_insn_for_size_p ())
13323 for (i = 2; i < 6; i++)
13324 operands[i] = gen_reg_rtx (XFmode);
13326 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13329 (define_expand "asin<mode>2"
13330 [(use (match_operand:MODEF 0 "register_operand" ""))
13331 (use (match_operand:MODEF 1 "general_operand" ""))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13334 || TARGET_MIX_SSE_I387)
13335 && flag_unsafe_math_optimizations"
13337 rtx op0 = gen_reg_rtx (XFmode);
13338 rtx op1 = gen_reg_rtx (XFmode);
13340 if (optimize_insn_for_size_p ())
13343 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13344 emit_insn (gen_asinxf2 (op0, op1));
13345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13349 (define_expand "acosxf2"
13350 [(set (match_dup 2)
13351 (mult:XF (match_operand:XF 1 "register_operand" "")
13353 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13354 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13355 (parallel [(set (match_operand:XF 0 "register_operand" "")
13356 (unspec:XF [(match_dup 1) (match_dup 5)]
13358 (clobber (match_scratch:XF 6 ""))])]
13359 "TARGET_USE_FANCY_MATH_387
13360 && flag_unsafe_math_optimizations"
13364 if (optimize_insn_for_size_p ())
13367 for (i = 2; i < 6; i++)
13368 operands[i] = gen_reg_rtx (XFmode);
13370 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13373 (define_expand "acos<mode>2"
13374 [(use (match_operand:MODEF 0 "register_operand" ""))
13375 (use (match_operand:MODEF 1 "general_operand" ""))]
13376 "TARGET_USE_FANCY_MATH_387
13377 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13378 || TARGET_MIX_SSE_I387)
13379 && flag_unsafe_math_optimizations"
13381 rtx op0 = gen_reg_rtx (XFmode);
13382 rtx op1 = gen_reg_rtx (XFmode);
13384 if (optimize_insn_for_size_p ())
13387 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13388 emit_insn (gen_acosxf2 (op0, op1));
13389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393 (define_insn "fyl2xxf3_i387"
13394 [(set (match_operand:XF 0 "register_operand" "=f")
13395 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13396 (match_operand:XF 2 "register_operand" "u")]
13398 (clobber (match_scratch:XF 3 "=2"))]
13399 "TARGET_USE_FANCY_MATH_387
13400 && flag_unsafe_math_optimizations"
13402 [(set_attr "type" "fpspc")
13403 (set_attr "mode" "XF")])
13405 (define_insn "fyl2x_extend<mode>xf3_i387"
13406 [(set (match_operand:XF 0 "register_operand" "=f")
13407 (unspec:XF [(float_extend:XF
13408 (match_operand:MODEF 1 "register_operand" "0"))
13409 (match_operand:XF 2 "register_operand" "u")]
13411 (clobber (match_scratch:XF 3 "=2"))]
13412 "TARGET_USE_FANCY_MATH_387
13413 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13414 || TARGET_MIX_SSE_I387)
13415 && flag_unsafe_math_optimizations"
13417 [(set_attr "type" "fpspc")
13418 (set_attr "mode" "XF")])
13420 (define_expand "logxf2"
13421 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13422 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13423 (match_dup 2)] UNSPEC_FYL2X))
13424 (clobber (match_scratch:XF 3 ""))])]
13425 "TARGET_USE_FANCY_MATH_387
13426 && flag_unsafe_math_optimizations"
13428 operands[2] = gen_reg_rtx (XFmode);
13429 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13432 (define_expand "log<mode>2"
13433 [(use (match_operand:MODEF 0 "register_operand" ""))
13434 (use (match_operand:MODEF 1 "register_operand" ""))]
13435 "TARGET_USE_FANCY_MATH_387
13436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13437 || TARGET_MIX_SSE_I387)
13438 && flag_unsafe_math_optimizations"
13440 rtx op0 = gen_reg_rtx (XFmode);
13442 rtx op2 = gen_reg_rtx (XFmode);
13443 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13445 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13446 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13450 (define_expand "log10xf2"
13451 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13452 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13453 (match_dup 2)] UNSPEC_FYL2X))
13454 (clobber (match_scratch:XF 3 ""))])]
13455 "TARGET_USE_FANCY_MATH_387
13456 && flag_unsafe_math_optimizations"
13458 operands[2] = gen_reg_rtx (XFmode);
13459 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13462 (define_expand "log10<mode>2"
13463 [(use (match_operand:MODEF 0 "register_operand" ""))
13464 (use (match_operand:MODEF 1 "register_operand" ""))]
13465 "TARGET_USE_FANCY_MATH_387
13466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13467 || TARGET_MIX_SSE_I387)
13468 && flag_unsafe_math_optimizations"
13470 rtx op0 = gen_reg_rtx (XFmode);
13472 rtx op2 = gen_reg_rtx (XFmode);
13473 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13475 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13480 (define_expand "log2xf2"
13481 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13482 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13483 (match_dup 2)] UNSPEC_FYL2X))
13484 (clobber (match_scratch:XF 3 ""))])]
13485 "TARGET_USE_FANCY_MATH_387
13486 && flag_unsafe_math_optimizations"
13488 operands[2] = gen_reg_rtx (XFmode);
13489 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13492 (define_expand "log2<mode>2"
13493 [(use (match_operand:MODEF 0 "register_operand" ""))
13494 (use (match_operand:MODEF 1 "register_operand" ""))]
13495 "TARGET_USE_FANCY_MATH_387
13496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13497 || TARGET_MIX_SSE_I387)
13498 && flag_unsafe_math_optimizations"
13500 rtx op0 = gen_reg_rtx (XFmode);
13502 rtx op2 = gen_reg_rtx (XFmode);
13503 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13505 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13506 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13510 (define_insn "fyl2xp1xf3_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13513 (match_operand:XF 2 "register_operand" "u")]
13515 (clobber (match_scratch:XF 3 "=2"))]
13516 "TARGET_USE_FANCY_MATH_387
13517 && flag_unsafe_math_optimizations"
13519 [(set_attr "type" "fpspc")
13520 (set_attr "mode" "XF")])
13522 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (unspec:XF [(float_extend:XF
13525 (match_operand:MODEF 1 "register_operand" "0"))
13526 (match_operand:XF 2 "register_operand" "u")]
13528 (clobber (match_scratch:XF 3 "=2"))]
13529 "TARGET_USE_FANCY_MATH_387
13530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13531 || TARGET_MIX_SSE_I387)
13532 && flag_unsafe_math_optimizations"
13534 [(set_attr "type" "fpspc")
13535 (set_attr "mode" "XF")])
13537 (define_expand "log1pxf2"
13538 [(use (match_operand:XF 0 "register_operand" ""))
13539 (use (match_operand:XF 1 "register_operand" ""))]
13540 "TARGET_USE_FANCY_MATH_387
13541 && flag_unsafe_math_optimizations"
13543 if (optimize_insn_for_size_p ())
13546 ix86_emit_i387_log1p (operands[0], operands[1]);
13550 (define_expand "log1p<mode>2"
13551 [(use (match_operand:MODEF 0 "register_operand" ""))
13552 (use (match_operand:MODEF 1 "register_operand" ""))]
13553 "TARGET_USE_FANCY_MATH_387
13554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13555 || TARGET_MIX_SSE_I387)
13556 && flag_unsafe_math_optimizations"
13560 if (optimize_insn_for_size_p ())
13563 op0 = gen_reg_rtx (XFmode);
13565 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13567 ix86_emit_i387_log1p (op0, operands[1]);
13568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13572 (define_insn "fxtractxf3_i387"
13573 [(set (match_operand:XF 0 "register_operand" "=f")
13574 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13575 UNSPEC_XTRACT_FRACT))
13576 (set (match_operand:XF 1 "register_operand" "=u")
13577 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13578 "TARGET_USE_FANCY_MATH_387
13579 && flag_unsafe_math_optimizations"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13584 (define_insn "fxtract_extend<mode>xf3_i387"
13585 [(set (match_operand:XF 0 "register_operand" "=f")
13586 (unspec:XF [(float_extend:XF
13587 (match_operand:MODEF 2 "register_operand" "0"))]
13588 UNSPEC_XTRACT_FRACT))
13589 (set (match_operand:XF 1 "register_operand" "=u")
13590 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13591 "TARGET_USE_FANCY_MATH_387
13592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13593 || TARGET_MIX_SSE_I387)
13594 && flag_unsafe_math_optimizations"
13596 [(set_attr "type" "fpspc")
13597 (set_attr "mode" "XF")])
13599 (define_expand "logbxf2"
13600 [(parallel [(set (match_dup 2)
13601 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13602 UNSPEC_XTRACT_FRACT))
13603 (set (match_operand:XF 0 "register_operand" "")
13604 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13605 "TARGET_USE_FANCY_MATH_387
13606 && flag_unsafe_math_optimizations"
13608 operands[2] = gen_reg_rtx (XFmode);
13611 (define_expand "logb<mode>2"
13612 [(use (match_operand:MODEF 0 "register_operand" ""))
13613 (use (match_operand:MODEF 1 "register_operand" ""))]
13614 "TARGET_USE_FANCY_MATH_387
13615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13616 || TARGET_MIX_SSE_I387)
13617 && flag_unsafe_math_optimizations"
13619 rtx op0 = gen_reg_rtx (XFmode);
13620 rtx op1 = gen_reg_rtx (XFmode);
13622 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13623 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13627 (define_expand "ilogbxf2"
13628 [(use (match_operand:SI 0 "register_operand" ""))
13629 (use (match_operand:XF 1 "register_operand" ""))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && flag_unsafe_math_optimizations"
13635 if (optimize_insn_for_size_p ())
13638 op0 = gen_reg_rtx (XFmode);
13639 op1 = gen_reg_rtx (XFmode);
13641 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13642 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13646 (define_expand "ilogb<mode>2"
13647 [(use (match_operand:SI 0 "register_operand" ""))
13648 (use (match_operand:MODEF 1 "register_operand" ""))]
13649 "TARGET_USE_FANCY_MATH_387
13650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13651 || TARGET_MIX_SSE_I387)
13652 && flag_unsafe_math_optimizations"
13656 if (optimize_insn_for_size_p ())
13659 op0 = gen_reg_rtx (XFmode);
13660 op1 = gen_reg_rtx (XFmode);
13662 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13663 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13667 (define_insn "*f2xm1xf2_i387"
13668 [(set (match_operand:XF 0 "register_operand" "=f")
13669 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13671 "TARGET_USE_FANCY_MATH_387
13672 && flag_unsafe_math_optimizations"
13674 [(set_attr "type" "fpspc")
13675 (set_attr "mode" "XF")])
13677 (define_insn "*fscalexf4_i387"
13678 [(set (match_operand:XF 0 "register_operand" "=f")
13679 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13680 (match_operand:XF 3 "register_operand" "1")]
13681 UNSPEC_FSCALE_FRACT))
13682 (set (match_operand:XF 1 "register_operand" "=u")
13683 (unspec:XF [(match_dup 2) (match_dup 3)]
13684 UNSPEC_FSCALE_EXP))]
13685 "TARGET_USE_FANCY_MATH_387
13686 && flag_unsafe_math_optimizations"
13688 [(set_attr "type" "fpspc")
13689 (set_attr "mode" "XF")])
13691 (define_expand "expNcorexf3"
13692 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13693 (match_operand:XF 2 "register_operand" "")))
13694 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13695 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13696 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13697 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13698 (parallel [(set (match_operand:XF 0 "register_operand" "")
13699 (unspec:XF [(match_dup 8) (match_dup 4)]
13700 UNSPEC_FSCALE_FRACT))
13702 (unspec:XF [(match_dup 8) (match_dup 4)]
13703 UNSPEC_FSCALE_EXP))])]
13704 "TARGET_USE_FANCY_MATH_387
13705 && flag_unsafe_math_optimizations"
13709 if (optimize_insn_for_size_p ())
13712 for (i = 3; i < 10; i++)
13713 operands[i] = gen_reg_rtx (XFmode);
13715 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13718 (define_expand "expxf2"
13719 [(use (match_operand:XF 0 "register_operand" ""))
13720 (use (match_operand:XF 1 "register_operand" ""))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && flag_unsafe_math_optimizations"
13726 if (optimize_insn_for_size_p ())
13729 op2 = gen_reg_rtx (XFmode);
13730 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13732 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13736 (define_expand "exp<mode>2"
13737 [(use (match_operand:MODEF 0 "register_operand" ""))
13738 (use (match_operand:MODEF 1 "general_operand" ""))]
13739 "TARGET_USE_FANCY_MATH_387
13740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13741 || TARGET_MIX_SSE_I387)
13742 && flag_unsafe_math_optimizations"
13746 if (optimize_insn_for_size_p ())
13749 op0 = gen_reg_rtx (XFmode);
13750 op1 = gen_reg_rtx (XFmode);
13752 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13753 emit_insn (gen_expxf2 (op0, op1));
13754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13758 (define_expand "exp10xf2"
13759 [(use (match_operand:XF 0 "register_operand" ""))
13760 (use (match_operand:XF 1 "register_operand" ""))]
13761 "TARGET_USE_FANCY_MATH_387
13762 && flag_unsafe_math_optimizations"
13766 if (optimize_insn_for_size_p ())
13769 op2 = gen_reg_rtx (XFmode);
13770 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13772 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13776 (define_expand "exp10<mode>2"
13777 [(use (match_operand:MODEF 0 "register_operand" ""))
13778 (use (match_operand:MODEF 1 "general_operand" ""))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 || TARGET_MIX_SSE_I387)
13782 && flag_unsafe_math_optimizations"
13786 if (optimize_insn_for_size_p ())
13789 op0 = gen_reg_rtx (XFmode);
13790 op1 = gen_reg_rtx (XFmode);
13792 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13793 emit_insn (gen_exp10xf2 (op0, op1));
13794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13798 (define_expand "exp2xf2"
13799 [(use (match_operand:XF 0 "register_operand" ""))
13800 (use (match_operand:XF 1 "register_operand" ""))]
13801 "TARGET_USE_FANCY_MATH_387
13802 && flag_unsafe_math_optimizations"
13806 if (optimize_insn_for_size_p ())
13809 op2 = gen_reg_rtx (XFmode);
13810 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13812 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13816 (define_expand "exp2<mode>2"
13817 [(use (match_operand:MODEF 0 "register_operand" ""))
13818 (use (match_operand:MODEF 1 "general_operand" ""))]
13819 "TARGET_USE_FANCY_MATH_387
13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821 || TARGET_MIX_SSE_I387)
13822 && flag_unsafe_math_optimizations"
13826 if (optimize_insn_for_size_p ())
13829 op0 = gen_reg_rtx (XFmode);
13830 op1 = gen_reg_rtx (XFmode);
13832 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13833 emit_insn (gen_exp2xf2 (op0, op1));
13834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13838 (define_expand "expm1xf2"
13839 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13841 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13842 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13843 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13844 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13845 (parallel [(set (match_dup 7)
13846 (unspec:XF [(match_dup 6) (match_dup 4)]
13847 UNSPEC_FSCALE_FRACT))
13849 (unspec:XF [(match_dup 6) (match_dup 4)]
13850 UNSPEC_FSCALE_EXP))])
13851 (parallel [(set (match_dup 10)
13852 (unspec:XF [(match_dup 9) (match_dup 8)]
13853 UNSPEC_FSCALE_FRACT))
13854 (set (match_dup 11)
13855 (unspec:XF [(match_dup 9) (match_dup 8)]
13856 UNSPEC_FSCALE_EXP))])
13857 (set (match_dup 12) (minus:XF (match_dup 10)
13858 (float_extend:XF (match_dup 13))))
13859 (set (match_operand:XF 0 "register_operand" "")
13860 (plus:XF (match_dup 12) (match_dup 7)))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && flag_unsafe_math_optimizations"
13866 if (optimize_insn_for_size_p ())
13869 for (i = 2; i < 13; i++)
13870 operands[i] = gen_reg_rtx (XFmode);
13873 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13875 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13878 (define_expand "expm1<mode>2"
13879 [(use (match_operand:MODEF 0 "register_operand" ""))
13880 (use (match_operand:MODEF 1 "general_operand" ""))]
13881 "TARGET_USE_FANCY_MATH_387
13882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13883 || TARGET_MIX_SSE_I387)
13884 && flag_unsafe_math_optimizations"
13888 if (optimize_insn_for_size_p ())
13891 op0 = gen_reg_rtx (XFmode);
13892 op1 = gen_reg_rtx (XFmode);
13894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13895 emit_insn (gen_expm1xf2 (op0, op1));
13896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13900 (define_expand "ldexpxf3"
13901 [(set (match_dup 3)
13902 (float:XF (match_operand:SI 2 "register_operand" "")))
13903 (parallel [(set (match_operand:XF 0 " register_operand" "")
13904 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13906 UNSPEC_FSCALE_FRACT))
13908 (unspec:XF [(match_dup 1) (match_dup 3)]
13909 UNSPEC_FSCALE_EXP))])]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13913 if (optimize_insn_for_size_p ())
13916 operands[3] = gen_reg_rtx (XFmode);
13917 operands[4] = gen_reg_rtx (XFmode);
13920 (define_expand "ldexp<mode>3"
13921 [(use (match_operand:MODEF 0 "register_operand" ""))
13922 (use (match_operand:MODEF 1 "general_operand" ""))
13923 (use (match_operand:SI 2 "register_operand" ""))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13926 || TARGET_MIX_SSE_I387)
13927 && flag_unsafe_math_optimizations"
13931 if (optimize_insn_for_size_p ())
13934 op0 = gen_reg_rtx (XFmode);
13935 op1 = gen_reg_rtx (XFmode);
13937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13938 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13943 (define_expand "scalbxf3"
13944 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13945 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13946 (match_operand:XF 2 "register_operand" "")]
13947 UNSPEC_FSCALE_FRACT))
13949 (unspec:XF [(match_dup 1) (match_dup 2)]
13950 UNSPEC_FSCALE_EXP))])]
13951 "TARGET_USE_FANCY_MATH_387
13952 && flag_unsafe_math_optimizations"
13954 if (optimize_insn_for_size_p ())
13957 operands[3] = gen_reg_rtx (XFmode);
13960 (define_expand "scalb<mode>3"
13961 [(use (match_operand:MODEF 0 "register_operand" ""))
13962 (use (match_operand:MODEF 1 "general_operand" ""))
13963 (use (match_operand:MODEF 2 "general_operand" ""))]
13964 "TARGET_USE_FANCY_MATH_387
13965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13966 || TARGET_MIX_SSE_I387)
13967 && flag_unsafe_math_optimizations"
13971 if (optimize_insn_for_size_p ())
13974 op0 = gen_reg_rtx (XFmode);
13975 op1 = gen_reg_rtx (XFmode);
13976 op2 = gen_reg_rtx (XFmode);
13978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13979 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13980 emit_insn (gen_scalbxf3 (op0, op1, op2));
13981 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985 (define_expand "significandxf2"
13986 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13988 UNSPEC_XTRACT_FRACT))
13990 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13994 operands[2] = gen_reg_rtx (XFmode);
13997 (define_expand "significand<mode>2"
13998 [(use (match_operand:MODEF 0 "register_operand" ""))
13999 (use (match_operand:MODEF 1 "register_operand" ""))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002 || TARGET_MIX_SSE_I387)
14003 && flag_unsafe_math_optimizations"
14005 rtx op0 = gen_reg_rtx (XFmode);
14006 rtx op1 = gen_reg_rtx (XFmode);
14008 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14009 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14014 (define_insn "sse4_1_round<mode>2"
14015 [(set (match_operand:MODEF 0 "register_operand" "=x")
14016 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14017 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14020 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14021 [(set_attr "type" "ssecvt")
14022 (set_attr "prefix_extra" "1")
14023 (set_attr "prefix" "maybe_vex")
14024 (set_attr "mode" "<MODE>")])
14026 (define_insn "rintxf2"
14027 [(set (match_operand:XF 0 "register_operand" "=f")
14028 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14030 "TARGET_USE_FANCY_MATH_387
14031 && flag_unsafe_math_optimizations"
14033 [(set_attr "type" "fpspc")
14034 (set_attr "mode" "XF")])
14036 (define_expand "rint<mode>2"
14037 [(use (match_operand:MODEF 0 "register_operand" ""))
14038 (use (match_operand:MODEF 1 "register_operand" ""))]
14039 "(TARGET_USE_FANCY_MATH_387
14040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041 || TARGET_MIX_SSE_I387)
14042 && flag_unsafe_math_optimizations)
14043 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14044 && !flag_trapping_math)"
14046 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14047 && !flag_trapping_math)
14049 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14052 emit_insn (gen_sse4_1_round<mode>2
14053 (operands[0], operands[1], GEN_INT (0x04)));
14055 ix86_expand_rint (operand0, operand1);
14059 rtx op0 = gen_reg_rtx (XFmode);
14060 rtx op1 = gen_reg_rtx (XFmode);
14062 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14063 emit_insn (gen_rintxf2 (op0, op1));
14065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070 (define_expand "round<mode>2"
14071 [(match_operand:MODEF 0 "register_operand" "")
14072 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14073 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14074 && !flag_trapping_math && !flag_rounding_math"
14076 if (optimize_insn_for_size_p ())
14078 if (TARGET_64BIT || (<MODE>mode != DFmode))
14079 ix86_expand_round (operand0, operand1);
14081 ix86_expand_rounddf_32 (operand0, operand1);
14085 (define_insn_and_split "*fistdi2_1"
14086 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14087 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14089 "TARGET_USE_FANCY_MATH_387
14090 && can_create_pseudo_p ()"
14095 if (memory_operand (operands[0], VOIDmode))
14096 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14099 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14100 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14105 [(set_attr "type" "fpspc")
14106 (set_attr "mode" "DI")])
14108 (define_insn "fistdi2"
14109 [(set (match_operand:DI 0 "memory_operand" "=m")
14110 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14112 (clobber (match_scratch:XF 2 "=&1f"))]
14113 "TARGET_USE_FANCY_MATH_387"
14114 "* return output_fix_trunc (insn, operands, 0);"
14115 [(set_attr "type" "fpspc")
14116 (set_attr "mode" "DI")])
14118 (define_insn "fistdi2_with_temp"
14119 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14120 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14122 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14123 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14124 "TARGET_USE_FANCY_MATH_387"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "DI")])
14130 [(set (match_operand:DI 0 "register_operand" "")
14131 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14133 (clobber (match_operand:DI 2 "memory_operand" ""))
14134 (clobber (match_scratch 3 ""))]
14136 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14137 (clobber (match_dup 3))])
14138 (set (match_dup 0) (match_dup 2))]
14142 [(set (match_operand:DI 0 "memory_operand" "")
14143 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14145 (clobber (match_operand:DI 2 "memory_operand" ""))
14146 (clobber (match_scratch 3 ""))]
14148 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14149 (clobber (match_dup 3))])]
14152 (define_insn_and_split "*fist<mode>2_1"
14153 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14154 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14156 "TARGET_USE_FANCY_MATH_387
14157 && can_create_pseudo_p ()"
14162 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14163 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14167 [(set_attr "type" "fpspc")
14168 (set_attr "mode" "<MODE>")])
14170 (define_insn "fist<mode>2"
14171 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14172 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14174 "TARGET_USE_FANCY_MATH_387"
14175 "* return output_fix_trunc (insn, operands, 0);"
14176 [(set_attr "type" "fpspc")
14177 (set_attr "mode" "<MODE>")])
14179 (define_insn "fist<mode>2_with_temp"
14180 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14181 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14183 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14184 "TARGET_USE_FANCY_MATH_387"
14186 [(set_attr "type" "fpspc")
14187 (set_attr "mode" "<MODE>")])
14190 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14191 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14193 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14195 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14196 (set (match_dup 0) (match_dup 2))]
14200 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14201 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14203 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14205 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14208 (define_expand "lrintxf<mode>2"
14209 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14210 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14212 "TARGET_USE_FANCY_MATH_387"
14215 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14216 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14217 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14218 UNSPEC_FIX_NOTRUNC))]
14219 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14220 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14223 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14224 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14225 (match_operand:MODEF 1 "register_operand" "")]
14226 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14227 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14228 && !flag_trapping_math && !flag_rounding_math"
14230 if (optimize_insn_for_size_p ())
14232 ix86_expand_lround (operand0, operand1);
14236 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14237 (define_insn_and_split "frndintxf2_floor"
14238 [(set (match_operand:XF 0 "register_operand" "")
14239 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14240 UNSPEC_FRNDINT_FLOOR))
14241 (clobber (reg:CC FLAGS_REG))]
14242 "TARGET_USE_FANCY_MATH_387
14243 && flag_unsafe_math_optimizations
14244 && can_create_pseudo_p ()"
14249 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14251 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14252 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14254 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14255 operands[2], operands[3]));
14258 [(set_attr "type" "frndint")
14259 (set_attr "i387_cw" "floor")
14260 (set_attr "mode" "XF")])
14262 (define_insn "frndintxf2_floor_i387"
14263 [(set (match_operand:XF 0 "register_operand" "=f")
14264 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14265 UNSPEC_FRNDINT_FLOOR))
14266 (use (match_operand:HI 2 "memory_operand" "m"))
14267 (use (match_operand:HI 3 "memory_operand" "m"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && flag_unsafe_math_optimizations"
14270 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14271 [(set_attr "type" "frndint")
14272 (set_attr "i387_cw" "floor")
14273 (set_attr "mode" "XF")])
14275 (define_expand "floorxf2"
14276 [(use (match_operand:XF 0 "register_operand" ""))
14277 (use (match_operand:XF 1 "register_operand" ""))]
14278 "TARGET_USE_FANCY_MATH_387
14279 && flag_unsafe_math_optimizations"
14281 if (optimize_insn_for_size_p ())
14283 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14287 (define_expand "floor<mode>2"
14288 [(use (match_operand:MODEF 0 "register_operand" ""))
14289 (use (match_operand:MODEF 1 "register_operand" ""))]
14290 "(TARGET_USE_FANCY_MATH_387
14291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14292 || TARGET_MIX_SSE_I387)
14293 && flag_unsafe_math_optimizations)
14294 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14295 && !flag_trapping_math)"
14297 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14298 && !flag_trapping_math
14299 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14301 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14304 emit_insn (gen_sse4_1_round<mode>2
14305 (operands[0], operands[1], GEN_INT (0x01)));
14306 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14307 ix86_expand_floorceil (operand0, operand1, true);
14309 ix86_expand_floorceildf_32 (operand0, operand1, true);
14315 if (optimize_insn_for_size_p ())
14318 op0 = gen_reg_rtx (XFmode);
14319 op1 = gen_reg_rtx (XFmode);
14320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14321 emit_insn (gen_frndintxf2_floor (op0, op1));
14323 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14328 (define_insn_and_split "*fist<mode>2_floor_1"
14329 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14330 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14331 UNSPEC_FIST_FLOOR))
14332 (clobber (reg:CC FLAGS_REG))]
14333 "TARGET_USE_FANCY_MATH_387
14334 && flag_unsafe_math_optimizations
14335 && can_create_pseudo_p ()"
14340 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14342 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14343 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14344 if (memory_operand (operands[0], VOIDmode))
14345 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14346 operands[2], operands[3]));
14349 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14350 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14351 operands[2], operands[3],
14356 [(set_attr "type" "fistp")
14357 (set_attr "i387_cw" "floor")
14358 (set_attr "mode" "<MODE>")])
14360 (define_insn "fistdi2_floor"
14361 [(set (match_operand:DI 0 "memory_operand" "=m")
14362 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14363 UNSPEC_FIST_FLOOR))
14364 (use (match_operand:HI 2 "memory_operand" "m"))
14365 (use (match_operand:HI 3 "memory_operand" "m"))
14366 (clobber (match_scratch:XF 4 "=&1f"))]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations"
14369 "* return output_fix_trunc (insn, operands, 0);"
14370 [(set_attr "type" "fistp")
14371 (set_attr "i387_cw" "floor")
14372 (set_attr "mode" "DI")])
14374 (define_insn "fistdi2_floor_with_temp"
14375 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14376 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14377 UNSPEC_FIST_FLOOR))
14378 (use (match_operand:HI 2 "memory_operand" "m,m"))
14379 (use (match_operand:HI 3 "memory_operand" "m,m"))
14380 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14381 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && flag_unsafe_math_optimizations"
14385 [(set_attr "type" "fistp")
14386 (set_attr "i387_cw" "floor")
14387 (set_attr "mode" "DI")])
14390 [(set (match_operand:DI 0 "register_operand" "")
14391 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14392 UNSPEC_FIST_FLOOR))
14393 (use (match_operand:HI 2 "memory_operand" ""))
14394 (use (match_operand:HI 3 "memory_operand" ""))
14395 (clobber (match_operand:DI 4 "memory_operand" ""))
14396 (clobber (match_scratch 5 ""))]
14398 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14399 (use (match_dup 2))
14400 (use (match_dup 3))
14401 (clobber (match_dup 5))])
14402 (set (match_dup 0) (match_dup 4))]
14406 [(set (match_operand:DI 0 "memory_operand" "")
14407 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14408 UNSPEC_FIST_FLOOR))
14409 (use (match_operand:HI 2 "memory_operand" ""))
14410 (use (match_operand:HI 3 "memory_operand" ""))
14411 (clobber (match_operand:DI 4 "memory_operand" ""))
14412 (clobber (match_scratch 5 ""))]
14414 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14415 (use (match_dup 2))
14416 (use (match_dup 3))
14417 (clobber (match_dup 5))])]
14420 (define_insn "fist<mode>2_floor"
14421 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14422 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14423 UNSPEC_FIST_FLOOR))
14424 (use (match_operand:HI 2 "memory_operand" "m"))
14425 (use (match_operand:HI 3 "memory_operand" "m"))]
14426 "TARGET_USE_FANCY_MATH_387
14427 && flag_unsafe_math_optimizations"
14428 "* return output_fix_trunc (insn, operands, 0);"
14429 [(set_attr "type" "fistp")
14430 (set_attr "i387_cw" "floor")
14431 (set_attr "mode" "<MODE>")])
14433 (define_insn "fist<mode>2_floor_with_temp"
14434 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14435 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14436 UNSPEC_FIST_FLOOR))
14437 (use (match_operand:HI 2 "memory_operand" "m,m"))
14438 (use (match_operand:HI 3 "memory_operand" "m,m"))
14439 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && flag_unsafe_math_optimizations"
14443 [(set_attr "type" "fistp")
14444 (set_attr "i387_cw" "floor")
14445 (set_attr "mode" "<MODE>")])
14448 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14449 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14450 UNSPEC_FIST_FLOOR))
14451 (use (match_operand:HI 2 "memory_operand" ""))
14452 (use (match_operand:HI 3 "memory_operand" ""))
14453 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14455 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14456 UNSPEC_FIST_FLOOR))
14457 (use (match_dup 2))
14458 (use (match_dup 3))])
14459 (set (match_dup 0) (match_dup 4))]
14463 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14464 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14465 UNSPEC_FIST_FLOOR))
14466 (use (match_operand:HI 2 "memory_operand" ""))
14467 (use (match_operand:HI 3 "memory_operand" ""))
14468 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14470 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14471 UNSPEC_FIST_FLOOR))
14472 (use (match_dup 2))
14473 (use (match_dup 3))])]
14476 (define_expand "lfloorxf<mode>2"
14477 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14478 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14479 UNSPEC_FIST_FLOOR))
14480 (clobber (reg:CC FLAGS_REG))])]
14481 "TARGET_USE_FANCY_MATH_387
14482 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14486 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14487 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14488 (match_operand:MODEF 1 "register_operand" "")]
14489 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14490 && !flag_trapping_math"
14492 if (TARGET_64BIT && optimize_insn_for_size_p ())
14494 ix86_expand_lfloorceil (operand0, operand1, true);
14498 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14499 (define_insn_and_split "frndintxf2_ceil"
14500 [(set (match_operand:XF 0 "register_operand" "")
14501 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14502 UNSPEC_FRNDINT_CEIL))
14503 (clobber (reg:CC FLAGS_REG))]
14504 "TARGET_USE_FANCY_MATH_387
14505 && flag_unsafe_math_optimizations
14506 && can_create_pseudo_p ()"
14511 ix86_optimize_mode_switching[I387_CEIL] = 1;
14513 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14514 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14516 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14517 operands[2], operands[3]));
14520 [(set_attr "type" "frndint")
14521 (set_attr "i387_cw" "ceil")
14522 (set_attr "mode" "XF")])
14524 (define_insn "frndintxf2_ceil_i387"
14525 [(set (match_operand:XF 0 "register_operand" "=f")
14526 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14527 UNSPEC_FRNDINT_CEIL))
14528 (use (match_operand:HI 2 "memory_operand" "m"))
14529 (use (match_operand:HI 3 "memory_operand" "m"))]
14530 "TARGET_USE_FANCY_MATH_387
14531 && flag_unsafe_math_optimizations"
14532 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14533 [(set_attr "type" "frndint")
14534 (set_attr "i387_cw" "ceil")
14535 (set_attr "mode" "XF")])
14537 (define_expand "ceilxf2"
14538 [(use (match_operand:XF 0 "register_operand" ""))
14539 (use (match_operand:XF 1 "register_operand" ""))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations"
14543 if (optimize_insn_for_size_p ())
14545 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14549 (define_expand "ceil<mode>2"
14550 [(use (match_operand:MODEF 0 "register_operand" ""))
14551 (use (match_operand:MODEF 1 "register_operand" ""))]
14552 "(TARGET_USE_FANCY_MATH_387
14553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14554 || TARGET_MIX_SSE_I387)
14555 && flag_unsafe_math_optimizations)
14556 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14557 && !flag_trapping_math)"
14559 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14560 && !flag_trapping_math
14561 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14564 emit_insn (gen_sse4_1_round<mode>2
14565 (operands[0], operands[1], GEN_INT (0x02)));
14566 else if (optimize_insn_for_size_p ())
14568 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14569 ix86_expand_floorceil (operand0, operand1, false);
14571 ix86_expand_floorceildf_32 (operand0, operand1, false);
14577 if (optimize_insn_for_size_p ())
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14582 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14583 emit_insn (gen_frndintxf2_ceil (op0, op1));
14585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14590 (define_insn_and_split "*fist<mode>2_ceil_1"
14591 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14592 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14594 (clobber (reg:CC FLAGS_REG))]
14595 "TARGET_USE_FANCY_MATH_387
14596 && flag_unsafe_math_optimizations
14597 && can_create_pseudo_p ()"
14602 ix86_optimize_mode_switching[I387_CEIL] = 1;
14604 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14605 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14606 if (memory_operand (operands[0], VOIDmode))
14607 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14608 operands[2], operands[3]));
14611 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14612 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14613 operands[2], operands[3],
14618 [(set_attr "type" "fistp")
14619 (set_attr "i387_cw" "ceil")
14620 (set_attr "mode" "<MODE>")])
14622 (define_insn "fistdi2_ceil"
14623 [(set (match_operand:DI 0 "memory_operand" "=m")
14624 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14626 (use (match_operand:HI 2 "memory_operand" "m"))
14627 (use (match_operand:HI 3 "memory_operand" "m"))
14628 (clobber (match_scratch:XF 4 "=&1f"))]
14629 "TARGET_USE_FANCY_MATH_387
14630 && flag_unsafe_math_optimizations"
14631 "* return output_fix_trunc (insn, operands, 0);"
14632 [(set_attr "type" "fistp")
14633 (set_attr "i387_cw" "ceil")
14634 (set_attr "mode" "DI")])
14636 (define_insn "fistdi2_ceil_with_temp"
14637 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14638 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14640 (use (match_operand:HI 2 "memory_operand" "m,m"))
14641 (use (match_operand:HI 3 "memory_operand" "m,m"))
14642 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14643 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && flag_unsafe_math_optimizations"
14647 [(set_attr "type" "fistp")
14648 (set_attr "i387_cw" "ceil")
14649 (set_attr "mode" "DI")])
14652 [(set (match_operand:DI 0 "register_operand" "")
14653 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14655 (use (match_operand:HI 2 "memory_operand" ""))
14656 (use (match_operand:HI 3 "memory_operand" ""))
14657 (clobber (match_operand:DI 4 "memory_operand" ""))
14658 (clobber (match_scratch 5 ""))]
14660 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14661 (use (match_dup 2))
14662 (use (match_dup 3))
14663 (clobber (match_dup 5))])
14664 (set (match_dup 0) (match_dup 4))]
14668 [(set (match_operand:DI 0 "memory_operand" "")
14669 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14671 (use (match_operand:HI 2 "memory_operand" ""))
14672 (use (match_operand:HI 3 "memory_operand" ""))
14673 (clobber (match_operand:DI 4 "memory_operand" ""))
14674 (clobber (match_scratch 5 ""))]
14676 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14677 (use (match_dup 2))
14678 (use (match_dup 3))
14679 (clobber (match_dup 5))])]
14682 (define_insn "fist<mode>2_ceil"
14683 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14684 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14686 (use (match_operand:HI 2 "memory_operand" "m"))
14687 (use (match_operand:HI 3 "memory_operand" "m"))]
14688 "TARGET_USE_FANCY_MATH_387
14689 && flag_unsafe_math_optimizations"
14690 "* return output_fix_trunc (insn, operands, 0);"
14691 [(set_attr "type" "fistp")
14692 (set_attr "i387_cw" "ceil")
14693 (set_attr "mode" "<MODE>")])
14695 (define_insn "fist<mode>2_ceil_with_temp"
14696 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14697 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14699 (use (match_operand:HI 2 "memory_operand" "m,m"))
14700 (use (match_operand:HI 3 "memory_operand" "m,m"))
14701 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14702 "TARGET_USE_FANCY_MATH_387
14703 && flag_unsafe_math_optimizations"
14705 [(set_attr "type" "fistp")
14706 (set_attr "i387_cw" "ceil")
14707 (set_attr "mode" "<MODE>")])
14710 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14711 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14713 (use (match_operand:HI 2 "memory_operand" ""))
14714 (use (match_operand:HI 3 "memory_operand" ""))
14715 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14717 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14719 (use (match_dup 2))
14720 (use (match_dup 3))])
14721 (set (match_dup 0) (match_dup 4))]
14725 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14726 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14728 (use (match_operand:HI 2 "memory_operand" ""))
14729 (use (match_operand:HI 3 "memory_operand" ""))
14730 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14732 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14734 (use (match_dup 2))
14735 (use (match_dup 3))])]
14738 (define_expand "lceilxf<mode>2"
14739 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14740 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14742 (clobber (reg:CC FLAGS_REG))])]
14743 "TARGET_USE_FANCY_MATH_387
14744 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14745 && flag_unsafe_math_optimizations"
14748 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14749 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14750 (match_operand:MODEF 1 "register_operand" "")]
14751 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14752 && !flag_trapping_math"
14754 ix86_expand_lfloorceil (operand0, operand1, false);
14758 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14759 (define_insn_and_split "frndintxf2_trunc"
14760 [(set (match_operand:XF 0 "register_operand" "")
14761 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14762 UNSPEC_FRNDINT_TRUNC))
14763 (clobber (reg:CC FLAGS_REG))]
14764 "TARGET_USE_FANCY_MATH_387
14765 && flag_unsafe_math_optimizations
14766 && can_create_pseudo_p ()"
14771 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14773 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14774 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14776 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14777 operands[2], operands[3]));
14780 [(set_attr "type" "frndint")
14781 (set_attr "i387_cw" "trunc")
14782 (set_attr "mode" "XF")])
14784 (define_insn "frndintxf2_trunc_i387"
14785 [(set (match_operand:XF 0 "register_operand" "=f")
14786 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14787 UNSPEC_FRNDINT_TRUNC))
14788 (use (match_operand:HI 2 "memory_operand" "m"))
14789 (use (match_operand:HI 3 "memory_operand" "m"))]
14790 "TARGET_USE_FANCY_MATH_387
14791 && flag_unsafe_math_optimizations"
14792 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14793 [(set_attr "type" "frndint")
14794 (set_attr "i387_cw" "trunc")
14795 (set_attr "mode" "XF")])
14797 (define_expand "btruncxf2"
14798 [(use (match_operand:XF 0 "register_operand" ""))
14799 (use (match_operand:XF 1 "register_operand" ""))]
14800 "TARGET_USE_FANCY_MATH_387
14801 && flag_unsafe_math_optimizations"
14803 if (optimize_insn_for_size_p ())
14805 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14809 (define_expand "btrunc<mode>2"
14810 [(use (match_operand:MODEF 0 "register_operand" ""))
14811 (use (match_operand:MODEF 1 "register_operand" ""))]
14812 "(TARGET_USE_FANCY_MATH_387
14813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14814 || TARGET_MIX_SSE_I387)
14815 && flag_unsafe_math_optimizations)
14816 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14817 && !flag_trapping_math)"
14819 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14820 && !flag_trapping_math
14821 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14824 emit_insn (gen_sse4_1_round<mode>2
14825 (operands[0], operands[1], GEN_INT (0x03)));
14826 else if (optimize_insn_for_size_p ())
14828 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14829 ix86_expand_trunc (operand0, operand1);
14831 ix86_expand_truncdf_32 (operand0, operand1);
14837 if (optimize_insn_for_size_p ())
14840 op0 = gen_reg_rtx (XFmode);
14841 op1 = gen_reg_rtx (XFmode);
14842 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14843 emit_insn (gen_frndintxf2_trunc (op0, op1));
14845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14850 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14851 (define_insn_and_split "frndintxf2_mask_pm"
14852 [(set (match_operand:XF 0 "register_operand" "")
14853 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14854 UNSPEC_FRNDINT_MASK_PM))
14855 (clobber (reg:CC FLAGS_REG))]
14856 "TARGET_USE_FANCY_MATH_387
14857 && flag_unsafe_math_optimizations
14858 && can_create_pseudo_p ()"
14863 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14865 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14866 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14868 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14869 operands[2], operands[3]));
14872 [(set_attr "type" "frndint")
14873 (set_attr "i387_cw" "mask_pm")
14874 (set_attr "mode" "XF")])
14876 (define_insn "frndintxf2_mask_pm_i387"
14877 [(set (match_operand:XF 0 "register_operand" "=f")
14878 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14879 UNSPEC_FRNDINT_MASK_PM))
14880 (use (match_operand:HI 2 "memory_operand" "m"))
14881 (use (match_operand:HI 3 "memory_operand" "m"))]
14882 "TARGET_USE_FANCY_MATH_387
14883 && flag_unsafe_math_optimizations"
14884 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14885 [(set_attr "type" "frndint")
14886 (set_attr "i387_cw" "mask_pm")
14887 (set_attr "mode" "XF")])
14889 (define_expand "nearbyintxf2"
14890 [(use (match_operand:XF 0 "register_operand" ""))
14891 (use (match_operand:XF 1 "register_operand" ""))]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14895 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14900 (define_expand "nearbyint<mode>2"
14901 [(use (match_operand:MODEF 0 "register_operand" ""))
14902 (use (match_operand:MODEF 1 "register_operand" ""))]
14903 "TARGET_USE_FANCY_MATH_387
14904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14905 || TARGET_MIX_SSE_I387)
14906 && flag_unsafe_math_optimizations"
14908 rtx op0 = gen_reg_rtx (XFmode);
14909 rtx op1 = gen_reg_rtx (XFmode);
14911 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14912 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14918 (define_insn "fxam<mode>2_i387"
14919 [(set (match_operand:HI 0 "register_operand" "=a")
14921 [(match_operand:X87MODEF 1 "register_operand" "f")]
14923 "TARGET_USE_FANCY_MATH_387"
14924 "fxam\n\tfnstsw\t%0"
14925 [(set_attr "type" "multi")
14926 (set_attr "length" "4")
14927 (set_attr "unit" "i387")
14928 (set_attr "mode" "<MODE>")])
14930 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14931 [(set (match_operand:HI 0 "register_operand" "")
14933 [(match_operand:MODEF 1 "memory_operand" "")]
14935 "TARGET_USE_FANCY_MATH_387
14936 && can_create_pseudo_p ()"
14939 [(set (match_dup 2)(match_dup 1))
14941 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14943 operands[2] = gen_reg_rtx (<MODE>mode);
14945 MEM_VOLATILE_P (operands[1]) = 1;
14947 [(set_attr "type" "multi")
14948 (set_attr "unit" "i387")
14949 (set_attr "mode" "<MODE>")])
14951 (define_expand "isinfxf2"
14952 [(use (match_operand:SI 0 "register_operand" ""))
14953 (use (match_operand:XF 1 "register_operand" ""))]
14954 "TARGET_USE_FANCY_MATH_387
14955 && TARGET_C99_FUNCTIONS"
14957 rtx mask = GEN_INT (0x45);
14958 rtx val = GEN_INT (0x05);
14962 rtx scratch = gen_reg_rtx (HImode);
14963 rtx res = gen_reg_rtx (QImode);
14965 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14967 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14968 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14969 cond = gen_rtx_fmt_ee (EQ, QImode,
14970 gen_rtx_REG (CCmode, FLAGS_REG),
14972 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14973 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14977 (define_expand "isinf<mode>2"
14978 [(use (match_operand:SI 0 "register_operand" ""))
14979 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && TARGET_C99_FUNCTIONS
14982 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14984 rtx mask = GEN_INT (0x45);
14985 rtx val = GEN_INT (0x05);
14989 rtx scratch = gen_reg_rtx (HImode);
14990 rtx res = gen_reg_rtx (QImode);
14992 /* Remove excess precision by forcing value through memory. */
14993 if (memory_operand (operands[1], VOIDmode))
14994 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14997 enum ix86_stack_slot slot = (virtuals_instantiated
15000 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15002 emit_move_insn (temp, operands[1]);
15003 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15006 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15007 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15008 cond = gen_rtx_fmt_ee (EQ, QImode,
15009 gen_rtx_REG (CCmode, FLAGS_REG),
15011 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15012 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15016 (define_expand "signbit<mode>2"
15017 [(use (match_operand:SI 0 "register_operand" ""))
15018 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15019 "TARGET_USE_FANCY_MATH_387
15020 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15022 rtx mask = GEN_INT (0x0200);
15024 rtx scratch = gen_reg_rtx (HImode);
15026 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15027 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15031 ;; Block operation instructions
15034 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15037 [(set_attr "length" "1")
15038 (set_attr "length_immediate" "0")
15039 (set_attr "modrm" "0")])
15041 (define_expand "movmemsi"
15042 [(use (match_operand:BLK 0 "memory_operand" ""))
15043 (use (match_operand:BLK 1 "memory_operand" ""))
15044 (use (match_operand:SI 2 "nonmemory_operand" ""))
15045 (use (match_operand:SI 3 "const_int_operand" ""))
15046 (use (match_operand:SI 4 "const_int_operand" ""))
15047 (use (match_operand:SI 5 "const_int_operand" ""))]
15050 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15051 operands[4], operands[5]))
15057 (define_expand "movmemdi"
15058 [(use (match_operand:BLK 0 "memory_operand" ""))
15059 (use (match_operand:BLK 1 "memory_operand" ""))
15060 (use (match_operand:DI 2 "nonmemory_operand" ""))
15061 (use (match_operand:DI 3 "const_int_operand" ""))
15062 (use (match_operand:SI 4 "const_int_operand" ""))
15063 (use (match_operand:SI 5 "const_int_operand" ""))]
15066 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15067 operands[4], operands[5]))
15073 ;; Most CPUs don't like single string operations
15074 ;; Handle this case here to simplify previous expander.
15076 (define_expand "strmov"
15077 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15078 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15079 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15080 (clobber (reg:CC FLAGS_REG))])
15081 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15082 (clobber (reg:CC FLAGS_REG))])]
15085 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15087 /* If .md ever supports :P for Pmode, these can be directly
15088 in the pattern above. */
15089 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15090 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15092 /* Can't use this if the user has appropriated esi or edi. */
15093 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15094 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15096 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15097 operands[2], operands[3],
15098 operands[5], operands[6]));
15102 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15105 (define_expand "strmov_singleop"
15106 [(parallel [(set (match_operand 1 "memory_operand" "")
15107 (match_operand 3 "memory_operand" ""))
15108 (set (match_operand 0 "register_operand" "")
15109 (match_operand 4 "" ""))
15110 (set (match_operand 2 "register_operand" "")
15111 (match_operand 5 "" ""))])]
15113 "ix86_current_function_needs_cld = 1;")
15115 (define_insn "*strmovdi_rex_1"
15116 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15117 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15118 (set (match_operand:DI 0 "register_operand" "=D")
15119 (plus:DI (match_dup 2)
15121 (set (match_operand:DI 1 "register_operand" "=S")
15122 (plus:DI (match_dup 3)
15126 [(set_attr "type" "str")
15127 (set_attr "mode" "DI")
15128 (set_attr "memory" "both")])
15130 (define_insn "*strmovsi_1"
15131 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15132 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15133 (set (match_operand:SI 0 "register_operand" "=D")
15134 (plus:SI (match_dup 2)
15136 (set (match_operand:SI 1 "register_operand" "=S")
15137 (plus:SI (match_dup 3)
15141 [(set_attr "type" "str")
15142 (set_attr "mode" "SI")
15143 (set_attr "memory" "both")])
15145 (define_insn "*strmovsi_rex_1"
15146 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15147 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15148 (set (match_operand:DI 0 "register_operand" "=D")
15149 (plus:DI (match_dup 2)
15151 (set (match_operand:DI 1 "register_operand" "=S")
15152 (plus:DI (match_dup 3)
15156 [(set_attr "type" "str")
15157 (set_attr "mode" "SI")
15158 (set_attr "memory" "both")])
15160 (define_insn "*strmovhi_1"
15161 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15162 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15163 (set (match_operand:SI 0 "register_operand" "=D")
15164 (plus:SI (match_dup 2)
15166 (set (match_operand:SI 1 "register_operand" "=S")
15167 (plus:SI (match_dup 3)
15171 [(set_attr "type" "str")
15172 (set_attr "memory" "both")
15173 (set_attr "mode" "HI")])
15175 (define_insn "*strmovhi_rex_1"
15176 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15177 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15178 (set (match_operand:DI 0 "register_operand" "=D")
15179 (plus:DI (match_dup 2)
15181 (set (match_operand:DI 1 "register_operand" "=S")
15182 (plus:DI (match_dup 3)
15186 [(set_attr "type" "str")
15187 (set_attr "memory" "both")
15188 (set_attr "mode" "HI")])
15190 (define_insn "*strmovqi_1"
15191 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15192 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15193 (set (match_operand:SI 0 "register_operand" "=D")
15194 (plus:SI (match_dup 2)
15196 (set (match_operand:SI 1 "register_operand" "=S")
15197 (plus:SI (match_dup 3)
15201 [(set_attr "type" "str")
15202 (set_attr "memory" "both")
15203 (set_attr "mode" "QI")])
15205 (define_insn "*strmovqi_rex_1"
15206 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15207 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15208 (set (match_operand:DI 0 "register_operand" "=D")
15209 (plus:DI (match_dup 2)
15211 (set (match_operand:DI 1 "register_operand" "=S")
15212 (plus:DI (match_dup 3)
15216 [(set_attr "type" "str")
15217 (set_attr "memory" "both")
15218 (set_attr "prefix_rex" "0")
15219 (set_attr "mode" "QI")])
15221 (define_expand "rep_mov"
15222 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15223 (set (match_operand 0 "register_operand" "")
15224 (match_operand 5 "" ""))
15225 (set (match_operand 2 "register_operand" "")
15226 (match_operand 6 "" ""))
15227 (set (match_operand 1 "memory_operand" "")
15228 (match_operand 3 "memory_operand" ""))
15229 (use (match_dup 4))])]
15231 "ix86_current_function_needs_cld = 1;")
15233 (define_insn "*rep_movdi_rex64"
15234 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15235 (set (match_operand:DI 0 "register_operand" "=D")
15236 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15238 (match_operand:DI 3 "register_operand" "0")))
15239 (set (match_operand:DI 1 "register_operand" "=S")
15240 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15241 (match_operand:DI 4 "register_operand" "1")))
15242 (set (mem:BLK (match_dup 3))
15243 (mem:BLK (match_dup 4)))
15244 (use (match_dup 5))]
15247 [(set_attr "type" "str")
15248 (set_attr "prefix_rep" "1")
15249 (set_attr "memory" "both")
15250 (set_attr "mode" "DI")])
15252 (define_insn "*rep_movsi"
15253 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15254 (set (match_operand:SI 0 "register_operand" "=D")
15255 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15257 (match_operand:SI 3 "register_operand" "0")))
15258 (set (match_operand:SI 1 "register_operand" "=S")
15259 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15260 (match_operand:SI 4 "register_operand" "1")))
15261 (set (mem:BLK (match_dup 3))
15262 (mem:BLK (match_dup 4)))
15263 (use (match_dup 5))]
15265 "rep{%;} movs{l|d}"
15266 [(set_attr "type" "str")
15267 (set_attr "prefix_rep" "1")
15268 (set_attr "memory" "both")
15269 (set_attr "mode" "SI")])
15271 (define_insn "*rep_movsi_rex64"
15272 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15273 (set (match_operand:DI 0 "register_operand" "=D")
15274 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15276 (match_operand:DI 3 "register_operand" "0")))
15277 (set (match_operand:DI 1 "register_operand" "=S")
15278 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15279 (match_operand:DI 4 "register_operand" "1")))
15280 (set (mem:BLK (match_dup 3))
15281 (mem:BLK (match_dup 4)))
15282 (use (match_dup 5))]
15284 "rep{%;} movs{l|d}"
15285 [(set_attr "type" "str")
15286 (set_attr "prefix_rep" "1")
15287 (set_attr "memory" "both")
15288 (set_attr "mode" "SI")])
15290 (define_insn "*rep_movqi"
15291 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15292 (set (match_operand:SI 0 "register_operand" "=D")
15293 (plus:SI (match_operand:SI 3 "register_operand" "0")
15294 (match_operand:SI 5 "register_operand" "2")))
15295 (set (match_operand:SI 1 "register_operand" "=S")
15296 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15297 (set (mem:BLK (match_dup 3))
15298 (mem:BLK (match_dup 4)))
15299 (use (match_dup 5))]
15302 [(set_attr "type" "str")
15303 (set_attr "prefix_rep" "1")
15304 (set_attr "memory" "both")
15305 (set_attr "mode" "SI")])
15307 (define_insn "*rep_movqi_rex64"
15308 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15309 (set (match_operand:DI 0 "register_operand" "=D")
15310 (plus:DI (match_operand:DI 3 "register_operand" "0")
15311 (match_operand:DI 5 "register_operand" "2")))
15312 (set (match_operand:DI 1 "register_operand" "=S")
15313 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15314 (set (mem:BLK (match_dup 3))
15315 (mem:BLK (match_dup 4)))
15316 (use (match_dup 5))]
15319 [(set_attr "type" "str")
15320 (set_attr "prefix_rep" "1")
15321 (set_attr "memory" "both")
15322 (set_attr "mode" "SI")])
15324 (define_expand "setmemsi"
15325 [(use (match_operand:BLK 0 "memory_operand" ""))
15326 (use (match_operand:SI 1 "nonmemory_operand" ""))
15327 (use (match_operand 2 "const_int_operand" ""))
15328 (use (match_operand 3 "const_int_operand" ""))
15329 (use (match_operand:SI 4 "const_int_operand" ""))
15330 (use (match_operand:SI 5 "const_int_operand" ""))]
15333 if (ix86_expand_setmem (operands[0], operands[1],
15334 operands[2], operands[3],
15335 operands[4], operands[5]))
15341 (define_expand "setmemdi"
15342 [(use (match_operand:BLK 0 "memory_operand" ""))
15343 (use (match_operand:DI 1 "nonmemory_operand" ""))
15344 (use (match_operand 2 "const_int_operand" ""))
15345 (use (match_operand 3 "const_int_operand" ""))
15346 (use (match_operand 4 "const_int_operand" ""))
15347 (use (match_operand 5 "const_int_operand" ""))]
15350 if (ix86_expand_setmem (operands[0], operands[1],
15351 operands[2], operands[3],
15352 operands[4], operands[5]))
15358 ;; Most CPUs don't like single string operations
15359 ;; Handle this case here to simplify previous expander.
15361 (define_expand "strset"
15362 [(set (match_operand 1 "memory_operand" "")
15363 (match_operand 2 "register_operand" ""))
15364 (parallel [(set (match_operand 0 "register_operand" "")
15366 (clobber (reg:CC FLAGS_REG))])]
15369 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15370 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15372 /* If .md ever supports :P for Pmode, this can be directly
15373 in the pattern above. */
15374 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15375 GEN_INT (GET_MODE_SIZE (GET_MODE
15377 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15379 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15385 (define_expand "strset_singleop"
15386 [(parallel [(set (match_operand 1 "memory_operand" "")
15387 (match_operand 2 "register_operand" ""))
15388 (set (match_operand 0 "register_operand" "")
15389 (match_operand 3 "" ""))])]
15391 "ix86_current_function_needs_cld = 1;")
15393 (define_insn "*strsetdi_rex_1"
15394 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15395 (match_operand:DI 2 "register_operand" "a"))
15396 (set (match_operand:DI 0 "register_operand" "=D")
15397 (plus:DI (match_dup 1)
15401 [(set_attr "type" "str")
15402 (set_attr "memory" "store")
15403 (set_attr "mode" "DI")])
15405 (define_insn "*strsetsi_1"
15406 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15407 (match_operand:SI 2 "register_operand" "a"))
15408 (set (match_operand:SI 0 "register_operand" "=D")
15409 (plus:SI (match_dup 1)
15413 [(set_attr "type" "str")
15414 (set_attr "memory" "store")
15415 (set_attr "mode" "SI")])
15417 (define_insn "*strsetsi_rex_1"
15418 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15419 (match_operand:SI 2 "register_operand" "a"))
15420 (set (match_operand:DI 0 "register_operand" "=D")
15421 (plus:DI (match_dup 1)
15425 [(set_attr "type" "str")
15426 (set_attr "memory" "store")
15427 (set_attr "mode" "SI")])
15429 (define_insn "*strsethi_1"
15430 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15431 (match_operand:HI 2 "register_operand" "a"))
15432 (set (match_operand:SI 0 "register_operand" "=D")
15433 (plus:SI (match_dup 1)
15437 [(set_attr "type" "str")
15438 (set_attr "memory" "store")
15439 (set_attr "mode" "HI")])
15441 (define_insn "*strsethi_rex_1"
15442 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15443 (match_operand:HI 2 "register_operand" "a"))
15444 (set (match_operand:DI 0 "register_operand" "=D")
15445 (plus:DI (match_dup 1)
15449 [(set_attr "type" "str")
15450 (set_attr "memory" "store")
15451 (set_attr "mode" "HI")])
15453 (define_insn "*strsetqi_1"
15454 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15455 (match_operand:QI 2 "register_operand" "a"))
15456 (set (match_operand:SI 0 "register_operand" "=D")
15457 (plus:SI (match_dup 1)
15461 [(set_attr "type" "str")
15462 (set_attr "memory" "store")
15463 (set_attr "mode" "QI")])
15465 (define_insn "*strsetqi_rex_1"
15466 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15467 (match_operand:QI 2 "register_operand" "a"))
15468 (set (match_operand:DI 0 "register_operand" "=D")
15469 (plus:DI (match_dup 1)
15473 [(set_attr "type" "str")
15474 (set_attr "memory" "store")
15475 (set_attr "prefix_rex" "0")
15476 (set_attr "mode" "QI")])
15478 (define_expand "rep_stos"
15479 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15480 (set (match_operand 0 "register_operand" "")
15481 (match_operand 4 "" ""))
15482 (set (match_operand 2 "memory_operand" "") (const_int 0))
15483 (use (match_operand 3 "register_operand" ""))
15484 (use (match_dup 1))])]
15486 "ix86_current_function_needs_cld = 1;")
15488 (define_insn "*rep_stosdi_rex64"
15489 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15493 (match_operand:DI 3 "register_operand" "0")))
15494 (set (mem:BLK (match_dup 3))
15496 (use (match_operand:DI 2 "register_operand" "a"))
15497 (use (match_dup 4))]
15500 [(set_attr "type" "str")
15501 (set_attr "prefix_rep" "1")
15502 (set_attr "memory" "store")
15503 (set_attr "mode" "DI")])
15505 (define_insn "*rep_stossi"
15506 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15507 (set (match_operand:SI 0 "register_operand" "=D")
15508 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15510 (match_operand:SI 3 "register_operand" "0")))
15511 (set (mem:BLK (match_dup 3))
15513 (use (match_operand:SI 2 "register_operand" "a"))
15514 (use (match_dup 4))]
15516 "rep{%;} stos{l|d}"
15517 [(set_attr "type" "str")
15518 (set_attr "prefix_rep" "1")
15519 (set_attr "memory" "store")
15520 (set_attr "mode" "SI")])
15522 (define_insn "*rep_stossi_rex64"
15523 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15524 (set (match_operand:DI 0 "register_operand" "=D")
15525 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15527 (match_operand:DI 3 "register_operand" "0")))
15528 (set (mem:BLK (match_dup 3))
15530 (use (match_operand:SI 2 "register_operand" "a"))
15531 (use (match_dup 4))]
15533 "rep{%;} stos{l|d}"
15534 [(set_attr "type" "str")
15535 (set_attr "prefix_rep" "1")
15536 (set_attr "memory" "store")
15537 (set_attr "mode" "SI")])
15539 (define_insn "*rep_stosqi"
15540 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15541 (set (match_operand:SI 0 "register_operand" "=D")
15542 (plus:SI (match_operand:SI 3 "register_operand" "0")
15543 (match_operand:SI 4 "register_operand" "1")))
15544 (set (mem:BLK (match_dup 3))
15546 (use (match_operand:QI 2 "register_operand" "a"))
15547 (use (match_dup 4))]
15550 [(set_attr "type" "str")
15551 (set_attr "prefix_rep" "1")
15552 (set_attr "memory" "store")
15553 (set_attr "mode" "QI")])
15555 (define_insn "*rep_stosqi_rex64"
15556 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15557 (set (match_operand:DI 0 "register_operand" "=D")
15558 (plus:DI (match_operand:DI 3 "register_operand" "0")
15559 (match_operand:DI 4 "register_operand" "1")))
15560 (set (mem:BLK (match_dup 3))
15562 (use (match_operand:QI 2 "register_operand" "a"))
15563 (use (match_dup 4))]
15566 [(set_attr "type" "str")
15567 (set_attr "prefix_rep" "1")
15568 (set_attr "memory" "store")
15569 (set_attr "prefix_rex" "0")
15570 (set_attr "mode" "QI")])
15572 (define_expand "cmpstrnsi"
15573 [(set (match_operand:SI 0 "register_operand" "")
15574 (compare:SI (match_operand:BLK 1 "general_operand" "")
15575 (match_operand:BLK 2 "general_operand" "")))
15576 (use (match_operand 3 "general_operand" ""))
15577 (use (match_operand 4 "immediate_operand" ""))]
15580 rtx addr1, addr2, out, outlow, count, countreg, align;
15582 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15585 /* Can't use this if the user has appropriated esi or edi. */
15586 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15591 out = gen_reg_rtx (SImode);
15593 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15594 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15595 if (addr1 != XEXP (operands[1], 0))
15596 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15597 if (addr2 != XEXP (operands[2], 0))
15598 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15600 count = operands[3];
15601 countreg = ix86_zero_extend_to_Pmode (count);
15603 /* %%% Iff we are testing strict equality, we can use known alignment
15604 to good advantage. This may be possible with combine, particularly
15605 once cc0 is dead. */
15606 align = operands[4];
15608 if (CONST_INT_P (count))
15610 if (INTVAL (count) == 0)
15612 emit_move_insn (operands[0], const0_rtx);
15615 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15616 operands[1], operands[2]));
15620 rtx (*cmp_insn)(rtx, rtx);
15623 cmp_insn = gen_cmpdi_1;
15625 cmp_insn = gen_cmpsi_1;
15626 emit_insn (cmp_insn (countreg, countreg));
15627 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15628 operands[1], operands[2]));
15631 outlow = gen_lowpart (QImode, out);
15632 emit_insn (gen_cmpintqi (outlow));
15633 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15635 if (operands[0] != out)
15636 emit_move_insn (operands[0], out);
15641 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15643 (define_expand "cmpintqi"
15644 [(set (match_dup 1)
15645 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15647 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15648 (parallel [(set (match_operand:QI 0 "register_operand" "")
15649 (minus:QI (match_dup 1)
15651 (clobber (reg:CC FLAGS_REG))])]
15653 "operands[1] = gen_reg_rtx (QImode);
15654 operands[2] = gen_reg_rtx (QImode);")
15656 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15657 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15659 (define_expand "cmpstrnqi_nz_1"
15660 [(parallel [(set (reg:CC FLAGS_REG)
15661 (compare:CC (match_operand 4 "memory_operand" "")
15662 (match_operand 5 "memory_operand" "")))
15663 (use (match_operand 2 "register_operand" ""))
15664 (use (match_operand:SI 3 "immediate_operand" ""))
15665 (clobber (match_operand 0 "register_operand" ""))
15666 (clobber (match_operand 1 "register_operand" ""))
15667 (clobber (match_dup 2))])]
15669 "ix86_current_function_needs_cld = 1;")
15671 (define_insn "*cmpstrnqi_nz_1"
15672 [(set (reg:CC FLAGS_REG)
15673 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15674 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15675 (use (match_operand:SI 6 "register_operand" "2"))
15676 (use (match_operand:SI 3 "immediate_operand" "i"))
15677 (clobber (match_operand:SI 0 "register_operand" "=S"))
15678 (clobber (match_operand:SI 1 "register_operand" "=D"))
15679 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15682 [(set_attr "type" "str")
15683 (set_attr "mode" "QI")
15684 (set_attr "prefix_rep" "1")])
15686 (define_insn "*cmpstrnqi_nz_rex_1"
15687 [(set (reg:CC FLAGS_REG)
15688 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15689 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15690 (use (match_operand:DI 6 "register_operand" "2"))
15691 (use (match_operand:SI 3 "immediate_operand" "i"))
15692 (clobber (match_operand:DI 0 "register_operand" "=S"))
15693 (clobber (match_operand:DI 1 "register_operand" "=D"))
15694 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15697 [(set_attr "type" "str")
15698 (set_attr "mode" "QI")
15699 (set_attr "prefix_rex" "0")
15700 (set_attr "prefix_rep" "1")])
15702 ;; The same, but the count is not known to not be zero.
15704 (define_expand "cmpstrnqi_1"
15705 [(parallel [(set (reg:CC FLAGS_REG)
15706 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15708 (compare:CC (match_operand 4 "memory_operand" "")
15709 (match_operand 5 "memory_operand" ""))
15711 (use (match_operand:SI 3 "immediate_operand" ""))
15712 (use (reg:CC FLAGS_REG))
15713 (clobber (match_operand 0 "register_operand" ""))
15714 (clobber (match_operand 1 "register_operand" ""))
15715 (clobber (match_dup 2))])]
15717 "ix86_current_function_needs_cld = 1;")
15719 (define_insn "*cmpstrnqi_1"
15720 [(set (reg:CC FLAGS_REG)
15721 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15723 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15724 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15726 (use (match_operand:SI 3 "immediate_operand" "i"))
15727 (use (reg:CC FLAGS_REG))
15728 (clobber (match_operand:SI 0 "register_operand" "=S"))
15729 (clobber (match_operand:SI 1 "register_operand" "=D"))
15730 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15733 [(set_attr "type" "str")
15734 (set_attr "mode" "QI")
15735 (set_attr "prefix_rep" "1")])
15737 (define_insn "*cmpstrnqi_rex_1"
15738 [(set (reg:CC FLAGS_REG)
15739 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15741 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15742 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15744 (use (match_operand:SI 3 "immediate_operand" "i"))
15745 (use (reg:CC FLAGS_REG))
15746 (clobber (match_operand:DI 0 "register_operand" "=S"))
15747 (clobber (match_operand:DI 1 "register_operand" "=D"))
15748 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15751 [(set_attr "type" "str")
15752 (set_attr "mode" "QI")
15753 (set_attr "prefix_rex" "0")
15754 (set_attr "prefix_rep" "1")])
15756 (define_expand "strlensi"
15757 [(set (match_operand:SI 0 "register_operand" "")
15758 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15759 (match_operand:QI 2 "immediate_operand" "")
15760 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15763 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15769 (define_expand "strlendi"
15770 [(set (match_operand:DI 0 "register_operand" "")
15771 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15772 (match_operand:QI 2 "immediate_operand" "")
15773 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15776 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15782 (define_expand "strlenqi_1"
15783 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15784 (clobber (match_operand 1 "register_operand" ""))
15785 (clobber (reg:CC FLAGS_REG))])]
15787 "ix86_current_function_needs_cld = 1;")
15789 (define_insn "*strlenqi_1"
15790 [(set (match_operand:SI 0 "register_operand" "=&c")
15791 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15792 (match_operand:QI 2 "register_operand" "a")
15793 (match_operand:SI 3 "immediate_operand" "i")
15794 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15795 (clobber (match_operand:SI 1 "register_operand" "=D"))
15796 (clobber (reg:CC FLAGS_REG))]
15799 [(set_attr "type" "str")
15800 (set_attr "mode" "QI")
15801 (set_attr "prefix_rep" "1")])
15803 (define_insn "*strlenqi_rex_1"
15804 [(set (match_operand:DI 0 "register_operand" "=&c")
15805 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15806 (match_operand:QI 2 "register_operand" "a")
15807 (match_operand:DI 3 "immediate_operand" "i")
15808 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15809 (clobber (match_operand:DI 1 "register_operand" "=D"))
15810 (clobber (reg:CC FLAGS_REG))]
15813 [(set_attr "type" "str")
15814 (set_attr "mode" "QI")
15815 (set_attr "prefix_rex" "0")
15816 (set_attr "prefix_rep" "1")])
15818 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15819 ;; handled in combine, but it is not currently up to the task.
15820 ;; When used for their truth value, the cmpstrn* expanders generate
15829 ;; The intermediate three instructions are unnecessary.
15831 ;; This one handles cmpstrn*_nz_1...
15834 (set (reg:CC FLAGS_REG)
15835 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15836 (mem:BLK (match_operand 5 "register_operand" ""))))
15837 (use (match_operand 6 "register_operand" ""))
15838 (use (match_operand:SI 3 "immediate_operand" ""))
15839 (clobber (match_operand 0 "register_operand" ""))
15840 (clobber (match_operand 1 "register_operand" ""))
15841 (clobber (match_operand 2 "register_operand" ""))])
15842 (set (match_operand:QI 7 "register_operand" "")
15843 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15844 (set (match_operand:QI 8 "register_operand" "")
15845 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15846 (set (reg FLAGS_REG)
15847 (compare (match_dup 7) (match_dup 8)))
15849 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15851 (set (reg:CC FLAGS_REG)
15852 (compare:CC (mem:BLK (match_dup 4))
15853 (mem:BLK (match_dup 5))))
15854 (use (match_dup 6))
15855 (use (match_dup 3))
15856 (clobber (match_dup 0))
15857 (clobber (match_dup 1))
15858 (clobber (match_dup 2))])]
15861 ;; ...and this one handles cmpstrn*_1.
15864 (set (reg:CC FLAGS_REG)
15865 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15867 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15868 (mem:BLK (match_operand 5 "register_operand" "")))
15870 (use (match_operand:SI 3 "immediate_operand" ""))
15871 (use (reg:CC FLAGS_REG))
15872 (clobber (match_operand 0 "register_operand" ""))
15873 (clobber (match_operand 1 "register_operand" ""))
15874 (clobber (match_operand 2 "register_operand" ""))])
15875 (set (match_operand:QI 7 "register_operand" "")
15876 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15877 (set (match_operand:QI 8 "register_operand" "")
15878 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15879 (set (reg FLAGS_REG)
15880 (compare (match_dup 7) (match_dup 8)))
15882 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15884 (set (reg:CC FLAGS_REG)
15885 (if_then_else:CC (ne (match_dup 6)
15887 (compare:CC (mem:BLK (match_dup 4))
15888 (mem:BLK (match_dup 5)))
15890 (use (match_dup 3))
15891 (use (reg:CC FLAGS_REG))
15892 (clobber (match_dup 0))
15893 (clobber (match_dup 1))
15894 (clobber (match_dup 2))])]
15899 ;; Conditional move instructions.
15901 (define_expand "mov<mode>cc"
15902 [(set (match_operand:SWIM 0 "register_operand" "")
15903 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
15904 (match_operand:SWIM 2 "general_operand" "")
15905 (match_operand:SWIM 3 "general_operand" "")))]
15907 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15909 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15910 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15911 ;; So just document what we're doing explicitly.
15913 (define_expand "x86_mov<mode>cc_0_m1"
15915 [(set (match_operand:SWI48 0 "register_operand" "")
15916 (if_then_else:SWI48
15917 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15918 [(match_operand 1 "flags_reg_operand" "")
15922 (clobber (reg:CC FLAGS_REG))])]
15926 (define_insn "*x86_mov<mode>cc_0_m1"
15927 [(set (match_operand:SWI48 0 "register_operand" "=r")
15928 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15929 [(reg FLAGS_REG) (const_int 0)])
15932 (clobber (reg:CC FLAGS_REG))]
15934 "sbb{<imodesuffix>}\t%0, %0"
15935 ; Since we don't have the proper number of operands for an alu insn,
15936 ; fill in all the blanks.
15937 [(set_attr "type" "alu")
15938 (set_attr "use_carry" "1")
15939 (set_attr "pent_pair" "pu")
15940 (set_attr "memory" "none")
15941 (set_attr "imm_disp" "false")
15942 (set_attr "mode" "<MODE>")
15943 (set_attr "length_immediate" "0")])
15945 (define_insn "*x86_mov<mode>cc_0_m1_se"
15946 [(set (match_operand:SWI48 0 "register_operand" "=r")
15947 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15948 [(reg FLAGS_REG) (const_int 0)])
15951 (clobber (reg:CC FLAGS_REG))]
15953 "sbb{<imodesuffix>}\t%0, %0"
15954 [(set_attr "type" "alu")
15955 (set_attr "use_carry" "1")
15956 (set_attr "pent_pair" "pu")
15957 (set_attr "memory" "none")
15958 (set_attr "imm_disp" "false")
15959 (set_attr "mode" "<MODE>")
15960 (set_attr "length_immediate" "0")])
15962 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15963 [(set (match_operand:SWI48 0 "register_operand" "=r")
15964 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15965 [(reg FLAGS_REG) (const_int 0)])))]
15967 "sbb{<imodesuffix>}\t%0, %0"
15968 [(set_attr "type" "alu")
15969 (set_attr "use_carry" "1")
15970 (set_attr "pent_pair" "pu")
15971 (set_attr "memory" "none")
15972 (set_attr "imm_disp" "false")
15973 (set_attr "mode" "<MODE>")
15974 (set_attr "length_immediate" "0")])
15976 (define_insn "*mov<mode>cc_noc"
15977 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15978 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15979 [(reg FLAGS_REG) (const_int 0)])
15980 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15981 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15982 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15984 cmov%O2%C1\t{%2, %0|%0, %2}
15985 cmov%O2%c1\t{%3, %0|%0, %3}"
15986 [(set_attr "type" "icmov")
15987 (set_attr "mode" "<MODE>")])
15989 (define_insn_and_split "*movqicc_noc"
15990 [(set (match_operand:QI 0 "register_operand" "=r,r")
15991 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15992 [(match_operand 4 "flags_reg_operand" "")
15994 (match_operand:QI 2 "register_operand" "r,0")
15995 (match_operand:QI 3 "register_operand" "0,r")))]
15996 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15998 "&& reload_completed"
15999 [(set (match_dup 0)
16000 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16003 "operands[0] = gen_lowpart (SImode, operands[0]);
16004 operands[2] = gen_lowpart (SImode, operands[2]);
16005 operands[3] = gen_lowpart (SImode, operands[3]);"
16006 [(set_attr "type" "icmov")
16007 (set_attr "mode" "SI")])
16009 (define_expand "mov<mode>cc"
16010 [(set (match_operand:X87MODEF 0 "register_operand" "")
16011 (if_then_else:X87MODEF
16012 (match_operand 1 "ix86_fp_comparison_operator" "")
16013 (match_operand:X87MODEF 2 "register_operand" "")
16014 (match_operand:X87MODEF 3 "register_operand" "")))]
16015 "(TARGET_80387 && TARGET_CMOVE)
16016 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16017 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16019 (define_insn "*movsfcc_1_387"
16020 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16021 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16022 [(reg FLAGS_REG) (const_int 0)])
16023 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16024 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16025 "TARGET_80387 && TARGET_CMOVE
16026 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16028 fcmov%F1\t{%2, %0|%0, %2}
16029 fcmov%f1\t{%3, %0|%0, %3}
16030 cmov%O2%C1\t{%2, %0|%0, %2}
16031 cmov%O2%c1\t{%3, %0|%0, %3}"
16032 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16033 (set_attr "mode" "SF,SF,SI,SI")])
16035 (define_insn "*movdfcc_1"
16036 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16037 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16038 [(reg FLAGS_REG) (const_int 0)])
16039 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16040 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16041 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16042 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16044 fcmov%F1\t{%2, %0|%0, %2}
16045 fcmov%f1\t{%3, %0|%0, %3}
16048 [(set_attr "type" "fcmov,fcmov,multi,multi")
16049 (set_attr "mode" "DF")])
16051 (define_insn "*movdfcc_1_rex64"
16052 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16053 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16054 [(reg FLAGS_REG) (const_int 0)])
16055 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16056 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16057 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16058 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16060 fcmov%F1\t{%2, %0|%0, %2}
16061 fcmov%f1\t{%3, %0|%0, %3}
16062 cmov%O2%C1\t{%2, %0|%0, %2}
16063 cmov%O2%c1\t{%3, %0|%0, %3}"
16064 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16065 (set_attr "mode" "DF")])
16068 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16069 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16070 [(match_operand 4 "flags_reg_operand" "")
16072 (match_operand:DF 2 "nonimmediate_operand" "")
16073 (match_operand:DF 3 "nonimmediate_operand" "")))]
16074 "!TARGET_64BIT && reload_completed"
16075 [(set (match_dup 2)
16076 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16080 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16084 split_di (&operands[2], 2, &operands[5], &operands[7]);
16085 split_di (&operands[0], 1, &operands[2], &operands[3]);
16088 (define_insn "*movxfcc_1"
16089 [(set (match_operand:XF 0 "register_operand" "=f,f")
16090 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16091 [(reg FLAGS_REG) (const_int 0)])
16092 (match_operand:XF 2 "register_operand" "f,0")
16093 (match_operand:XF 3 "register_operand" "0,f")))]
16094 "TARGET_80387 && TARGET_CMOVE"
16096 fcmov%F1\t{%2, %0|%0, %2}
16097 fcmov%f1\t{%3, %0|%0, %3}"
16098 [(set_attr "type" "fcmov")
16099 (set_attr "mode" "XF")])
16101 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16102 ;; the scalar versions to have only XMM registers as operands.
16104 ;; XOP conditional move
16105 (define_insn "*xop_pcmov_<mode>"
16106 [(set (match_operand:MODEF 0 "register_operand" "=x")
16107 (if_then_else:MODEF
16108 (match_operand:MODEF 1 "register_operand" "x")
16109 (match_operand:MODEF 2 "register_operand" "x")
16110 (match_operand:MODEF 3 "register_operand" "x")))]
16112 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16113 [(set_attr "type" "sse4arg")])
16115 ;; These versions of the min/max patterns are intentionally ignorant of
16116 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16117 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16118 ;; are undefined in this condition, we're certain this is correct.
16120 (define_insn "*avx_<code><mode>3"
16121 [(set (match_operand:MODEF 0 "register_operand" "=x")
16123 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16124 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16125 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16126 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16127 [(set_attr "type" "sseadd")
16128 (set_attr "prefix" "vex")
16129 (set_attr "mode" "<MODE>")])
16131 (define_insn "<code><mode>3"
16132 [(set (match_operand:MODEF 0 "register_operand" "=x")
16134 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16135 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16136 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16137 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16138 [(set_attr "type" "sseadd")
16139 (set_attr "mode" "<MODE>")])
16141 ;; These versions of the min/max patterns implement exactly the operations
16142 ;; min = (op1 < op2 ? op1 : op2)
16143 ;; max = (!(op1 < op2) ? op1 : op2)
16144 ;; Their operands are not commutative, and thus they may be used in the
16145 ;; presence of -0.0 and NaN.
16147 (define_insn "*avx_ieee_smin<mode>3"
16148 [(set (match_operand:MODEF 0 "register_operand" "=x")
16150 [(match_operand:MODEF 1 "register_operand" "x")
16151 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16153 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16154 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16155 [(set_attr "type" "sseadd")
16156 (set_attr "prefix" "vex")
16157 (set_attr "mode" "<MODE>")])
16159 (define_insn "*ieee_smin<mode>3"
16160 [(set (match_operand:MODEF 0 "register_operand" "=x")
16162 [(match_operand:MODEF 1 "register_operand" "0")
16163 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16165 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16166 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16167 [(set_attr "type" "sseadd")
16168 (set_attr "mode" "<MODE>")])
16170 (define_insn "*avx_ieee_smax<mode>3"
16171 [(set (match_operand:MODEF 0 "register_operand" "=x")
16173 [(match_operand:MODEF 1 "register_operand" "0")
16174 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16176 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16177 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16178 [(set_attr "type" "sseadd")
16179 (set_attr "prefix" "vex")
16180 (set_attr "mode" "<MODE>")])
16182 (define_insn "*ieee_smax<mode>3"
16183 [(set (match_operand:MODEF 0 "register_operand" "=x")
16185 [(match_operand:MODEF 1 "register_operand" "0")
16186 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16188 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16189 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16190 [(set_attr "type" "sseadd")
16191 (set_attr "mode" "<MODE>")])
16193 ;; Make two stack loads independent:
16195 ;; fld %st(0) -> fld bb
16196 ;; fmul bb fmul %st(1), %st
16198 ;; Actually we only match the last two instructions for simplicity.
16200 [(set (match_operand 0 "fp_register_operand" "")
16201 (match_operand 1 "fp_register_operand" ""))
16203 (match_operator 2 "binary_fp_operator"
16205 (match_operand 3 "memory_operand" "")]))]
16206 "REGNO (operands[0]) != REGNO (operands[1])"
16207 [(set (match_dup 0) (match_dup 3))
16208 (set (match_dup 0) (match_dup 4))]
16210 ;; The % modifier is not operational anymore in peephole2's, so we have to
16211 ;; swap the operands manually in the case of addition and multiplication.
16212 "if (COMMUTATIVE_ARITH_P (operands[2]))
16213 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16214 operands[0], operands[1]);
16216 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16217 operands[1], operands[0]);")
16219 ;; Conditional addition patterns
16220 (define_expand "add<mode>cc"
16221 [(match_operand:SWI 0 "register_operand" "")
16222 (match_operand 1 "comparison_operator" "")
16223 (match_operand:SWI 2 "register_operand" "")
16224 (match_operand:SWI 3 "const_int_operand" "")]
16226 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16229 ;; Misc patterns (?)
16231 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16232 ;; Otherwise there will be nothing to keep
16234 ;; [(set (reg ebp) (reg esp))]
16235 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16236 ;; (clobber (eflags)]
16237 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16239 ;; in proper program order.
16240 (define_insn "pro_epilogue_adjust_stack_1"
16241 [(set (match_operand:SI 0 "register_operand" "=r,r")
16242 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16243 (match_operand:SI 2 "immediate_operand" "i,i")))
16244 (clobber (reg:CC FLAGS_REG))
16245 (clobber (mem:BLK (scratch)))]
16248 switch (get_attr_type (insn))
16251 return "mov{l}\t{%1, %0|%0, %1}";
16254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16255 if (x86_maybe_negate_const_int (&operands[2], SImode))
16256 return "sub{l}\t{%2, %0|%0, %2}";
16258 return "add{l}\t{%2, %0|%0, %2}";
16261 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16262 return "lea{l}\t{%a2, %0|%0, %a2}";
16265 [(set (attr "type")
16266 (cond [(and (eq_attr "alternative" "0")
16267 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16268 (const_string "alu")
16269 (match_operand:SI 2 "const0_operand" "")
16270 (const_string "imov")
16272 (const_string "lea")))
16273 (set (attr "length_immediate")
16274 (cond [(eq_attr "type" "imov")
16276 (and (eq_attr "type" "alu")
16277 (match_operand 2 "const128_operand" ""))
16280 (const_string "*")))
16281 (set_attr "mode" "SI")])
16283 (define_insn "pro_epilogue_adjust_stack_rex64"
16284 [(set (match_operand:DI 0 "register_operand" "=r,r")
16285 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16286 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16287 (clobber (reg:CC FLAGS_REG))
16288 (clobber (mem:BLK (scratch)))]
16291 switch (get_attr_type (insn))
16294 return "mov{q}\t{%1, %0|%0, %1}";
16297 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16298 if (x86_maybe_negate_const_int (&operands[2], DImode))
16299 return "sub{q}\t{%2, %0|%0, %2}";
16301 return "add{q}\t{%2, %0|%0, %2}";
16304 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16305 return "lea{q}\t{%a2, %0|%0, %a2}";
16308 [(set (attr "type")
16309 (cond [(and (eq_attr "alternative" "0")
16310 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16311 (const_string "alu")
16312 (match_operand:DI 2 "const0_operand" "")
16313 (const_string "imov")
16315 (const_string "lea")))
16316 (set (attr "length_immediate")
16317 (cond [(eq_attr "type" "imov")
16319 (and (eq_attr "type" "alu")
16320 (match_operand 2 "const128_operand" ""))
16323 (const_string "*")))
16324 (set_attr "mode" "DI")])
16326 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16327 [(set (match_operand:DI 0 "register_operand" "=r,r")
16328 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16329 (match_operand:DI 3 "immediate_operand" "i,i")))
16330 (use (match_operand:DI 2 "register_operand" "r,r"))
16331 (clobber (reg:CC FLAGS_REG))
16332 (clobber (mem:BLK (scratch)))]
16335 switch (get_attr_type (insn))
16338 return "add{q}\t{%2, %0|%0, %2}";
16341 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16342 return "lea{q}\t{%a2, %0|%0, %a2}";
16345 gcc_unreachable ();
16348 [(set_attr "type" "alu,lea")
16349 (set_attr "mode" "DI")])
16351 (define_insn "allocate_stack_worker_32"
16352 [(set (match_operand:SI 0 "register_operand" "=a")
16353 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16354 UNSPECV_STACK_PROBE))
16355 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16356 (clobber (reg:CC FLAGS_REG))]
16357 "!TARGET_64BIT && TARGET_STACK_PROBE"
16359 [(set_attr "type" "multi")
16360 (set_attr "length" "5")])
16362 (define_insn "allocate_stack_worker_64"
16363 [(set (match_operand:DI 0 "register_operand" "=a")
16364 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16365 UNSPECV_STACK_PROBE))
16366 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16367 (clobber (reg:DI R10_REG))
16368 (clobber (reg:DI R11_REG))
16369 (clobber (reg:CC FLAGS_REG))]
16370 "TARGET_64BIT && TARGET_STACK_PROBE"
16372 [(set_attr "type" "multi")
16373 (set_attr "length" "5")])
16375 (define_expand "allocate_stack"
16376 [(match_operand 0 "register_operand" "")
16377 (match_operand 1 "general_operand" "")]
16378 "TARGET_STACK_PROBE"
16382 #ifndef CHECK_STACK_LIMIT
16383 #define CHECK_STACK_LIMIT 0
16386 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16387 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16389 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16390 stack_pointer_rtx, 0, OPTAB_DIRECT);
16391 if (x != stack_pointer_rtx)
16392 emit_move_insn (stack_pointer_rtx, x);
16396 x = copy_to_mode_reg (Pmode, operands[1]);
16398 x = gen_allocate_stack_worker_64 (x, x);
16400 x = gen_allocate_stack_worker_32 (x, x);
16404 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16408 ;; Use IOR for stack probes, this is shorter.
16409 (define_expand "probe_stack"
16410 [(match_operand 0 "memory_operand" "")]
16413 if (GET_MODE (operands[0]) == DImode)
16414 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16416 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16420 (define_expand "builtin_setjmp_receiver"
16421 [(label_ref (match_operand 0 "" ""))]
16422 "!TARGET_64BIT && flag_pic"
16428 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16429 rtx label_rtx = gen_label_rtx ();
16430 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16431 xops[0] = xops[1] = picreg;
16432 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16433 ix86_expand_binary_operator (MINUS, SImode, xops);
16437 emit_insn (gen_set_got (pic_offset_table_rtx));
16441 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16444 [(set (match_operand 0 "register_operand" "")
16445 (match_operator 3 "promotable_binary_operator"
16446 [(match_operand 1 "register_operand" "")
16447 (match_operand 2 "aligned_operand" "")]))
16448 (clobber (reg:CC FLAGS_REG))]
16449 "! TARGET_PARTIAL_REG_STALL && reload_completed
16450 && ((GET_MODE (operands[0]) == HImode
16451 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16452 /* ??? next two lines just !satisfies_constraint_K (...) */
16453 || !CONST_INT_P (operands[2])
16454 || satisfies_constraint_K (operands[2])))
16455 || (GET_MODE (operands[0]) == QImode
16456 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16457 [(parallel [(set (match_dup 0)
16458 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16459 (clobber (reg:CC FLAGS_REG))])]
16460 "operands[0] = gen_lowpart (SImode, operands[0]);
16461 operands[1] = gen_lowpart (SImode, operands[1]);
16462 if (GET_CODE (operands[3]) != ASHIFT)
16463 operands[2] = gen_lowpart (SImode, operands[2]);
16464 PUT_MODE (operands[3], SImode);")
16466 ; Promote the QImode tests, as i386 has encoding of the AND
16467 ; instruction with 32-bit sign-extended immediate and thus the
16468 ; instruction size is unchanged, except in the %eax case for
16469 ; which it is increased by one byte, hence the ! optimize_size.
16471 [(set (match_operand 0 "flags_reg_operand" "")
16472 (match_operator 2 "compare_operator"
16473 [(and (match_operand 3 "aligned_operand" "")
16474 (match_operand 4 "const_int_operand" ""))
16476 (set (match_operand 1 "register_operand" "")
16477 (and (match_dup 3) (match_dup 4)))]
16478 "! TARGET_PARTIAL_REG_STALL && reload_completed
16479 && optimize_insn_for_speed_p ()
16480 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16481 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16482 /* Ensure that the operand will remain sign-extended immediate. */
16483 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16484 [(parallel [(set (match_dup 0)
16485 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16488 (and:SI (match_dup 3) (match_dup 4)))])]
16491 = gen_int_mode (INTVAL (operands[4])
16492 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16493 operands[1] = gen_lowpart (SImode, operands[1]);
16494 operands[3] = gen_lowpart (SImode, operands[3]);
16497 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16498 ; the TEST instruction with 32-bit sign-extended immediate and thus
16499 ; the instruction size would at least double, which is not what we
16500 ; want even with ! optimize_size.
16502 [(set (match_operand 0 "flags_reg_operand" "")
16503 (match_operator 1 "compare_operator"
16504 [(and (match_operand:HI 2 "aligned_operand" "")
16505 (match_operand:HI 3 "const_int_operand" ""))
16507 "! TARGET_PARTIAL_REG_STALL && reload_completed
16508 && ! TARGET_FAST_PREFIX
16509 && optimize_insn_for_speed_p ()
16510 /* Ensure that the operand will remain sign-extended immediate. */
16511 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16512 [(set (match_dup 0)
16513 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16517 = gen_int_mode (INTVAL (operands[3])
16518 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16519 operands[2] = gen_lowpart (SImode, operands[2]);
16523 [(set (match_operand 0 "register_operand" "")
16524 (neg (match_operand 1 "register_operand" "")))
16525 (clobber (reg:CC FLAGS_REG))]
16526 "! TARGET_PARTIAL_REG_STALL && reload_completed
16527 && (GET_MODE (operands[0]) == HImode
16528 || (GET_MODE (operands[0]) == QImode
16529 && (TARGET_PROMOTE_QImode
16530 || optimize_insn_for_size_p ())))"
16531 [(parallel [(set (match_dup 0)
16532 (neg:SI (match_dup 1)))
16533 (clobber (reg:CC FLAGS_REG))])]
16534 "operands[0] = gen_lowpart (SImode, operands[0]);
16535 operands[1] = gen_lowpart (SImode, operands[1]);")
16538 [(set (match_operand 0 "register_operand" "")
16539 (not (match_operand 1 "register_operand" "")))]
16540 "! TARGET_PARTIAL_REG_STALL && reload_completed
16541 && (GET_MODE (operands[0]) == HImode
16542 || (GET_MODE (operands[0]) == QImode
16543 && (TARGET_PROMOTE_QImode
16544 || optimize_insn_for_size_p ())))"
16545 [(set (match_dup 0)
16546 (not:SI (match_dup 1)))]
16547 "operands[0] = gen_lowpart (SImode, operands[0]);
16548 operands[1] = gen_lowpart (SImode, operands[1]);")
16551 [(set (match_operand 0 "register_operand" "")
16552 (if_then_else (match_operator 1 "comparison_operator"
16553 [(reg FLAGS_REG) (const_int 0)])
16554 (match_operand 2 "register_operand" "")
16555 (match_operand 3 "register_operand" "")))]
16556 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16557 && (GET_MODE (operands[0]) == HImode
16558 || (GET_MODE (operands[0]) == QImode
16559 && (TARGET_PROMOTE_QImode
16560 || optimize_insn_for_size_p ())))"
16561 [(set (match_dup 0)
16562 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16563 "operands[0] = gen_lowpart (SImode, operands[0]);
16564 operands[2] = gen_lowpart (SImode, operands[2]);
16565 operands[3] = gen_lowpart (SImode, operands[3]);")
16568 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16569 ;; transform a complex memory operation into two memory to register operations.
16571 ;; Don't push memory operands
16573 [(set (match_operand:SI 0 "push_operand" "")
16574 (match_operand:SI 1 "memory_operand" ""))
16575 (match_scratch:SI 2 "r")]
16576 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16577 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16578 [(set (match_dup 2) (match_dup 1))
16579 (set (match_dup 0) (match_dup 2))]
16583 [(set (match_operand:DI 0 "push_operand" "")
16584 (match_operand:DI 1 "memory_operand" ""))
16585 (match_scratch:DI 2 "r")]
16586 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16587 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16588 [(set (match_dup 2) (match_dup 1))
16589 (set (match_dup 0) (match_dup 2))]
16592 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16595 [(set (match_operand:SF 0 "push_operand" "")
16596 (match_operand:SF 1 "memory_operand" ""))
16597 (match_scratch:SF 2 "r")]
16598 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16599 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16600 [(set (match_dup 2) (match_dup 1))
16601 (set (match_dup 0) (match_dup 2))]
16605 [(set (match_operand:HI 0 "push_operand" "")
16606 (match_operand:HI 1 "memory_operand" ""))
16607 (match_scratch:HI 2 "r")]
16608 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16609 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16610 [(set (match_dup 2) (match_dup 1))
16611 (set (match_dup 0) (match_dup 2))]
16615 [(set (match_operand:QI 0 "push_operand" "")
16616 (match_operand:QI 1 "memory_operand" ""))
16617 (match_scratch:QI 2 "q")]
16618 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16619 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16620 [(set (match_dup 2) (match_dup 1))
16621 (set (match_dup 0) (match_dup 2))]
16624 ;; Don't move an immediate directly to memory when the instruction
16627 [(match_scratch:SI 1 "r")
16628 (set (match_operand:SI 0 "memory_operand" "")
16630 "optimize_insn_for_speed_p ()
16631 && ! TARGET_USE_MOV0
16632 && TARGET_SPLIT_LONG_MOVES
16633 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16634 && peep2_regno_dead_p (0, FLAGS_REG)"
16635 [(parallel [(set (match_dup 1) (const_int 0))
16636 (clobber (reg:CC FLAGS_REG))])
16637 (set (match_dup 0) (match_dup 1))]
16641 [(match_scratch:HI 1 "r")
16642 (set (match_operand:HI 0 "memory_operand" "")
16644 "optimize_insn_for_speed_p ()
16645 && ! TARGET_USE_MOV0
16646 && TARGET_SPLIT_LONG_MOVES
16647 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16648 && peep2_regno_dead_p (0, FLAGS_REG)"
16649 [(parallel [(set (match_dup 2) (const_int 0))
16650 (clobber (reg:CC FLAGS_REG))])
16651 (set (match_dup 0) (match_dup 1))]
16652 "operands[2] = gen_lowpart (SImode, operands[1]);")
16655 [(match_scratch:QI 1 "q")
16656 (set (match_operand:QI 0 "memory_operand" "")
16658 "optimize_insn_for_speed_p ()
16659 && ! TARGET_USE_MOV0
16660 && TARGET_SPLIT_LONG_MOVES
16661 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16662 && peep2_regno_dead_p (0, FLAGS_REG)"
16663 [(parallel [(set (match_dup 2) (const_int 0))
16664 (clobber (reg:CC FLAGS_REG))])
16665 (set (match_dup 0) (match_dup 1))]
16666 "operands[2] = gen_lowpart (SImode, operands[1]);")
16669 [(match_scratch:SI 2 "r")
16670 (set (match_operand:SI 0 "memory_operand" "")
16671 (match_operand:SI 1 "immediate_operand" ""))]
16672 "optimize_insn_for_speed_p ()
16673 && TARGET_SPLIT_LONG_MOVES
16674 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16675 [(set (match_dup 2) (match_dup 1))
16676 (set (match_dup 0) (match_dup 2))]
16680 [(match_scratch:HI 2 "r")
16681 (set (match_operand:HI 0 "memory_operand" "")
16682 (match_operand:HI 1 "immediate_operand" ""))]
16683 "optimize_insn_for_speed_p ()
16684 && TARGET_SPLIT_LONG_MOVES
16685 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16686 [(set (match_dup 2) (match_dup 1))
16687 (set (match_dup 0) (match_dup 2))]
16691 [(match_scratch:QI 2 "q")
16692 (set (match_operand:QI 0 "memory_operand" "")
16693 (match_operand:QI 1 "immediate_operand" ""))]
16694 "optimize_insn_for_speed_p ()
16695 && TARGET_SPLIT_LONG_MOVES
16696 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16697 [(set (match_dup 2) (match_dup 1))
16698 (set (match_dup 0) (match_dup 2))]
16701 ;; Don't compare memory with zero, load and use a test instead.
16703 [(set (match_operand 0 "flags_reg_operand" "")
16704 (match_operator 1 "compare_operator"
16705 [(match_operand:SI 2 "memory_operand" "")
16707 (match_scratch:SI 3 "r")]
16708 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16709 [(set (match_dup 3) (match_dup 2))
16710 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16713 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16714 ;; Don't split NOTs with a displacement operand, because resulting XOR
16715 ;; will not be pairable anyway.
16717 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16718 ;; represented using a modRM byte. The XOR replacement is long decoded,
16719 ;; so this split helps here as well.
16721 ;; Note: Can't do this as a regular split because we can't get proper
16722 ;; lifetime information then.
16725 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16726 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16727 "optimize_insn_for_speed_p ()
16728 && ((TARGET_NOT_UNPAIRABLE
16729 && (!MEM_P (operands[0])
16730 || !memory_displacement_operand (operands[0], SImode)))
16731 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16732 && peep2_regno_dead_p (0, FLAGS_REG)"
16733 [(parallel [(set (match_dup 0)
16734 (xor:SI (match_dup 1) (const_int -1)))
16735 (clobber (reg:CC FLAGS_REG))])]
16739 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16740 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16741 "optimize_insn_for_speed_p ()
16742 && ((TARGET_NOT_UNPAIRABLE
16743 && (!MEM_P (operands[0])
16744 || !memory_displacement_operand (operands[0], HImode)))
16745 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16746 && peep2_regno_dead_p (0, FLAGS_REG)"
16747 [(parallel [(set (match_dup 0)
16748 (xor:HI (match_dup 1) (const_int -1)))
16749 (clobber (reg:CC FLAGS_REG))])]
16753 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16754 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16755 "optimize_insn_for_speed_p ()
16756 && ((TARGET_NOT_UNPAIRABLE
16757 && (!MEM_P (operands[0])
16758 || !memory_displacement_operand (operands[0], QImode)))
16759 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16760 && peep2_regno_dead_p (0, FLAGS_REG)"
16761 [(parallel [(set (match_dup 0)
16762 (xor:QI (match_dup 1) (const_int -1)))
16763 (clobber (reg:CC FLAGS_REG))])]
16766 ;; Non pairable "test imm, reg" instructions can be translated to
16767 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16768 ;; byte opcode instead of two, have a short form for byte operands),
16769 ;; so do it for other CPUs as well. Given that the value was dead,
16770 ;; this should not create any new dependencies. Pass on the sub-word
16771 ;; versions if we're concerned about partial register stalls.
16774 [(set (match_operand 0 "flags_reg_operand" "")
16775 (match_operator 1 "compare_operator"
16776 [(and:SI (match_operand:SI 2 "register_operand" "")
16777 (match_operand:SI 3 "immediate_operand" ""))
16779 "ix86_match_ccmode (insn, CCNOmode)
16780 && (true_regnum (operands[2]) != AX_REG
16781 || satisfies_constraint_K (operands[3]))
16782 && peep2_reg_dead_p (1, operands[2])"
16784 [(set (match_dup 0)
16785 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16788 (and:SI (match_dup 2) (match_dup 3)))])]
16791 ;; We don't need to handle HImode case, because it will be promoted to SImode
16792 ;; on ! TARGET_PARTIAL_REG_STALL
16795 [(set (match_operand 0 "flags_reg_operand" "")
16796 (match_operator 1 "compare_operator"
16797 [(and:QI (match_operand:QI 2 "register_operand" "")
16798 (match_operand:QI 3 "immediate_operand" ""))
16800 "! TARGET_PARTIAL_REG_STALL
16801 && ix86_match_ccmode (insn, CCNOmode)
16802 && true_regnum (operands[2]) != AX_REG
16803 && peep2_reg_dead_p (1, operands[2])"
16805 [(set (match_dup 0)
16806 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16809 (and:QI (match_dup 2) (match_dup 3)))])]
16813 [(set (match_operand 0 "flags_reg_operand" "")
16814 (match_operator 1 "compare_operator"
16817 (match_operand 2 "ext_register_operand" "")
16820 (match_operand 3 "const_int_operand" ""))
16822 "! TARGET_PARTIAL_REG_STALL
16823 && ix86_match_ccmode (insn, CCNOmode)
16824 && true_regnum (operands[2]) != AX_REG
16825 && peep2_reg_dead_p (1, operands[2])"
16826 [(parallel [(set (match_dup 0)
16835 (set (zero_extract:SI (match_dup 2)
16846 ;; Don't do logical operations with memory inputs.
16848 [(match_scratch:SI 2 "r")
16849 (parallel [(set (match_operand:SI 0 "register_operand" "")
16850 (match_operator:SI 3 "arith_or_logical_operator"
16852 (match_operand:SI 1 "memory_operand" "")]))
16853 (clobber (reg:CC FLAGS_REG))])]
16854 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16855 [(set (match_dup 2) (match_dup 1))
16856 (parallel [(set (match_dup 0)
16857 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16858 (clobber (reg:CC FLAGS_REG))])]
16862 [(match_scratch:SI 2 "r")
16863 (parallel [(set (match_operand:SI 0 "register_operand" "")
16864 (match_operator:SI 3 "arith_or_logical_operator"
16865 [(match_operand:SI 1 "memory_operand" "")
16867 (clobber (reg:CC FLAGS_REG))])]
16868 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16869 [(set (match_dup 2) (match_dup 1))
16870 (parallel [(set (match_dup 0)
16871 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16872 (clobber (reg:CC FLAGS_REG))])]
16875 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16876 ;; refers to the destination of the load!
16879 [(set (match_operand:SI 0 "register_operand" "")
16880 (match_operand:SI 1 "register_operand" ""))
16881 (parallel [(set (match_dup 0)
16882 (match_operator:SI 3 "commutative_operator"
16884 (match_operand:SI 2 "memory_operand" "")]))
16885 (clobber (reg:CC FLAGS_REG))])]
16886 "REGNO (operands[0]) != REGNO (operands[1])
16887 && GENERAL_REGNO_P (REGNO (operands[0]))
16888 && GENERAL_REGNO_P (REGNO (operands[1]))"
16889 [(set (match_dup 0) (match_dup 4))
16890 (parallel [(set (match_dup 0)
16891 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16892 (clobber (reg:CC FLAGS_REG))])]
16893 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16896 [(set (match_operand 0 "register_operand" "")
16897 (match_operand 1 "register_operand" ""))
16899 (match_operator 3 "commutative_operator"
16901 (match_operand 2 "memory_operand" "")]))]
16902 "REGNO (operands[0]) != REGNO (operands[1])
16903 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16904 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16905 [(set (match_dup 0) (match_dup 2))
16907 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
16910 ; Don't do logical operations with memory outputs
16912 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16913 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16914 ; the same decoder scheduling characteristics as the original.
16917 [(match_scratch:SI 2 "r")
16918 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16919 (match_operator:SI 3 "arith_or_logical_operator"
16921 (match_operand:SI 1 "nonmemory_operand" "")]))
16922 (clobber (reg:CC FLAGS_REG))])]
16923 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16924 /* Do not split stack checking probes. */
16925 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16926 [(set (match_dup 2) (match_dup 0))
16927 (parallel [(set (match_dup 2)
16928 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16929 (clobber (reg:CC FLAGS_REG))])
16930 (set (match_dup 0) (match_dup 2))]
16934 [(match_scratch:SI 2 "r")
16935 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16936 (match_operator:SI 3 "arith_or_logical_operator"
16937 [(match_operand:SI 1 "nonmemory_operand" "")
16939 (clobber (reg:CC FLAGS_REG))])]
16940 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16941 /* Do not split stack checking probes. */
16942 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16943 [(set (match_dup 2) (match_dup 0))
16944 (parallel [(set (match_dup 2)
16945 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16946 (clobber (reg:CC FLAGS_REG))])
16947 (set (match_dup 0) (match_dup 2))]
16950 ;; Attempt to always use XOR for zeroing registers.
16952 [(set (match_operand 0 "register_operand" "")
16953 (match_operand 1 "const0_operand" ""))]
16954 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16955 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16956 && GENERAL_REG_P (operands[0])
16957 && peep2_regno_dead_p (0, FLAGS_REG)"
16958 [(parallel [(set (match_dup 0) (const_int 0))
16959 (clobber (reg:CC FLAGS_REG))])]
16961 operands[0] = gen_lowpart (word_mode, operands[0]);
16965 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16967 "(GET_MODE (operands[0]) == QImode
16968 || GET_MODE (operands[0]) == HImode)
16969 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16970 && peep2_regno_dead_p (0, FLAGS_REG)"
16971 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16972 (clobber (reg:CC FLAGS_REG))])])
16974 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16976 [(set (match_operand 0 "register_operand" "")
16978 "(GET_MODE (operands[0]) == HImode
16979 || GET_MODE (operands[0]) == SImode
16980 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16981 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16982 && peep2_regno_dead_p (0, FLAGS_REG)"
16983 [(parallel [(set (match_dup 0) (const_int -1))
16984 (clobber (reg:CC FLAGS_REG))])]
16985 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16988 ;; Attempt to convert simple leas to adds. These can be created by
16991 [(set (match_operand:SI 0 "register_operand" "")
16992 (plus:SI (match_dup 0)
16993 (match_operand:SI 1 "nonmemory_operand" "")))]
16994 "peep2_regno_dead_p (0, FLAGS_REG)"
16995 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16996 (clobber (reg:CC FLAGS_REG))])]
17000 [(set (match_operand:SI 0 "register_operand" "")
17001 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17002 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17003 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17004 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17005 (clobber (reg:CC FLAGS_REG))])]
17006 "operands[2] = gen_lowpart (SImode, operands[2]);")
17009 [(set (match_operand:DI 0 "register_operand" "")
17010 (plus:DI (match_dup 0)
17011 (match_operand:DI 1 "x86_64_general_operand" "")))]
17012 "peep2_regno_dead_p (0, FLAGS_REG)"
17013 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17014 (clobber (reg:CC FLAGS_REG))])]
17018 [(set (match_operand:SI 0 "register_operand" "")
17019 (mult:SI (match_dup 0)
17020 (match_operand:SI 1 "const_int_operand" "")))]
17021 "exact_log2 (INTVAL (operands[1])) >= 0
17022 && peep2_regno_dead_p (0, FLAGS_REG)"
17023 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17024 (clobber (reg:CC FLAGS_REG))])]
17025 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17028 [(set (match_operand:DI 0 "register_operand" "")
17029 (mult:DI (match_dup 0)
17030 (match_operand:DI 1 "const_int_operand" "")))]
17031 "exact_log2 (INTVAL (operands[1])) >= 0
17032 && peep2_regno_dead_p (0, FLAGS_REG)"
17033 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17034 (clobber (reg:CC FLAGS_REG))])]
17035 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17038 [(set (match_operand:SI 0 "register_operand" "")
17039 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17040 (match_operand:DI 2 "const_int_operand" "")) 0))]
17041 "exact_log2 (INTVAL (operands[2])) >= 0
17042 && REGNO (operands[0]) == REGNO (operands[1])
17043 && peep2_regno_dead_p (0, FLAGS_REG)"
17044 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17045 (clobber (reg:CC FLAGS_REG))])]
17046 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17048 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17049 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17050 ;; many CPUs it is also faster, since special hardware to avoid esp
17051 ;; dependencies is present.
17053 ;; While some of these conversions may be done using splitters, we use peepholes
17054 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17056 ;; Convert prologue esp subtractions to push.
17057 ;; We need register to push. In order to keep verify_flow_info happy we have
17059 ;; - use scratch and clobber it in order to avoid dependencies
17060 ;; - use already live register
17061 ;; We can't use the second way right now, since there is no reliable way how to
17062 ;; verify that given register is live. First choice will also most likely in
17063 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17064 ;; call clobbered registers are dead. We may want to use base pointer as an
17065 ;; alternative when no register is available later.
17068 [(match_scratch:SI 0 "r")
17069 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17070 (clobber (reg:CC FLAGS_REG))
17071 (clobber (mem:BLK (scratch)))])]
17072 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17073 [(clobber (match_dup 0))
17074 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17075 (clobber (mem:BLK (scratch)))])])
17078 [(match_scratch:SI 0 "r")
17079 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17080 (clobber (reg:CC FLAGS_REG))
17081 (clobber (mem:BLK (scratch)))])]
17082 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17083 [(clobber (match_dup 0))
17084 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17085 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17086 (clobber (mem:BLK (scratch)))])])
17088 ;; Convert esp subtractions to push.
17090 [(match_scratch:SI 0 "r")
17091 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17092 (clobber (reg:CC FLAGS_REG))])]
17093 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17094 [(clobber (match_dup 0))
17095 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17098 [(match_scratch:SI 0 "r")
17099 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17100 (clobber (reg:CC FLAGS_REG))])]
17101 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17102 [(clobber (match_dup 0))
17103 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17104 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17106 ;; Convert epilogue deallocator to pop.
17108 [(match_scratch:SI 0 "r")
17109 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17110 (clobber (reg:CC FLAGS_REG))
17111 (clobber (mem:BLK (scratch)))])]
17112 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17113 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17114 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17115 (clobber (mem:BLK (scratch)))])]
17118 ;; Two pops case is tricky, since pop causes dependency on destination register.
17119 ;; We use two registers if available.
17121 [(match_scratch:SI 0 "r")
17122 (match_scratch:SI 1 "r")
17123 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17124 (clobber (reg:CC FLAGS_REG))
17125 (clobber (mem:BLK (scratch)))])]
17126 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17127 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17128 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17129 (clobber (mem:BLK (scratch)))])
17130 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17131 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17135 [(match_scratch:SI 0 "r")
17136 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17137 (clobber (reg:CC FLAGS_REG))
17138 (clobber (mem:BLK (scratch)))])]
17139 "optimize_insn_for_size_p ()"
17140 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17141 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17142 (clobber (mem:BLK (scratch)))])
17143 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17144 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17147 ;; Convert esp additions to pop.
17149 [(match_scratch:SI 0 "r")
17150 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17151 (clobber (reg:CC FLAGS_REG))])]
17153 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17154 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17157 ;; Two pops case is tricky, since pop causes dependency on destination register.
17158 ;; We use two registers if available.
17160 [(match_scratch:SI 0 "r")
17161 (match_scratch:SI 1 "r")
17162 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17163 (clobber (reg:CC FLAGS_REG))])]
17165 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17167 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17168 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17172 [(match_scratch:SI 0 "r")
17173 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17174 (clobber (reg:CC FLAGS_REG))])]
17175 "optimize_insn_for_size_p ()"
17176 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17177 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17178 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17179 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17182 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17183 ;; required and register dies. Similarly for 128 to -128.
17185 [(set (match_operand 0 "flags_reg_operand" "")
17186 (match_operator 1 "compare_operator"
17187 [(match_operand 2 "register_operand" "")
17188 (match_operand 3 "const_int_operand" "")]))]
17189 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17190 && incdec_operand (operands[3], GET_MODE (operands[3])))
17191 || (!TARGET_FUSE_CMP_AND_BRANCH
17192 && INTVAL (operands[3]) == 128))
17193 && ix86_match_ccmode (insn, CCGCmode)
17194 && peep2_reg_dead_p (1, operands[2])"
17195 [(parallel [(set (match_dup 0)
17196 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17197 (clobber (match_dup 2))])]
17201 [(match_scratch:DI 0 "r")
17202 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17203 (clobber (reg:CC FLAGS_REG))
17204 (clobber (mem:BLK (scratch)))])]
17205 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17206 [(clobber (match_dup 0))
17207 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17208 (clobber (mem:BLK (scratch)))])])
17211 [(match_scratch:DI 0 "r")
17212 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17213 (clobber (reg:CC FLAGS_REG))
17214 (clobber (mem:BLK (scratch)))])]
17215 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17216 [(clobber (match_dup 0))
17217 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17218 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17219 (clobber (mem:BLK (scratch)))])])
17221 ;; Convert esp subtractions to push.
17223 [(match_scratch:DI 0 "r")
17224 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17225 (clobber (reg:CC FLAGS_REG))])]
17226 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17227 [(clobber (match_dup 0))
17228 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17231 [(match_scratch:DI 0 "r")
17232 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17233 (clobber (reg:CC FLAGS_REG))])]
17234 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17235 [(clobber (match_dup 0))
17236 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17237 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17239 ;; Convert epilogue deallocator to pop.
17241 [(match_scratch:DI 0 "r")
17242 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17243 (clobber (reg:CC FLAGS_REG))
17244 (clobber (mem:BLK (scratch)))])]
17245 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17246 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17247 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17248 (clobber (mem:BLK (scratch)))])]
17251 ;; Two pops case is tricky, since pop causes dependency on destination register.
17252 ;; We use two registers if available.
17254 [(match_scratch:DI 0 "r")
17255 (match_scratch:DI 1 "r")
17256 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17257 (clobber (reg:CC FLAGS_REG))
17258 (clobber (mem:BLK (scratch)))])]
17259 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17260 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17261 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17262 (clobber (mem:BLK (scratch)))])
17263 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17264 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17268 [(match_scratch:DI 0 "r")
17269 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17270 (clobber (reg:CC FLAGS_REG))
17271 (clobber (mem:BLK (scratch)))])]
17272 "optimize_insn_for_size_p ()"
17273 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17274 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17275 (clobber (mem:BLK (scratch)))])
17276 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17277 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17280 ;; Convert esp additions to pop.
17282 [(match_scratch:DI 0 "r")
17283 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17284 (clobber (reg:CC FLAGS_REG))])]
17286 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17287 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17290 ;; Two pops case is tricky, since pop causes dependency on destination register.
17291 ;; We use two registers if available.
17293 [(match_scratch:DI 0 "r")
17294 (match_scratch:DI 1 "r")
17295 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17296 (clobber (reg:CC FLAGS_REG))])]
17298 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17299 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17300 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17301 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17305 [(match_scratch:DI 0 "r")
17306 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17307 (clobber (reg:CC FLAGS_REG))])]
17308 "optimize_insn_for_size_p ()"
17309 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17310 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17311 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17312 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17315 ;; Convert imul by three, five and nine into lea
17318 [(set (match_operand:SI 0 "register_operand" "")
17319 (mult:SI (match_operand:SI 1 "register_operand" "")
17320 (match_operand:SI 2 "const_int_operand" "")))
17321 (clobber (reg:CC FLAGS_REG))])]
17322 "INTVAL (operands[2]) == 3
17323 || INTVAL (operands[2]) == 5
17324 || INTVAL (operands[2]) == 9"
17325 [(set (match_dup 0)
17326 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17328 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17332 [(set (match_operand:SI 0 "register_operand" "")
17333 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17334 (match_operand:SI 2 "const_int_operand" "")))
17335 (clobber (reg:CC FLAGS_REG))])]
17336 "optimize_insn_for_speed_p ()
17337 && (INTVAL (operands[2]) == 3
17338 || INTVAL (operands[2]) == 5
17339 || INTVAL (operands[2]) == 9)"
17340 [(set (match_dup 0) (match_dup 1))
17342 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17344 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17348 [(set (match_operand:DI 0 "register_operand" "")
17349 (mult:DI (match_operand:DI 1 "register_operand" "")
17350 (match_operand:DI 2 "const_int_operand" "")))
17351 (clobber (reg:CC FLAGS_REG))])]
17353 && (INTVAL (operands[2]) == 3
17354 || INTVAL (operands[2]) == 5
17355 || INTVAL (operands[2]) == 9)"
17356 [(set (match_dup 0)
17357 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17359 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17363 [(set (match_operand:DI 0 "register_operand" "")
17364 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17365 (match_operand:DI 2 "const_int_operand" "")))
17366 (clobber (reg:CC FLAGS_REG))])]
17368 && optimize_insn_for_speed_p ()
17369 && (INTVAL (operands[2]) == 3
17370 || INTVAL (operands[2]) == 5
17371 || INTVAL (operands[2]) == 9)"
17372 [(set (match_dup 0) (match_dup 1))
17374 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17376 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17378 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17379 ;; imul $32bit_imm, reg, reg is direct decoded.
17381 [(match_scratch:DI 3 "r")
17382 (parallel [(set (match_operand:DI 0 "register_operand" "")
17383 (mult:DI (match_operand:DI 1 "memory_operand" "")
17384 (match_operand:DI 2 "immediate_operand" "")))
17385 (clobber (reg:CC FLAGS_REG))])]
17386 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17387 && !satisfies_constraint_K (operands[2])"
17388 [(set (match_dup 3) (match_dup 1))
17389 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17390 (clobber (reg:CC FLAGS_REG))])]
17394 [(match_scratch:SI 3 "r")
17395 (parallel [(set (match_operand:SI 0 "register_operand" "")
17396 (mult:SI (match_operand:SI 1 "memory_operand" "")
17397 (match_operand:SI 2 "immediate_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))])]
17399 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17400 && !satisfies_constraint_K (operands[2])"
17401 [(set (match_dup 3) (match_dup 1))
17402 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17403 (clobber (reg:CC FLAGS_REG))])]
17407 [(match_scratch:SI 3 "r")
17408 (parallel [(set (match_operand:DI 0 "register_operand" "")
17410 (mult:SI (match_operand:SI 1 "memory_operand" "")
17411 (match_operand:SI 2 "immediate_operand" ""))))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17414 && !satisfies_constraint_K (operands[2])"
17415 [(set (match_dup 3) (match_dup 1))
17416 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17417 (clobber (reg:CC FLAGS_REG))])]
17420 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17421 ;; Convert it into imul reg, reg
17422 ;; It would be better to force assembler to encode instruction using long
17423 ;; immediate, but there is apparently no way to do so.
17425 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17426 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17427 (match_operand:DI 2 "const_int_operand" "")))
17428 (clobber (reg:CC FLAGS_REG))])
17429 (match_scratch:DI 3 "r")]
17430 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17431 && satisfies_constraint_K (operands[2])"
17432 [(set (match_dup 3) (match_dup 2))
17433 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17434 (clobber (reg:CC FLAGS_REG))])]
17436 if (!rtx_equal_p (operands[0], operands[1]))
17437 emit_move_insn (operands[0], operands[1]);
17441 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17442 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17443 (match_operand:SI 2 "const_int_operand" "")))
17444 (clobber (reg:CC FLAGS_REG))])
17445 (match_scratch:SI 3 "r")]
17446 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17447 && satisfies_constraint_K (operands[2])"
17448 [(set (match_dup 3) (match_dup 2))
17449 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17450 (clobber (reg:CC FLAGS_REG))])]
17452 if (!rtx_equal_p (operands[0], operands[1]))
17453 emit_move_insn (operands[0], operands[1]);
17457 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17458 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17459 (match_operand:HI 2 "immediate_operand" "")))
17460 (clobber (reg:CC FLAGS_REG))])
17461 (match_scratch:HI 3 "r")]
17462 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17463 [(set (match_dup 3) (match_dup 2))
17464 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17465 (clobber (reg:CC FLAGS_REG))])]
17467 if (!rtx_equal_p (operands[0], operands[1]))
17468 emit_move_insn (operands[0], operands[1]);
17471 ;; After splitting up read-modify operations, array accesses with memory
17472 ;; operands might end up in form:
17474 ;; movl 4(%esp), %edx
17476 ;; instead of pre-splitting:
17478 ;; addl 4(%esp), %eax
17480 ;; movl 4(%esp), %edx
17481 ;; leal (%edx,%eax,4), %eax
17484 [(parallel [(set (match_operand 0 "register_operand" "")
17485 (ashift (match_operand 1 "register_operand" "")
17486 (match_operand 2 "const_int_operand" "")))
17487 (clobber (reg:CC FLAGS_REG))])
17488 (set (match_operand 3 "register_operand")
17489 (match_operand 4 "x86_64_general_operand" ""))
17490 (parallel [(set (match_operand 5 "register_operand" "")
17491 (plus (match_operand 6 "register_operand" "")
17492 (match_operand 7 "register_operand" "")))
17493 (clobber (reg:CC FLAGS_REG))])]
17494 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17495 /* Validate MODE for lea. */
17496 && ((!TARGET_PARTIAL_REG_STALL
17497 && (GET_MODE (operands[0]) == QImode
17498 || GET_MODE (operands[0]) == HImode))
17499 || GET_MODE (operands[0]) == SImode
17500 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17501 /* We reorder load and the shift. */
17502 && !rtx_equal_p (operands[1], operands[3])
17503 && !reg_overlap_mentioned_p (operands[0], operands[4])
17504 /* Last PLUS must consist of operand 0 and 3. */
17505 && !rtx_equal_p (operands[0], operands[3])
17506 && (rtx_equal_p (operands[3], operands[6])
17507 || rtx_equal_p (operands[3], operands[7]))
17508 && (rtx_equal_p (operands[0], operands[6])
17509 || rtx_equal_p (operands[0], operands[7]))
17510 /* The intermediate operand 0 must die or be same as output. */
17511 && (rtx_equal_p (operands[0], operands[5])
17512 || peep2_reg_dead_p (3, operands[0]))"
17513 [(set (match_dup 3) (match_dup 4))
17514 (set (match_dup 0) (match_dup 1))]
17516 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17517 int scale = 1 << INTVAL (operands[2]);
17518 rtx index = gen_lowpart (Pmode, operands[1]);
17519 rtx base = gen_lowpart (Pmode, operands[3]);
17520 rtx dest = gen_lowpart (mode, operands[5]);
17522 operands[1] = gen_rtx_PLUS (Pmode, base,
17523 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17525 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17526 operands[0] = dest;
17529 ;; Call-value patterns last so that the wildcard operand does not
17530 ;; disrupt insn-recog's switch tables.
17532 (define_insn "*call_value_pop_0"
17533 [(set (match_operand 0 "" "")
17534 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17535 (match_operand:SI 2 "" "")))
17536 (set (reg:SI SP_REG)
17537 (plus:SI (reg:SI SP_REG)
17538 (match_operand:SI 3 "immediate_operand" "")))]
17541 if (SIBLING_CALL_P (insn))
17544 return "call\t%P1";
17546 [(set_attr "type" "callv")])
17548 (define_insn "*call_value_pop_1"
17549 [(set (match_operand 0 "" "")
17550 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17551 (match_operand:SI 2 "" "")))
17552 (set (reg:SI SP_REG)
17553 (plus:SI (reg:SI SP_REG)
17554 (match_operand:SI 3 "immediate_operand" "i")))]
17555 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17557 if (constant_call_address_operand (operands[1], Pmode))
17558 return "call\t%P1";
17559 return "call\t%A1";
17561 [(set_attr "type" "callv")])
17563 (define_insn "*sibcall_value_pop_1"
17564 [(set (match_operand 0 "" "")
17565 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17566 (match_operand:SI 2 "" "")))
17567 (set (reg:SI SP_REG)
17568 (plus:SI (reg:SI SP_REG)
17569 (match_operand:SI 3 "immediate_operand" "i,i")))]
17570 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17574 [(set_attr "type" "callv")])
17576 (define_insn "*call_value_0"
17577 [(set (match_operand 0 "" "")
17578 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17579 (match_operand:SI 2 "" "")))]
17582 if (SIBLING_CALL_P (insn))
17585 return "call\t%P1";
17587 [(set_attr "type" "callv")])
17589 (define_insn "*call_value_0_rex64"
17590 [(set (match_operand 0 "" "")
17591 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17592 (match_operand:DI 2 "const_int_operand" "")))]
17595 if (SIBLING_CALL_P (insn))
17598 return "call\t%P1";
17600 [(set_attr "type" "callv")])
17602 (define_insn "*call_value_0_rex64_ms_sysv"
17603 [(set (match_operand 0 "" "")
17604 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17605 (match_operand:DI 2 "const_int_operand" "")))
17606 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17607 (clobber (reg:TI XMM6_REG))
17608 (clobber (reg:TI XMM7_REG))
17609 (clobber (reg:TI XMM8_REG))
17610 (clobber (reg:TI XMM9_REG))
17611 (clobber (reg:TI XMM10_REG))
17612 (clobber (reg:TI XMM11_REG))
17613 (clobber (reg:TI XMM12_REG))
17614 (clobber (reg:TI XMM13_REG))
17615 (clobber (reg:TI XMM14_REG))
17616 (clobber (reg:TI XMM15_REG))
17617 (clobber (reg:DI SI_REG))
17618 (clobber (reg:DI DI_REG))]
17619 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17621 if (SIBLING_CALL_P (insn))
17624 return "call\t%P1";
17626 [(set_attr "type" "callv")])
17628 (define_insn "*call_value_1"
17629 [(set (match_operand 0 "" "")
17630 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17631 (match_operand:SI 2 "" "")))]
17632 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17634 if (constant_call_address_operand (operands[1], Pmode))
17635 return "call\t%P1";
17636 return "call\t%A1";
17638 [(set_attr "type" "callv")])
17640 (define_insn "*sibcall_value_1"
17641 [(set (match_operand 0 "" "")
17642 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17643 (match_operand:SI 2 "" "")))]
17644 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17648 [(set_attr "type" "callv")])
17650 (define_insn "*call_value_1_rex64"
17651 [(set (match_operand 0 "" "")
17652 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17653 (match_operand:DI 2 "" "")))]
17654 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17655 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17657 if (constant_call_address_operand (operands[1], Pmode))
17658 return "call\t%P1";
17659 return "call\t%A1";
17661 [(set_attr "type" "callv")])
17663 (define_insn "*call_value_1_rex64_ms_sysv"
17664 [(set (match_operand 0 "" "")
17665 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17666 (match_operand:DI 2 "" "")))
17667 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17668 (clobber (reg:TI XMM6_REG))
17669 (clobber (reg:TI XMM7_REG))
17670 (clobber (reg:TI XMM8_REG))
17671 (clobber (reg:TI XMM9_REG))
17672 (clobber (reg:TI XMM10_REG))
17673 (clobber (reg:TI XMM11_REG))
17674 (clobber (reg:TI XMM12_REG))
17675 (clobber (reg:TI XMM13_REG))
17676 (clobber (reg:TI XMM14_REG))
17677 (clobber (reg:TI XMM15_REG))
17678 (clobber (reg:DI SI_REG))
17679 (clobber (reg:DI DI_REG))]
17680 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17682 if (constant_call_address_operand (operands[1], Pmode))
17683 return "call\t%P1";
17684 return "call\t%A1";
17686 [(set_attr "type" "callv")])
17688 (define_insn "*call_value_1_rex64_large"
17689 [(set (match_operand 0 "" "")
17690 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17691 (match_operand:DI 2 "" "")))]
17692 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17694 [(set_attr "type" "callv")])
17696 (define_insn "*sibcall_value_1_rex64"
17697 [(set (match_operand 0 "" "")
17698 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17699 (match_operand:DI 2 "" "")))]
17700 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17704 [(set_attr "type" "callv")])
17706 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17707 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17708 ;; caught for use by garbage collectors and the like. Using an insn that
17709 ;; maps to SIGILL makes it more likely the program will rightfully die.
17710 ;; Keeping with tradition, "6" is in honor of #UD.
17711 (define_insn "trap"
17712 [(trap_if (const_int 1) (const_int 6))]
17714 { return ASM_SHORT "0x0b0f"; }
17715 [(set_attr "length" "2")])
17717 (define_expand "sse_prologue_save"
17718 [(parallel [(set (match_operand:BLK 0 "" "")
17719 (unspec:BLK [(reg:DI XMM0_REG)
17726 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17727 (clobber (reg:CC FLAGS_REG))
17728 (clobber (match_operand:DI 1 "register_operand" ""))
17729 (use (match_operand:DI 2 "immediate_operand" ""))
17730 (use (label_ref:DI (match_operand 3 "" "")))
17731 (clobber (match_operand:DI 4 "register_operand" ""))
17732 (use (match_dup 1))])]
17736 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
17737 ;; what the size of save instruction will be.
17738 ;; Operand 0+operand 6 is the memory save area
17739 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
17740 ;; Operand 2 is number of non-vaargs SSE arguments
17741 ;; Operand 3 is label starting the save block
17742 ;; Operand 4 is used for temporary computation of jump address
17743 (define_insn "*sse_prologue_save_insn1"
17744 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17745 (match_operand:DI 6 "const_int_operand" "n")))
17746 (unspec:BLK [(reg:DI XMM0_REG)
17753 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17754 (clobber (reg:CC FLAGS_REG))
17755 (clobber (match_operand:DI 1 "register_operand" "=r"))
17756 (use (match_operand:DI 2 "const_int_operand" "i"))
17757 (use (label_ref:DI (match_operand 3 "" "X")))
17758 (clobber (match_operand:DI 4 "register_operand" "=&r"))
17759 (use (match_operand:DI 5 "register_operand" "1"))]
17761 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17762 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
17764 [(set_attr "type" "other")
17765 (set_attr "memory" "store")
17766 (set_attr "mode" "DI")])
17768 ;; We know size of save instruction; expand the computation of jump address
17769 ;; in the jumptable.
17771 [(parallel [(set (match_operand:BLK 0 "" "")
17772 (unspec:BLK [(reg:DI XMM0_REG)
17779 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17780 (clobber (reg:CC FLAGS_REG))
17781 (clobber (match_operand:DI 1 "register_operand" ""))
17782 (use (match_operand:DI 2 "const_int_operand" ""))
17783 (use (match_operand 3 "" ""))
17784 (clobber (match_operand:DI 4 "register_operand" ""))
17785 (use (match_operand:DI 5 "register_operand" ""))])]
17787 [(parallel [(set (match_dup 0)
17788 (unspec:BLK [(reg:DI XMM0_REG)
17795 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17796 (use (match_dup 1))
17797 (use (match_dup 2))
17798 (use (match_dup 3))
17799 (use (match_dup 5))])]
17801 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
17802 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
17804 /* Compute address to jump to:
17805 label - eax*size + nnamed_sse_arguments*size. */
17807 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17810 gen_rtx_MULT (Pmode, operands[1],
17813 else if (size == 4)
17814 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17815 gen_rtx_MULT (Pmode, operands[1],
17818 gcc_unreachable ();
17819 if (INTVAL (operands[2]))
17822 gen_rtx_CONST (DImode,
17823 gen_rtx_PLUS (DImode,
17825 GEN_INT (INTVAL (operands[2])
17828 emit_move_insn (operands[1], operands[3]);
17829 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
17830 operands[5] = GEN_INT (size);
17833 (define_insn "sse_prologue_save_insn"
17834 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17835 (match_operand:DI 4 "const_int_operand" "n")))
17836 (unspec:BLK [(reg:DI XMM0_REG)
17843 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17844 (use (match_operand:DI 1 "register_operand" "r"))
17845 (use (match_operand:DI 2 "const_int_operand" "i"))
17846 (use (label_ref:DI (match_operand 3 "" "X")))
17847 (use (match_operand:DI 5 "const_int_operand" "i"))]
17849 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17850 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
17853 operands[0] = gen_rtx_MEM (Pmode,
17854 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
17855 /* VEX instruction with a REX prefix will #UD. */
17856 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
17857 gcc_unreachable ();
17859 output_asm_insn ("jmp\t%A1", operands);
17860 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
17862 operands[4] = adjust_address (operands[0], DImode, i*16);
17863 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
17864 PUT_MODE (operands[4], TImode);
17865 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
17866 output_asm_insn ("rex", operands);
17867 if (crtl->stack_alignment_needed < 128)
17868 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
17870 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
17872 (*targetm.asm_out.internal_label) (asm_out_file, "L",
17873 CODE_LABEL_NUMBER (operands[3]));
17876 [(set_attr "type" "other")
17877 (set_attr "length_immediate" "0")
17878 (set_attr "length_address" "0")
17879 ;; 2 bytes for jump and opernds[4] bytes for each save.
17880 (set (attr "length")
17881 (plus (const_int 2)
17882 (mult (symbol_ref ("INTVAL (operands[5])"))
17883 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
17884 (set_attr "memory" "store")
17885 (set_attr "modrm" "0")
17886 (set_attr "prefix" "maybe_vex")
17887 (set_attr "mode" "DI")])
17889 (define_expand "prefetch"
17890 [(prefetch (match_operand 0 "address_operand" "")
17891 (match_operand:SI 1 "const_int_operand" "")
17892 (match_operand:SI 2 "const_int_operand" ""))]
17893 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17895 int rw = INTVAL (operands[1]);
17896 int locality = INTVAL (operands[2]);
17898 gcc_assert (rw == 0 || rw == 1);
17899 gcc_assert (locality >= 0 && locality <= 3);
17900 gcc_assert (GET_MODE (operands[0]) == Pmode
17901 || GET_MODE (operands[0]) == VOIDmode);
17903 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17904 supported by SSE counterpart or the SSE prefetch is not available
17905 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17907 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17908 operands[2] = GEN_INT (3);
17910 operands[1] = const0_rtx;
17913 (define_insn "*prefetch_sse_<mode>"
17914 [(prefetch (match_operand:P 0 "address_operand" "p")
17916 (match_operand:SI 1 "const_int_operand" ""))]
17917 "TARGET_PREFETCH_SSE"
17919 static const char * const patterns[4] = {
17920 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17923 int locality = INTVAL (operands[1]);
17924 gcc_assert (locality >= 0 && locality <= 3);
17926 return patterns[locality];
17928 [(set_attr "type" "sse")
17929 (set_attr "atom_sse_attr" "prefetch")
17930 (set (attr "length_address")
17931 (symbol_ref "memory_address_length (operands[0])"))
17932 (set_attr "memory" "none")])
17934 (define_insn "*prefetch_3dnow_<mode>"
17935 [(prefetch (match_operand:P 0 "address_operand" "p")
17936 (match_operand:SI 1 "const_int_operand" "n")
17940 if (INTVAL (operands[1]) == 0)
17941 return "prefetch\t%a0";
17943 return "prefetchw\t%a0";
17945 [(set_attr "type" "mmx")
17946 (set (attr "length_address")
17947 (symbol_ref "memory_address_length (operands[0])"))
17948 (set_attr "memory" "none")])
17950 (define_expand "stack_protect_set"
17951 [(match_operand 0 "memory_operand" "")
17952 (match_operand 1 "memory_operand" "")]
17955 #ifdef TARGET_THREAD_SSP_OFFSET
17957 emit_insn (gen_stack_tls_protect_set_di (operands[0],
17958 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17960 emit_insn (gen_stack_tls_protect_set_si (operands[0],
17961 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17964 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17966 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17971 (define_insn "stack_protect_set_si"
17972 [(set (match_operand:SI 0 "memory_operand" "=m")
17973 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17974 (set (match_scratch:SI 2 "=&r") (const_int 0))
17975 (clobber (reg:CC FLAGS_REG))]
17977 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17978 [(set_attr "type" "multi")])
17980 (define_insn "stack_protect_set_di"
17981 [(set (match_operand:DI 0 "memory_operand" "=m")
17982 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17983 (set (match_scratch:DI 2 "=&r") (const_int 0))
17984 (clobber (reg:CC FLAGS_REG))]
17986 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17987 [(set_attr "type" "multi")])
17989 (define_insn "stack_tls_protect_set_si"
17990 [(set (match_operand:SI 0 "memory_operand" "=m")
17991 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17992 UNSPEC_SP_TLS_SET))
17993 (set (match_scratch:SI 2 "=&r") (const_int 0))
17994 (clobber (reg:CC FLAGS_REG))]
17996 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17997 [(set_attr "type" "multi")])
17999 (define_insn "stack_tls_protect_set_di"
18000 [(set (match_operand:DI 0 "memory_operand" "=m")
18001 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
18002 UNSPEC_SP_TLS_SET))
18003 (set (match_scratch:DI 2 "=&r") (const_int 0))
18004 (clobber (reg:CC FLAGS_REG))]
18007 /* The kernel uses a different segment register for performance reasons; a
18008 system call would not have to trash the userspace segment register,
18009 which would be expensive */
18010 if (ix86_cmodel != CM_KERNEL)
18011 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18013 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18015 [(set_attr "type" "multi")])
18017 (define_expand "stack_protect_test"
18018 [(match_operand 0 "memory_operand" "")
18019 (match_operand 1 "memory_operand" "")
18020 (match_operand 2 "" "")]
18023 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18025 #ifdef TARGET_THREAD_SSP_OFFSET
18027 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18028 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18030 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18031 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18034 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18036 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18039 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18040 flags, const0_rtx, operands[2]));
18044 (define_insn "stack_protect_test_si"
18045 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18046 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18047 (match_operand:SI 2 "memory_operand" "m")]
18049 (clobber (match_scratch:SI 3 "=&r"))]
18051 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18052 [(set_attr "type" "multi")])
18054 (define_insn "stack_protect_test_di"
18055 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18056 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18057 (match_operand:DI 2 "memory_operand" "m")]
18059 (clobber (match_scratch:DI 3 "=&r"))]
18061 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18062 [(set_attr "type" "multi")])
18064 (define_insn "stack_tls_protect_test_si"
18065 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18066 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18067 (match_operand:SI 2 "const_int_operand" "i")]
18068 UNSPEC_SP_TLS_TEST))
18069 (clobber (match_scratch:SI 3 "=r"))]
18071 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18072 [(set_attr "type" "multi")])
18074 (define_insn "stack_tls_protect_test_di"
18075 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18076 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18077 (match_operand:DI 2 "const_int_operand" "i")]
18078 UNSPEC_SP_TLS_TEST))
18079 (clobber (match_scratch:DI 3 "=r"))]
18082 /* The kernel uses a different segment register for performance reasons; a
18083 system call would not have to trash the userspace segment register,
18084 which would be expensive */
18085 if (ix86_cmodel != CM_KERNEL)
18086 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18088 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18090 [(set_attr "type" "multi")])
18092 (define_insn "sse4_2_crc32<mode>"
18093 [(set (match_operand:SI 0 "register_operand" "=r")
18095 [(match_operand:SI 1 "register_operand" "0")
18096 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18098 "TARGET_SSE4_2 || TARGET_CRC32"
18099 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18100 [(set_attr "type" "sselog1")
18101 (set_attr "prefix_rep" "1")
18102 (set_attr "prefix_extra" "1")
18103 (set (attr "prefix_data16")
18104 (if_then_else (match_operand:HI 2 "" "")
18106 (const_string "*")))
18107 (set (attr "prefix_rex")
18108 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18110 (const_string "*")))
18111 (set_attr "mode" "SI")])
18113 (define_insn "sse4_2_crc32di"
18114 [(set (match_operand:DI 0 "register_operand" "=r")
18116 [(match_operand:DI 1 "register_operand" "0")
18117 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18119 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18120 "crc32{q}\t{%2, %0|%0, %2}"
18121 [(set_attr "type" "sselog1")
18122 (set_attr "prefix_rep" "1")
18123 (set_attr "prefix_extra" "1")
18124 (set_attr "mode" "DI")])
18126 (define_expand "rdpmc"
18127 [(match_operand:DI 0 "register_operand" "")
18128 (match_operand:SI 1 "register_operand" "")]
18131 rtx reg = gen_reg_rtx (DImode);
18134 /* Force operand 1 into ECX. */
18135 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18136 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18137 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18142 rtvec vec = rtvec_alloc (2);
18143 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18144 rtx upper = gen_reg_rtx (DImode);
18145 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18146 gen_rtvec (1, const0_rtx),
18148 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18149 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18151 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18152 NULL, 1, OPTAB_DIRECT);
18153 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18157 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18158 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18162 (define_insn "*rdpmc"
18163 [(set (match_operand:DI 0 "register_operand" "=A")
18164 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18168 [(set_attr "type" "other")
18169 (set_attr "length" "2")])
18171 (define_insn "*rdpmc_rex64"
18172 [(set (match_operand:DI 0 "register_operand" "=a")
18173 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18175 (set (match_operand:DI 1 "register_operand" "=d")
18176 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18179 [(set_attr "type" "other")
18180 (set_attr "length" "2")])
18182 (define_expand "rdtsc"
18183 [(set (match_operand:DI 0 "register_operand" "")
18184 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18189 rtvec vec = rtvec_alloc (2);
18190 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18191 rtx upper = gen_reg_rtx (DImode);
18192 rtx lower = gen_reg_rtx (DImode);
18193 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18194 gen_rtvec (1, const0_rtx),
18196 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18197 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18199 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18200 NULL, 1, OPTAB_DIRECT);
18201 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18203 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18208 (define_insn "*rdtsc"
18209 [(set (match_operand:DI 0 "register_operand" "=A")
18210 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18213 [(set_attr "type" "other")
18214 (set_attr "length" "2")])
18216 (define_insn "*rdtsc_rex64"
18217 [(set (match_operand:DI 0 "register_operand" "=a")
18218 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18219 (set (match_operand:DI 1 "register_operand" "=d")
18220 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18223 [(set_attr "type" "other")
18224 (set_attr "length" "2")])
18226 (define_expand "rdtscp"
18227 [(match_operand:DI 0 "register_operand" "")
18228 (match_operand:SI 1 "memory_operand" "")]
18231 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18232 gen_rtvec (1, const0_rtx),
18234 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18235 gen_rtvec (1, const0_rtx),
18237 rtx reg = gen_reg_rtx (DImode);
18238 rtx tmp = gen_reg_rtx (SImode);
18242 rtvec vec = rtvec_alloc (3);
18243 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18244 rtx upper = gen_reg_rtx (DImode);
18245 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18246 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18247 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18249 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18250 NULL, 1, OPTAB_DIRECT);
18251 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18256 rtvec vec = rtvec_alloc (2);
18257 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18258 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18259 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18262 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18263 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18267 (define_insn "*rdtscp"
18268 [(set (match_operand:DI 0 "register_operand" "=A")
18269 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18270 (set (match_operand:SI 1 "register_operand" "=c")
18271 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18274 [(set_attr "type" "other")
18275 (set_attr "length" "3")])
18277 (define_insn "*rdtscp_rex64"
18278 [(set (match_operand:DI 0 "register_operand" "=a")
18279 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18280 (set (match_operand:DI 1 "register_operand" "=d")
18281 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18282 (set (match_operand:SI 2 "register_operand" "=c")
18283 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18286 [(set_attr "type" "other")
18287 (set_attr "length" "3")])
18289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18291 ;; LWP instructions
18293 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18295 (define_expand "lwp_llwpcb"
18296 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18297 UNSPECV_LLWP_INTRINSIC)]
18301 (define_insn "*lwp_llwpcb<mode>1"
18302 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18303 UNSPECV_LLWP_INTRINSIC)]
18306 [(set_attr "type" "lwp")
18307 (set_attr "mode" "<MODE>")
18308 (set_attr "length" "5")])
18310 (define_expand "lwp_slwpcb"
18311 [(set (match_operand 0 "register_operand" "=r")
18312 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18316 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18318 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18322 (define_insn "lwp_slwpcb<mode>"
18323 [(set (match_operand:P 0 "register_operand" "=r")
18324 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18327 [(set_attr "type" "lwp")
18328 (set_attr "mode" "<MODE>")
18329 (set_attr "length" "5")])
18331 (define_expand "lwp_lwpval<mode>3"
18332 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18333 (match_operand:SI 2 "nonimmediate_operand" "rm")
18334 (match_operand:SI 3 "const_int_operand" "i")]
18335 UNSPECV_LWPVAL_INTRINSIC)]
18337 "/* Avoid unused variable warning. */
18340 (define_insn "*lwp_lwpval<mode>3_1"
18341 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18342 (match_operand:SI 1 "nonimmediate_operand" "rm")
18343 (match_operand:SI 2 "const_int_operand" "i")]
18344 UNSPECV_LWPVAL_INTRINSIC)]
18346 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18347 [(set_attr "type" "lwp")
18348 (set_attr "mode" "<MODE>")
18349 (set (attr "length")
18350 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18352 (define_expand "lwp_lwpins<mode>3"
18353 [(set (reg:CCC FLAGS_REG)
18354 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18355 (match_operand:SI 2 "nonimmediate_operand" "rm")
18356 (match_operand:SI 3 "const_int_operand" "i")]
18357 UNSPECV_LWPINS_INTRINSIC))
18358 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18359 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18363 (define_insn "*lwp_lwpins<mode>3_1"
18364 [(set (reg:CCC FLAGS_REG)
18365 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18366 (match_operand:SI 1 "nonimmediate_operand" "rm")
18367 (match_operand:SI 2 "const_int_operand" "i")]
18368 UNSPECV_LWPINS_INTRINSIC))]
18370 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18371 [(set_attr "type" "lwp")
18372 (set_attr "mode" "<MODE>")
18373 (set (attr "length")
18374 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18378 (include "sync.md")